我正在尝试将简单state machine
的流程图转换为Verilog
代码。
但我不知何故坚持以下,因为我对Verilog几乎没有任何了解,我可能会遗漏一些东西。
如果0 and 1
的计数可以除以3(或简单地说:如果已经有3次数为1),则状态机会检测到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
我不确定:
我是否必须将输入+输出定义为reg
或wire
?或者是input
和output
!足够?
我必须为reg state, nextstate
提供向量维度吗?如果是,我如何知道要选择哪个尺寸?
我可以像state0 & input1
一样在最后写这些断言吗?或者我应该使用state = state0 & input1 = ??
- 是的,什么?
答案 0 :(得分:2)
我必须将输入+输出定义为reg或wire吗?或输入输出!足够?
输入始终是连线,但由于您没有分配它们并不重要。默认情况下,输出是连线,但如果您想要一个寄存器,也可以声明output reg
。
我必须为reg状态提供向量维度吗,nextstate?如果是,我该如何知道要选择哪个尺寸?
是的,你必须声明一个维度,否则当verilog默默地将你的所有状态截断为0
或1
时,你的设计将会灾难性地失败。状态的宽度应与用于定义状态名称的localparams的宽度相同,或者更一般地,宽度应为log2(number of input states)
。
我可以在最后写出这种断言,如state0&amp;输入1?
我认为这不是你想要的。 State0只是一个常数。如果您想知道状态机是否处于state0 ,那么您需要将当前状态与常量state0进行比较。此外,您可能不希望在此处使用按位AND,因此请使用常规和&&
。应该是:
output = (state == state0) && input1;
答案 1 :(得分: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
答案 2 :(得分: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