4

我正在尝试将简单的流程图转换state machineVerilog代码。但我不知何故陷入了以下问题,而且由于我对 Verilog 几乎一无所知,我可能遗漏了一些东西。

状态机检测 的输入流0 and 1,如果 s 的计数1可以除以 3(或者简单地说:如果有 3 次数字 1)。

在此处输入图像描述

module example (
  input clk,
  input rst,
  input input1,
  output output
);

reg state;
reg nextstate;

localparam state2 = 3'd0;
localparam state1 = 3'd1;
localparam state0 = 3'd2;

always @(posedge clk or posedge rst) begin
  if (rst)
    state <= state0;
  else
    state <= nextstate;
end

always @* begin
  case(state)
    state0: begin
      if(input1)
        nextstate = state1;
      end
    state2: begin
      if(input1)
        nextstate = state0;
      end
    state1: begin
      if(input1)
        nextstate = state2;
      end
    default: nextstate = state0;
  endcase
end

always @* begin
  output1 = state0 & input1;
end

endmodule

我不知道:

  • 我必须将输入+输出定义为regwire吗?或者是inputoutput!充足的?

  • 我必须提供向量维度reg state, nextstate吗?如果是,我怎么知道要选择哪个维度?

  • 我可以在最后写这些断言state0 & input1吗?或者我应该使用state = state0 & input1 = ??- 是的,什么?

4

3 回答 3

2

我必须将输入+输出定义为reg或wire吗?或者是输入输出!充足的?

输入总是电线,尽管它并不重要,因为你没有分配给它们。默认情况下,输出是电线,但您也可以声明output reg是否需要寄存器。

我必须为 reg 状态 nextstate 提供向量维度吗?如果是,我怎么知道要选择哪个维度?

是的,您必须声明一个维度,否则当 verilog 默默地将您的所有状态截断为0or时,您的设计将灾难性地失败1。状态的宽度应该与用于定义状态名称的 localparams 的宽度相同,或者更一般地说,宽度应该是log2(number of input states).

我可以像 state0 和 input1 一样在最后写这种断言吗?

我不认为这是你想要的。State0 只是一个常数。如果您想知道状态机是否处于 state0,那么您需要将当前状态与常量 state0 进行比较。此外,您可能不希望在此处使用按位 AND,因此请使用常规的 and &&。应该:

output = (state == state0) && input1;
于 2013-04-10T17:44:58.153 回答
2
always @* begin
  case(state)
    state0: begin
      if(input1)begin
        nextstate = state1;
         output1 = 0;
      end end
       else begin
        nextstate = state0;
         output1 = 1;
      end
    state2: begin
      if(input1)begin
        nextstate = state0;
        output1   = 1 ;
      end end
      begin
        nextstate = state2;
         output1 = 0;
      end
    state1: begin
      if(input1)begin
        nextstate = state2;
        output1   = 0;
      end end
     else begin
        nextstate = state1;
         output1 = 0;
      end
    default: nextstate = state0;
  endcase
end
于 2013-04-10T23:30:15.127 回答
1

虽然为时已晚,但我加入了学习 Verilog 的潮流,并决定对您的询问进行尝试。我编写了设计模块并为它创建了一个测试平台。这符合您的期望。

`timescale 1ns/1ns
`define WIDTH 4
module FSM_Detect_Stream_Top();

    reg in_clk;
    reg in_rst_n;
    reg [`WIDTH-1:0] in_input;

    wire out_ouput;

    FSM Test (.i_clk(in_clk), .i_rst_n(in_rst_n), .i_input(in_input), .o_output(out_output));

    initial
        begin
            in_clk = 1'b0; // clk at t=0
            #1 in_rst_n = 1'b1;
            #2 in_rst_n = 1'b0;
            #5 in_rst_n = 1'b1;
            @ (negedge in_clk)
                in_input = 2'b01;
            @ (posedge in_clk)  
                $display("output:%b ", out_output);
            @ (negedge in_clk)
                in_input = 2'b01;
            @ (posedge in_clk)  
                $display("output:%b ", out_output);
            @ (negedge in_clk)
                in_input = 2'b01;
            @ (posedge in_clk)  
                $display("output:%b ", out_output);
            @ (negedge in_clk)
                in_input = 2'b01;
            @ (posedge in_clk)  
                $display("output:%b ", out_output);
            @ (negedge in_clk)
                in_input = 2'b01;
            @ (posedge in_clk)  
                $display("output:%b ", out_output);
            @ (negedge in_clk)
                in_input = 2'b00;
            @ (posedge in_clk)  
                $display("output:%b ", out_output);
            @ (negedge in_clk)
                in_rst_n = 1'b0;
            @ (posedge in_clk)  
                $display("output:%b ", out_output);
            @ (negedge in_clk)
                in_input = 2'b00; in_rst_n = 1'b1;
            @ (posedge in_clk)  
                $display("output:%b ", out_output);
            $finish;
        end


    // Generating a 20ns width clock pulse with 50% duty cycle
    always
        #10 in_clk = ~in_clk;

endmodule // FSM_Detect_Stream_Top

//*********************************************************************************************
module FSM(input i_clk, input i_rst_n, input [`WIDTH-1:0] i_input, output reg o_output);
//*********************************************************************************************

    parameter S0 = 2'b00;   //FIRST STATE or DEFAULT
    parameter S1 = 2'b01;   //SECOND STATE
    parameter S2 = 2'b10;   //THIRD STATE
    parameter S3 = 2'b11;   //FOURTH STATE

    reg [`WIDTH-3:0] curr_state;
    reg [`WIDTH-3:0] next_state;

    //Sequential Logic for Storing Current State
    always @ (posedge i_clk or negedge i_rst_n) begin
        if(~i_rst_n)
            curr_state <= S0;
        else
            curr_state <= next_state;
        end

    //Combinational Logic for Next State
    always @ (curr_state or i_input)    begin
        case(curr_state)
            S0: begin
                if (i_input == 2'b01)
                    next_state <= S1;
                else
                    next_state <= S0;
            end
            S1: begin
                if (i_input == 2'b01)
                    next_state <= S2;
                else
                    next_state <= S1;
            end
            S2: begin
                if (i_input == 2'b01)
                    next_state <= S3;
                else
                    next_state <= S2;
            end
            S3: begin
                if (i_input == 2'b01)
                    next_state <= S0;
                else
                    next_state <= S3;
            end 
            default: next_state <= S0;
        endcase // curr_state
    end

    // Output Logic
    always @(posedge i_clk) begin
        if (~i_rst_n)
            o_output <= 1'b0;
        else begin
            case(curr_state)    
                S0: begin
                    if (i_input == 2'b01)
                        o_output <= 1'b1;
                    else
                        o_output <= 1'b1;
                    end
                S1: begin
                    if (i_input == 2'b01)
                        o_output <= 1'b1;
                    else
                        o_output <= 1'b0;
                    end
                S2: begin
                    if (i_input == 2'b01)
                        o_output <= 1'b1;
                    else 
                        o_output <= 1'b0;
                    end
                S3: begin
                    if (i_input == 2'b01)
                        o_output <= 1'b1;
                    else 
                        o_output <= 1'b0;
                    end
                default: o_output <= 1'b0;
            endcase
        end
    end 

endmodule
于 2018-03-18T03:35:35.410 回答