debugged rram mux branch Verilog generation

This commit is contained in:
tangxifan 2019-09-02 16:21:29 -06:00
parent 4490c78195
commit d2d750a15c
2 changed files with 556 additions and 16 deletions

View File

@ -0,0 +1,524 @@
<architecture>
<models>
<model name="io">
<input_ports>
<port name="outpad"/>
</input_ports>
<output_ports>
<port name="inpad"/>
</output_ports>
</model>
</models>
<!-- ODIN II specific config ends -->
<!-- Physical descriptions begin -->
<layout auto="1.0"/>
<!-- <layout width="20" height="20"/> -->
<!--mrFPGA_settings-->
<!-- below is the timing parameters for a single memristor device (or so called RRAM) -->
<!--mrFPGA R="1e3" C="2.24e-17" Tdel="0"-->
<!-- below is the timing parameters for the buffers to insert in channels -->
<!--buffer R="193.5" Cin="3.66e-15" Cout="3.56e-15" Tdel="6.14e-12"/-->
<!--cblock R_opin_cblock="193.5" T_opin_cblock="6.14e-12"/-->
<!--/mrFPGA-->
<!--/mrFPGA_settings-->
<spice_settings>
<parameters>
<options sim_temp="25" post="off" captab="off" fast="on"/>
<monte_carlo mc_sim="off" num_mc_points="3" cmos_variation="off" rram_variation="on">
<cmos abs_variation="0.1" num_sigma="1"/>
<rram abs_variation="0.1" num_sigma="1"/>
</monte_carlo>
<measure sim_num_clock_cycle="auto" accuracy="1e-12" accuracy_type="abs">
<slew>
<rise upper_thres_pct="0.95" lower_thres_pct="0.05"/>
<fall upper_thres_pct="0.05" lower_thres_pct="0.95"/>
</slew>
<delay>
<rise input_thres_pct="0.5" output_thres_pct="0.5"/>
<fall input_thres_pct="0.5" output_thres_pct="0.5"/>
</delay>
</measure>
<stimulate>
<clock op_freq="auto" sim_slack="0.2" prog_freq="2.5e6">
<rise slew_time="20e-12" slew_type="abs"/>
<fall slew_time="20e-12" slew_type="abs"/>
</clock>
<input>
<rise slew_time="25e-12" slew_type="abs"/>
<fall slew_time="25e-12" slew_type="abs"/>
</input>
</stimulate>
</parameters>
<tech_lib lib_type="industry" transistor_type="TT" lib_path="/research/ece/lnis/CAD_TOOLS/DKITS/wibond_R90_1P4M_v1.3/models/hspice/r90es_logic_v1d3.l" nominal_vdd="1.2" io_vdd="2.5"/>
<transistors pn_ratio="2" model_ref="M">
<nmos model_name="nch" chan_length="100e-9" min_width="120e-9"/>
<pmos model_name="pch" chan_length="100e-9" min_width="120e-9"/>
<io_nmos model_name="nch_25" chan_length="100e-9" min_width="120e-9"/>
<io_pmos model_name="pch_25" chan_length="100e-9" min_width="120e-9"/>
</transistors>
<module_circuit_models>
<circuit_model type="inv_buf" name="INVTX1" prefix="INVTX1" dump_explicit_port_map="true" is_default="0">
<design_technology type="cmos" topology="inverter" size="3" tapered="off" power_gated="true"/>
<port type="input" prefix="in" size="1" lib_name="I"/>
<port type="input" prefix="EN" size="1" lib_name="EN" is_global="true" default_val="0" is_config_enable="true"/>
<port type="input" prefix="ENB" size="1" lib_name="ENB" is_global="true" default_val="1" is_config_enable="true"/>
<port type="output" prefix="out" size="1" lib_name="Z"/>
</circuit_model>
<circuit_model type="inv_buf" name="INVD4BWP" prefix="INVD4BWP" dump_explicit_port_map="true" is_default="0">
<design_technology type="cmos" topology="buffer" size="1" tapered="on" tap_drive_level="2" f_per_stage="4"/>
<port type="input" prefix="in" lib_name="I" size="1"/>
<port type="output" prefix="out" lib_name="ZN" size="1"/>
</circuit_model>
<circuit_model type="inv_buf" name="INVD1BWP" prefix="INVD1BWP" dump_explicit_port_map="true" is_default="0">
<design_technology type="cmos" topology="buffer" size="1" tapered="on" tap_drive_level="2" f_per_stage="4"/>
<port type="input" prefix="in" lib_name="I" size="1"/>
<port type="output" prefix="out" lib_name="ZN" size="1"/>
</circuit_model>
<circuit_model type="inv_buf" name="INVD2BWP" prefix="INVD2BWP" dump_explicit_port_map="true" is_default="0">
<design_technology type="cmos" topology="buffer" size="1" tapered="on" tap_drive_level="2" f_per_stage="4"/>
<port type="input" prefix="in" lib_name="I" size="1"/>
<port type="output" prefix="out" lib_name="ZN" size="1"/>
</circuit_model>
<circuit_model type="inv_buf" name="INVD3BWP" prefix="INVD3BWP" dump_explicit_port_map="true" is_default="0">
<design_technology type="cmos" topology="buffer" size="1" tapered="on" tap_drive_level="2" f_per_stage="4"/>
<port type="input" prefix="in" lib_name="I" size="1"/>
<port type="output" prefix="out" lib_name="ZN" size="1"/>
</circuit_model>
<circuit_model type="inv_buf" name="BUFFD2BWP" prefix="BUFFD2BWP" dump_explicit_port_map="true" is_default="0">
<design_technology type="cmos" topology="buffer" size="1" tapered="on" tap_drive_level="2" f_per_stage="4"/>
<port type="input" prefix="in" lib_name="I" size="1"/>
<port type="output" prefix="out" lib_name="Z" size="1"/>
</circuit_model>
<circuit_model type="inv_buf" name="BUFFD3BWP" prefix="BUFFD3BWP" dump_explicit_port_map="true" is_default="0">
<design_technology type="cmos" topology="buffer" size="1" tapered="on" tap_drive_level="2" f_per_stage="4"/>
<port type="input" prefix="in" lib_name="I" size="1"/>
<port type="output" prefix="out" lib_name="Z" size="1"/>
</circuit_model>
<circuit_model type="inv_buf" name="BUFFD1BWP" prefix="BUFFD1BWP" dump_explicit_port_map="true" is_default="0">
<design_technology type="cmos" topology="buffer" size="1" tapered="on" tap_drive_level="2" f_per_stage="4"/>
<port type="input" prefix="in" lib_name="I" size="1"/>
<port type="output" prefix="out" lib_name="Z" size="1"/>
</circuit_model>
<circuit_model type="inv_buf" name="buf4" prefix="buf4" is_default="0">
<design_technology type="cmos" topology="buffer" size="3" tapered="on" tap_drive_level="2" f_per_stage="4"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
</circuit_model>
<circuit_model type="inv_buf" name="tap_buf4" prefix="tap_buf4" is_default="0">
<design_technology type="cmos" topology="buffer" size="3" tapered="on" tap_drive_level="3" f_per_stage="4"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
</circuit_model>
<circuit_model type="pass_gate" name="TGATE" prefix="TGATE" is_default="1">
<design_technology type="cmos" topology="transmission_gate" nmos_size="1" pmos_size="2"/>
<input_buffer exist="off"/>
<output_buffer exist="off"/>
<port type="input" prefix="in" size="1"/>
<port type="input" prefix="sel" size="1"/>
<port type="input" prefix="selb" size="1"/>
<port type="output" prefix="out" size="1"/>
</circuit_model>
<circuit_model type="chan_wire" name="chan_segment" prefix="track_seg" is_default="1">
<design_technology type="cmos"/>
<input_buffer exist="off"/>
<output_buffer exist="off"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<wire_param model_type="pie" res_val="0" cap_val="0" level="1"/>
<!-- model_type could be T, res_val and cap_val DON'T CARE -->
</circuit_model>
<circuit_model type="wire" name="direct_interc" prefix="direct_interc" is_default="1">
<design_technology type="cmos"/>
<input_buffer exist="off"/>
<output_buffer exist="off"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<wire_param model_type="pie" res_val="0" cap_val="0" level="1"/>
<!-- model_type could be T, res_val cap_val should be defined -->
</circuit_model>
<circuit_model type="mux" name="mux_1level" prefix="mux_1level" is_default="1" dump_structural_verilog="false">
<!-- <design_technology type="cmos" structure="one-level"/?]> -->
<design_technology type="rram" ron="2e3" roff="30e6" wprog_set_nmos="1.5" wprog_reset_nmos="1.6" wprog_set_pmos="3" wprog_reset_pmos="3.2" structure="one-level" advanced_rram_design="true"/>
<input_buffer exist="on" circuit_model_name="INVTX1"/>
<output_buffer exist="on" circuit_model_name="INVD1BWP"/>
<!--mux2to1 subckt_name="mux2to1"/-->
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="1"/>
<port type="input" prefix="EN" size="1" is_global="true" default_val="0" is_config_enable="true"/>
<port type="input" prefix="ENB" size="1" is_global="true" default_val="1" is_config_enable="true"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="1" circuit_model_name="sram6T_rram"/>
</circuit_model>
<circuit_model type="mux" name="mux_1level_tapbuf4" prefix="mux_1level_tapbuf4" is_default="0" dump_structural_verilog="false">
<!-- <design_technology type="cmos" structure="one-level"/?]> -->
<design_technology type="rram" ron="2e3" roff="30e6" wprog_set_nmos="1.5" wprog_reset_nmos="1.6" wprog_set_pmos="3" wprog_reset_pmos="3.2" structure="one-level" advanced_rram_design="true"/>
<input_buffer exist="on" circuit_model_name="INVTX1"/>
<output_buffer exist="on" circuit_model_name="tap_buf4"/>
<!--mux2to1 subckt_name="mux2to1"/-->
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="1"/>
<port type="input" prefix="EN" size="1" is_global="true" default_val="0" is_config_enable="true"/>
<port type="input" prefix="ENB" size="1" is_global="true" default_val="1" is_config_enable="true"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="1" circuit_model_name="sram6T_rram"/>
</circuit_model>
<!--DFF subckt ports should be defined as <D> <Q> <CLK> <RESET> <SET> -->
<circuit_model type="ff" name="static_dff" prefix="dff" spice_netlist="${OPENFPGA_PATH}/vpr7_x2p/vpr/SpiceNetlists/ff.sp" verilog_netlist="${OPENFPGA_PATH}/vpr7_x2p/vpr/VerilogNetlists/ff.v">
<design_technology type="cmos"/>
<input_buffer exist="on" circuit_model_name="INVD1BWP"/>
<output_buffer exist="on" circuit_model_name="INVD1BWP"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="D" size="1"/>
<port type="input" prefix="Set" size="1" is_global="true" default_val="0" is_set="true"/>
<port type="input" prefix="Reset" size="1" is_global="true" default_val="0" is_reset="true"/>
<port type="output" prefix="Q" size="1"/>
<port type="clock" prefix="clk" size="1" is_global="true" default_val="0" />
</circuit_model>
<circuit_model type="lut" name="lut6" prefix="lut6" dump_structural_verilog="true">
<design_technology type="cmos"/>
<input_buffer exist="on" circuit_model_name="INVD1BWP"/>
<output_buffer exist="on" circuit_model_name="INVD1BWP"/>
<lut_input_buffer exist="on" circuit_model_name="BUFFD3BWP"/>
<!-- <lut_intermediate_buffer exist="on" circuit_model_name="BUFFD1BWP" location_map="-1-1-"/> -->
<lut_input_inverter exist="on" circuit_model_name="INVD3BWP"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="6"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="64" circuit_model_name="sram6T_rram" default_val="1"/>
</circuit_model>
<circuit_model type="sram" name="sram6T" prefix="sram" spice_netlist="/research/ece/lnis/USERS/alacchi/Ganesh/OpenFPGA/vpr7_x2p/vpr/SpiceNetlists/sram.sp" verilog_netlist="${OPENFPGA_PATH}/vpr7_x2p/vpr/VerilogNetlists/sram.v">
<design_technology type="cmos"/>
<input_buffer exist="on" circuit_model_name="INVD1BWP"/>
<output_buffer exist="on" circuit_model_name="INVD1BWP"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="2"/>
</circuit_model>
<circuit_model type="sram" name="sram6T_rram" prefix="nvsram" spice_netlist="/research/ece/lnis/USERS/alacchi/Ganesh/OpenFPGA/vpr7_x2p/vpr/SpiceNetlists/sram.sp" verilog_netlist="${OPENFPGA_PATH}/vpr7_x2p/vpr/VerilogNetlists/sram.v">
<!--design_technology type="cmos"/-->
<design_technology type="rram" ron="3e3" roff="1e6" wprog_set_nmos="1.5" wprog_reset_nmos="1.6" wprog_set_pmos="3" wprog_reset_pmos="3.2"/>
<input_buffer exist="on" circuit_model_name="INVD1BWP"/>
<output_buffer exist="on" circuit_model_name="INVD1BWP"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="1"/>
<port type="input" prefix="read" size="1" is_global="true" default_val="0" />
<port type="input" prefix="nequalize" size="1" is_global="true" default_val="1" />
<port type="output" prefix="out" size="2"/>
<port type="bl" prefix="bl" size="3" default_val="0" inv_circuit_model_name="INVD1BWP"/>
<port type="wl" prefix="wl" size="3" default_val="0" inv_circuit_model_name="INVD1BWP"/>
</circuit_model>
<circuit_model type="sram" name="sram6T_blwl" prefix="sram_blwl" spice_netlist="/research/ece/lnis/USERS/alacchi/Ganesh/OpenFPGA/vpr7_x2p/vpr/SpiceNetlists/sram.sp" verilog_netlist="${OPENFPGA_PATH}/vpr7_x2p/vpr/VerilogNetlists/sram.v">
<design_technology type="cmos"/>
<input_buffer exist="on" circuit_model_name="INVD1BWP"/>
<output_buffer exist="on" circuit_model_name="INVD1BWP"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="1"/>
<port type="input" prefix="read" size="1" is_global="true" default_val="0" />
<port type="input" prefix="nequalize" size="1" is_global="true" default_val="0" />
<port type="output" prefix="out" size="2"/>
<port type="bl" prefix="bl" size="1"/>
<port type="wl" prefix="wl" size="1"/>
</circuit_model>
<!--Scan-chain DFF subckt ports should be defined as <D> <Q> <Qb> <CLK> <RESET> <SET> -->
<circuit_model type="sff" name="sc_ff" prefix="scff" spice_netlist="/research/ece/lnis/USERS/alacchi/Ganesh/OpenFPGA/vpr7_x2p/vpr/SpiceNetlists/ff.sp" verilog_netlist="${OPENFPGA_PATH}/vpr7_x2p/vpr/VerilogNetlists/ff.v">
<design_technology type="cmos"/>
<input_buffer exist="on" circuit_model_name="INVD1BWP"/>
<output_buffer exist="on" circuit_model_name="INVD1BWP"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="D" size="1"/>
<port type="input" prefix="Set" size="1"/>
<port type="input" prefix="Reset" size="1"/>
<port type="output" prefix="Q" size="1"/>
<port type="output" prefix="Qb" size="1"/>
<port type="clock" prefix="clk" size="1"/>
</circuit_model>
<circuit_model type="iopad" name="iopad" prefix="iopad" spice_netlist="/research/ece/lnis/USERS/alacchi/Ganesh/OpenFPGA/vpr7_x2p/vpr/SpiceNetlists/io.sp" verilog_netlist="${OPENFPGA_PATH}/vpr7_x2p/vpr/VerilogNetlists/io.v">
<!--design_technology type="cmos"/-->
<design_technology type="rram" ron="3e3" roff="1e6" wprog_set_nmos="1.5" wprog_reset_nmos="1.6" wprog_set_pmos="3" wprog_reset_pmos="3.2"/>
<input_buffer exist="on" circuit_model_name="INVD1BWP"/>
<output_buffer exist="on" circuit_model_name="INVD1BWP"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="inout" prefix="pad" size="1"/>
<port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sram6T_rram" default_val="1"/>
<port type="input" prefix="outpad" size="1"/>
<port type="input" prefix="zin" size="1" is_global="true" default_val="0" />
<port type="output" prefix="inpad" size="1"/>
</circuit_model>
</module_circuit_models>
</spice_settings>
<device>
<sizing R_minW_nmos="8926" R_minW_pmos="16067" ipin_mux_trans_size="3"/>
<timing C_ipin_cblock="596e-18" T_ipin_cblock="45.54e-12"/>
<area grid_logic_tile_area="0"/>
<!--sram area="6" organization="standalone" circuit_model_name="sram6T"-->
<!--sram area="6" organization="scan-chain" circuit_model_name="sc_dff"-->
<sram area="6">
<verilog organization="memory-bank" circuit_model_name="sram6T_rram" />
<spice organization="standalone" circuit_model_name="sram6T" />
</sram>
<chan_width_distr>
<io width="1.000000"/>
<x distr="uniform" peak="1.000000"/>
<y distr="uniform" peak="1.000000"/>
</chan_width_distr>
<switch_block type="wilton" fs="3"/>
</device>
<cblocks>
<switch type="mux" name="cb_mux" R="0" Cin="596e-18" Cout="0" Tdel="45.54e-12" mux_trans_size="1.5" buf_size="4" circuit_model_name="mux_1level_tapbuf4" structure="one-level" num_level="1">
</switch>
</cblocks>
<switchlist>
<!-- VB: the mux_trans_size and buf_size data below is in minimum width transistor *areas*, assuming the purple
book area formula. This means the mux transistors are about 5x minimum drive strength.
We assume the first stage of the buffer is 3x min drive strength to be reasonable given the large
mux transistors, and this gives a reasonable stage ratio of a bit over 5x to the second stage. We assume
the n and p transistors in the first stage are equal-sized to lower the buffer trip point, since it's fed
by a pass transistor mux. We can then reverse engineer the buffer second stage to hit the specified
buf_size (really buffer area) - 16.2x minimum drive nmos and 1.8*16.2 = 29.2x minimum drive.
I then took the data from Jeff G.'s PTM modeling of 45 nm to get the Cin (gate of first stage) and Cout
(diff of second stage) listed below. Jeff's models are in tech/ptm_45nm, and are in min feature multiples.
The minimum contactable transistor is 2.5 * 45 nm, so I need to multiply the drive strength sizes above by
2.5x when looking up in Jeff's tables.
Finally, we choose a switch delay (58 ps) that leads to length 4 wires having a delay equal to that of SIV of 126 ps.
This also leads to the switch being 46% of the total wire delay, which is reasonable. -->
<switch type="mux" name="sb_mux_L4" R="106" Cin="596e-18" Cout="0e-15" Tdel="35.8e-12" mux_trans_size="1.5" buf_size="27.645901" circuit_model_name="mux_1level_tapbuf4" structure="one-level" num_level="1">
</switch>
<switch type="mux" name="sb_mux_L2" R="121" Cin="596e-18" Cout="0e-15" Tdel="35.8e-12" mux_trans_size="1.5" buf_size="27.645901" circuit_model_name="mux_1level_tapbuf4" structure="one-level" num_level="1">
</switch>
<switch type="mux" name="sb_mux_L1" R="147" Cin="596e-18" Cout="0e-15" Tdel="35.8e-12" mux_trans_size="1.5" buf_size="27.645901" circuit_model_name="mux_1level_tapbuf4" structure="one-level" num_level="1">
</switch>
</switchlist>
<segmentlist>
<!--- VB & JL: using ITRS metal stack data, 96 nm half pitch wires, which are intermediate metal width/space.
With the 96 nm half pitch, such wires would take 60 um of height, vs. a 90 nm high (approximated as square) Stratix IV tile so this seems
reasonable. Using a tile length of 90 nm, corresponding to the length of a Stratix IV tile if it were square. -->
<segment freq="0.4" length="4" type="unidir" Rmetal="101" Cmetal="22.5e-15" circuit_model_name="chan_segment">
<mux name="sb_mux_L4"/>
<sb type="pattern">1 1 1 1 1</sb>
<cb type="pattern">1 1 1 1</cb>
</segment>
<segment freq="0.3" length="2" type="unidir" Rmetal="101" Cmetal="22.5e-15" circuit_model_name="chan_segment">
<mux name="sb_mux_L4"/>
<sb type="pattern">1 1 1</sb>
<cb type="pattern">1 1</cb>
</segment>
<segment freq="0.3" length="1" type="unidir" Rmetal="101" Cmetal="22.5e-15" circuit_model_name="chan_segment">
<mux name="sb_mux_L4"/>
<sb type="pattern">1 1</sb>
<cb type="pattern">1</cb>
</segment>
</segmentlist>
<complexblocklist>
<!-- Define I/O pads begin -->
<!-- Capacity is a unique property of I/Os, it is the maximum number of I/Os that can be placed at the same (X,Y) location on the FPGA -->
<!-- Not sure of the area of an I/O (varies widely), and it's not relevant to the design of the FPGA core, so we're setting it to 0. -->
<pb_type name="io" capacity="8" area="0" idle_mode_name="inpad" physical_mode_name="io_phy">
<input name="outpad" num_pins="1"/>
<output name="inpad" num_pins="1"/>
<!-- physical design description -->
<mode name="io_phy" disabled_in_packing="true">
<pb_type name="iopad" blif_model=".subckt io" num_pb="1" circuit_model_name="iopad" mode_bits="1">
<input name="outpad" num_pins="1"/>
<output name="inpad" num_pins="1"/>
</pb_type>
<interconnect>
<direct name="inpad" input="iopad.inpad" output="io.inpad">
<delay_constant max="0e-11" in_port="iopad.inpad" out_port="io.inpad"/>
</direct>
<direct name="outpad" input="io.outpad" output="iopad.outpad">
<delay_constant max="0e-11" in_port="io.outpad" out_port="iopad.outpad"/>
</direct>
</interconnect>
</mode>
<!-- IOs can operate as either inputs or outputs.§
Delays below come from Ian Kuon. They are small, so they should be interpreted as
the delays to and from registers in the I/O (and generally I/Os are registered
today and that is when you timing analyze them.
-->
<mode name="inpad">
<pb_type name="inpad" blif_model=".input" num_pb="1" physical_pb_type_name="iopad" mode_bits="1">
<output name="inpad" num_pins="1" physical_mode_pin="inpad"/>
</pb_type>
<interconnect>
<direct name="inpad" input="inpad.inpad" output="io.inpad">
<delay_constant max="0e-11" in_port="inpad.inpad" out_port="io.inpad"/>
</direct>
</interconnect>
</mode>
<mode name="outpad">
<pb_type name="outpad" blif_model=".output" num_pb="1" physical_pb_type_name="iopad" mode_bits="0">
<input name="outpad" num_pins="1" physical_mode_pin="outpad"/>
</pb_type>
<interconnect>
<direct name="outpad" input="io.outpad" output="outpad.outpad">
<delay_constant max="0e-11" in_port="io.outpad" out_port="outpad.outpad"/>
</direct>
</interconnect>
</mode>
<!-- Every input pin is driven by 15% of the tracks in a channel, every output pin is driven by 10% of the tracks in a channel -->
<fc default_in_type="frac" default_in_val="0.15" default_out_type="frac" default_out_val="0.10"/>
<!-- IOs go on the periphery of the FPGA, for consistency,
make it physically equivalent on all sides so that only one definition of I/Os is needed.
If I do not make a physically equivalent definition, then I need to define 4 different I/Os, one for each side of the FPGA
-->
<pinlocations pattern="custom">
<loc side="left">io.outpad io.inpad</loc>
<loc side="top">io.outpad io.inpad</loc>
<loc side="right">io.outpad io.inpad</loc>
<loc side="bottom">io.outpad io.inpad</loc>
</pinlocations>
<!-- Place I/Os on the sides of the FPGA -->
<gridlocations>
<loc type="perimeter" priority="10"/>
</gridlocations>
<power method="ignore"/>
</pb_type>
<!-- Define I/O pads ends -->
<!-- Define general purpose logic block (CLB) begin -->
<!--- Area calculation: Total Stratix IV tile area is about 8100 um^2, and a minimum width transistor
area is 60 L^2 yields a tile area of 84375 MWTAs.
Routing at W=300 is 30481 MWTAs, leaving us with a total of 53000 MWTAs for logic block area
This means that only 37% of our area is in the general routing, and 63% is inside the logic
block. Note that the crossbar / local interconnect is considered part of the logic block
area in this analysis. That is a lower proportion of of routing area than most academics
assume, but note that the total routing area really includes the crossbar, which would push
routing area up significantly, we estimate into the ~70% range.
-->
<pb_type name="clb" area="53894" opin_to_cb="false">
<pin_equivalence_auto_detect input_ports ="off" output_ports="off"/>
<input name="I" num_pins="40" equivalent="true"/>
<output name="O" num_pins="10" equivalent="false"/>
<!--input name="I" num_pins="40" equivalent="true"/-->
<!--output name="O" num_pins="20" equivalent="false"/-->
<clock name="clk" num_pins="1"/>
<!-- Describe fracturable logic element.
Each fracturable logic element has a 6-LUT that can alternatively operate as two 5-LUTs with shared inputs.
The outputs of the fracturable logic element can be optionally registered
For spice modeling: in each primitive pb_type, user should define a circuit_model_name that linkes to the
defined spice models
-->
<pb_type name="fle" num_pb="10" idle_mode_name="n1_lut6" physical_mode_name="n1_lut6">
<input name="in" num_pins="6"/>
<output name="out" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- 6-LUT mode definition begin -->
<mode name="n1_lut6">
<!-- Define 6-LUT mode -->
<pb_type name="ble6" num_pb="1">
<input name="in" num_pins="6"/>
<output name="out" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- Define LUT -->
<pb_type name="lut6" blif_model=".names" num_pb="1" class="lut" circuit_model_name="lut6">
<input name="in" num_pins="6" port_class="lut_in"/>
<output name="out" num_pins="1" port_class="lut_out"/>
<delay_matrix type="max" in_port="lut6.in" out_port="lut6.out">
2.094e-09
2.094e-09
2.094e-09
2.094e-09
2.094e-09
2.094e-09
</delay_matrix>
</pb_type>
<!-- Define flip-flop -->
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop" circuit_model_name="static_dff">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="29e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="16e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="direct1" input="ble6.in" output="lut6[0:0].in"/>
<direct name="direct2" input="lut6.out" output="ff.D">
<!-- Advanced user option that tells CAD tool to find LUT+FF pairs in netlist -->
<pack_pattern name="ble6" in_port="lut6.out" out_port="ff.D"/>
</direct>
<direct name="direct3" input="ble6.clk" output="ff.clk"/>
<mux name="mux1" input="ff.Q lut6.out" output="ble6.out" circuit_model_name="mux_1level">
<delay_constant max="2.736e-10" in_port="lut6.out" out_port="ble6.out" />
<delay_constant max="2.736e-10" in_port="ff.Q" out_port="ble6.out" />
</mux>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="fle.in" output="ble6.in"/>
<direct name="direct2" input="ble6.out" output="fle.out[0:0]"/>
<direct name="direct3" input="fle.clk" output="ble6.clk"/>
</interconnect>
</mode>
<!-- 6-LUT mode definition end -->
</pb_type>
<interconnect>
<!-- We use a full crossbar to get logical equivalence at inputs of CLB
The delays below come from Stratix IV. the delay through a connection block
input mux + the crossbar in Stratix IV is 167 ps. We already have a 72 ps
delay on the connection block input mux (modeled by Ian Kuon), so the remaining
delay within the crossbar is 95 ps.
The delays of cluster feedbacks in Stratix IV is 100 ps, when driven by a LUT.
Since all our outputs LUT outputs go to a BLE output, and have a delay of
25 ps to do so, we subtract 25 ps from the 100 ps delay of a feedback
to get the part that should be marked on the crossbar. -->
<complete name="crossbar" input="clb.I fle[9:0].out" output="fle[9:0].in" circuit_model_name="mux_1level">
<delay_constant max="1.0877e-09" in_port="clb.I" out_port="fle[9:0].in" />
<delay_constant max="1.0877e-09" in_port="fle[9:0].out" out_port="fle[9:0].in" />
</complete>
<complete name="clks" input="clb.clk" output="fle[9:0].clk">
</complete>
<!-- This way of specifying direct connection to clb outputs is important because this architecture uses automatic spreading of opins.
By grouping to output pins in this fashion, if a logic block is completely filled by 6-LUTs,
then the outputs those 6-LUTs take get evenly distributed across all four sides of the CLB instead of clumped on two sides (which is what happens with a more
naive specification).
-->
<direct name="clbouts1" input="fle[9:0].out[0:0]" output="clb.O[9:0]"/>
<!--direct name="clbouts2" input="fle[9:0].out[1:1]" output="clb.O[19:10]"/-->
<!--complete name="clbouts1" input="fle[9:0].out[0:0]" output="clb.O[9:0]"/-->
</interconnect>
<!-- Every input pin is driven by 15% of the tracks in a channel, every output pin is driven by 10% of the tracks in a channel -->
<fc default_in_type="frac" default_in_val="0.15" default_out_type="frac" default_out_val="0.10"/>
<!--pinlocations pattern="spread"/-->
<pinlocations pattern="custom">
<loc side="top">clb.clk </loc>
<loc side="right">clb.I[19:0] clb.O[4:0] </loc>
<loc side="bottom">clb.I[39:20] clb.O[9:5] </loc>
</pinlocations>
<!-- Place this general purpose logic block in any unspecified column -->
<gridlocations>
<loc type="fill" priority="1"/>
</gridlocations>
</pb_type>
</complexblocklist>
<power>
<local_interconnect C_wire="0"/>
<mux_transistor_size mux_transistor_size="3"/>
<FF_size FF_size="4"/>
<LUT_transistor_size LUT_transistor_size="4"/>
</power>
<clocks>
<clock buffer_size="auto" C_wire="0"/>
</clocks>
</architecture>

View File

@ -507,11 +507,11 @@ void generate_verilog_rram_mux_branch_body_behavioral(std::fstream& fp,
/* Print the internal logics */
fp << "\t" << "always @(";
fp << generate_verilog_port(VERILOG_PORT_CONKT, blb_port) << ";" << std::endl;
fp << generate_verilog_port(VERILOG_PORT_CONKT, blb_port);
fp << ", ";
fp << generate_verilog_port(VERILOG_PORT_CONKT, wl_port) << ";" << std::endl;
fp << ")" << std::endl;
fp << "\t" << "begin" << std::endl;
fp << generate_verilog_port(VERILOG_PORT_CONKT, wl_port);
fp << ")";
fp << " begin" << std::endl;
/* Only when the last bit of wl is enabled,
* the propagating path can be changed
@ -531,11 +531,12 @@ void generate_verilog_rram_mux_branch_body_behavioral(std::fstream& fp,
/* Create a port object */
fp << " && ";
BasicPort prog_en_port(circuit_lib.port_prefix(port), circuit_lib.port_size(port));
if ( 1 == circuit_lib.port_default_value(port)) {
if ( 0 == circuit_lib.port_default_value(port)) {
/* Default value = 0 means that this is a prog_EN port */
fp << generate_verilog_port(VERILOG_PORT_CONKT, prog_en_port);
find_prog_EN = true;
} else {
VTR_ASSERT ( 1 == circuit_lib.port_default_value(port));
/* Default value = 1 means that this is a prog_ENb port, add inversion in the if condition */
fp << "(~" << generate_verilog_port(VERILOG_PORT_CONKT, prog_en_port) << ")";
find_prog_ENb = true;
@ -559,19 +560,23 @@ void generate_verilog_rram_mux_branch_body_behavioral(std::fstream& fp,
fp << ") begin" << std::endl;
for (const auto& mux_input : mux_graph.inputs()) {
fp << "\t\t" << "if (1 == ";
/* First if clause need tabs */
if ( 0 == size_t(mux_graph.input_id(mux_input)) ) {
fp << "\t\t\t";
}
fp << "if (1 == ";
/* Create a temp port of a BLB bit */
BasicPort cur_blb_port(blb_port.get_name(), size_t(mux_graph.input_id(mux_input)), size_t(mux_graph.input_id(mux_input)));
fp << generate_verilog_port(VERILOG_PORT_CONKT, cur_blb_port);
fp << ") begin" << std::endl;
fp << "\t\t\t" << "assign ";
fp << generate_verilog_port(VERILOG_PORT_CONKT, outreg_port);
fp << "\t\t\t\t" << "assign ";
fp << outreg_port.get_name();
fp << " = " << size_t(mux_graph.input_id(mux_input)) << ";" << std::endl;
fp << "\t\t" << "end else " << std::endl;
fp << "\t\t\t" << "end else ";
}
fp << "\t\t\t" << "begin" << std::endl;
fp << "begin" << std::endl;
fp << "\t\t\t\t" << "assign ";
fp << generate_verilog_port(VERILOG_PORT_CONKT, outreg_port);
fp << outreg_port.get_name();
fp << " = 0;" << std::endl;
fp << "\t\t\t" << "end" << std::endl;
fp << "\t\t" << "end" << std::endl;
@ -581,7 +586,7 @@ void generate_verilog_rram_mux_branch_body_behavioral(std::fstream& fp,
fp << generate_verilog_port(VERILOG_PORT_CONKT, output_port);
fp << " = ";
fp << input_port.get_name() << "[";
fp << generate_verilog_port(VERILOG_PORT_CONKT, outreg_port);
fp << outreg_port.get_name();
fp << "];" << std::endl;
}
@ -618,18 +623,28 @@ void generate_verilog_rram_mux_branch_module(ModuleManager& module_manager,
/* Create a Verilog Module based on the circuit model, and add to module manager */
ModuleId module_id = module_manager.add_module(module_name);
VTR_ASSERT(ModuleId::INVALID() != module_id);
/* Add module ports */
/* Add programming enable/disable ports */
/* Add each global programming enable/disable ports */
std::vector<CircuitPortId> prog_enable_ports = circuit_lib.model_global_ports_by_type(circuit_model, SPICE_MODEL_PORT_INPUT, true);
for (const auto& port : prog_enable_ports) {
/* Configure each global port */
BasicPort global_port(circuit_lib.port_lib_name(port), circuit_lib.port_size(port));
module_manager.add_port(module_id, global_port, ModuleManager::MODULE_GLOBAL_PORT);
}
/* Add each input port */
BasicPort input_port("in", num_inputs);
module_manager.add_port(module_id, input_port, ModuleManager::MODULE_INPUT_PORT);
/* Add each output port */
BasicPort output_port("out", num_outputs);
module_manager.add_port(module_id, output_port, ModuleManager::MODULE_OUTPUT_PORT);
/* Add RRAM programming ports */
BasicPort blb_port("bl", num_mems);
/* Add RRAM programming ports,
* RRAM MUXes require one more pair of BLB and WL
* to configure the memories. See schematic for details
*/
BasicPort blb_port("blb", num_mems + 1);
module_manager.add_port(module_id, blb_port, ModuleManager::MODULE_INPUT_PORT);
BasicPort wl_port("wl", num_mems);
BasicPort wl_port("wl", num_mems + 1);
module_manager.add_port(module_id, wl_port, ModuleManager::MODULE_INPUT_PORT);
/* dump module definition + ports */
@ -718,6 +733,7 @@ void print_verilog_submodule_muxes(ModuleManager& module_manager,
generate_verilog_mux_branch_module(module_manager, circuit_lib, fp, mux_circuit_model,
mux_graph.num_inputs(), branch_mux_graph);
}
/* TODO: create MUX modules */
}
/* Dump MUX graph one by one */