I did simulate the design, I'm not at that level where a design of this complexity (writing/reading MachXO2 UFM flash via Wishbone - relatively complex, at least for me) would work without simulation with no bugs right away.
I didn't simulate the top level (test) module though...
It mostly worked but there was this gotcha with the register value.
I ended up using just plain Verilog because Lattice LSE is presumably better, gives more clear warnings pointing to concrete lines of code, doesn't give false warnings.
But even with Lattice LSE the below design didn't work without zeroing the led register first in the procedural block:
module ufmtest(clk, led, debug, debug2);
input clk;
output reg led = 0;
output debug, debug2;
parameter ST_IDL = 3'd0;
parameter ST_READING = 3'd1;
parameter ST_WRITING = 3'd2;
parameter ST_FINISHED = 3'd3;
reg [2:0] st = ST_IDL;
reg wr_rq = 0;
reg rd_rq = 0;
reg [7:0] wr_data = 0;
reg [7:0] rd_data;
reg [4:0] matches = 0;
wire wb_clk, wb_rst, wb_cyc, wb_stb, wb_we, wb_ack, ufm_rd_ack, ufm_wr_ack, ufm_done;
wire [7:0] wb_addr;
wire [7:0] wb_dat_i;
wire [7:0] wb_dat_o;
wire [7:0] ufm_rd_data;
ufm1 ufm1(.clk(clk),
.ufm_wr_rq(wr_rq),
.ufm_rd_rq(rd_rq),
.ufm_wr_data(wr_data),
.ufm_wr_ack(ufm_wr_ack),
.ufm_rd_data(ufm_rd_data),
.ufm_rd_ack(ufm_rd_ack),
.ufm_done(ufm_done),
.wb_clk(wb_clk),
.wb_rst(wb_rst),
.wb_cyc(wb_cyc),
.wb_stb(wb_stb),
.wb_we(wb_we),
.wb_addr(wb_addr),
.wb_dat_i(wb_dat_i),
.wb_dat_o(wb_dat_o),
.wb_ack(wb_ack)
);
efbif efbif(.wb_clk_i(wb_clk), .wb_rst_i(wb_rst), .wb_cyc_i(wb_cyc), .wb_stb_i(wb_stb), .wb_we_i(wb_we),
.wb_adr_i(wb_addr), .wb_dat_i(wb_dat_i), .wb_dat_o(wb_dat_o), .wb_ack_o(wb_ack));
assign debug = !wb_rst && wb_cyc && wb_stb && wb_we;
assign debug2 = !wb_rst && wb_cyc && wb_stb && !wb_we;
always @(posedge clk)
begin
case(st)
ST_IDL:
begin
rd_rq <= 1;
led <= 0; // !!this was necessary to get the clk input detected as clock, it apparently inferred that led was always 1 for some reason otherwise
st <= ST_READING;
rd_data <= 8'hA5;
wr_data <= 8'hAA;
end
ST_READING:
begin
rd_rq <= 0;
if(ufm_rd_ack && ufm_rd_data == rd_data)
begin
rd_data <= rd_data + 8'd1;
matches <= matches + 5'd1;
end
if(matches == 5'd16)
begin
led <= 1;
end
if(ufm_done)
begin
wr_rq <= 1;
wr_data <= 8'hA5;
st <= ST_WRITING;
end
end
ST_WRITING:
begin
wr_rq <= 0;
if(ufm_wr_ack)
begin
wr_data <= wr_data + 8'd1;
end
if(ufm_done)
begin
st <= ST_FINISHED;
end
end
endcase
end
endmodule