题目
- 编写一个0 1 2 3 3 2 1 0输出的循环计数器
- 编写一个0 1 2 3 4 5 6 6 5 4 3 2 1 0输出的循环计数器
代码
DUT
//function: count 0 1 2 3 3 2 1 0
module Count(
input wire clk,
input wire rst_n,
output wire [1:0] out
);
reg [2:0] count;
always_ff @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
count <= 0;
end else begin
count <= count + 1'b1 ;
end
end
assign out = count[2] ? ~count[1:0] : count[1:0];
endmodule
//function2: count 0 1 2 3 4 5 6 6 5 4 3 2 1 0
module Count6(
input wire clk,
input wire rst_n,
output wire [2:0] out
);
reg [2:0] count1;
reg [2:0] count2;
reg flag;
always_ff @(posedge clk or negedge rst_n) begin : proc_count1
if(~rst_n) begin
count1 <= 'd0;
end else if (count1 == 'd6)begin
count1 <= 'd0;
end else begin
count1 <= count1 + 1'b1 ;
end
end
always_ff @(posedge clk or negedge rst_n) begin : proc_flag
if(~rst_n) begin
flag <= 0;
end else if (count1=='d6) begin
flag <= ~flag;
end
else
flag <= flag;
end
always_ff @(posedge clk or negedge rst_n) begin : proc_count2
if(~rst_n) begin
count2 <= 'd6;
end else if (count2 == 'd0)begin
count2 <= 'd6;
end else begin
count2 <= count2 - 1'b1;
end
end
assign out = flag ? count2 : count1;
endmodule
TB
module tb_Count();
reg clk, rst_n;
wire [1:0] out;
wire [2:0] out2;
initial begin
clk = 'b0;
rst_n = 'b0;
# 10
rst_n = 'b1;
end
always #5 clk = ~clk;
Count dut1(
clk,
rst_n,
out
);
Count6 dut2(
clk,
rst_n,
out2
);
endmodule
仿真
小结
这是华为的一道手撕代码题,一开始写的时候一直想用一个计数器完成,然后加一个flag进行判断什么时候加什么时候减,但是因为最大值或者最小值重复了一次,flag就很不好判断。反正就是被局限住了,最后想到可以用两个计数器就方便很多。欢迎大家在评论区提出更好的解决方案。