一、题目
8个Led灯以0.5s的的速率循环闪烁,参数化设计并且调用三八译码器模块完成该设计
二、思路
之前的例程中,要改变counter的次数,需要改好几个地方,改漏了结果就错了,所以接下来使用参数来代替之前例程里的499999。并且调用三八译码器子模块。
三、设计文件
module pipeline_led(clk,reset_n,led
);
input clk;
input reset_n;
output [7:0] led;
reg [24:0] counter;
parameter MCNT = 8'd24999999;//parameter 参数
always@(posedge clk or negedge reset_n)
if(!reset_n)
counter <=0;
else if(counter == MCNT)
counter <=0;
else
counter <=counter +1'b1;
reg [2:0] counter2;//用3种状态控制8个led灯
always@(posedge clk or negedge reset_n)
if(!reset_n)
counter2 <=0;
else if(counter == MCNT)
counter2 <=counter2 +1'b1; //当counter2 ==7 时,自动溢出变成0
//调用其他的子模块
decoder_3_8 decoder_3_8_inst0(
.a(counter2[2]),//是因为decoder_3_8子模块中的位拼接,a是高位,c是最低位
.b(counter2[1]),
.c(counter2[0]),
.out(led)//使用调用模块的功能,对于在该设计文件输出则不需要定义reg型,是因为在子模块中已经对out进行了reg定义,out在此模块中是隐藏的wire。
);
endmodule
四、激励文件
module pipeline_led_tb( );
reg clk;
reg reset_n;
wire [7:0]led;
defparam pipeline_led_inst0.MCNT=2499;//与设计文件中的参数无关 parameter MCNT = 8'd24999999;,这里仿真的值为MCNT=2499; 即能保持源文件不变但是仿真的时间被缩短
pipeline_led pipeline_led_inst0(
.clk(clk),
.reset_n(reset_n),
.led(led)
);
initial clk=1;
always #10 clk=~clk;
initial begin
reset_n=0;
#201;
reset_n=1;
#4000000000;
$stop;
end
endmodule
五、总结
1、采用参数化设计,定义一个MCNT参数,可以将其用在程序的所有位置,只需要对一处就行修改,程序所有对应位置值都能得到修改;
parameter MCNT = 8'd24999;//parameter 参数
让所有的24999都用MCNT来代替,以后只要修改MCNT就行了
2、对于缩短仿真时间,可以不改变设计文件,在testbench中使用defparam;或者用#例化参数MCNT。
defparam pipeline_led_inst0.MCNT=2499;//注意例化的标签名要有唯一性
pipeline_led pipeline_led_inst0(
.clk(clk),
.reset_n(reset_n),
.led(led)
);
pipeline_led
#(
.MCNT(249)
)
pipeline_led_inst0(
.clk(clk),
.reset_n(reset_n),
.led(led)
);
3、defparam和#例化参数也可以用在设计文件引用其他子模块中。
(第一种用途是:激励文件去调用设计文件模块来进行例化时
第二种用途是:设计文件1去调用设计文件2的模块时进行例化)
//对于decoder_3_8模块进行参数化设计
module decoder_3_8(a,b,c,out);
input a;
input b;
input c;
parameter WIDTH = 15;//parameter 参数,该处参数可以任意设计,因为调用的时候,我们可以修改
output [WIDTH:0] out;
reg [WIDTH:0] out;
//在pipeline_led模块中调用decoder_3_8模块,方法一:
defparam decoder_3_8_inst0.WIDTH=7;//注意例化的标签名要有唯一性
decoder_3_8 decoder_3_8_inst0(
.a(counter2[2]),
.b(counter2[1]),
.c(counter2[0]),
.out(led)
);
//在pipeline_led模块中调用decoder_3_8模块,方法二:
// defparam decoder_3_8_inst0.WIDTH=7;//注意例化的标签名要有唯一性
decoder_3_8
#(
.WIDTH(7)
)
decoder_3_8_inst0(
.a(counter2[2]),
.b(counter2[1]),
.c(counter2[0]),
.out(led)
);