我一直在玩弄SpinalHDL及其SoC和模块,但遇到了一个普遍的问题--几乎所有使用FSM的代码都无法工作。我把这个问题告诉了Yosys,当它检测到FSM时,它会做一些奇怪的事情。下面是一个简单明了的Verilog (由SpinalHDL生成),它不能按预期工作,除非您将FSM状态寄存器" state“与( fsm_encoding = "none”)属性合并。这样做可以使它工作良好,但这绝对不是一个解决方案,因为您不能修改现有Verilog的调色,我也找不到一种方法让SpinalHDL做到这一点。我已经在SpinalHDL gitter上讨论过这个问题了,那里的人建议在Yosys上提交一个bug报告,我认为情况并非如此,我想我错过了一些选择。
我正在使用github最新的Yosys:
Yosys 0.9+3667 (git sha1 e7f36d01, gcc 7.3.0-27ubuntu1~18.04 -fPIC -Os)不起作用的Verilog:
// Generator : SpinalHDL v1.4.2 git head : 804c7bd7b7feaddcc1d25ecef6c208fd5f776f79
// Component : MyTopLevel
module MyTopLevel (
input io_but0,
input io_but1,
output [1:0] io_leds,
input clk,
input reset
);
reg [31:0] counter;
//(* fsm_encoding = "none" *) reg [1:0] state;
reg [1:0] state;
reg [1:0] leds;
assign io_leds = leds;
always @ (posedge clk) begin
if(reset) begin
counter <= 32'h0;
state <= 2'b00;
leds <= 2'b00;
end else begin
counter <= (counter + 32'h00000001);
if((state == 2'b00))begin
if(((io_but0 == 1'b0) && (io_but1 == 1'b0)))begin
state <= 2'b10;
leds[0] <= 1'b1;
leds[1] <= 1'b1;
end
end else begin
if((state == 2'b01))begin
if(((io_but0 == 1'b1) && (io_but1 == 1'b1)))begin
state <= 2'b00;
leds[0] <= 1'b0;
leds[1] <= 1'b0;
end
end else begin
if(((io_but0 == 1'b0) && (io_but1 == 1'b1)))begin
state <= 2'b01;
leds[0] <= 1'b1;
leds[1] <= 1'b0;
end
if(((io_but0 == 1'b1) && (io_but1 == 1'b0)))begin
state <= 2'b01;
leds[0] <= 1'b0;
leds[1] <= 1'b1;
end
end
end
end
end
endmodule我使用以下命令从Makefile调用Yosys:
yosys -v2 -p "synth_ice40 -top MyTopLevel -json MyTopLevel.json" MyTopLevel.v发布于 2020-11-30 00:22:41
嗯,我已经找到了问题的根源,但找不到一个像样的解决办法。
Yosys确实在没有任何许可的情况下对FSM进行重新编码(使用synth_ice40命令),它将FSM状态寄存器转换为一个热点,在引导过程中初始化为零(FPGA配置),因此我们在开机时进入无效的FSM状态。这里有三种解决方案,在我看来: 1)不依赖于FPGA重置,实现我自己的硬重置,2)在每个FSM状态寄存器前面加上fsm_encoding none属性,3)在Verilog中分配初始状态恢复值--在此之后停止使用它的FSM技巧。不幸的是,这些都对我没有好处。我真的很想依赖于FPGA重置,我不想修改别人的代码(SpinalHDL框架)只是为了取悦你。根据yosys的手册,可以禁用使用fsm -recode选项的FSM编码,但是当您使用synth_命令时,它不起作用--它似乎是一个硬编码脚本,它覆盖命令行上给它的任何内容。这能被认为是你的错误吗?我也这么想!
https://stackoverflow.com/questions/65061562
复制相似问题