lnis-uofu / OpenFPGA

An Open-source FPGA IP Generator
https://openfpga.readthedocs.io/en/master/
MIT License
816 stars 160 forks source link

How to deal with the $false signal in OpenFPGA? #1501

Closed narutozxp closed 4 months ago

narutozxp commented 8 months ago

There is a bug that puzzles me a lot, and OpenFPGA does not raise any error while the bitstream seems not correct. I have a name.blif file, and its contents are as follows.

# Generated by Yosys 0.34+9 (git sha1 a79b15e94, gcc 11.4.0-1ubuntu1~22.04 -fPIC -Os)

.model only_ahb_8bit
.inputs clk rst_n
.outputs
.names $false
.names $true
1
.names $undef
.subckt ahb_slave_interface haddr_o[31]=haddr[0] haddr_o[30]=haddr[1] haddr_o[29]=haddr[2] haddr_o[28]=haddr[3] haddr_o[27]=haddr[4] haddr_o[26]=haddr[5] haddr_o[25]=haddr[6] haddr_o[24]=haddr[7] haddr_o[23]=haddr[8] haddr_o[22]=haddr[9] haddr_o[21]=haddr[10] haddr_o[20]=haddr[11] haddr_o[19]=haddr[12] haddr_o[18]=haddr[13] haddr_o[17]=haddr[14] haddr_o[16]=haddr[15] haddr_o[15]=haddr[16] haddr_o[14]=haddr[17] haddr_o[13]=haddr[18] haddr_o[12]=haddr[19] haddr_o[11]=haddr[20] haddr_o[10]=haddr[21] haddr_o[9]=haddr[22] haddr_o[8]=haddr[23] haddr_o[7]=haddr[24] haddr_o[6]=haddr[25] haddr_o[5]=haddr[26] haddr_o[4]=haddr[27] haddr_o[3]=haddr[28] haddr_o[2]=haddr[29] haddr_o[1]=haddr[30] haddr_o[0]=haddr[31] hclk_i=clk hrdata_i[31]=ram_data_o[0] hrdata_i[30]=ram_data_o[1] hrdata_i[29]=ram_data_o[2] hrdata_i[28]=ram_data_o[3] hrdata_i[27]=ram_data_o[4] hrdata_i[26]=ram_data_o[5] hrdata_i[25]=ram_data_o[6] hrdata_i[24]=ram_data_o[7] hrdata_i[23]=$false hrdata_i[22]=$false hrdata_i[21]=$false hrdata_i[20]=$false hrdata_i[19]=$false hrdata_i[18]=$false hrdata_i[17]=$false hrdata_i[16]=$false hrdata_i[15]=$false hrdata_i[14]=$false hrdata_i[13]=$false hrdata_i[12]=$false hrdata_i[11]=$false hrdata_i[10]=$false hrdata_i[9]=$false hrdata_i[8]=$false hrdata_i[7]=$false hrdata_i[6]=$false hrdata_i[5]=$false hrdata_i[4]=$false hrdata_i[3]=$false hrdata_i[2]=$false hrdata_i[1]=$false hrdata_i[0]=$false hready_i=$true hready_o=hready hresetn_i=rst_n hresp_i=$true hsel_o=hsel hwdata_o[31]=data_o[0] hwdata_o[30]=data_o[1] hwdata_o[29]=data_o[2] hwdata_o[28]=data_o[3] hwdata_o[27]=data_o[4] hwdata_o[26]=data_o[5] hwdata_o[25]=data_o[6] hwdata_o[24]=data_o[7] hwdata_o[23]=data_o[8] hwdata_o[22]=data_o[9] hwdata_o[21]=data_o[10] hwdata_o[20]=data_o[11] hwdata_o[19]=data_o[12] hwdata_o[18]=data_o[13] hwdata_o[17]=data_o[14] hwdata_o[16]=data_o[15] hwdata_o[15]=data_o[16] hwdata_o[14]=data_o[17] hwdata_o[13]=data_o[18] hwdata_o[12]=data_o[19] hwdata_o[11]=data_o[20] hwdata_o[10]=data_o[21] hwdata_o[9]=data_o[22] hwdata_o[8]=data_o[23] hwdata_o[7]=data_o[24] hwdata_o[6]=data_o[25] hwdata_o[5]=data_o[26] hwdata_o[4]=data_o[27] hwdata_o[3]=data_o[28] hwdata_o[2]=data_o[29] hwdata_o[1]=data_o[30] hwdata_o[0]=data_o[31] hwrite_o=hwrite
.subckt dpram_1024x8 clk=clk data_in[7]=data_o[0] data_in[6]=data_o[1] data_in[5]=data_o[2] data_in[4]=data_o[3] data_in[3]=data_o[4] data_in[2]=data_o[5] data_in[1]=data_o[6] data_in[0]=data_o[7] data_out[7]=ram_data_o[0] data_out[6]=ram_data_o[1] data_out[5]=ram_data_o[2] data_out[4]=ram_data_o[3] data_out[3]=ram_data_o[4] data_out[2]=ram_data_o[5] data_out[1]=ram_data_o[6] data_out[0]=ram_data_o[7] raddr[9]=$false raddr[8]=$false raddr[7]=$false raddr[6]=$false raddr[5]=$false raddr[4]=$false raddr[3]=$false raddr[2]=$false raddr[1]=$false raddr[0]=$false ren=$true waddr[9]=haddr[0] waddr[8]=haddr[1] waddr[7]=haddr[2] waddr[6]=haddr[3] waddr[5]=haddr[4] waddr[4]=haddr[5] waddr[3]=haddr[6] waddr[2]=haddr[7] waddr[1]=$false waddr[0]=$false wen=hwrite
.end

the $false should represent constant 1. However, the sim shows that the values of all the pins connected with $false are 0. `)7MS IB5S~OUF{@(6(66$X I have no idea about the reason for such a bug. I guess that the following code makes MUX provide the constant 1, and the constant 1 is used as zero by OpenFPGA.

    <circuit_model type="mux" name="mux_tree" prefix="mux_tree_prefix" is_default="true" dump_structural_verilog="false">
      <design_technology type="cmos" structure="tree" add_const_input="true" const_input_val="1"/>
      <input_buffer exist="false"/>
      <output_buffer exist="false"/>
      <pass_gate_logic circuit_model_name="MUX2"/>
      <port type="input" prefix="in" size="1"/>
      <port type="output" prefix="out" size="1"/>
      <port type="sram" prefix="sram" size="1"/>
    </circuit_model>
mustafaarslan0 commented 8 months ago

@narutozxp Output of MUX (which has constant 1) is zero because constant values do not pass through input buffer but output buffer. So constant 1 will be inverted and output will be zero.

But I think, VPR will be generate a LUT for that $false and use it. I know that MUX constant inputs are not used in benchmarks because VPR do not know there is a constant 0 or 1.

narutozxp commented 8 months ago

@mustafaarslan0 However, our muxes have no input buffer or output buffer. Besides, According to my experiment, if there is an output pin that drivers more than one input pin, these input pins will be set to the constant of MUX.

narutozxp commented 8 months ago

@tangxifan It would be very helpful if you could provid me some suggustions.

tangxifan commented 4 months ago

@narutozxp For the constant signals applied to your heterogeneous blocks, where 0 or 1 matters, please enable the option --constant_net_method route when calling vpr.

Take the following example:

https://github.com/lnis-uofu/OpenFPGA/blob/fddb700d7b55a616c643db7fc99e281fc56cc7d8/openfpga_flow/openfpga_shell_scripts/fix_heterogeneous_device_example_script.openfpga#L3