题意整理
题目要求编写一个十六进制计数器,即输出数值number每次变化1,在0-15之间循环。set信号的值为一时,将输出数值num置为set_num。
题解主体
首先明确number的取值逻辑,声明number变量为4位无符号数,数值每个时钟加一,则每次数值达到15,下一个时钟因为位宽的限制,自动变为1,可以实现十六进制计数。当set信号为1时,将set_num的值赋给number。
always @(posedge clk or negedge rst_n)
if (!rst_n)
begin
number<= 4'b0;
end
else if(set)
begin
number<= set_num;
end
else
begin
number<= number+ 1'd1;
end
然后确定zero的取值逻辑,在默认情况下为0,当number=0时,zero值为1。
always @(posedge clk or negedge rst_n)
if (!rst_n)
begin
zero <= 1'd0;
end
else if (number == 4'd0)
begin
zero <= 1'b1;
end
else
begin
zero <= 1'b0;
end
按照以上代码,因为判断number==4’d0需要一个时钟,zero信号为1,总是滞后number==0一个时钟周期。所以可以考虑将number延迟一个时钟再输出。使用num变量代替上述的number,再通过以下语句实现number延迟一个时钟输出。
reg [3:0]num;
always @(posedge clk or negedge rst_n)
if (!rst_n)
begin
number <= 4'd0;
end
else
begin
number <= num;
end
参考答案
`timescale 1ns/1ns module count_module( input clk, input rst_n, input set, input [3:0] set_num, output reg [3:0]number, output reg zero ); reg [3:0]num; always @(posedge clk or negedge rst_n) if (!rst_n) begin zero <= 1'd0; end else if (num == 4'd0) begin zero <= 1'b1; end else begin zero <= 1'b0; end always @(posedge clk or negedge rst_n) if (!rst_n) begin num <= 4'b0; end else if(set) begin num <= set_num; end else begin num <= num + 1'd1; end always @(posedge clk or negedge rst_n) if (!rst_n) begin number <= 1'd0; end else begin number <= num; end endmodule