Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tried build with latest yosys(0.26)/nextpnr(0.5)- results in a design with 25x the LUTs of an ice40? #9

Open
dirkenstein opened this issue Feb 16, 2023 · 12 comments

Comments

@dirkenstein
Copy link

Ouput was this?
Any idea what's going on here?

Info: Device utilisation:
Info: ICESTORM_LC: 195891/ 7680 2550%
Info: ICESTORM_RAM: 8/ 32 25%
Info: SB_IO: 51/ 256 19%
Info: SB_GB: 8/ 8 100%
Info: ICESTORM_PLL: 2/ 2 100%
Info: SB_WARMBOOT: 0/ 1 0%

Info: Placed 57 cells based on constraints.
ERROR: Unable to place cell 'vexrv_inst.ram[988]_SB_DFFE_Q_7_E_SB_DFFE_E_2_DFFLC', no BELs remaining to implement cell type 'ICESTORM_LC'
0 warnings, 1 error

@dirkenstein
Copy link
Author

It's a problem with yosys not recognizing the ram in vexriscv_wrapper.v as BRAM and trying ro implement it a DFFs.
Still breaks in latest yosys but there is a bug reported in relation to it.

@zeldin
Copy link
Owner

zeldin commented Feb 16, 2023

Yeah, when the number of ICESTORM_LC increases explosively for no apparent reason, that is usually what has happened. 😄

This is what I get with yosys 0.17 and nextpnr 0.3:

Info: Device utilisation:
Info:            ICESTORM_LC:  4546/ 7680    59%
Info:           ICESTORM_RAM:    32/   32   100%
Info:                  SB_IO:    51/  256    19%
Info:                  SB_GB:     8/    8   100%
Info:           ICESTORM_PLL:     2/    2   100%
Info:            SB_WARMBOOT:     0/    1     0%

Info: Placed 57 cells based on constraints.

Note that the ICESTORM_RAM utilisation is expected to be 100%.
Could you please point me towards the yosys bug report you mentioned? Thanks.

@dirkenstein
Copy link
Author

I think it's this:

YosysHQ/yosys#3627

But the fix (-no-rw-check on synth_ice40) doesn't resolve your issue. I've tried it on the HEAD release, too.

@dirkenstein
Copy link
Author

Or possibly this:

YosysHQ/yosys#3370

@dirkenstein
Copy link
Author

Is it actually something todo with this? Yosys being formal about BRAM having a clocked output?

https://www.reddit.com/r/yosys/comments/adlsv4/inferring_a_single_cycle_2w1r_register_file_in/
http://zipcpu.com/formal/2018/07/21/zipcpu-icoboard.html

@zeldin
Copy link
Owner

zeldin commented Feb 16, 2023

Well, the ram array does have a clocked output -- the read data is always assigned to ram_read on a clock edge. So it's already specifically written to support the BRAMs of ICE40.

@dirkenstein
Copy link
Author

dirkenstein commented Feb 16, 2023

It's definitely written to only use registered output, however,here is the wacky thing:

The following code sythesizes correctly:(though i'm not sure it's correct. Verilog hurts my head.)

   wire [$clog2(mem_size*256):0] ram_read_addr;

   always @(posedge clk) begin
     if (prog_mode) begin
        ram_read_addr <= prog_addr >> 1;
     end else if (!rst_out) begin
        if (dBus_cmd_valid && !dBus_cmd_payload_wr && dbus_ram_access)
          ram_read_addr <= dBus_cmd_payload_address[15:2];
        else if (ibus_stalled)
          ram_read_addr <= ibus_stall_pc;
        else if (iBus_cmd_valid)
          ram_read_addr <= iBus_cmd_payload_pc[15:2];
     end
     ram_read <= ram[ram_read_addr];
   end

This doesn't synthesize bram either:


  always @(posedge clk)
     if (prog_mode) begin
        ram_read <= ram[prog_addr >> 1];
     end else if (!rst_out) begin
        if (dBus_cmd_valid && !dBus_cmd_payload_wr && dbus_ram_access)
          ram_read <= ram[dBus_cmd_payload_address[15:2]];
        else if (ibus_stalled)
          ram_read <= ram[ibus_stall_pc];
        else if (iBus_cmd_valid)
          ram_read <= ram[iBus_cmd_payload_pc[15:2]];
        else
          ram_read <= ram[0];
     end else
       ram_read <= ram[0];

looks like it doesn't like conditional output register assignments even if every possble condition is covered.

@zeldin
Copy link
Owner

zeldin commented Feb 17, 2023

That can probably be considered a bug, since it does work in 0.17. I'll see if I can construct a minimal reproduction recipe.

@zeldin
Copy link
Owner

zeldin commented Feb 17, 2023

(BTW, your alternate implementation will not work since it introduces an extra cycle of latency for reads. But it could probably be made to work if the assignments of ram_read_addr are moved to an always @(*) block instead.)

@dirkenstein
Copy link
Author

Hmm - with always @(*) it fails with:

ERROR: timing analysis failed due to presence of combinatorial loops, incomplete specification of timing ports, etc.

@zeldin
Copy link
Owner

zeldin commented Feb 17, 2023

You need to put only the assignments of ram_read_addr in the always @(*), not anything else (like the assignment of ram_read).
Anyway, I have a stand-alone reproduction recipe now, so I'll create a yosys ticket once I minimized it a little more.

@zeldin
Copy link
Owner

zeldin commented Feb 18, 2023

@dirkenstein I took the liberty of tacking on my reproduction recipe to YosysHQ/yosys#3679.
Also, I pushed a workaround so it should be possible to build iceGDROM with yosys 0.26 now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants