verilogfpgalatticeyosysice40

Understanding the SB_IO primitive in Lattice ICE40


I am playing with cliffordwolf/picorv32 and am having some problem understanding the following snippet in picosoc (link to source):

SB_IO #(
    .PIN_TYPE(6'b 1010_01),
    .PULLUP(1'b 0)
) flash_io_buf [3:0] (
    .PACKAGE_PIN({flash_io3, flash_io2, flash_io1, flash_io0}),
    .OUTPUT_ENABLE({flash_io3_oe, flash_io2_oe, flash_io1_oe, flash_io0_oe}),
    .D_OUT_0({flash_io3_do, flash_io2_do, flash_io1_do, flash_io0_do}),
    .D_IN_0({flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di})
);

I have found a graphic description for the SB_IO primitive in Lattice iCE40 technology library documentation, but I still cannot understand its purpose because it's too complex for me to interpret. There is another question about the primitive, after reading which I would assume it creates some kind of bidirectional connection, but I failed to understand how that is related to making the output pin "tristated".

I would appreciate a high-level description of the effect of the SB_IO cell under this particular configuration. Which pin is connected to which pin? Which are inputs and which are outputs? What is the purpose of instantiating this cell?


Solution

  • This instance was used because at the time Yosys didn't support tristates in Verilog well enough, it does now but in general tristate support in FPGA toolchains isn't always trusted.

    It could be replaced with the following generic Verilog, repeated 4 times from 0 to 4.

    assign flash_io0 = flash_io0_oe ? flash_io0_do : 1'bz;
    assign flash_io0_di = flash_io0;