2014-09-29 75 views
0

我很熟悉在Verilog中创建计数器,方法是定义状态(计数)和状态之间的转换。具有重复状态的计数器

例如,使得计数0,1 ...... 8,9和计数器回到0

不过,我也不太清楚,如果说伯爵走到像1我将如何实现它, 2,3,3,3,4,0然后回到1.

任何人都可以给我一些想法,我可以如何实现这一点?

回答

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 
+0

复位后代码中的输出序列是0,1,2,3,3,3,4,0,0,1,...这与OP所要求的略有不同。 – Ari 2014-09-29 17:46:39

+0

@ari您的正确,但考虑到这不是一个代码写作服务,我认为这给OP足够的提示如何实现他们想要的。 – Morgan 2014-09-29 20:22:01

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; 
0

有时你可以优化计数器值的映射,考虑从摩根的代码更换“案例”部分到这样的事情:

value < = cnt [2]? (cnt [1]→4:3):cnt;

但它的可读性较差,如此糟糕的主意,直到这部分成倍增加,而你缺乏盖茨。