在Verilog HDL中使用任务(task)
模块源代码
1) module ex7_1(ra,rb,rc,rd,a,b,c,d);
output[7:0] ra,rb,rc,rd;
input[7:0] a,b,c,d;
reg[7:0] ra,rb,rc,rd;
reg[7:0] va,vb,vc,vd;
always @ (a or b or c or d)
begin
{va,vb,vc,vd}={a,b,c,d};
sort2(va,vb);
sort2(vb,vc);
sort2(vc,vd);
sort2(va,vb);
sort2(vb,vc);
sort2(va,vb);
{ra,rb,rc,rd}={va,vb,vc,vd};
end
task sort2;
inout[7:0] x,y;
reg[7:0] tmp;
if(x>y)
begin
tmp=x; //x与y变量的内容互换,要求顺序执行,所以采用阻塞赋值方式。
x=y;
y=tmp;
end
endtask
endmodule
2) module ex7_2(clk,reset,ra,rb,rc,rd,a);
output[7:0] ra,rb,rc,rd;
input[7:0] a;
input clk,reset;
reg[7:0] ra,rb,rc,rd;
reg[7:0] va,vb,vc,vd;
reg[2:0] i;
always @ (posedge clk)
begin
if(!reset)
begin
va=0;vb=0;vc=0;vd=0;i=0;
end
else
begin
if (i<4)
begin
i=i+1;
va=a;
sort2(va,vb);
sort2(vb,vc);
sort2(vc,vd);
sort2(va,vb);
sort2(vb,vc);
sort2(va,vb);
{ra,rb,rc,rd}={va,vb,vc,vd};
end
end
end
task
sort2;
inout[7:0] x,y;
reg[7:0] tmp;
if(x>y)
begin
tmp=x;
x=y;
y=tmp;
end
endtask
endmodule
测试模块源代码
1)`timescale 1ns/100ps
`include "ex7.v"
module testmodule;
reg[7:0] a,b,c,d;
wire[7:0] ra,rb,rc,rd;
initial
begin
a=0;b=0;c=0;d=0;
repeat(4)
begin
#100 a ={8{$random}};
b ={8{$random}};
c ={8{$random}};
d ={8{$random}};
end
#100 $stop;
end
ex7_1 m (.a(a),.b(b),.c(c),.d(d), .ra(ra),.rb(rb),.rc(rc),.rd(rd));
endmodule
2) `timescale 1ns/100ps
`include "ex7_2.v"
module testmodule;
reg reset,clk;
reg[7:0] a,b,c,d;
wire[7:0] ra,rb,rc,rd;
initial
begin
reset=0;
clk=0;
#100 reset=1;
a ={8{$random}};
#100 a ={8{$random}};
#100 a ={8{$random}};
#100 a ={8{$random}};
#100 $stop;
end
always #50 clk=~clk;
ex7_2 m (.clk(clk),.reset(reset),.ra(ra),.rb(rb),.rc(rc),.rd(rd),.a(a));
endmodule
利用有限状态机进行时序逻辑的设计
模块测试代码
module ex8_1(x,z,clk,rst,state);
input x,clk,rst;
output z;
output[3:0] state;
reg[3:0] state;
wire z;
assign z = (state==4)? 1:0;
always @(posedge clk)
if(!rst)
begin
state = 0;
end
else
begin
if (x==0) state=0;
if ((x==1) && (state<4)) state=state+1;
end
endmodule
测试模块代码
`timescale 1ns/1ns
`include "ex8.v"
module testmodule;
reg clk,rst;
reg[23:0] data;
wire[3:0] state;
wire z,x;
assign x=data[23];
always #10 clk = ~clk;
always @(posedge clk)
data={data[22:0],data[23]};
initial
begin
clk=0;
rst=1;
#2 rst=0;
#30 rst=1;
data ='b1110_0111_1110_1001_1110_0110;
#500 $stop;
end
ex8_1 m(x,z,clk,rst,state);
endmodule
利用SRAM设计一个LIFO
测试程序
`define lifo_SIZE 8
`timescale 1ns/1ns
module t;
reg [7:0] in_data;
reg liford,lifowr;
wire[7:0] out_data;
wire nfull, nempty;
reg clk,rst;
wire[7:0] sram_data;
wire[10:0] address;
wire rd,wr;
reg [7:0] data_buf[`lifo_SIZE:0];
integer index;
initial clk=0;
always #25 clk=~clk;
initial
begin
liford=1;
lifowr=1;
rst=1;
#40 rst=0;
#42 rst=1;
if (nempty) $display($time,"Error: lifo be empty, nempty should be low.\n");
index = 0;
repeat(`lifo_SIZE) begin
data_buf[index]=$random;
write_lifo(data_buf[index]);
index = index + 1;
end
if (nfull) $display($time,"Error: lifo full, nfull should be low.\n");
repeat(2) write_lifo($random);
#200
index=0;
read_lifo_compare(data_buf[index]);
if (~nfull) $display($time,"Error: lifo not full, nfull should be high.\n");
repeat(`lifo_SIZE-1) begin
index = index + 1;
read_lifo_compare(data_buf[index]);
end
if (nempty) $display($time,"Error: lifo be empty, nempty should be low.\n");
repeat(2) read_lifo_compare(8'bx);
reset_lifo;
repeat(`lifo_SIZE*2)
begin
data_buf[0] = $random;
write_lifo(data_buf[0]);
read_lifo_compare(data_buf[0]);
end
reset_lifo;
read_lifo_compare(8'bx);
write_lifo(data_buf[0]);
read_lifo_compare(data_buf[0]);
$stop;
end
lifo_interface lifo_interface(
.in_data(in_data),.out_data(out_data),
.liford(liford),.lifowr(lifowr),
.nfull(nfull),.nempty(nempty),
.address(address),.sram_data(sram_data),
.rd(rd),.wr(wr),
.clk(clk),.rst(rst)
);
sram m1( .Address(address),
.Data(sram_data),
.SRG(rd),
.SRE(1'b0),
.SRW(wr));
task write_lifo;
input [7:0] data;
begin
in_data=data;
#50 lifowr=0;
#200 lifowr=1;
#50;
end
endtask
task read_lifo_compare;
input [7:0] data;
begin
#50 liford=0;
#200 liford=1;
if (out_data != data)
$display($time,"Error: Data retrieved (%h) not match the one stored (%h). \n",
out_data, data);
#50;
end
endtask
task reset_lifo;
begin
#40 rst=0;
#40 rst=1;
end
endtask
endmodule
LIFO接口设计
`define SRAM_SIZE 8
`timescale 1ns/1ns
module lifo_interface(
in_data,
out_data,
liford,
lifowr,
nfull,
nempty,
address,
sram_data,
rd,
wr,
clk,
rst);
input liford, lifowr, clk, rst;
input[7:0] in_data;
output[7:0] out_data;
reg[7:0] in_data_buf,
out_data_buf;
output nfull, nempty;
reg nfull, nempty;
output rd, wr;
inout[7:0] sram_data;
output[10:0] address;
reg[10:0] address;
reg[10:0] lifo_wp,
lifo_rp;
reg[10:0] lifo_wp_next,
lifo_rp_next;
reg near_full, near_empty;
reg[3:0] state;
parameter idle = 'b0000,
read_ready = 'b0100,
read = 'b0101,
read_over = 'b0111,
write_ready = 'b1000,
write = 'b1001,
write_over = 'b1011;
always @(posedge clk or negedge rst)
if (~rst)
state <= idle;
else
case(state)
idle:
if (lifowr==0 && nfull)
state<=write_ready;
else if(liford==0 && nempty)
state<=read_ready;
else
state<=idle;
read_ready:
state <= read;
read:
if (liford == 1)
state <= read_over;
else