我很熟悉在Verilog中创建计数器,方法是定义状态(计数)和状态之间的转换。具有重复状态的计数器
例如,使得计数0,1 ...... 8,9和计数器回到0
不过,我也不太清楚,如果说伯爵走到像1我将如何实现它, 2,3,3,3,4,0然后回到1.
任何人都可以给我一些想法,我可以如何实现这一点?
我很熟悉在Verilog中创建计数器,方法是定义状态(计数)和状态之间的转换。具有重复状态的计数器
例如,使得计数0,1 ...... 8,9和计数器回到0
不过,我也不太清楚,如果说伯爵走到像1我将如何实现它, 2,3,3,3,4,0然后回到1.
任何人都可以给我一些想法,我可以如何实现这一点?
在你的计数器例子中,你有一个FSM(有限状态机),其输出是状态。解决您的问题的一种方法是将此视为FSM,但这不是真的,并且您在状态和输出之间添加了解码。
logic [2:0] state;
logic [2:0] value;
always @(posedge clk, negedge rst_n) begin
if (~rst_n) begin
state <= 'b0;
end
else begin
if (state >= 3'd6) begin
//reset state when get to max as non-power of 2 states
state <= 'b0;
end
else begin
state <= state +1;
end
end
always @* begin
case (state)
3'd0 : value ='d1;
3'd1 : value ='d2;
3'd2 : value ='d3;
3'd3 : value ='d3;
3'd4 : value ='d3;
3'd5 : value ='d4;
3'd6 : value ='d0;
default: value ='d0;
endcase
end
如果你有一个计数器,你可以重用它。建议使用已经测试过的通用模块。
我会假设你的计数器有以下接口:
counter (
input rst,
input clk,
ouput [2:0] count
);
使用这个计数器,你可以得到你想要的值:
module your_module (
input rst,
input clk,
ouptut [2:0] value
);
wire [2:0] count;
counter counter (// creating a counter from 0 to 6
.rst (rst)
.clk (clk)
.count (count)
);
always (*) begin // converting 0,1,2,3,4,5,6 into 1,2,3,3,3,4,0
case (count)
3'd0 : value = 3'd1;
3'd1 : value = 3'd2;
3'd2 : value = 3'd3;
3'd3 : value = 3'd3;
3'd4 : value = 3'd3;
3'd5 : value = 3'd4;
3'd6 : value = 3'd0;
default : value = 3'bxxx; // just to make sure no other state
endcase
end
endmodule;
有时你可以优化计数器值的映射,考虑从摩根的代码更换“案例”部分到这样的事情:
value < = cnt [2]? (cnt [1]→4:3):cnt;
但它的可读性较差,如此糟糕的主意,直到这部分成倍增加,而你缺乏盖茨。
复位后代码中的输出序列是0,1,2,3,3,3,4,0,0,1,...这与OP所要求的略有不同。 – Ari 2014-09-29 17:46:39
@ari您的正确,但考虑到这不是一个代码写作服务,我认为这给OP足够的提示如何实现他们想要的。 – Morgan 2014-09-29 20:22:01