我非常熟悉通过定义状态(计数)和状态之间的转换来在Verilog中创建计数器。
例如,制作一个计数为0,1 ...,9并返回0的计数器。
但是,我不太确定如果将计数变为1,2,3,3,3,4,0然后又回到1,我将如何实施它。
有人能就我如何实现这个问题向我提出一些想法吗?
答案 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
答案 1 :(得分:0)
如果您有计数器,可以重复使用。建议使用已经测试过的通用模块。
我假设你的计数器有以下界面:
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;
答案 2 :(得分:0)
有时你可以优化计数器到值的映射,考虑将摩根代码中的替换“case”部分改为:
值&lt; = cnt [2]? (cnt [1]?4:3):cnt;
但是它的可读性不那么差,直到这部分成倍增加并且你缺乏门。