我正在尝试在verilog中创建一个有限状态机。系统有4个1-bit
输入 rst
,clk
,A
,B
和一个输出 ,Z
。
如果是,则Z等于1: A在最后两个时钟边沿具有相同的值。
自上一条规则为真以来,或B在每个时钟边沿都为高(1)。
否则z=0
;
我没有工具来模拟我的尝试。所以我想知道这是否是正确的方法,如果我走在正确的轨道上?
module StateMachine( R, A, B, clk, Z);
input R, A, B, clk;
output reg Z;
reg ATemp;
reg state;
always @ (posedge clk or A)
if (A == 1'b1)
/////////////////
begin
if (ATemp == 1'b1) state <= 1'b1;
else ATemp <= A;
end
////////////////
else
////////////
begin
if (ATemp == 1'b0) state <= 1'b1;
else ATemp <= A;
end
always @ (state)
case(state)
1'b0: Z=0;
1'b1: Z=1;
default: Z=0;
endcase
endmodule
答案 0 :(得分:1)
您可以使用以下工具:
GHDL是VHDL语言的开源模拟器(User Guide)
此外,这些是最受欢迎的模拟工具:
更多资源:
还有stackexchange electronics社区和codereview。
另外,请注意C to HDL编译器工具
(..我怀疑很多人可以在3分钟内检查你的代码,我也不想要它们)
答案 1 :(得分:0)
你没有下一个状态逻辑,所以状态永远不会改变,并且没有复位所以状态将从1'bz开始。我建议在编码状态机时从Xilinx guidelines开始。
答案 2 :(得分:0)
你对触发器的定义有点不对劲。你有always @ (posedge clk or A)
。您不应该组合边缘触发器和非边缘触发器。它可能在模拟中起作用,但你不会在合成中得到你想要的东西。
如果您只想在时钟边缘上更改值,请使用always @( posedge clk)
或组合输入,输出会随输入使用always @( A )
或更现代版本always @*
而变化。 @ *将触发任何更改。敏感列表中缺少的项目是合成代码不能与RTL模拟相同的主要原因。
如果你正在构建一个触发器,你应该包括一个重置。 always @ (posedge clk or negedge rst_n)
另请注意,状态永远不会设置为0,因此第一印象是这将锁定到特定的状态/输出。我很难看到代码如何实现被问到的问题。我的解决方案有点像:
module statemachine(
input rst,
input A,
input B,
input clk,
output reg Z
);
reg [1:0] a_last_two;
wire rule_one;
always @ (posedge clk or negedge rst) begin
if (~rst) begin
a_last_two <= 2'b0;
end
else begin
a_last_two <= {a_last_two[0] ,A};
end
end
assign rule_one = (a_last_two[1] == a_last_two[0]);
//rule one could be written as ~^a_last_two (xnor reduction operator)
reg rule_two;
always @ (posedge clk or negedge rst) begin
if (~rst) begin
rule_two <= 1'b0 ;
end
else begin
//rule 2 resets when rule_one is true
if (rule_one) begin
rule_two <= 1'b1 ;
end
else begin
rule_two <= rule_two & B ;
end
end
end
assign Z = rule_one | rule_two ;
endmodule