反复的状态反击

时间:2014-09-29 05:40:52

标签: counter verilog

我非常熟悉通过定义状态(计数)和状态之间的转换来在Verilog中创建计数器。

例如,制作一个计数为0,1 ...,9并返回0的计数器。

但是,我不太确定如果将计数变为1,2,3,3,3,4,0然后又回到1,我将如何实施它。

有人能就我如何实现这个问题向我提出一些想法吗?

3 个答案:

答案 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;

但是它的可读性不那么差,直到这部分成倍增加并且你缺乏门。