画图
写代码
module counter
#(
//参数的设置,类似于C语言的形参和python中的建议参数
parameter CNT_MAX = 25'd24_999_999 //这里是最后一个,是不需要逗号的
)
(
input wire sys_clk,
input wire sys_rst_n,
output reg led_out //在always语句里面被赋值过,用reg
);
reg [24:0] cnt;
always @(posedge sys_clk or negedge sys_rst_n)
begin //begin和end相当于c语言里面的{}但是这里可以不写
if (sys_rst_n == 1'b0)
begin
cnt <= 25'd0;
end
else if (cnt == CNT_MAX)
begin
cnt <= 25'd0;
end
else
cnt = cnt + 25'd1; //cnt + = 25'd1;这个赋值方式是要报错的
end
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
led_out <= 1'b0;
else if(cnt == CNT_MAX)
led_out <= ~led_out;
else
led_out <= led_out;//最后一个需要else避免latch的产生
endmodule
写仿真代码
`timescale 1ns/1ns
module tb_counter();
reg sys_clk ;
reg sys_rst_n;
wire led_out ;
initial
begin
sys_clk = 1'b0;
sys_rst_n <= 1'b0;
#2
sys_rst_n <= 1'b1;
end
always #1 sys_clk = ~sys_clk;
counter
#(
//参数的设置,类似于C语言的形参和python中的建议参数
.CNT_MAX (25'd24) //这里是最后一个,是不需要逗号的
)
counter_inst
(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.led_out (led_out) //在always语句里面被赋值过,用reg
);
endmodule
仿真结果
这个明显就是不符合实验预期的仿真结果,那么问题在哪儿呢 ?
问题在于之前的阻塞赋值和非阻塞赋值,在于我打代码少打了一个<,但是令我不解的是为什么少了就会那样,结果不应该影响的是赋值和计数吗,为什么相反是led——out受到了影响,目前准备下周问一下老师,先插个眼
生成的rtl也是一样的,但是经过实物并用示波器显示波形显示输出的数据表明两种输入方式并没有什么不一样,都是50%的占空比,频率也是一样的
经过查阅资料还是总结一下阻塞赋值和非阻塞赋值需要注意的问题
(4)使用方法
在描述组合逻辑的always块中用阻塞赋值=,综合成组合逻辑的电路结构;
这种电路结构只与输入电平的变化有关系。
在描述时序逻辑的always块中用非阻塞赋值<=,综合成时序逻辑的电路结构;
这种电路结构往往与触发沿有关系,只有在触发沿时才可能发生赋值的变化。
注意:在同一个always块中不要即用非阻塞赋值又用阻塞赋值
不允许在多个always块中对同一个变量进行赋值!
后面老师也讲到脉冲标志信号,我没有继续写,只需要知道脉冲标志信号更加的高级,更加便于人工查看,就像相当于你只需要标志,而不需要再去理解代码本身,而且也更加节省fpga的内部资源,你想想,一个比较器是一位的资源占用更少还是很多位占用更少,而且需要当位数特别多的时候需要判断的位次数也就多起来了,然后后面还会讲到使能信号