I have been toying with SpinalHDL and its SoCs and modules, but came to a general problem - almost none of the code that uses FSMs works. I nailed this issue down to Yosys, which does something weird when it detects a FSM. Here below is a simple and straightforward Verilog (generated by SpinalHDL) that does NOT work as expected unless you pepend FSM state register "state" with ( fsm_encoding = "none" ) attribute. Doing so makes it working well, but that is definitely not a solution because you cannot modify tonns of existing Verilog, neither I could find a way to make SpinalHDL do this. I discussed this issue on SpinalHDL gitter already, the guys there advised to file a bug report on Yosys which I think is not the case, I think I'm missing some option.
I'm using the latest Yosys from github:
Yosys 0.9+3667 (git sha1 e7f36d01, gcc 7.3.0-27ubuntu1~18.04 -fPIC -Os)
Verilog that does not work:
// 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
I'm using the following command to invoke Yosys from my Makefile:
yosys -v2 -p "synth_ice40 -top MyTopLevel -json MyTopLevel.json" MyTopLevel.v