This commit is contained in:
tangxifan 2019-07-03 14:12:47 -06:00
commit c9743e84da
34 changed files with 14393 additions and 289 deletions

4
.gitignore vendored
View File

@ -32,3 +32,7 @@ vpr7_x2p/vpr/vpr
vpr7_x2p/printhandler/printhandlerdemo
vpr7_x2p/libarchfpga/read_arch
vpr7_x2p/pcre/pcredemo
# Some local temporary files
.vscode
*_local.bat

10
Dockerfile Executable file
View File

@ -0,0 +1,10 @@
FROM ubuntu:16.04
RUN apt-get update -qq -y
RUN apt-get -y install python3 python3-dev tcl tcl8.6-dev gawk libreadline-dev
RUN apt-get -y install autoconf automake bison build-essential cmake ctags curl doxygen flex fontconfig g++-4.9 gcc-4.9 gdb git gperf libffi-dev libcairo2-dev libevent-dev libfontconfig1-dev liblist-moreutils-perl libncurses5-dev libx11-dev libxft-dev libxml++2.6-dev perl texinfo time valgrind zip qt5-default
RUN git clone https://github.com/LNIS-Projects/OpenFPGA.git OpenFPGA
RUN cd OpenFPGA && make

View File

@ -0,0 +1,553 @@
<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="2" height="2"/> -->
<!--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-13" 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_spice_models>
<spice_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"/>
</spice_model>
<spice_model type="inv_buf" name="INVD4BWP" prefix="INVD4BWP" dump_explicit_port_map="true" is_default="0" verilog_netlist="VerilogNetlists/essential_gates.v">
<design_technology type="cmos" topology="buffer" size="1" tapered="on" tap_buf_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"/>
</spice_model>
<spice_model type="inv_buf" name="INVD1BWP" prefix="INVD1BWP" dump_explicit_port_map="true" is_default="0" verilog_netlist="VerilogNetlists/essential_gates.v">
<design_technology type="cmos" topology="buffer" size="1" tapered="on" tap_buf_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"/>
</spice_model>
<spice_model type="inv_buf" name="INVD2BWP" prefix="INVD2BWP" dump_explicit_port_map="true" is_default="0" verilog_netlist="VerilogNetlists/essential_gates.v">
<design_technology type="cmos" topology="buffer" size="1" tapered="on" tap_buf_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"/>
</spice_model>
<spice_model type="inv_buf" name="INVD3BWP" prefix="INVD3BWP" dump_explicit_port_map="true" is_default="0" verilog_netlist="VerilogNetlists/essential_gates.v">
<design_technology type="cmos" topology="buffer" size="1" tapered="on" tap_buf_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"/>
</spice_model>
<spice_model type="inv_buf" name="BUFFD2BWP" prefix="BUFFD2BWP" dump_explicit_port_map="true" is_default="0" verilog_netlist="VerilogNetlists/essential_gates.v">
<design_technology type="cmos" topology="buffer" size="1" tapered="on" tap_buf_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"/>
</spice_model>
<spice_model type="inv_buf" name="BUFFD3BWP" prefix="BUFFD3BWP" dump_explicit_port_map="true" is_default="0" verilog_netlist="VerilogNetlists/essential_gates.v">
<design_technology type="cmos" topology="buffer" size="1" tapered="on" tap_buf_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"/>
</spice_model>
<spice_model type="inv_buf" name="BUFFD1BWP" prefix="BUFFD1BWP" dump_explicit_port_map="true" is_default="0" verilog_netlist="VerilogNetlists/essential_gates.v">
<design_technology type="cmos" topology="buffer" size="1" tapered="on" tap_buf_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"/>
</spice_model>
<spice_model type="inv_buf" name="buf4" prefix="buf4" is_default="0">
<design_technology type="cmos" topology="buffer" size="3" tapered="on" tap_buf_level="2" f_per_stage="4"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
</spice_model>
<spice_model type="inv_buf" name="tap_buf4" prefix="tap_buf4" is_default="0">
<design_technology type="cmos" topology="buffer" size="3" tapered="on" tap_buf_level="3" f_per_stage="4"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
</spice_model>
<spice_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"/>
</spice_model>
<spice_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 -->
</spice_model>
<spice_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 -->
</spice_model>
<spice_model type="mux" name="mux_1level" prefix="mux_1level" is_default="1" dump_structural_verilog="true">
<!--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" spice_model_name="INVTX1"/>
<output_buffer exist="on" spice_model_name="INVD1BWP"/>
<!--mux2to1 subckt_name="mux2to1"/-->
<pass_gate_logic spice_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" spice_model_name="sram6T_rram"/>
</spice_model>
<spice_model type="mux" name="mux_1level_tapbuf4" prefix="mux_1level_tapbuf4" is_default="0" dump_structural_verilog="true">
<!--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" spice_model_name="INVTX1"/>
<output_buffer exist="on" spice_model_name="tap_buf4"/>
<!--mux2to1 subckt_name="mux2to1"/-->
<pass_gate_logic spice_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" spice_model_name="sram6T_rram"/>
</spice_model>
<!--DFF subckt ports should be defined as <D> <Q> <CLK> <RESET> <SET> -->
<spice_model type="ff" name="static_dff" prefix="dff" spice_netlist="/home/u1235811/Ganesh/OpenFPGA/vpr7_x2p/vpr/SpiceNetlists/ff.sp" verilog_netlist="VerilogNetlists/ff.v">
<design_technology type="cmos"/>
<input_buffer exist="on" spice_model_name="INVD1BWP"/>
<output_buffer exist="on" spice_model_name="INVD1BWP"/>
<pass_gate_logic spice_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" />
</spice_model>
<spice_model type="lut" name="lut6" prefix="lut6" dump_structural_verilog="true">
<design_technology type="cmos"/>
<input_buffer exist="on" spice_model_name="INVD1BWP"/>
<output_buffer exist="on" spice_model_name="INVD1BWP"/>
<lut_input_buffer exist="on" spice_model_name="BUFFD3BWP"/>
<!-- <lut_intermediate_buffer exist="on" spice_model_name="BUFFD1BWP" location_map="-1-1-"/> -->
<lut_input_inverter exist="on" spice_model_name="INVD3BWP"/>
<pass_gate_logic spice_model_name="TGATE"/>
<port type="input" prefix="in" size="6"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="64" spice_model_name="sram6T_rram" default_val="1"/>
</spice_model>
<spice_model type="sram" name="sram6T" prefix="sram" spice_netlist="/home/u1235811/Ganesh/OpenFPGA/vpr7_x2p/vpr/SpiceNetlists/sram.sp" verilog_netlist="VerilogNetlists/sram.v">
<design_technology type="cmos"/>
<input_buffer exist="on" spice_model_name="INVD1BWP"/>
<output_buffer exist="on" spice_model_name="INVD1BWP"/>
<pass_gate_logic spice_model_name="TGATE"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="2"/>
</spice_model>
<spice_model type="sram" name="sram6T_rram" prefix="nvsram" spice_netlist="/home/u1235811/Ganesh/OpenFPGA/vpr7_x2p/vpr/SpiceNetlists/sram.sp" verilog_netlist="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" spice_model_name="INVD1BWP"/>
<output_buffer exist="on" spice_model_name="INVD1BWP"/>
<pass_gate_logic spice_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_spice_model_name="INVD1BWP"/>
<port type="wl" prefix="wl" size="3" default_val="0" inv_spice_model_name="INVD1BWP"/>
</spice_model>
<spice_model type="sram" name="sram6T_blwl" prefix="sram_blwl" spice_netlist="/home/u1235811/Ganesh/OpenFPGA/vpr7_x2p/vpr/SpiceNetlists/sram.sp" verilog_netlist="VerilogNetlists/sram.v">
<design_technology type="cmos"/>
<input_buffer exist="on" spice_model_name="INVD1BWP"/>
<output_buffer exist="on" spice_model_name="INVD1BWP"/>
<pass_gate_logic spice_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"/>
</spice_model>
<!--Scan-chain DFF subckt ports should be defined as <D> <Q> <Qb> <CLK> <RESET> <SET> -->
<spice_model type="sff" name="sc_ff" prefix="scff" spice_netlist="/home/u1235811/Ganesh/OpenFPGA/vpr7_x2p/vpr/SpiceNetlists/ff.sp" verilog_netlist="VerilogNetlists/ff.v">
<design_technology type="cmos"/>
<input_buffer exist="on" spice_model_name="INVD1BWP"/>
<output_buffer exist="on" spice_model_name="INVD1BWP"/>
<pass_gate_logic spice_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"/>
</spice_model>
<spice_model type="iopad" name="iopad" prefix="iopad" spice_netlist="/home/u1235811/Ganesh/OpenFPGA/vpr7_x2p/vpr/SpiceNetlists/io.sp" verilog_netlist="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" spice_model_name="INVD1BWP"/>
<output_buffer exist="on" spice_model_name="INVD1BWP"/>
<pass_gate_logic spice_model_name="TGATE"/>
<port type="inout" prefix="pad" size="1"/>
<port type="sram" prefix="en" size="1" mode_select="true" spice_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"/>
</spice_model>
</module_spice_models>
</spice_settings>
<device>
<!-- VB & JL: Using Ian Kuon's transistor sizing and drive strength data for routing, at 40 nm. Ian used BPTM
models. We are modifying the delay values however, to include metal C and R, which allows more architecture
experimentation. We are also modifying the relative resistance of PMOS to be 1.8x that of NMOS
(vs. Ian's 3x) as 1.8x lines up with Jeff G's data from a 45 nm process (and is more typical of
45 nm in general). I'm upping the Rmin_nmos from Ian's just over 6k to nearly 9k, and dropping
RminW_pmos from 18k to 16k to hit this 1.8x ratio, while keeping the delays of buffers approximately
lined up with Stratix IV.
We are using Jeff G.'s capacitance data for 45 nm (in tech/ptm_45nm).
Jeff's tables list C in for transistors with widths in multiples of the minimum feature size (45 nm).
The minimum contactable transistor is 2.5 * 45 nm, so I need to multiply drive strength sizes in this file
by 2.5x when looking up in Jeff's tables.
The delay values are lined up with Stratix IV, which has an architecture similar to this
proposed FPGA, and which is also 40 nm
C_ipin_cblock: input capacitance of a track buffer, which VPR assumes is a single-stage
4x minimum drive strength buffer. -->
<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"/>
<!-- The grid_logic_tile_area below will be used for all blocks that do not explicitly set their own (non-routing)
area; set to 0 since we explicitly set the area of all blocks currently in this architecture file.
-->
<area grid_logic_tile_area="0"/>
<!--sram area="6" organization="standalone" spice_model_name="sram6T"-->
<!--sram area="6" organization="scan-chain" spice_model_name="sc_dff"-->
<sram area="6">
<verilog organization="memory-bank" spice_model_name="sram6T_rram" />
<spice organization="standalone" spice_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" spice_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" spice_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" spice_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" spice_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" spice_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" spice_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" spice_model_name="chan_segment">
<mux name="sb_mux_L4"/>
<sb type="pattern">1 1</sb>
<cb type="pattern">1</cb>
</segment>
</segmentlist>
<!-- <directlist>
</directlist> -->
<!--switch_segment_patterns>
<pattern type="unbuf_sb" seg_length="1" seg_type="unidir" pattern_length="2">
<unbuf_mux name="1"/>
<sb type ="pattern">0 1</sb>
</pattern>
</switch_segment_patterns-->
<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" spice_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 spice_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" spice_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">
127e-12
127e-12
127e-12
127e-12
127e-12
127e-12
</delay_matrix>
</pb_type>
<!-- Define flip-flop -->
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop" spice_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" spice_model_name="mux_1level">
<!-- LUT to output is faster than FF to output on a Stratix IV -->
<delay_constant max="42.24e-12" in_port="lut6.out" out_port="ble6.out" />
<delay_constant max="42.24e-12" 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" spice_model_name="mux_1level">
<delay_constant max="21.4e-12" in_port="clb.I" out_port="fle[9:0].in" />
<delay_constant max="21.4e-12" 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

@ -0,0 +1,2 @@
# Circuit Names, fixed routing channel width,
PID/*.v, 120

View File

@ -0,0 +1 @@
lattice_ultra_example_source/

View File

@ -0,0 +1,8 @@
# Ignore everything
*
# But descend into directories
!*/
!.gitignore
# Recursively allow files under subtree
!/UG73-iCE40_Ultra_Barcode_Emulation/hardware/source/top_module/**
!/PID_Controller/**

View File

@ -0,0 +1,259 @@
/*Carry look-ahead adder
Author: Zhu Xu
Email: m99a1@yahoo.cn
*/
module operator_A(
input A,
input B,
output P,
output G
);
assign P=A^B;
assign G=A&B;
endmodule
module operator_B(
input P,G,P1,G1,
output Po,Go
);
assign Po=P&P1;
assign Go=G|(P&G1);
endmodule
module operator_C(
input P,G,G1,
output Go
);
assign Go=G|(P&G1);
endmodule
/* 32-bit prefix-2 Han-Carlson adder
stage 0: Number of Generation=32, NP=32, NOA=32, NOB=0, NOC=0.
stage 1: NG=16, NP=15, NOA=0, NOB=15, NOC=1.
stage 2: NG=16, NP=14, NOA=0, NOB=14, NOC=1.
stage 3: NG=16, NP=12, NOA=0, NOB=12, NOC=2.
stage 4: NG=16, NP=8, NOA=0, NOB=8, NOC=4.
stage 5: NG=16, NP=0, NOA=0, NOB=0, NOC=8.
stage 6; NG=32, NP=0, NOA=0, NOB=0, NOC=15.
*/
module adder_32bit(
input [31:0]i_a,i_b,
input i_c,
output [31:0]o_s,
output o_c
);
//stage 0
wire [31:0]P0,G0;
operator_A operator_A_0(i_a[0],i_b[0],P0[0],G0[0]);
operator_A operator_A_1(i_a[1],i_b[1],P0[1],G0[1]);
operator_A operator_A_2(i_a[2],i_b[2],P0[2],G0[2]);
operator_A operator_A_3(i_a[3],i_b[3],P0[3],G0[3]);
operator_A operator_A_4(i_a[4],i_b[4],P0[4],G0[4]);
operator_A operator_A_5(i_a[5],i_b[5],P0[5],G0[5]);
operator_A operator_A_6(i_a[6],i_b[6],P0[6],G0[6]);
operator_A operator_A_7(i_a[7],i_b[7],P0[7],G0[7]);
operator_A operator_A_8(i_a[8],i_b[8],P0[8],G0[8]);
operator_A operator_A_9(i_a[9],i_b[9],P0[9],G0[9]);
operator_A operator_A_10(i_a[10],i_b[10],P0[10],G0[10]);
operator_A operator_A_11(i_a[11],i_b[11],P0[11],G0[11]);
operator_A operator_A_12(i_a[12],i_b[12],P0[12],G0[12]);
operator_A operator_A_13(i_a[13],i_b[13],P0[13],G0[13]);
operator_A operator_A_14(i_a[14],i_b[14],P0[14],G0[14]);
operator_A operator_A_15(i_a[15],i_b[15],P0[15],G0[15]);
operator_A operator_A_16(i_a[16],i_b[16],P0[16],G0[16]);
operator_A operator_A_17(i_a[17],i_b[17],P0[17],G0[17]);
operator_A operator_A_18(i_a[18],i_b[18],P0[18],G0[18]);
operator_A operator_A_19(i_a[19],i_b[19],P0[19],G0[19]);
operator_A operator_A_20(i_a[20],i_b[20],P0[20],G0[20]);
operator_A operator_A_21(i_a[21],i_b[21],P0[21],G0[21]);
operator_A operator_A_22(i_a[22],i_b[22],P0[22],G0[22]);
operator_A operator_A_23(i_a[23],i_b[23],P0[23],G0[23]);
operator_A operator_A_24(i_a[24],i_b[24],P0[24],G0[24]);
operator_A operator_A_25(i_a[25],i_b[25],P0[25],G0[25]);
operator_A operator_A_26(i_a[26],i_b[26],P0[26],G0[26]);
operator_A operator_A_27(i_a[27],i_b[27],P0[27],G0[27]);
operator_A operator_A_28(i_a[28],i_b[28],P0[28],G0[28]);
operator_A operator_A_29(i_a[29],i_b[29],P0[29],G0[29]);
operator_A operator_A_30(i_a[30],i_b[30],P0[30],G0[30]);
operator_A operator_A_31(i_a[31],i_b[31],P0[31],G0[31]);
//stage 1
wire [15:0]G1;
wire [15:1]P1;
operator_C operator_C_stage_1_0(P0[0],G0[0],i_c,G1[0]);
operator_B operator_B_stage_1_1(P0[2],G0[2],P0[1],G0[1],P1[1],G1[1]);
operator_B operator_B_stage_1_2(P0[4],G0[4],P0[3],G0[3],P1[2],G1[2]);
operator_B operator_B_stage_1_3(P0[6],G0[6],P0[5],G0[5],P1[3],G1[3]);
operator_B operator_B_stage_1_4(P0[8],G0[8],P0[7],G0[7],P1[4],G1[4]);
operator_B operator_B_stage_1_5(P0[10],G0[10],P0[9],G0[9],P1[5],G1[5]);
operator_B operator_B_stage_1_6(P0[12],G0[12],P0[11],G0[11],P1[6],G1[6]);
operator_B operator_B_stage_1_7(P0[14],G0[14],P0[13],G0[13],P1[7],G1[7]);
operator_B operator_B_stage_1_8(P0[16],G0[16],P0[15],G0[15],P1[8],G1[8]);
operator_B operator_B_stage_1_9(P0[18],G0[18],P0[17],G0[17],P1[9],G1[9]);
operator_B operator_B_stage_1_10(P0[20],G0[20],P0[19],G0[19],P1[10],G1[10]);
operator_B operator_B_stage_1_11(P0[22],G0[22],P0[21],G0[21],P1[11],G1[11]);
operator_B operator_B_stage_1_12(P0[24],G0[24],P0[23],G0[23],P1[12],G1[12]);
operator_B operator_B_stage_1_13(P0[26],G0[26],P0[25],G0[25],P1[13],G1[13]);
operator_B operator_B_stage_1_14(P0[28],G0[28],P0[27],G0[27],P1[14],G1[14]);
operator_B operator_B_stage_1_15(P0[30],G0[30],P0[29],G0[29],P1[15],G1[15]);
//stage 2
wire [15:0]G2;
wire [15:2]P2;
assign G2[0]=G1[0];
operator_C operator_C_stage_2_1(P1[1],G1[1],G1[0],G2[1]);
operator_B operator_B_stage_2_2(P1[2], G1[2],P1[1],G1[1],P2[2],G2[2]);
operator_B operator_B_stage_2_3(P1[3], G1[3],P1[2],G1[2],P2[3],G2[3]);
operator_B operator_B_stage_2_4(P1[4], G1[4],P1[3],G1[3],P2[4],G2[4]);
operator_B operator_B_stage_2_5(P1[5], G1[5],P1[4],G1[4],P2[5],G2[5]);
operator_B operator_B_stage_2_6(P1[6], G1[6],P1[5],G1[5],P2[6],G2[6]);
operator_B operator_B_stage_2_7(P1[7], G1[7],P1[6],G1[6],P2[7],G2[7]);
operator_B operator_B_stage_2_8(P1[8], G1[8],P1[7],G1[7],P2[8],G2[8]);
operator_B operator_B_stage_2_9(P1[9], G1[9],P1[8],G1[8],P2[9],G2[9]);
operator_B operator_B_stage_2_10(P1[10], G1[10],P1[9],G1[9],P2[10],G2[10]);
operator_B operator_B_stage_2_11(P1[11], G1[11],P1[10],G1[10],P2[11],G2[11]);
operator_B operator_B_stage_2_12(P1[12], G1[12],P1[11],G1[11],P2[12],G2[12]);
operator_B operator_B_stage_2_13(P1[13], G1[13],P1[12],G1[12],P2[13],G2[13]);
operator_B operator_B_stage_2_14(P1[14], G1[14],P1[13],G1[13],P2[14],G2[14]);
operator_B operator_B_stage_2_15(P1[15], G1[15],P1[14],G1[14],P2[15],G2[15]);
//stage 3
wire [15:0]G3;
wire [15:4]P3;
assign G3[0]=G2[0];
assign G3[1]=G2[1];
operator_C operator_C_stage_3_2(P2[2],G2[2],G2[0],G3[2]);
operator_C operator_C_stage_3_3(P2[3],G2[3],G2[1],G3[3]);
operator_B operator_B_stage_3_4(P2[4], G2[4],P2[2],G2[2],P3[4],G3[4]);
operator_B operator_B_stage_3_5(P2[5], G2[5],P2[3],G2[3],P3[5],G3[5]);
operator_B operator_B_stage_3_6(P2[6], G2[6],P2[4],G2[4],P3[6],G3[6]);
operator_B operator_B_stage_3_7(P2[7], G2[7],P2[5],G2[5],P3[7],G3[7]);
operator_B operator_B_stage_3_8(P2[8], G2[8],P2[6],G2[6],P3[8],G3[8]);
operator_B operator_B_stage_3_9(P2[9], G2[9],P2[7],G2[7],P3[9],G3[9]);
operator_B operator_B_stage_3_10(P2[10], G2[10],P2[8],G2[8],P3[10],G3[10]);
operator_B operator_B_stage_3_11(P2[11], G2[11],P2[9],G2[9],P3[11],G3[11]);
operator_B operator_B_stage_3_12(P2[12], G2[12],P2[10],G2[10],P3[12],G3[12]);
operator_B operator_B_stage_3_13(P2[13], G2[13],P2[11],G2[11],P3[13],G3[13]);
operator_B operator_B_stage_3_14(P2[14], G2[14],P2[12],G2[12],P3[14],G3[14]);
operator_B operator_B_stage_3_15(P2[15], G2[15],P2[13],G2[13],P3[15],G3[15]);
//stage 4
wire [15:0]G4;
wire [15:8]P4;
assign G4[0]=G3[0];
assign G4[1]=G3[1];
assign G4[2]=G3[2];
assign G4[3]=G3[3];
operator_C operator_C_stage_4_4(P3[4],G3[4],G3[0],G4[4]);
operator_C operator_C_stage_4_5(P3[5],G3[5],G3[1],G4[5]);
operator_C operator_C_stage_4_6(P3[6],G3[6],G3[2],G4[6]);
operator_C operator_C_stage_4_7(P3[7],G3[7],G3[3],G4[7]);
operator_B operator_B_stage_4_8(P3[8], G3[8],P3[4],G3[4],P4[8],G4[8]);
operator_B operator_B_stage_4_9(P3[9], G3[9],P3[5],G3[5],P4[9],G4[9]);
operator_B operator_B_stage_4_10(P3[10], G3[10],P3[6],G3[6],P4[10],G4[10]);
operator_B operator_B_stage_4_11(P3[11], G3[11],P3[7],G3[7],P4[11],G4[11]);
operator_B operator_B_stage_4_12(P3[12], G3[12],P3[8],G3[8],P4[12],G4[12]);
operator_B operator_B_stage_4_13(P3[13], G3[13],P3[9],G3[9],P4[13],G4[13]);
operator_B operator_B_stage_4_14(P3[14], G3[14],P3[10],G3[10],P4[14],G4[14]);
operator_B operator_B_stage_4_15(P3[15], G3[15],P3[11],G3[11],P4[15],G4[15]);
//stage 5
wire [15:0]G5;
assign G5[0]=G4[0];
assign G5[1]=G4[1];
assign G5[2]=G4[2];
assign G5[3]=G4[3];
assign G5[4]=G4[4];
assign G5[5]=G4[5];
assign G5[6]=G4[6];
assign G5[7]=G4[7];
operator_C operator_C_stage_5_8(P4[8],G4[8],G4[0],G5[8]);
operator_C operator_C_stage_5_9(P4[9],G4[9],G4[1],G5[9]);
operator_C operator_C_stage_5_10(P4[10],G4[10],G4[2],G5[10]);
operator_C operator_C_stage_5_11(P4[11],G4[11],G4[3],G5[11]);
operator_C operator_C_stage_5_12(P4[12],G4[12],G4[4],G5[12]);
operator_C operator_C_stage_5_13(P4[13],G4[13],G4[5],G5[13]);
operator_C operator_C_stage_5_14(P4[14],G4[14],G4[6],G5[14]);
operator_C operator_C_stage_5_15(P4[15],G4[15],G4[7],G5[15]);
//stage 6
wire [31:0]G6;
assign G6[0]=G5[0];
assign G6[2]=G5[1];
assign G6[4]=G5[2];
assign G6[6]=G5[3];
assign G6[8]=G5[4];
assign G6[10]=G5[5];
assign G6[12]=G5[6];
assign G6[14]=G5[7];
assign G6[16]=G5[8];
assign G6[18]=G5[9];
assign G6[20]=G5[10];
assign G6[22]=G5[11];
assign G6[24]=G5[12];
assign G6[26]=G5[13];
assign G6[28]=G5[14];
assign G6[30]=G5[15];
operator_C operator_C_stage_6_0(P0[1],G0[1],G5[0],G6[1]);
operator_C operator_C_stage_6_1(P0[3],G0[3],G5[1],G6[3]);
operator_C operator_C_stage_6_2(P0[5],G0[5],G5[2],G6[5]);
operator_C operator_C_stage_6_3(P0[7],G0[7],G5[3],G6[7]);
operator_C operator_C_stage_6_4(P0[9],G0[9],G5[4],G6[9]);
operator_C operator_C_stage_6_5(P0[11],G0[11],G5[5],G6[11]);
operator_C operator_C_stage_6_6(P0[13],G0[13],G5[6],G6[13]);
operator_C operator_C_stage_6_7(P0[15],G0[15],G5[7],G6[15]);
operator_C operator_C_stage_6_8(P0[17],G0[17],G5[8],G6[17]);
operator_C operator_C_stage_6_9(P0[19],G0[19],G5[9],G6[19]);
operator_C operator_C_stage_6_10(P0[21],G0[21],G5[10],G6[21]);
operator_C operator_C_stage_6_11(P0[23],G0[23],G5[11],G6[23]);
operator_C operator_C_stage_6_12(P0[25],G0[25],G5[12],G6[25]);
operator_C operator_C_stage_6_13(P0[27],G0[27],G5[13],G6[27]);
operator_C operator_C_stage_6_14(P0[29],G0[29],G5[14],G6[29]);
operator_C operator_C_stage_6_15(P0[31],G0[31],G5[15],G6[31]);
assign o_s[0]=P0[0]^i_c;
assign o_s[1]=P0[1]^G6[0];
assign o_s[2]=P0[2]^G6[1];
assign o_s[3]=P0[3]^G6[2];
assign o_s[4]=P0[4]^G6[3];
assign o_s[5]=P0[5]^G6[4];
assign o_s[6]=P0[6]^G6[5];
assign o_s[7]=P0[7]^G6[6];
assign o_s[8]=P0[8]^G6[7];
assign o_s[9]=P0[9]^G6[8];
assign o_s[10]=P0[10]^G6[9];
assign o_s[11]=P0[11]^G6[10];
assign o_s[12]=P0[12]^G6[11];
assign o_s[13]=P0[13]^G6[12];
assign o_s[14]=P0[14]^G6[13];
assign o_s[15]=P0[15]^G6[14];
assign o_s[16]=P0[16]^G6[15];
assign o_s[17]=P0[17]^G6[16];
assign o_s[18]=P0[18]^G6[17];
assign o_s[19]=P0[19]^G6[18];
assign o_s[20]=P0[20]^G6[19];
assign o_s[21]=P0[21]^G6[20];
assign o_s[22]=P0[22]^G6[21];
assign o_s[23]=P0[23]^G6[22];
assign o_s[24]=P0[24]^G6[23];
assign o_s[25]=P0[25]^G6[24];
assign o_s[26]=P0[26]^G6[25];
assign o_s[27]=P0[27]^G6[26];
assign o_s[28]=P0[28]^G6[27];
assign o_s[29]=P0[29]^G6[28];
assign o_s[30]=P0[30]^G6[29];
assign o_s[31]=P0[31]^G6[30];
assign o_c=G6[31];
endmodule

View File

@ -0,0 +1,434 @@
/* PID controller
sigma=Ki*e(n)+sigma
u(n)=(Kp+Kd)*e(n)+sigma+Kd*(-e(n-1))
Data width of Wishbone slave port can be can be toggled between 64-bit, 32-bit and 16-bit.
Address width of Wishbone slave port can be can be modified by changing parameter adr_wb_nb.
Wishbone compliant
Work as Wishbone slave, support Classic standard SINGLE/BLOCK READ/WRITE Cycle
registers or wires
[15:0]kp,ki,kd,sp,pv; can be both read and written
[15:0]kpd; read only
[15:0]err[0:1]; read only
[15:0]mr,md; not accessable
[31:0]p,b; not accessable
[31:0]un,sigma; read only
RS write 0 to RS will reset err[0], OF, un and sigma
[4:0]of; overflow register, read only through Wishbone interface, address: 0x40
of[0]==1 : kpd overflow
of[1]==1 : err[0] overflow
of[2]==1 : err[1] overflow
of[3]==1 : un overflow
of[4]==1 : sigma overflow
[0:15]rl; read lock, when asserted corelated reagister can not be read through Wishbone interface
[0:7]wl; write lock, when asserted corelated reagister can not be written through Wishbone interface
*/
`include "PID_defines.v"
module PID #(
`ifdef wb_16bit
parameter wb_nb=16,
`endif
`ifdef wb_32bit
parameter wb_nb=32,
`endif
`ifdef wb_64bit
parameter wb_nb=64,
`endif
adr_wb_nb=16,
kp_adr = 0,
ki_adr = 1,
kd_adr = 2,
sp_adr = 3,
pv_adr = 4,
kpd_adr = 5,
err_0_adr = 6,
err_1_adr = 7,
un_adr = 8,
sigma_adr = 9,
of_adr = 10,
RS_adr = 11
)(
input i_clk,
input i_rst, //reset when high
//Wishbone Slave port
input i_wb_cyc,
input i_wb_stb,
input i_wb_we,
input [adr_wb_nb-1:0]i_wb_adr,
input [wb_nb-1:0]i_wb_data,
output o_wb_ack,
output [wb_nb-1:0]o_wb_data,
//u(n) output
output [31:0]o_un,
output o_valid
);
reg [15:0]kp,ki,kd,sp,pv;
reg wla,wlb; // write locks
wire wlRS;
assign wlRS=wla|wlb;
wire [0:7]wl={{3{wla}},{2{wlb}},3'h0};
reg wack; //write acknowledged
wire [2:0]adr; // address for write
`ifdef wb_16bit
assign adr=i_wb_adr[3:1];
`endif
`ifdef wb_32bit
assign adr=i_wb_adr[4:2];
`endif
`ifdef wb_64bit
assign adr=i_wb_adr[5:3];
`endif
wire [3:0]adr_1; // address for read
`ifdef wb_32bit
assign adr_1=i_wb_adr[5:2];
`endif
`ifdef wb_16bit
assign adr_1=i_wb_adr[4:1];
`endif
`ifdef wb_64bit
assign adr_1=i_wb_adr[6:3];
`endif
wire we; // write enable
assign we=i_wb_cyc&i_wb_we&i_wb_stb;
wire re; //read enable
assign re=i_wb_cyc&(~i_wb_we)&i_wb_stb;
reg state_0; //state machine No.1's state register
wire adr_check_1; // A '1' means address is within the range of adr_1
`ifdef wb_32bit
assign adr_check_1=i_wb_adr[adr_wb_nb-1:6]==0;
`endif
`ifdef wb_16bit
assign adr_check_1=i_wb_adr[adr_wb_nb-1:5]==0;
`endif
`ifdef wb_64bit
assign adr_check_1=i_wb_adr[adr_wb_nb-1:7]==0;
`endif
wire adr_check; // A '1' means address is within the range of adr
`ifdef wb_16bit
assign adr_check=i_wb_adr[4]==0&&adr_check_1;
`endif
`ifdef wb_32bit
assign adr_check=i_wb_adr[5]==0&&adr_check_1;
`endif
`ifdef wb_64bit
assign adr_check=i_wb_adr[6]==0&&adr_check_1;
`endif
//state machine No.1
reg RS;
always@(posedge i_clk or posedge i_rst)
if(i_rst)begin
state_0<=0;
wack<=0;
kp<=0;
ki<=0;
kd<=0;
sp<=0;
pv<=0;
RS<=0;
end
else begin
if(wack&&(!i_wb_stb)) wack<=0;
if(RS)RS<=0;
case(state_0)
0: begin
if(we&&(!wack)) state_0<=1;
end
1: begin
if(adr_check)begin
if(!wl[adr])begin
wack<=1;
state_0<=0;
case(adr)
0: begin
kp<=i_wb_data[15:0];
end
1: begin
ki<=i_wb_data[15:0];
end
2: begin
kd<=i_wb_data[15:0];
end
3: begin
sp<=i_wb_data[15:0];
end
4: begin
pv<=i_wb_data[15:0];
end
endcase
end
end
else if((adr_1==RS_adr)&&(!wlRS)&&(i_wb_data==0))begin
wack<=1;
state_0<=0;
RS<=1;
end
else begin
wack<=1;
state_0<=0;
end
end
endcase
end
//state machine No.2
reg [9:0]state_1;
wire update_kpd;
assign update_kpd=wack&&(~adr[2])&&(~adr[0])&&adr_check; //adr==0||adr==2
wire update_esu; //update e(n), sigma and u(n)
assign update_esu=wack&&(adr==4)&&adr_check;
reg rla; // read locks
reg rlb;
reg [4:0]of;
reg [15:0]kpd;
reg [15:0]err[0:1];
wire [15:0]mr,md;
reg [31:0]p;
reg [31:0]a,sigma,un;
reg cout;
wire cin;
wire [31:0]sum;
wire [31:0]product;
reg start; //start signal for multiplier
reg [1:0]mr_index;
reg [1:0]md_index;
assign mr= mr_index==1?kpd:
mr_index==2?kd:ki;
assign md= md_index==2?err[1]:
md_index==1?err[0]:sum[15:0];
wire of_addition[0:1];
assign of_addition[0]=(p[15]&&a[15]&&(!sum[15]))||((!p[15])&&(!a[15])&&sum[15]);
assign of_addition[1]=(p[31]&&a[31]&&(!sum[31]))||((!p[31])&&(!a[31])&&sum[31]);
always@(posedge i_clk or posedge i_rst)
if(i_rst)begin
state_1<=12'b000000000001;
wla<=0;
wlb<=0;
rla<=0;
rlb<=0;
of<=0;
kpd<=0;
err[0]<=0;
err[1]<=0;
p<=0;
a<=0;
sigma<=0;
un<=0;
start<=0;
mr_index<=0;
md_index<=0;
cout<=0;
end
else begin
case(state_1)
10'b0000000001: begin
if(update_kpd)begin
state_1<=10'b0000000010;
wla<=1;
rla<=1;
end
else if(update_esu)begin
state_1<=10'b0000001000;
wla<=1;
wlb<=1;
rlb<=1;
end
else if(RS)begin //start a new sequance of U(n)
un<=0;
sigma<=0;
of<=0;
err[0]<=0;
end
end
10'b0000000010: begin
p<={{16{kp[15]}},kp};
a<={{16{kd[15]}},kd};
state_1<=10'b0000000100;
end
10'b0000000100: begin
kpd<=sum[15:0];
wla<=0;
rla<=0;
of[0]<=of_addition[0];
state_1<=10'b0000000001;
end
10'b0000001000: begin
p<={{16{sp[15]}},sp};
a<={{16{~pv[15]}},~pv};
cout<=1;
start<=1; // start calculate err0 * ki
state_1<=10'b0000010000;
end
10'b0000010000: begin
err[0]<=sum[15:0];
of[1]<=of_addition[0];
of[2]<=of[1];
p<={{16{~err[0][15]}},~err[0]};
a<={31'b0,1'b1};
cout<=0;
mr_index<=1; // start calculate err0 * kpd
md_index<=1;
state_1<=10'b0000100000;
end
10'b0000100000: begin
err[1]<=sum[15:0];
mr_index<=2; // start calculate err1 * kd
md_index<=2;
state_1<=10'b0001000000;
end
10'b0001000000: begin
mr_index<=0;
md_index<=0;
start<=0;
p<=product; // start calculate err0*ki + sigma_last
a<=sigma;
state_1<=10'b0010000000;
end
10'b0010000000: begin
a<=sum; // start calculate err0*kpd + sigma_recent
sigma<=sum;
of[3]<=of[4]|of_addition[1];
of[4]<=of[4]|of_addition[1];
p<=product;
state_1<=10'b0100000000;
end
10'b0100000000: begin
a<=sum; // start calculate err0*kpd + sigma_recent+err1*kd
of[3]<=of[3]|of_addition[1];
p<=product;
state_1<=10'b1000000000;
end
10'b1000000000: begin
un<=sum;
of[3]<=of[3]|of_addition[1];
state_1<=10'b0000000001;
wla<=0;
wlb<=0;
rlb<=0;
end
endcase
end
wire ready;
multiplier_16x16bit_pipelined multiplier_16x16bit_pipelined(
i_clk,
~i_rst,
start,
md,
mr,
product,
ready
);
adder_32bit adder_32bit_0(
a,
p,
cout,
sum,
cin
);
wire [wb_nb-1:0]rdata[0:15]; //wishbone read data array
`ifdef wb_16bit
assign rdata[0]=kp;
assign rdata[1]=ki;
assign rdata[2]=kd;
assign rdata[3]=sp;
assign rdata[4]=pv;
assign rdata[5]=kpd;
assign rdata[6]=err[0];
assign rdata[7]=err[1];
assign rdata[8]=un[15:0];
assign rdata[9]=sigma[15:0];
assign rdata[10]={11'b0,of};
`endif
`ifdef wb_32bit
assign rdata[0]={{16{kp[15]}},kp};
assign rdata[1]={{16{ki[15]}},ki};
assign rdata[2]={{16{kd[15]}},kd};
assign rdata[3]={{16{sp[15]}},sp};
assign rdata[4]={{16{pv[15]}},pv};
assign rdata[5]={{16{kpd[15]}},kpd};
assign rdata[6]={{16{err[0][15]}},err[0]};
assign rdata[7]={{16{err[1][15]}},err[1]};
assign rdata[8]=un;
assign rdata[9]=sigma;
assign rdata[10]={27'b0,of};
`endif
`ifdef wb_64bit
assign rdata[0]={{48{kp[15]}},kp};
assign rdata[1]={{48{ki[15]}},ki};
assign rdata[2]={{48{kd[15]}},kd};
assign rdata[3]={{48{sp[15]}},sp};
assign rdata[4]={{48{pv[15]}},pv};
assign rdata[5]={{48{kpd[15]}},kpd};
assign rdata[6]={{48{err[0][15]}},err[0]};
assign rdata[7]={{48{err[1][15]}},err[1]};
assign rdata[8]={{32{un[31]}},un};
assign rdata[9]={{32{sigma[31]}},sigma};
assign rdata[10]={59'b0,of};
`endif
assign rdata[11]=0;
assign rdata[12]=0;
assign rdata[13]=0;
assign rdata[14]=0;
assign rdata[15]=0;
wire [0:15]rl;
assign rl={5'b0,rla,{4{rlb}},rla|rlb,5'b0};
wire rack; // wishbone read acknowledged
assign rack=(re&adr_check_1&(~rl[adr_1]))|(re&(~adr_check_1));
assign o_wb_ack=(wack|rack)&i_wb_stb;
assign o_wb_data=adr_check_1?rdata[adr_1]:0;
assign o_un=un;
assign o_valid=~rlb;
endmodule

View File

@ -0,0 +1,8 @@
//`define wb_16bit
`define wb_32bit
//`define wb_64bit
//`define PID_test
//`define PID_direct_test

View File

@ -0,0 +1,37 @@
/*Booth Encoder
Author: Zhu Xu
Email: m99a1@yahoo.cn
*/
module booth_radix4(
input [2:0]codes,
output zero,
output double,
output negation
);
wire A;
assign A=codes[2];
wire B;
assign B=codes[1];
wire C;
assign C=codes[0];
wire nB,nC,nA;
assign nB=~B;
assign nC=~C;
assign nA=~A;
wire BC;
assign BC=B&C;
wire nBnC;
assign nBnC=nB&nC;
wire nBanC;
assign nBanC=nB|nC;
assign double=(nBnC&A)|(BC&nA);
assign negation=A&nBanC;
assign zero=(A&BC)|(nA&nBnC);
endmodule

View File

@ -0,0 +1,207 @@
//==================================================================
// >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// ------------------------------------------------------------------
// Copyright (c) 2014 by Lattice Semiconductor Corporation
// ALL RIGHTS RESERVED
// ------------------------------------------------------------------
//
// Permission:
//
// Lattice SG Pte. Ltd. grants permission to use this code for use
// in synthesis for any Lattice programmable logic product. Other
// use of this code, including the selling or duplication of any
// portion is strictly prohibited.
//
// Disclaimer:
//
// This VHDL or Verilog source code is intended as a design reference
// which illustrates how these types of functions can be implemented.
// It is the user's responsibility to verify their design for
// consistency and functionality through the use of formal
// verification methods. Lattice provides no warranty
// regarding the use or functionality of this code.
//
// --------------------------------------------------------------------
//
// Lattice SG Pte. Ltd.
// 101 Thomson Road, United Square #07-02
// Singapore 307591
//
//
// TEL: 1-800-Lattice (USA and Canada)
// +65-6631-2000 (Singapore)
// +1-503-268-8001 (other locations)
//
// web: http://www.latticesemi.com/
// email: techsupport@latticesemi.com
//
// --------------------------------------------------------------------
//
module delay_gen_ihd_ipd_isd(
input clk,
input rst,
input start_stop,
input [15:0] isd_val,
input [15:0] ipd_val,
input config_reg_done,
input symbol_shift_done,
input packet_shift_done,
input hop_shift_done,
output reg isd_delay_en,
output reg ipd_delay_en
);
reg [15:0] isd_val_temp;
reg [15:0] ipd_val_temp;
reg [15:0] isd_count;
reg [15:0] ipd_count;
wire [20:0] max_count;
wire [20:0] max_count_pkt /* synthesis syn_multstyle = logic */;
reg clk_count,clk_count_pkt;
reg count_done,count_done_pkt;
parameter const_fact=20;
assign max_count=isd_val_temp * const_fact;
assign max_count_pkt=ipd_val_temp * const_fact;
//wire count_enable,count_enable_pkt;
reg count_enable,count_enable_pkt;
//wire config_done;
//assign config_done= !rst_n ? 0 : config_reg_done ? 1 : config_done; //orignal
//assign count_enable= rst ? 0 : count_done ? 0 : symbol_shift_done ? 1 : count_enable; //orignal
//assign count_enable_pkt= rst ? 0 : count_done_pkt ? 0 : (packet_shift_done || hop_shift_done) ? 1 : count_enable_pkt;
//assign isd_delay_en=symbol_shift_done ? 1 : (isd_count==max_count-1) :
///////**********modified 11/feb/2014*************** /////////
always @(posedge clk or posedge rst) begin
if(rst || !start_stop) begin
count_enable=0;
end
else begin
if(count_done)
count_enable=0;
else if(symbol_shift_done)
count_enable=1;
else
count_enable=count_enable;
end
end
always @(posedge clk or posedge rst) begin
if(rst || !start_stop) begin
count_enable_pkt=0;
end
else begin
if(count_done_pkt)
count_enable_pkt=0;
else if(packet_shift_done || hop_shift_done)
count_enable_pkt=1;
else
count_enable_pkt=count_enable_pkt;
end
end
/////////////////******************************//////////
///////////////////////symbol////////////////////////////////////
always @(posedge clk or posedge rst) begin
if(rst || !start_stop) begin
isd_count<=0;
count_done<=0;
isd_delay_en<=0;
end
else begin
count_done<=0;
if(count_enable) begin
if(isd_count==max_count) begin
isd_count<=0;
count_done<=1;
isd_delay_en<=0;
end
else begin
isd_delay_en<=1;
isd_count<=isd_count+1;
end
end
else begin
isd_delay_en<=0;
isd_count<=0;
end
end
end
always @(posedge clk or posedge rst) begin
if(rst || !start_stop) begin
isd_val_temp<=0;
clk_count<=0;
end
else begin
if(!config_reg_done) begin
isd_val_temp<=isd_val;
clk_count<=0;
end
else if(config_reg_done) begin
clk_count<=clk_count+1;
isd_val_temp<=isd_val;
end
else begin
isd_val_temp<=isd_val_temp;
end
end
end
///////////////packet//////////////////////
always @(posedge clk or posedge rst) begin
if(rst || !start_stop) begin
ipd_count<=0;
count_done_pkt<=0;
ipd_delay_en<=0;
end
else begin
count_done_pkt<=0;
if(count_enable_pkt) begin
if(ipd_count==max_count_pkt) begin
ipd_count<=0;
count_done_pkt<=1;
ipd_delay_en<=0;
end
else begin
ipd_delay_en<=1;
ipd_count<=ipd_count+1;
end
end
else begin
ipd_delay_en<=0;
ipd_count<=0;
end
end
end
always @(posedge clk or posedge rst) begin
if(rst || !start_stop) begin
ipd_val_temp<=0;
clk_count_pkt<=0;
end
else begin
if(!config_reg_done) begin
ipd_val_temp<=ipd_val;
clk_count_pkt<=0;
end
else if(config_reg_done) begin
clk_count_pkt<=clk_count_pkt+1;
ipd_val_temp<=ipd_val;
end
else begin // if(!config_reg_done) begin
ipd_val_temp<=ipd_val_temp;
end
end
end
endmodule

View File

@ -0,0 +1,369 @@
//==================================================================
// >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// ------------------------------------------------------------------
// Copyright (c) 2014 by Lattice Semiconductor Corporation
// ALL RIGHTS RESERVED
// ------------------------------------------------------------------
//
// Permission:
//
// Lattice SG Pte. Ltd. grants permission to use this code for use
// in synthesis for any Lattice programmable logic product. Other
// use of this code, including the selling or duplication of any
// portion is strictly prohibited.
//
// Disclaimer:
//
// This VHDL or Verilog source code is intended as a design reference
// which illustrates how these types of functions can be implemented.
// It is the user's responsibility to verify their design for
// consistency and functionality through the use of formal
// verification methods. Lattice provides no warranty
// regarding the use or functionality of this code.
//
// --------------------------------------------------------------------
//
// Lattice SG Pte. Ltd.
// 101 Thomson Road, United Square #07-02
// Singapore 307591
//
//
// TEL: 1-800-Lattice (USA and Canada)
// +65-6631-2000 (Singapore)
// +1-503-268-8001 (other locations)
//
// web: http://www.latticesemi.com/
// email: techsupport@latticesemi.com
//
// --------------------------------------------------------------------
//
/***********************************************************************
* *
* EFB REGISTER SET *
* *
***********************************************************************/
`define MICO_EFB_I2C_CR 8'h08
`define MICO_EFB_I2C_CMDR 8'h09
`define MICO_EFB_I2C_BLOR 8'h0a
`define MICO_EFB_I2C_BHIR 8'h0b
`define MICO_EFB_I2C_TXDR 8'h0d
`define MICO_EFB_I2C_SR 8'h0c
`define MICO_EFB_I2C_GCDR 8'h0f
`define MICO_EFB_I2C_RXDR 8'h0e
`define MICO_EFB_I2C_IRQSR 8'h06
`define MICO_EFB_I2C_IRQENR 8'h09
/***********************************************************************
* *
* EFB I2C CONTROLLER PHYSICAL DEVICE SPECIFIC INFORMATION *
* *
***********************************************************************/
// Control Register Bit Masks
`define MICO_EFB_I2C_CR_I2CEN 8'h80
`define MICO_EFB_I2C_CR_GCEN 8'h40
`define MICO_EFB_I2C_CR_WKUPEN 8'h20
// Status Register Bit Masks
`define MICO_EFB_I2C_SR_TIP 8'h80
`define MICO_EFB_I2C_SR_BUSY 8'h40
`define MICO_EFB_I2C_SR_RARC 8'h20
`define MICO_EFB_I2C_SR_SRW 8'h10
`define MICO_EFB_I2C_SR_ARBL 8'h08
`define MICO_EFB_I2C_SR_TRRDY 8'h04
`define MICO_EFB_I2C_SR_TROE 8'h02
`define MICO_EFB_I2C_SR_HGC 8'h01
// Command Register Bit Masks
`define MICO_EFB_I2C_CMDR_STA 8'h80
`define MICO_EFB_I2C_CMDR_STO 8'h40
`define MICO_EFB_I2C_CMDR_RD 8'h20
`define MICO_EFB_I2C_CMDR_WR 8'h10
`define MICO_EFB_I2C_CMDR_NACK 8'h08
`define MICO_EFB_I2C_CMDR_CKSDIS 8'h04
/***********************************************************************
* *
* CODE SPECIFIC *
* *
***********************************************************************/
`define ALL_ZERO 8'h00
`define READ 1'b0
`define READ 1'b0
`define HIGH 1'b1
`define WRITE 1'b1
`define LOW 1'b0
`define READ_STATUS 1'b0
`define READ_DATA 1'b0
/***********************************************************************
* *
* State Machine Variables *
* *
***********************************************************************/
`define state0 8'd00
`define state1 8'd01
`define state2 8'd02
`define state3 8'd03
`define state4 8'd04
`define state5 8'd05
`define state6 8'd06
`define state7 8'd07
`define state8 8'd08
`define state9 8'd09
`define state10 8'd10
`define state11 8'd11
`define state12 8'd12
`define state13 8'd13
`define state14 8'd14
`define state15 8'd15
`define state16 8'd16
`define state17 8'd17
`define state18 8'd18
`define state19 8'd19
`define state20 8'd20
`define state21 8'd21
`define state22 8'd22
`define state23 8'd23
`define state24 8'd24
`define state25 8'd25
`define state26 8'd26
`define state27 8'd27
`define state28 8'd28
`define state29 8'd29
`define state30 8'd30
`define state31 8'd31
`define state32 8'd32
`define state33 8'd33
`define state34 8'd34
`define state35 8'd35
`define state36 8'd36
`define state37 8'd37
`define state38 8'd38
`define state39 8'd39
`define state40 8'd40
`define state41 8'd41
`define state42 8'd42
`define state43 8'd43
`define state44 8'd44
`define state45 8'd45
`define state46 8'd46
`define state47 8'd47
`define state48 8'd48
`define state49 8'd49
`define state50 8'd50
`define state51 8'd51
`define state52 8'd52
`define state53 8'd53
`define state54 8'd54
`define state55 8'd55
`define state56 8'd56
`define state57 8'd57
`define state58 8'd58
`define state59 8'd59
`define state60 8'd60
`define state61 8'd61
`define state62 8'd62
`define state63 8'd63
`define state64 8'd64
`define state65 8'd65
`define state66 8'd66
`define state67 8'd67
`define state68 8'd68
`define state69 8'd69
`define state70 8'd70
`define state71 8'd71
`define state72 8'd72
`define state73 8'd73
`define state74 8'd74
`define state75 8'd75
`define state76 8'd76
`define state77 8'd77
`define state78 8'd78
`define state79 8'd79
`define state80 8'd80
`define state81 8'd81
`define state82 8'd82
`define state83 8'd83
`define state84 8'd84
`define state85 8'd85
`define state86 8'd86
`define state87 8'd87
`define state88 8'd88
`define state89 8'd89
`define state90 8'd90
`define state91 8'd91
`define state92 8'd92
`define state93 8'd93
`define state94 8'd94
`define state95 8'd95
`define state96 8'd96
`define state97 8'd97
`define state98 8'd98
`define state99 8'd99
`define state100 8'd100
`define state101 8'd101
`define state102 8'd102
`define state103 8'd103
`define state104 8'd104
`define state105 8'd105
`define state106 8'd106
`define state107 8'd107
`define state108 8'd108
`define state109 8'd109
`define state110 8'd110
`define state111 8'd111
`define state112 8'd112
`define state113 8'd113
`define state114 8'd114
`define state115 8'd115
`define state116 8'd116
`define state117 8'd117
`define state118 8'd118
`define state119 8'd119
`define state120 8'd120
`define state121 8'd121
`define state122 8'd122
`define state123 8'd123
`define state124 8'd124
`define state125 8'd125
`define state126 8'd126
`define state127 8'd127
`define state128 8'd128
`define state129 8'd129
`define state130 8'd130
`define state131 8'd131
`define state132 8'd132
`define state133 8'd133
`define state134 8'd134
`define state135 8'd135
`define state136 8'd136
`define state137 8'd137
`define state138 8'd138
`define state139 8'd139
`define state140 8'd140
`define state141 8'd141
`define state142 8'd142
`define state143 8'd143
`define state144 8'd144
`define state145 8'd145
`define state146 8'd146
`define state147 8'd147
`define state148 8'd148
`define state149 8'd149
`define state150 8'd150
`define state151 8'd151
`define state152 8'd152
`define state153 8'd153
`define state154 8'd154
`define state155 8'd155
`define state156 8'd156
`define state157 8'd157
`define state158 8'd158
`define state159 8'd159
`define state160 8'd160
`define state161 8'd161
`define state162 8'd162
`define state163 8'd163
`define state164 8'd164
`define state165 8'd165
`define state166 8'd166
`define state167 8'd167
`define state168 8'd168
`define state169 8'd169
`define state170 8'd170
`define state171 8'd171
`define state172 8'd172
`define state173 8'd173
`define state174 8'd174
`define state175 8'd175
`define state176 8'd176
`define state177 8'd177
`define state178 8'd178
`define state179 8'd179
`define state180 8'd180
`define state181 8'd181
`define state182 8'd182
`define state183 8'd183
`define state184 8'd184
`define state185 8'd185
`define state186 8'd186
`define state187 8'd187
`define state188 8'd188
`define state189 8'd189
`define state190 8'd190
`define state191 8'd191
`define state192 8'd192
`define state193 8'd193
`define state194 8'd194
`define state195 8'd195
`define state196 8'd196
`define state197 8'd197
`define state198 8'd198
`define state199 8'd199
`define state200 8'd200
`define state201 8'd201
`define state202 8'd202
`define state203 8'd203
`define state204 8'd204
`define state205 8'd205
`define state206 8'd206
`define state207 8'd207
`define state208 8'd208
`define state209 8'd209
`define state210 8'd210
`define state211 8'd211
`define state212 8'd212
`define state213 8'd213
`define state214 8'd214
`define state215 8'd215
`define state216 8'd216
`define state217 8'd217
`define state218 8'd218
`define state219 8'd219
`define state220 8'd220
`define state221 8'd221
`define state222 8'd222
`define state223 8'd223
`define state224 8'd224
`define state225 8'd225
`define state226 8'd226
`define state227 8'd227
`define state228 8'd228
`define state229 8'd229
`define state230 8'd230
`define state231 8'd231
`define state232 8'd232
`define state233 8'd233
`define state234 8'd234
`define state235 8'd235
`define state236 8'd236
`define state237 8'd237
`define state238 8'd238
`define state239 8'd239
`define state240 8'd240
`define state241 8'd241
`define state242 8'd242
`define state243 8'd243
`define state244 8'd244
`define state245 8'd245
`define state246 8'd246
`define state247 8'd247
`define state248 8'd248
`define state249 8'd249
`define state250 8'd250
`define state251 8'd251
`define state252 8'd252
`define state253 8'd253
`define state254 8'd254
`define state255 8'd255

View File

@ -0,0 +1,649 @@
//==================================================================
// >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// ------------------------------------------------------------------
// Copyright (c) 2014 by Lattice Semiconductor Corporation
// ALL RIGHTS RESERVED
// ------------------------------------------------------------------
//
// Permission:
//
// Lattice SG Pte. Ltd. grants permission to use this code for use
// in synthesis for any Lattice programmable logic product. Other
// use of this code, including the selling or duplication of any
// portion is strictly prohibited.
//
// Disclaimer:
//
// This VHDL or Verilog source code is intended as a design reference
// which illustrates how these types of functions can be implemented.
// It is the user's responsibility to verify their design for
// consistency and functionality through the use of formal
// verification methods. Lattice provides no warranty
// regarding the use or functionality of this code.
//
// --------------------------------------------------------------------
//
// Lattice SG Pte. Ltd.
// 101 Thomson Road, United Square #07-02
// Singapore 307591
//
//
// TEL: 1-800-Lattice (USA and Canada)
// +65-6631-2000 (Singapore)
// +1-503-268-8001 (other locations)
//
// web: http://www.latticesemi.com/
// email: techsupport@latticesemi.com
//
// --------------------------------------------------------------------
//
`include "i2c_defines.v"
`include "i2c_new_reg.v"
`timescale 1 ns / 1 ns
module serialInterface (/*AUTOARG*/
// Outputs
dataOut, regAddr, sdaOut, writeEn, readEn, i2c_start,
// Inputs
clk, dataIn, rst, scl, sdaIn
);
input clk;
input [7:0] dataIn;
input rst;
input scl;
input sdaIn;
output [7:0] dataOut;
output [7:0] regAddr;
output sdaOut;
output writeEn;
output readEn;
output i2c_start;
// I2C_SLAVE_INIT_ADDR: Upper Bits <9:2> can be changed. Lower bits <1:0> are fixed.
// For I2C Hard IP located in Upper Left <1:0> must be set to "01".
// For I2C Hard IP located in Upper Right <1:0> must be set to "10".
parameter I2C_SLAVE_INIT_ADDR = "0b1111100001"; //Upper Left
//parameter I2C_SLAVE_INIT_ADDR = "0b1111100010"; //Upper Right
// BUS_ADDR74: Fixed value. SBADRI [7:4] bits also should match with this value to
// activate the IP.
// For I2C Hard IP located in Upper Left [7:4] must be set to "0001".
// For I2C Hard IP located in Upper Right [7:4] must be set to "0011".
parameter BUS_ADDR74_STRING = "0b0001"; //Upper Left
//parameter BUS_ADDR74_STRING = "0b0011"; //Upper Right
// These are for the "OR" function with "wb_adr_i". Note that bits [7:4] are copies
// of BUS_ADDR74_STRING.
parameter BUS_ADDR74 = 8'b0001_0000; //Upper Left
//parameter BUS_ADDR74 = 8'b0011_0000; //Upper Right
reg [7:0] regAddr;
reg writeEn;
wire [7:0] dataOut;
reg i2c_start;
/*
* System bus interface signals
*/
reg [7:0] wb_dat_i;
reg wb_stb_i;
reg [7:0] wb_adr_i;
reg wb_we_i;
wire [7:0] wb_dat_o;
wire wb_ack_o;
/*
* Data Read and Write Register
*/
reg [7:0] temp0;
reg [7:0] temp1;
reg [7:0] temp2;
reg [7:0] temp3;
reg [7:0] n_temp0;
reg [7:0] n_temp1;
reg [7:0] n_temp2;
reg [7:0] n_temp3;
reg readEn;
/*
* i2c Module Instanitiation
*/
i2c UUT1 (
.wb_clk_i (clk),
.wb_dat_i (wb_dat_i),
.wb_stb_i (wb_stb_i),
.wb_adr_i (wb_adr_i | BUS_ADDR74),
.wb_we_i (wb_we_i),
.wb_dat_o (wb_dat_o),
.wb_ack_o (wb_ack_o),
.i2c_irqo ( ),
.i2c_scl (scl),
.i2c_sda (sdaOut),
.i2c_sda_in (sdaIn),
.rst_i(rst)
);
defparam UUT1.I2C_SLAVE_INIT_ADDR = I2C_SLAVE_INIT_ADDR;
defparam UUT1.BUS_ADDR74_STRING = BUS_ADDR74_STRING;
/*
* Signal & wire Declartion
*/
reg efb_flag;
reg n_efb_flag;
reg [7:0] n_wb_dat_i;
reg n_wb_stb_i;
reg [7:0] n_wb_adr_i;
reg n_wb_we_i;
reg [7:0] c_state;
reg [7:0] n_state;
reg n_count_en;
reg count_en;
wire invalid_command = 0;
/*
* Output generation
*/
assign dataOut = temp3;
always @(posedge clk or posedge rst)begin
if (rst)begin
writeEn <= 0;
readEn <= 0;
end else begin
if(c_state == `state14)begin
writeEn <= 1'b1;
end else begin
writeEn <= 1'b0;
end
if(c_state == `state15)begin
readEn <= 1'b1;
end else if (c_state == `state13) begin //**
if (n_temp2 & (`MICO_EFB_I2C_SR_SRW)) begin
readEn <= 1'b1;
end else begin
readEn <= 1'b0;
end
end else begin
readEn <= 1'b0;
end
end
end
always @(posedge clk or posedge rst)begin
if (rst)begin
regAddr <= 0;
end else begin
if(c_state == `state2)begin
regAddr <= 8'd0;
end else if(c_state == `state9)begin
regAddr <= temp1;
//end else if(writeEn || readEn)begin
// regAddr <= regAddr + 1;
end
end
end
//slave start detect
always @(posedge clk or posedge rst) begin
if (rst) begin
i2c_start <= 0;
end else begin
if (c_state == `state12) begin
i2c_start <= 0;
end else if (c_state == `state9) begin
i2c_start <= 1;
end
end
end
/*
* Main state machine
*/
always @ (posedge clk or posedge rst) begin
if(rst) begin
wb_dat_i <= 8'h00;
wb_stb_i <= 1'b0 ;
wb_adr_i <= 8'h00;
wb_we_i <= 1'b0;
end else begin
wb_dat_i <= #1 n_wb_dat_i;
wb_stb_i <= #1 n_wb_stb_i;
wb_adr_i <= #1 n_wb_adr_i;
wb_we_i <= #1 n_wb_we_i ;
end
end
always @ (posedge clk or posedge rst) begin
if(rst) begin
c_state <= 10'h000;
efb_flag <= 1'b0 ;
count_en <= 1'b0;
end else begin
c_state <= n_state ;
efb_flag <= n_efb_flag;
count_en <= n_count_en;
end
end
always @ (posedge clk or posedge rst) begin
if(rst) begin
temp0 <= 8'h00 ;
temp1 <= 8'h00 ;
temp2 <= 8'h00 ;
temp3 <= 8'h00 ;
end else begin
temp0 <= n_temp0 ;
temp1 <= n_temp1 ;
temp2 <= n_temp2 ;
temp3 <= n_temp3 ;
end
end
always @(posedge clk or posedge rst) begin
if (rst) begin
n_temp2 <= 0;
end else begin
n_temp2 <= wb_dat_o; //**
end
end
/*
* FSM combinational block
*/
always @ ( * ) begin
n_efb_flag = 1'b0 ;
n_state = c_state ;
n_wb_dat_i = 8'h00;
n_wb_stb_i = 1'b0 ;
n_wb_adr_i = 8'h00;
n_wb_we_i = 1'b0;
n_count_en = 1'b0;
n_temp0 = temp0;
n_temp1 = temp1;
n_temp3 = temp3;
case(c_state)
`state0: begin
n_wb_dat_i = 8'h00;
n_wb_stb_i = 1'b0 ;
n_wb_adr_i = 8'h00;
n_wb_we_i = 1'b0;
n_wb_stb_i = 1'b0 ;
n_state = `state1 ;
end
`state1: begin // Enable I2C Interface
if (wb_ack_o && efb_flag) begin
n_wb_dat_i = `ALL_ZERO ;
n_wb_adr_i = `ALL_ZERO ;
n_wb_we_i = `LOW ;
n_wb_stb_i = `LOW ;
n_efb_flag = `LOW ;
n_count_en = `LOW ;
n_state = `state2;
end else begin
n_efb_flag = `HIGH ;
n_wb_we_i = `WRITE;
n_wb_adr_i = `MICO_EFB_I2C_CR;
n_wb_dat_i = 8'h80;
n_wb_stb_i = `HIGH ;
n_state = c_state;
end
end
`state2: begin // Clock Disable
if (wb_ack_o && efb_flag) begin
n_wb_dat_i = `ALL_ZERO ;
n_wb_adr_i = `ALL_ZERO ;
n_wb_we_i = `LOW ;
n_wb_stb_i = `LOW ;
n_efb_flag = `LOW ;
n_count_en = `LOW ;
n_state = `state3;
end else begin
n_efb_flag = `HIGH ;
n_wb_we_i = `WRITE;
n_wb_adr_i = `MICO_EFB_I2C_CMDR;
n_wb_dat_i = 8'h04;
n_wb_stb_i = `HIGH ;
n_state = c_state;
end
end
`state3: begin // Wait for not BUSY
if (wb_ack_o && efb_flag) begin
n_wb_dat_i = `ALL_ZERO ;
n_wb_adr_i = `ALL_ZERO ;
n_wb_we_i = `LOW ;
n_wb_stb_i = `LOW ;
n_efb_flag = `LOW ;
n_count_en = `LOW ;
if(wb_dat_o & (`MICO_EFB_I2C_SR_BUSY))begin
n_state = `state4;
end else begin
n_state = c_state;
end
end else begin
n_efb_flag = `HIGH ;
n_wb_we_i = `READ_STATUS;
n_wb_adr_i = `MICO_EFB_I2C_SR;
n_wb_dat_i = 0 ;
n_wb_stb_i = `HIGH ;
n_state = c_state;
end
end
`state4: begin // Discard data 1
if (wb_ack_o && efb_flag) begin
n_wb_dat_i = `ALL_ZERO ;
n_wb_adr_i = `ALL_ZERO ;
n_wb_we_i = `LOW ;
n_wb_stb_i = `LOW ;
n_efb_flag = `LOW ;
n_count_en = `LOW ;
n_temp0 = wb_dat_o;
n_state = `state5;
end else begin
n_efb_flag = `HIGH ;
n_wb_we_i = `READ_DATA;
n_wb_adr_i = `MICO_EFB_I2C_RXDR;
n_wb_dat_i = 0 ;
n_wb_stb_i = `HIGH ;
n_state = c_state;
end
end
`state5: begin // Discard data 2
if (wb_ack_o && efb_flag) begin
n_wb_dat_i = `ALL_ZERO ;
n_wb_adr_i = `ALL_ZERO ;
n_wb_we_i = `LOW ;
n_wb_stb_i = `LOW ;
n_efb_flag = `LOW ;
n_count_en = `LOW ;
n_temp0 = wb_dat_o;
n_state = `state6;
end else begin
n_efb_flag = `HIGH ;
n_wb_we_i = `READ_DATA;
n_wb_adr_i = `MICO_EFB_I2C_RXDR;
n_wb_dat_i = 0 ;
n_wb_stb_i = `HIGH ;
n_state = c_state;
end
end
`state6: begin // Clock Enable
if (wb_ack_o && efb_flag) begin
n_wb_dat_i = `ALL_ZERO ;
n_wb_adr_i = `ALL_ZERO ;
n_wb_we_i = `LOW ;
n_wb_stb_i = `LOW ;
n_efb_flag = `LOW ;
n_count_en = `LOW ;
n_state = `state7;
end else begin
n_efb_flag = `HIGH;
n_wb_we_i = `WRITE;
n_wb_adr_i = `MICO_EFB_I2C_CMDR;
n_wb_dat_i = 8'h00;
n_wb_stb_i = `HIGH ;
n_state = c_state;
end
end
`state7: begin // wait for data to come
if (wb_ack_o && efb_flag) begin
n_wb_dat_i = `ALL_ZERO ;
n_wb_adr_i = `ALL_ZERO ;
n_wb_we_i = `LOW ;
n_wb_stb_i = `LOW ;
n_efb_flag = `LOW ;
n_count_en = `LOW ;
n_temp1 = 8'h00;
if((wb_dat_o & (`MICO_EFB_I2C_SR_TRRDY)))begin
n_state = `state8; // Slave acknowledged
end else if (~wb_dat_o[6])begin
n_state = `state2; // Disable clock
end else begin
n_state = c_state;
end
end else begin
n_efb_flag = `HIGH ;
n_wb_we_i = `READ_STATUS;
n_wb_adr_i = `MICO_EFB_I2C_SR;
n_wb_dat_i = 0 ;
n_wb_stb_i = `HIGH ;
n_state = c_state;
end
end
`state8: begin // Store i2C Command Information
if (wb_ack_o && efb_flag) begin
n_wb_dat_i = `ALL_ZERO ;
n_wb_adr_i = `ALL_ZERO ;
n_wb_we_i = `LOW ;
n_wb_stb_i = `LOW ;
n_efb_flag = `LOW ;
n_count_en = `LOW ;
n_temp1 = wb_dat_o;
n_state = `state9;
end else begin
n_efb_flag = `HIGH ;
n_wb_we_i = `READ_DATA;
n_wb_adr_i = `MICO_EFB_I2C_RXDR;
n_wb_dat_i = 0 ;
n_wb_stb_i = `HIGH ;
n_state = c_state;
end
end
`state9: begin // Send ACK or NACK Based upon Command Receive & Wait for Stop `state 17
if (wb_ack_o && efb_flag) begin
n_wb_dat_i = `ALL_ZERO ;
n_wb_adr_i = `ALL_ZERO ;
n_wb_we_i = `LOW ;
n_wb_stb_i = `LOW ;
n_efb_flag = `LOW ;
n_count_en = `LOW ;
if(invalid_command)begin // This is tied to '0' at present
n_state = `state17;
end else begin
n_state = `state12;
end
end else begin
n_efb_flag = `HIGH ;
n_wb_we_i = `WRITE;
n_wb_adr_i = `MICO_EFB_I2C_CMDR;
n_wb_dat_i = {4'h0,invalid_command,3'b000};
n_wb_stb_i = `HIGH ;
n_state = c_state;
end
end
`state12: begin // Wait for TRRDY Bit
if (wb_ack_o && efb_flag) begin
n_wb_dat_i = `ALL_ZERO ;
n_wb_adr_i = `ALL_ZERO ;
n_wb_we_i = `LOW ;
n_wb_stb_i = `LOW ;
n_efb_flag = `LOW ;
n_count_en = `LOW ;
if(wb_dat_o & (`MICO_EFB_I2C_SR_TRRDY))begin
n_state = `state13;
end else if (~wb_dat_o[6])begin
n_state = `state2;
end else begin
n_state = c_state;
end
end else begin
n_efb_flag = `HIGH ;
n_wb_we_i = `READ_STATUS;
n_wb_adr_i = `MICO_EFB_I2C_SR;
n_wb_dat_i = 0 ;
n_wb_stb_i = `HIGH ;
n_state = c_state;
end
end
`state13: begin // Check for read or write operation
if (wb_ack_o && efb_flag) begin
n_wb_dat_i = `ALL_ZERO ;
n_wb_adr_i = `ALL_ZERO ;
n_wb_we_i = `LOW ;
n_wb_stb_i = `LOW ;
n_efb_flag = `LOW ;
n_count_en = `LOW ;
if(wb_dat_o & (`MICO_EFB_I2C_SR_SRW))begin
n_state = `state15; //Read from slave
end else begin
n_state = `state14; //Write to slave
end
end else begin
n_efb_flag = `HIGH ;
n_wb_we_i = `READ_STATUS;
n_wb_adr_i = `MICO_EFB_I2C_SR;
n_wb_dat_i = 0 ;
n_wb_stb_i = `HIGH ;
n_state = c_state;
end
end
`state14: begin // Write data
if (wb_ack_o && efb_flag) begin
n_wb_dat_i = `ALL_ZERO ;
n_wb_adr_i = `ALL_ZERO ;
n_wb_we_i = `LOW ;
n_wb_stb_i = `LOW ;
n_efb_flag = `LOW ;
n_count_en = `LOW ;
n_temp3 = wb_dat_o;
n_state = `state19;
end else begin
n_efb_flag = `HIGH ;
n_wb_we_i = `READ_DATA;
n_wb_adr_i = `MICO_EFB_I2C_RXDR;
n_wb_dat_i = 0 ;
n_wb_stb_i = `HIGH ;
n_state = c_state;
end
end
`state15: begin // Send Data to Master
if (wb_ack_o && efb_flag) begin
n_wb_dat_i = `ALL_ZERO ;
n_wb_adr_i = `ALL_ZERO ;
n_wb_we_i = `LOW ;
n_wb_stb_i = `LOW ;
n_efb_flag = `LOW ;
n_count_en = `LOW ;
n_state = `state18;
end else begin
n_efb_flag = `HIGH ;
n_wb_we_i = `WRITE;
n_wb_adr_i = `MICO_EFB_I2C_TXDR;
n_wb_dat_i = dataIn;
n_wb_stb_i = `HIGH ;
n_state = c_state;
end
end
`state17: begin // Wait till Stop is Send
if (wb_ack_o && efb_flag) begin
n_wb_dat_i = `ALL_ZERO ;
n_wb_adr_i = `ALL_ZERO ;
n_wb_we_i = `LOW ;
n_wb_stb_i = `LOW ;
n_efb_flag = `LOW ;
n_count_en = `LOW ;
if(~wb_dat_o[6])begin
n_state = `state2;
end else begin
n_state = c_state;
end
end else begin
n_efb_flag = `HIGH ;
n_wb_we_i = `READ_STATUS;
n_wb_adr_i = `MICO_EFB_I2C_SR;
n_wb_dat_i = 0 ;
n_wb_stb_i = `HIGH ;
n_state = c_state;
end
end
`state18: begin // Wait for TxRDY flag and send data again if required
if (wb_ack_o && efb_flag) begin
n_wb_dat_i = `ALL_ZERO ;
n_wb_adr_i = `ALL_ZERO ;
n_wb_we_i = `LOW ;
n_wb_stb_i = `LOW ;
n_efb_flag = `LOW ;
n_count_en = `LOW ;
if(wb_dat_o & (`MICO_EFB_I2C_SR_TRRDY))begin
n_state = `state15; // Send Data
end else if (~wb_dat_o[6]) begin// If Stop go to beginning
n_state = `state2;
end else begin
n_state = c_state;
end
end else begin
n_efb_flag = `HIGH ;
n_wb_we_i = `READ_STATUS;
n_wb_adr_i = `MICO_EFB_I2C_SR;
n_wb_dat_i = 0 ;
n_wb_stb_i = `HIGH ;
n_state = c_state;
end
end
`state19: begin // Wait for TRRDY bit
if (wb_ack_o && efb_flag) begin
n_wb_dat_i = `ALL_ZERO ;
n_wb_adr_i = `ALL_ZERO ;
n_wb_we_i = `LOW ;
n_wb_stb_i = `LOW ;
n_efb_flag = `LOW ;
n_count_en = `LOW ;
if(wb_dat_o & (`MICO_EFB_I2C_SR_TRRDY)) begin
n_state = `state14;
end else if (~wb_dat_o[6])begin
n_state = `state2;
end else begin
n_state = c_state;
end
end else begin
n_efb_flag = `HIGH ;
n_wb_we_i = `READ_STATUS;
n_wb_adr_i = `MICO_EFB_I2C_SR;
n_wb_dat_i = 0 ;
n_wb_stb_i = `HIGH ;
n_state = c_state;
end
end
endcase
end
endmodule

View File

@ -0,0 +1,203 @@
//==================================================================
// >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// ------------------------------------------------------------------
// Copyright (c) 2014 by Lattice Semiconductor Corporation
// ALL RIGHTS RESERVED
// ------------------------------------------------------------------
//
// Permission:
//
// Lattice SG Pte. Ltd. grants permission to use this code for use
// in synthesis for any Lattice programmable logic product. Other
// use of this code, including the selling or duplication of any
// portion is strictly prohibited.
//
// Disclaimer:
//
// This VHDL or Verilog source code is intended as a design reference
// which illustrates how these types of functions can be implemented.
// It is the user's responsibility to verify their design for
// consistency and functionality through the use of formal
// verification methods. Lattice provides no warranty
// regarding the use or functionality of this code.
//
// --------------------------------------------------------------------
//
// Lattice SG Pte. Ltd.
// 101 Thomson Road, United Square #07-02
// Singapore 307591
//
//
// TEL: 1-800-Lattice (USA and Canada)
// +65-6631-2000 (Singapore)
// +1-503-268-8001 (other locations)
//
// web: http://www.latticesemi.com/
// email: techsupport@latticesemi.com
//
// --------------------------------------------------------------------
//
module led_driver (
input sys_clk,
input rst_n,
input txn_start,
input mobeam_start_stop,
input led_polarity,
input [7:0] bar_width,
input [7:0] barcode_array,
output drive_on,
output byte_done,
output bit_done,
output oled
//output dynamic_clk);
);
//reg [15:0] clk_count;
/*
always @(posedge sys_clk or negedge rst_n)
begin
if (~rst_n)
clk_count <= 16'b0;
else
if (clk_count==16'd4)
clk_count<= 0;
else
clk_count <= clk_count + 1'b1;
end */// always @ (posedge sys_clk or negedge rst_n)
// assign dynamic_clk = (clk_count==16'd4);
reg oled,drive_on;
reg oled_int;
reg [15:0] bw_count;
reg [7:0] ba_reg = 8'b10011001;
reg reload_ba_reg;
reg driver_busy;
wire [7:0] BW;
reg [15:0] BWx10 /* synthesis syn_multstyle = logic */;
reg [2:0] bit_cnt;
reg byte_done_int;
reg txn_start_d;
/////////////////TXN_Start edge detect/////////////////
always @(posedge sys_clk or negedge rst_n)
begin
if (~rst_n || !mobeam_start_stop) begin
txn_start_d<= 1'b0;
end
else
txn_start_d<=txn_start;
end
assign txn_start_pos = txn_start & (~txn_start_d);
assign BW =bar_width;
//assign byte_done_mod= (&bit_cnt) & reload_ba_reg;
//assign byte_done_mod= (&bit_cnt) && (bw_count==1'b1);
assign byte_done_mod= (BWx10==16'd4)?(&bit_cnt) && (bw_count==1'b1):byte_done_int;
assign byte_done = byte_done_mod;
assign bit_done = reload_ba_reg;
// assign BWx10 = BW * 10 - 1'b1;
always @(posedge sys_clk or negedge rst_n)
begin
if (~rst_n || !mobeam_start_stop) begin
ba_reg <= 8'd0;
BWx10<=16'd4;
byte_done_int<= 1'b0;
bit_cnt<= 3'd0;
end
else begin
if (BW==0)
BWx10<= 4;
else begin
BWx10 <= BW * 10 - 1'b1;
// BWX5 <= BW * 5 - 1'b1; //for 25% duty cycle
// BWX15 <=
end
//if (txn_start_pos) begin
if (txn_start && bit_cnt==3'd0) begin
ba_reg <=barcode_array;
end
if (reload_ba_reg) begin
//ba_reg <= {ba_reg[0],ba_reg[7:1]}; //lsb first
ba_reg <= {ba_reg[6:0],ba_reg[7]}; //msb first
if (bit_cnt==3'd7)
byte_done_int<=1'b1;
else
byte_done_int<=1'b0;
if (&bit_cnt) begin
//byte_done_int<=1'b1;
bit_cnt<= 3'd0;
end
else begin
// byte_done_int<= 1'b0;
bit_cnt<= bit_cnt + 1'b1;
end
end
else
byte_done_int<= 1'b0;
end
end
always @(posedge sys_clk or negedge rst_n)
begin
if (~rst_n || !mobeam_start_stop)
begin
oled_int <= 1'b0;
bw_count <= 16'b0;
reload_ba_reg <= 1'b0;
driver_busy<= 1'b0;
end
else
if (txn_start) begin
// driver_busy<= 1'b1;
if (bw_count == BWx10)
begin
//oled<=ba_reg[0]; //lsb_first
oled_int<=ba_reg[7]; //msb first
bw_count<=16'b0;
reload_ba_reg <= 1'b1;
end
else begin
oled_int<= oled_int;
bw_count<= bw_count + 1'b1;
reload_ba_reg <= 1'b0;
end
end
else
reload_ba_reg <= 1'b0;
end // always @ (posedge sys_clk or negedge rst_n)
always @(posedge sys_clk ) begin
if (~rst_n || !mobeam_start_stop) begin
oled<=0;
end else begin
if(led_polarity)begin
oled <= oled_int;
drive_on<=oled_int;
end else begin
oled <= ~oled_int;
drive_on<=~oled_int;
end
end
end
endmodule // clk_gen

View File

@ -0,0 +1,160 @@
//==================================================================
// >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// ------------------------------------------------------------------
// Copyright (c) 2014 by Lattice Semiconductor Corporation
// ALL RIGHTS RESERVED
// ------------------------------------------------------------------
//
// Permission:
//
// Lattice SG Pte. Ltd. grants permission to use this code for use
// in synthesis for any Lattice programmable logic product. Other
// use of this code, including the selling or duplication of any
// portion is strictly prohibited.
//
// Disclaimer:
//
// This VHDL or Verilog source code is intended as a design reference
// which illustrates how these types of functions can be implemented.
// It is the user's responsibility to verify their design for
// consistency and functionality through the use of formal
// verification methods. Lattice provides no warranty
// regarding the use or functionality of this code.
//
// --------------------------------------------------------------------
//
// Lattice SG Pte. Ltd.
// 101 Thomson Road, United Square #07-02
// Singapore 307591
//
//
// TEL: 1-800-Lattice (USA and Canada)
// +65-6631-2000 (Singapore)
// +1-503-268-8001 (other locations)
//
// web: http://www.latticesemi.com/
// email: techsupport@latticesemi.com
//
// --------------------------------------------------------------------
//
module mobeam_delay_gen(
input clk,
input rst_n,
input [15:0] isd_val,
input [15:0] ipd_val,
input config_reg_done,
input symbol_shift_done,
input packet_shift_done,
output reg isd_delay_en,
output reg ipd_delay_en
);
reg [15:0] isd_val_temp;
reg [15:0] ipd_val_temp;
reg [15:0] isd_count;
reg [15:0] ipd_count;
wire [15:0] max_count,max_count_pkt;
reg clk_count,clk_count_pkt;
reg count_done,count_done_pkt;
parameter const=10;
assign max_count=isd_val_temp * const;
assign max_count_pkt=ipd_val_temp * const;
wire count_enable,count_enable_pkt;
//wire config_done;
//assign config_done= !rst_n ? 0 : config_reg_done ? 1 : config_done;
assign count_enable= !rst_n ? 0 : count_done ? 0 : symbol_shift_done ? 1 : count_enable;
assign count_enable_pkt= !rst_n ? 0 : count_done_pkt ? 0 : packet_shift_done ? 1 : count_enable_pkt;
//assign isd_delay_en=symbol_shift_done ? 1 : (isd_count==max_count-1) :
///////////////////////symbol////////////////////////////////////
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
isd_count<=0;
count_done<=0;
end
else begin
count_done<=0;
if(count_enable) begin
if(isd_count==max_count-1) begin
isd_count<=0;
count_done<=1;
isd_delay_en<=0;
end
else begin
isd_delay_en<=1;
isd_count<=isd_count+1;
end
end
else begin
isd_delay_en<=0;
isd_count<=0;
end
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
isd_val_temp<=0;
clk_count<=0;
end
else begin
if(clk_count)
isd_val_temp<=isd_val_temp;
else if(config_reg_done) begin
clk_count<=clk_count+1;
isd_val_temp<=isd_val;
end
else
isd_val_temp<=isd_val_temp;
end
end
///////////////packet//////////////////////
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
ipd_count<=0;
count_done_pkt<=0;
end
else begin
count_done_pkt<=0;
if(count_enable_pkt) begin
if(ipd_count==max_count_pkt-1) begin
ipd_count<=0;
count_done_pkt<=1;
ipd_delay_en<=0;
end
else begin
ipd_delay_en<=1;
ipd_count<=ipd_count+1;
end
end
else begin
ipd_delay_en<=0;
ipd_count<=0;
end
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
ipd_val_temp<=0;
clk_count_pkt<=0;
end
else begin
if(clk_count_pkt)
ipd_val_temp<=ipd_val_temp;
else if(config_reg_done) begin
clk_count_pkt<=clk_count_pkt+1;
ipd_val_temp<=ipd_val;
end
else
ipd_val_temp<=ipd_val_temp;
end
end
endmodule

View File

@ -0,0 +1,377 @@
//==================================================================
// >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// ------------------------------------------------------------------
// Copyright (c) 2014 by Lattice Semiconductor Corporation
// ALL RIGHTS RESERVED
// ------------------------------------------------------------------
//
// Permission:
//
// Lattice SG Pte. Ltd. grants permission to use this code for use
// in synthesis for any Lattice programmable logic product. Other
// use of this code, including the selling or duplication of any
// portion is strictly prohibited.
//
// Disclaimer:
//
// This VHDL or Verilog source code is intended as a design reference
// which illustrates how these types of functions can be implemented.
// It is the user's responsibility to verify their design for
// consistency and functionality through the use of formal
// verification methods. Lattice provides no warranty
// regarding the use or functionality of this code.
//
// --------------------------------------------------------------------
//
// Lattice SG Pte. Ltd.
// 101 Thomson Road, United Square #07-02
// Singapore 307591
//
//
// TEL: 1-800-Lattice (USA and Canada)
// +65-6631-2000 (Singapore)
// +1-503-268-8001 (other locations)
//
// web: http://www.latticesemi.com/
// email: techsupport@latticesemi.com
//
// --------------------------------------------------------------------
//
module mobeam_i2c_reg_interface(
rst_i,
clk_i,
//i2c slave interface signals///
i2c_master_to_slave_data_i,
i2c_slave_to_master_data_o,
i2c_slave_data_address_i,
wr_en_i,
rd_en_i,
i2c_start_i,
//MoBeam control logic interface//
rd_revision_code,
rst_mobeam,
mobeam_start_stop,
led_polarity,
o_ba_mem_data,
i_ba_mem_addr,
i_ba_mem_rd_en,
i_ba_mem_rd_clk,
o_bsr_mem_data,
i_bsr_mem_addr,
i_bsr_mem_rd_en,
i_bsr_mem_rd_clk
// i_config_reg_done,
// o_new_data_rd,
// o_data_strobe
);
//i2c slave interface signals///
input [7:0] i2c_master_to_slave_data_i;
output reg [7:0]i2c_slave_to_master_data_o;
input [7:0] i2c_slave_data_address_i;
input wr_en_i;
input rd_en_i;
input i2c_start_i;
input rst_i;
input clk_i;
//mobeam control logic interface//
output [15:0] o_ba_mem_data;
input [7:0] i_ba_mem_addr;
input i_ba_mem_rd_en;
input i_ba_mem_rd_clk;
output reg rd_revision_code=0;
output reg rst_mobeam=0;
//input[7:0] i_revision_code_data;
//input rd_revision_code;
output [7:0] o_bsr_mem_data;
//output reg [15:0] mem_data_buf16;
input [8:0] i_bsr_mem_addr;
input i_bsr_mem_rd_en;
input i_bsr_mem_rd_clk;
output reg mobeam_start_stop=1'b0;
output reg led_polarity=1'b0;
//output reg o_new_data_rd=1'b0;
//output reg o_data_strobe=1'b0;
//input i_config_reg_done;
//////////////wire & reg declarations//////////////////
wire wr_en;
wire rd_en;
reg d1_wr_en_i;
reg d2_wr_en_i;
reg d1_rd_en_i;
reg d2_rd_en_i;
parameter revision_code=8'hF1;
/////////////////////BSR and CONFIG data memory//////////////
SB_RAM512x8 ram512x8_inst
(
.RDATA(o_bsr_mem_data),// EBR512x8_data
.RADDR(i_bsr_mem_addr),// EBR512x8_addr
.RCLK(i_bsr_mem_rd_clk),
.RCLKE(i_bsr_mem_rd_en),
.RE(i_bsr_mem_rd_en),// EBR512x8_re
.WADDR({1'b0,bsr_mem_addr_in}),
.WCLK(clk_i),
.WCLKE(1'b1),///*bsr_wr_en/*wr_en*/),
.WDATA(i2c_master_to_slave_data_i),
.WE(bsr_wr_en) ////*bsr_wr_en/*wr_en*/)
);
defparam ram512x8_inst.INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
//ICE Technology Library 66
//Lattice Semiconductor Corporation Confidential
defparam ram512x8_inst.INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
///////////////////////BA i.e. beamable data memory//////////////
SB_RAM256x16 ram256x16_inst (
.RDATA(o_ba_mem_data),
.RADDR(i_ba_mem_addr),
.RCLK(i_ba_mem_rd_clk),
.RCLKE(i_ba_mem_rd_en),
.RE(i_ba_mem_rd_en),
.WADDR(ba_mem_addr_in_delayed_1),
.WCLK(clk_i),
.WCLKE(1'b1),///*ba_wr_en/*wr_en*/),
.WDATA(ba_mem_data_buffer),
.WE(ba_wr_en_delayed),///*wr_en*/),
.MASK(16'd0)
);
defparam ram256x16_inst.INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
// Write valid pulse
always @(posedge clk_i or posedge rst_i) begin
if (rst_i) begin
d1_wr_en_i <= 0;
d2_wr_en_i <= 0;
end else begin
d1_wr_en_i <= wr_en_i;
d2_wr_en_i <= d1_wr_en_i;
end
end
assign wr_en = d2_wr_en_i && ~d1_wr_en_i;
// Read enable pulse
always @(posedge clk_i or posedge rst_i) begin
if (rst_i) begin
d1_rd_en_i <= 0;
d2_rd_en_i <= 0;
end else begin
d1_rd_en_i <= rd_en_i;
d2_rd_en_i <= d1_rd_en_i;
end
end
assign rd_en = ~d2_rd_en_i && d1_rd_en_i;
reg [7:0] bsr_mem_addr_in;
reg [7:0] ba_mem_addr_in;
reg ba_wr_en;
always @(posedge clk_i or posedge rst_i) begin
if (rst_i) begin
bsr_mem_addr_in <= 9'd0;
end
else
if (i2c_start_i)
bsr_mem_addr_in <= i2c_slave_data_address_i;
else if (i2c_slave_data_address_i == 8'h80) begin
if (wr_en) begin
bsr_mem_addr_in <=bsr_mem_addr_in + 1'b1;
end
end
end
assign bsr_wr_en = (i2c_slave_data_address_i == 8'h00)?1'b0:wr_en;
//MOBEAM START-STOP
always @(posedge clk_i or posedge rst_i) begin
if (rst_i) begin
mobeam_start_stop<=1'b0;
end
else
if (i2c_slave_data_address_i == 8'hF0) //8'hEC
if (wr_en & (i2c_master_to_slave_data_i==8'b00000001))begin
mobeam_start_stop<=1'b1;
end
else if(wr_en & (i2c_master_to_slave_data_i==8'b00000000))begin
mobeam_start_stop<=1'b0;
end
end
//MOBEAM RESET
always @(posedge clk_i or posedge rst_i) begin
if (rst_i) begin
rst_mobeam<=1'b0;
end
else
if (i2c_slave_data_address_i == 8'hF1)
if (wr_en & (i2c_master_to_slave_data_i==8'b00000001))begin
rst_mobeam<=1'b1;
end
else if(wr_en & (i2c_master_to_slave_data_i==8'b00000000))begin
rst_mobeam<=1'b0;
end
end
//REVISION CODE
always @(posedge clk_i or posedge rst_i) begin
if (rst_i) begin
rd_revision_code<=1'b0;
end
else
if (rd_en)begin
if (i2c_slave_data_address_i == 8'hF2) begin
rd_revision_code<=1'b1;
i2c_slave_to_master_data_o<=revision_code;
end
else begin
rd_revision_code<=1'b0;
i2c_slave_to_master_data_o<=0;
end
end
else
i2c_slave_to_master_data_o<=0;
end
//LED POLARITY
always @(posedge clk_i or posedge rst_i) begin
if (rst_i) begin
led_polarity<=1'b0;
end else begin
//if (wr_en)begin
//if (i2c_slave_data_address_i == 8'hEB)begin
//if (i2c_master_to_slave_data_i==8'b00000001)begin
led_polarity<=1'b1;
//end else begin
//led_polarity<=1'b0;
//end
//end
//end
end
end
reg ba_wr_en_delayed;
reg wr_en_cnt;
reg [7:0] ba_mem_addr_in_delayed,ba_mem_addr_in_delayed_1;
reg [7:0] data_buffer;
reg [15:0] ba_mem_data_buffer;
always @(posedge clk_i or posedge rst_i) begin
if (rst_i) begin
ba_mem_addr_in_delayed<=8'd0;
ba_mem_addr_in_delayed_1<=8'd0;
ba_wr_en_delayed<= 1'b0;
end
else begin
ba_mem_addr_in_delayed<= ba_mem_addr_in;
ba_mem_addr_in_delayed_1<= ba_mem_addr_in_delayed;
ba_wr_en_delayed<= ba_wr_en;
end
end
//assign ba_mem_data_buffer = { i2c_master_to_slave_data_i,data_buffer};
always @(posedge clk_i or posedge rst_i) begin
if (rst_i) begin
ba_mem_addr_in <= 9'd0;
ba_wr_en<= 1'b0;
wr_en_cnt<= 1'b0;
end
else
if (i2c_slave_data_address_i == 8'h00) begin
if (wr_en_cnt) begin
ba_mem_data_buffer <= { i2c_master_to_slave_data_i,data_buffer};
end
if (wr_en) begin
wr_en_cnt<= wr_en_cnt + 1'b1;
ba_wr_en<= 1'b1;
if (~wr_en_cnt)begin
data_buffer <= i2c_master_to_slave_data_i;
end
else
ba_mem_addr_in <= ba_mem_addr_in + 1'b1;
end
else
ba_wr_en<= 1'b0;
end
else begin
ba_mem_addr_in<=0;
ba_wr_en<= 1'b0;
wr_en_cnt<=0;
end
end
endmodule

View File

@ -0,0 +1,82 @@
//==================================================================
// >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// ------------------------------------------------------------------
// Copyright (c) 2014 by Lattice Semiconductor Corporation
// ALL RIGHTS RESERVED
// ------------------------------------------------------------------
//
// Permission:
//
// Lattice SG Pte. Ltd. grants permission to use this code for use
// in synthesis for any Lattice programmable logic product. Other
// use of this code, including the selling or duplication of any
// portion is strictly prohibited.
//
// Disclaimer:
//
// This VHDL or Verilog source code is intended as a design reference
// which illustrates how these types of functions can be implemented.
// It is the user's responsibility to verify their design for
// consistency and functionality through the use of formal
// verification methods. Lattice provides no warranty
// regarding the use or functionality of this code.
//
// --------------------------------------------------------------------
//
// Lattice SG Pte. Ltd.
// 101 Thomson Road, United Square #07-02
// Singapore 307591
//
//
// TEL: 1-800-Lattice (USA and Canada)
// +65-6631-2000 (Singapore)
// +1-503-268-8001 (other locations)
//
// web: http://www.latticesemi.com/
// email: techsupport@latticesemi.com
//
// --------------------------------------------------------------------
//
module testpll_pll(REFERENCECLK,
PLLOUTCORE,
PLLOUTGLOBAL,
RESET,
LOCK);
input REFERENCECLK;
input RESET; /* To initialize the simulation properly, the RESET signal (Active Low) must be asserted at the beginning of the simulation */
output PLLOUTCORE;
output PLLOUTGLOBAL;
output LOCK;
SB_PLL40_CORE testpll_pll_inst(.REFERENCECLK(REFERENCECLK),
.PLLOUTCORE(PLLOUTCORE),
.PLLOUTGLOBAL(PLLOUTGLOBAL),
.EXTFEEDBACK(),
.DYNAMICDELAY(),
.RESETB(RESET),
.BYPASS(1'b0),
.LATCHINPUTVALUE(),
.LOCK(LOCK),
.SDI(),
.SDO(),
.SCLK());
//\\ Fin=27, Fout=20.05;
defparam testpll_pll_inst.DIVR = 4'b0000;
defparam testpll_pll_inst.DIVF = 7'b0010111;
defparam testpll_pll_inst.DIVQ = 3'b101;
defparam testpll_pll_inst.FILTER_RANGE = 3'b011;
defparam testpll_pll_inst.FEEDBACK_PATH = "SIMPLE";
defparam testpll_pll_inst.DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
defparam testpll_pll_inst.FDA_FEEDBACK = 4'b0000;
defparam testpll_pll_inst.DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
defparam testpll_pll_inst.FDA_RELATIVE = 4'b0000;
defparam testpll_pll_inst.SHIFTREG_DIV_MODE = 2'b00;
defparam testpll_pll_inst.PLLOUT_SELECT = "GENCLK";
defparam testpll_pll_inst.ENABLE_ICEGATE = 1'b0;
endmodule

View File

@ -0,0 +1,334 @@
//==================================================================
// >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// ------------------------------------------------------------------
// Copyright (c) 2014 by Lattice Semiconductor Corporation
// ALL RIGHTS RESERVED
// ------------------------------------------------------------------
//
// Permission:
//
// Lattice SG Pte. Ltd. grants permission to use this code for use
// in synthesis for any Lattice programmable logic product. Other
// use of this code, including the selling or duplication of any
// portion is strictly prohibited.
//
// Disclaimer:
//
// This VHDL or Verilog source code is intended as a design reference
// which illustrates how these types of functions can be implemented.
// It is the user's responsibility to verify their design for
// consistency and functionality through the use of formal
// verification methods. Lattice provides no warranty
// regarding the use or functionality of this code.
//
// --------------------------------------------------------------------
//
// Lattice SG Pte. Ltd.
// 101 Thomson Road, United Square #07-02
// Singapore 307591
//
//
// TEL: 1-800-Lattice (USA and Canada)
// +65-6631-2000 (Singapore)
// +1-503-268-8001 (other locations)
//
// web: http://www.latticesemi.com/
// email: techsupport@latticesemi.com
//
// --------------------------------------------------------------------
//
//`define SIM
`define i2c
//`define spi
//`define uart
module top_module
// Outputs
( o_led,
// Inouts
`ifdef i2c
io_i2c_scl, io_i2c_sda,
`endif
//spi signals
`ifdef spi
i_sck, i_csn, i_mosi,o_miso,
`endif
`ifdef uart
o_tx,i_rx,
`endif
//testpoints
drive_on,
// Inputs
i_clk
)/*synthesis syn_dspstyle=logic*/;
//input i_rst;
output wire o_led;
output drive_on;
input i_clk;
`ifdef i2c
inout io_i2c_scl;
inout io_i2c_sda;
`endif
`ifdef spi
input i_sck;
input i_csn;
input i_mosi;
output o_miso;
`endif
`ifdef uart
output o_tx;
input i_rx;
`endif
wire sclin_i;
wire sdain_i;
wire sdaout_i;
wire [7:0] datain_i;
wire write_en_i;
wire [7:0] dataout_i;
wire [7:0] regaddr_i;
wire read_en_i;
reg [15:0] poweron_reset_count_i = 0; //initialized for simulation
reg poweron_reset_n_i = 0; // initialized for simulation
wire rst_i;
//mobeam control logic interface//
wire [15:0] o_ba_mem_data;
wire [7:0] i_ba_mem_addr;
wire i_ba_mem_rd_en;
wire i_ba_mem_rd_clk;
wire rd_revision_code;
wire rst_mobeam;
wire [7:0] o_bsr_mem_data;
wire [8:0] i_bsr_mem_addr;
wire i_bsr_mem_rd_en;
wire i_bsr_mem_rd_clk;
wire o_new_data_rd;
wire o_bsr_data_strobe;
wire i_config_reg_done;
////////////////////////////////
wire clk_20mhz_g;
testpll_pll testpll_pll_inst(.REFERENCECLK(i_clk),
.PLLOUTCORE(),
.PLLOUTGLOBAL(clk_20mhz_g),
.RESET(~rst_i/*1'b1*/),
.LOCK());
//selection of SPI or I2C///
`ifdef spi
user_logic_control_reg_spidata_buf spi_mobeam_logic_interface
(
///spi Signal/////
.i_sys_clk(i_clk),
.rst(rst_i),
.i_sck(i_sck),
.i_csn(i_csn),
.i_mosi(i_mosi),
.o_miso(o_miso),
///Mobeam Control Signals///
.rd_revision_code(rd_revision_code),
.rst_mobeam(rst_mobeam),
.led_polarity(led_polarity),
.mobeam_start_stop(mobeam_start_stop),
.o_ba_mem_data(o_ba_mem_data),
.i_ba_mem_addr(i_ba_mem_addr),
.i_ba_mem_rd_en(i_ba_mem_rd_en),
.i_ba_mem_rd_clk(i_ba_mem_rd_clk),
.o_bsr_mem_data(o_bsr_mem_data),
.i_bsr_mem_addr(i_bsr_mem_addr),
.i_bsr_mem_rd_en(i_bsr_mem_rd_en),
.i_bsr_mem_rd_clk(i_bsr_mem_rd_clk)
// .i_config_reg_done(i_config_reg_done),
// .o_new_data_rd(o_new_data_rd),
// .o_data_strobe(o_bsr_data_strobe)
);
`endif
`ifdef i2c
user_logic_control_reg_data_buf i2c_mobeam_logic_interface
(
///i2c Signal/////
.clk(clk_20mhz_g),
.rst(rst_i),
.scl(sclin_i),
.sdaout(sdaout_i),
.sdaIn(sdain_i),
///Mobeam Control Signals///
.rd_revision_code(rd_revision_code),
.rst_mobeam(rst_mobeam),
.led_polarity(led_polarity),
.mobeam_start_stop(mobeam_start_stop),
.o_ba_mem_data(o_ba_mem_data),
.i_ba_mem_addr(i_ba_mem_addr),
.i_ba_mem_rd_en(i_ba_mem_rd_en),
.i_ba_mem_rd_clk(i_ba_mem_rd_clk),
.o_bsr_mem_data(o_bsr_mem_data),
.i_bsr_mem_addr(i_bsr_mem_addr),
.i_bsr_mem_rd_en(i_bsr_mem_rd_en),
.i_bsr_mem_rd_clk(i_bsr_mem_rd_clk)
// .i_config_reg_done(i_config_reg_done),
// .o_new_data_rd(o_new_data_rd),
// .o_data_strobe(o_bsr_data_strobe)
);
`endif
//--------------------------------------------------------------
//uart module instantiation
`ifdef uart
uart_top u_inst(
.i_sys_clk (clk_20mhz_g),
.i_sys_rst (rst_i),
.i_rx (i_rx),
//outputs
.o_tx (o_tx),
.o_done (done_i),
///Mobeam Control Signals
.rd_revision_code (rd_revision_code),
.rst_mobeam (rst_mobeam),
.led_polarity (led_polarity),
.mobeam_start_stop (mobeam_start_stop),
.o_ba_mem_data (o_ba_mem_data),
.i_ba_mem_addr (i_ba_mem_addr),
.i_ba_mem_rd_en (i_ba_mem_rd_en),
.i_ba_mem_rd_clk (i_ba_mem_rd_clk),
.o_bsr_mem_data (o_bsr_mem_data),
.i_bsr_mem_addr (i_bsr_mem_addr),
.i_bsr_mem_rd_en (i_bsr_mem_rd_en),
.i_bsr_mem_rd_clk (i_bsr_mem_rd_clk)
);
`endif
///////////////////////////////////////////////////////
////MobeamControlFSM//////
mobeam_control_fsm fsm_mobeam(
.sys_clk_i(clk_20mhz_g),
///Mobeam Control Signals///
.start_stop(mobeam_start_stop),
.rst_mobeam(rst_mobeam|rst_i),
//bsr memory signals
.bsr_mem_data(o_bsr_mem_data),
.bsr_mem_clk(i_bsr_mem_rd_clk),
.bsr_mem_addr(i_bsr_mem_addr),
.bsr_mem_rd_en(i_bsr_mem_rd_en),
//ba memory signals
.ba_mem_data(o_ba_mem_data),
.ba_mem_clk(i_ba_mem_rd_clk),
.ba_mem_addr(i_ba_mem_addr),
.ba_mem_rd_en(i_ba_mem_rd_en),
//TO LED DRIVER
.o_byte_data(barcode_array),
.shift_done(byte_done),
.bit_done(bit_done),
.txn_start(txn_start),
// .bsr_load_done(),
.bsr_bw(bar_width)
);
wire [7:0] bar_width, barcode_array;
/////LED Driver//////
led_driver led_drive_inst (
.sys_clk(clk_20mhz_g),
.mobeam_start_stop(mobeam_start_stop),
.led_polarity(led_polarity),
.rst_n(~rst_i|rst_mobeam),
.txn_start(txn_start),
.bar_width(bar_width),
.barcode_array(barcode_array),
.byte_done(byte_done),
.bit_done(bit_done),
.drive_on(drive_on),
.oled(o_led)
//output dynamic_clk);
);
////////////////////////////////////////
////////////////////////////////////////////////
/////oled data verification/////////////////////
`ifdef SIM
reg [7:0] capture_oled=0;
reg [7:0] oled_check=0;
integer i=8;
integer mon;
initial begin
mon = $fopen("monitor.txt","w"); //file to write
end
always @(posedge i_clk) begin
// $fwrite(mon,"%h \n",oled_check);
if(txn_start && /*rise_reload_ba_reg_dtc*/fall_reload_ba_reg_dtc) begin
//if(led_polarity)
capture_oled[i]= o_led;
//else
// capture_oled[i]= ~o_led;
end
end
always @( negedge fall_reload_ba_reg_dtc) begin
if(i==0) begin
oled_check=capture_oled;
i<=7;
end
else
i<=i-1;
end
always @(posedge i_clk) begin
if(txn_start && byte_done)
$fwrite(mon,"%h \n",oled_check);
end
reg q_reload_ba_reg;
always @(posedge i_clk or posedge rst_i) begin
if(rst_i)
q_reload_ba_reg<=0;
else
q_reload_ba_reg<=led_drive_inst.reload_ba_reg;
end
assign rise_reload_ba_reg_dtc=(~q_reload_ba_reg) && led_drive_inst.reload_ba_reg;
assign fall_reload_ba_reg_dtc=(q_reload_ba_reg) && (~led_drive_inst.reload_ba_reg);
`endif
//end
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
`ifdef i2c
assign io_i2c_sda = (sdaout_i == 1'b0) ? 1'b0 : 1'bz;
assign sdain_i = io_i2c_sda;
assign sclin_i = io_i2c_scl;
`endif
always @(posedge i_clk)begin
if(poweron_reset_count_i == 256)begin
poweron_reset_count_i <= 256;
end else begin
poweron_reset_count_i <= poweron_reset_count_i + 1;
end
end
always @(posedge i_clk)begin
if(poweron_reset_count_i == 256)begin
poweron_reset_n_i <= 1;
end else begin
poweron_reset_n_i <= 0;
end
end
assign rst_i = ~poweron_reset_n_i;
endmodule // i2c_slave

View File

@ -0,0 +1,138 @@
//==================================================================
// >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// ------------------------------------------------------------------
// Copyright (c) 2014 by Lattice Semiconductor Corporation
// ALL RIGHTS RESERVED
// ------------------------------------------------------------------
//
// Permission:
//
// Lattice SG Pte. Ltd. grants permission to use this code for use
// in synthesis for any Lattice programmable logic product. Other
// use of this code, including the selling or duplication of any
// portion is strictly prohibited.
//
// Disclaimer:
//
// This VHDL or Verilog source code is intended as a design reference
// which illustrates how these types of functions can be implemented.
// It is the user's responsibility to verify their design for
// consistency and functionality through the use of formal
// verification methods. Lattice provides no warranty
// regarding the use or functionality of this code.
//
// --------------------------------------------------------------------
//
// Lattice SG Pte. Ltd.
// 101 Thomson Road, United Square #07-02
// Singapore 307591
//
//
// TEL: 1-800-Lattice (USA and Canada)
// +65-6631-2000 (Singapore)
// +1-503-268-8001 (other locations)
//
// web: http://www.latticesemi.com/
// email: techsupport@latticesemi.com
//
// --------------------------------------------------------------------
//
module user_logic_control_reg_data_buf
(
///i2c signal/////
clk,
rst,
scl,
sdaout,
sdaIn,
///mobeam control signals///
rd_revision_code,
rst_mobeam,
led_polarity,
mobeam_start_stop,
o_ba_mem_data,
i_ba_mem_addr,
i_ba_mem_rd_en,
i_ba_mem_rd_clk,
o_bsr_mem_data,
i_bsr_mem_addr,
i_bsr_mem_rd_en,
i_bsr_mem_rd_clk
);
///////i2c signals interface///////
input clk;
input rst;
inout scl;
output sdaout;
input sdaIn;
//////////////////////////////////
//mobeam control logic interface//
output [15:0] o_ba_mem_data;
input [7:0] i_ba_mem_addr;
input i_ba_mem_rd_en;
input i_ba_mem_rd_clk;
output rd_revision_code;
output rst_mobeam;
output mobeam_start_stop;
output [7:0] o_bsr_mem_data;
input [8:0] i_bsr_mem_addr;
input i_bsr_mem_rd_en;
input i_bsr_mem_rd_clk;
output led_polarity;
//////////////////////////////////
///////wires and reg declarations////
wire[7:0]dataOut;
wire[7:0]regAddr;
wire writeEn;
wire readEn;
wire i2c_start;
wire[7:0]dataIn;
///////////////////////////////////////
serialInterface i2cslavedatafsm(/*AUTOARG*/
// Outputs
.dataOut(dataOut),
.regAddr(regAddr),
.sdaOut(sdaout),
.writeEn(writeEn),
.readEn(readEn),
.i2c_start(i2c_start),
// Inputs
.clk(clk),
.dataIn(dataIn),
.rst(rst),
.scl(scl),
.sdaIn(sdaIn)
);
/*mobeam_reg_sets*/mobeam_i2c_reg_interface mobeam_registers(
.rst_i(rst),
.clk_i(clk),
//i2c slave interface signals///
.i2c_master_to_slave_data_i(dataOut),
.i2c_slave_to_master_data_o(dataIn),
.i2c_slave_data_address_i(regAddr),
.wr_en_i(writeEn),
.rd_en_i(readEn),
.i2c_start_i(i2c_start),
//MoBeam control logic interface//
.rd_revision_code(rd_revision_code),
.rst_mobeam(rst_mobeam),
.led_polarity(led_polarity),
.mobeam_start_stop(mobeam_start_stop),
.o_ba_mem_data(o_ba_mem_data),
.i_ba_mem_addr(i_ba_mem_addr),
.i_ba_mem_rd_en(i_ba_mem_rd_en),
.i_ba_mem_rd_clk(i_ba_mem_rd_clk),
.o_bsr_mem_data(o_bsr_mem_data),
.i_bsr_mem_addr(i_bsr_mem_addr),
.i_bsr_mem_rd_en(i_bsr_mem_rd_en),
.i_bsr_mem_rd_clk(i_bsr_mem_rd_clk)
);
endmodule

View File

@ -0,0 +1,31 @@
# Standard Configuration Example
[dir_path]
script_base = OPENFPGAPATHKEYWORD/fpga_flow/scripts/
benchmark_dir = OPENFPGAPATHKEYWORD/fpga_flow/benchmarks/Verilog/lattice_ultra_example/PID_Controller
yosys_path = OPENFPGAPATHKEYWORD/yosys/yosys
odin2_path = OPENFPGAPATHKEYWORD/fpga_flow/not_used_atm/odin2.exe
cirkit_path = OPENFPGAPATHKEYWORD/fpga_flow/not_used_atm/cirkit
abc_path = OPENFPGAPATHKEYWORD/yosys/yosys-abc
abc_mccl_path = OPENFPGAPATHKEYWORD/abc_with_bb_support/abc
abc_with_bb_support_path = OPENFPGAPATHKEYWORD/abc_with_bb_support/abc
mpack1_path = OPENFPGAPATHKEYWORD/fpga_flow/not_used_atm/mpack1
m2net_path = OPENFPGAPATHKEYWORD/fpga_flow/not_used_atm/m2net
mpack2_path = OPENFPGAPATHKEYWORD/fpga_flow/not_used_atm/mpack2
vpr_path = OPENFPGAPATHKEYWORD/vpr7_x2p/vpr/vpr
rpt_dir = OPENFPGAPATHKEYWORD/fpga_flow/results
ace_path = OPENFPGAPATHKEYWORD/ace2/ace
[flow_conf]
#Flow Types standard|mpack2|mpack1|vtr_standard|vtr|yosys_vpr
flow_type = yosys_vpr
vpr_arch = OPENFPGAPATHKEYWORD/fpga_flow/arch/winbond90/k6_N10_rram_memory_bank_SC_winbond90.xml
mpack1_abc_stdlib = Not_Required
m2net_conf = Not_Required
mpack2_arch = Not_Required
power_tech_xml = OPENFPGAPATHKEYWORD/fpga_flow/tech/winbond90nm/winbond90nm_power_properties.xml
[csv_tags]
mpack1_tags = Global mapping efficiency: | efficiency: | occupancy wo buf: | efficiency wo buf:
mpack2_tags = BLE Number: | BLE Fill Rate:
vpr_tags = Netlist clb blocks: | Final critical path: | Total logic delay: | total net delay: | Total routing area: | Total used logic block area: | Total wirelength: | Packing took | Placement took | Routing took | Average net density: | Median net density: | Recommend no. of clock cycles:
vpr_power_tags = PB Types | Routing | Switch Box | Connection Box | Primitives | Interc Structures | lut6 | ff

View File

@ -0,0 +1,71 @@
#! /bin/bash
# Exit if error occurs
set -e
# Make sure a clear start
default_task='lattice_benchmark'
pwd_path="$PWD"
task_name=${1:-$default_task} # run task defined in argument else run default task
config_file="$PWD/configs/${task_name}.conf"
bench_txt="$PWD/benchmarks/List/${task_name}.txt"
rpt_file="$PWD/csv_rpts/fpga_spice/${task_name}.csv"
task_file="$PWD/vpr_fpga_spice_task_lists/${task_name}"
verilog_path="${PWD}/regression_${task_name}"
config_file_final=$(echo ${config_file/.conf/_final.conf})
# List of argument passed to FPGA flow
vpr_config_flags=(
'-N 10'
'-K 6'
'-ace_d 0.5'
'-multi_thread 1'
'-vpr_fpga_x2p_rename_illegal_port'
'-vpr_fpga_verilog'
'-vpr_fpga_bitstream_generator'
'-vpr_fpga_verilog_print_autocheck_top_testbench'
'-vpr_fpga_verilog_include_timing'
'-vpr_fpga_verilog_include_signal_init'
'-vpr_fpga_verilog_formal_verification_top_netlist'
'-fix_route_chan_width'
'-vpr_fpga_verilog_include_icarus_simulator'
'-power'
)
# vpr_config_flags+=("$@") # Append provided arguments
#=============== Argument Sanity Check =====================
#Check if script running in correct (OpenFPGA/fpga_flow) folder
if [[ $pwd_path != *"OpenFPGA/fpga_flow"* ]]; then
echo "Error : Execute script from OpenFPGA/fpga_flow project folder"
exitflag=1
fi
#Check if fconfig and benchmark_list file exists
for filepath in $config_file $bench_txt; do
if [ ! -f $filepath ]; then
echo "$filepath File not found!"
exitflag=1
fi
done
if [ -n "$exitflag" ]; then
echo "Terminating script . . . . . . "
exit 1
fi
#=======================================================
#======== Replace variables in config file =============
#Extract OpenFPGA Project Path and Escape
OPENFPGAPATHKEYWORD=$(echo "$(echo $pwd_path | sed 's/.OpenFPGA.*$//')/OpenFPGA" | sed 's/\//\\\//g')
# Create final config file with replaced keywords replaced variables
sed 's/OPENFPGAPATHKEYWORD/'"${OPENFPGAPATHKEYWORD}"'/g' $config_file >$config_file_final
#==================Clean result, change directory and execute ===============
cd ${pwd_path}/scripts
# perl fpga_flow.pl -conf ${config_file_final} -benchmark ${bench_txt} -rpt ${rpt_file} -vpr_fpga_verilog_dir $verilog_path $(echo "${vpr_config_flags[@]}")
perl fpga_flow.pl -conf ${config_file_final} -benchmark ${bench_txt} -rpt ${rpt_file} -N 10 -K 6 -ace_d 0.5 -multi_thread 1 -vpr_fpga_x2p_rename_illegal_port -vpr_fpga_verilog -vpr_fpga_verilog_dir $verilog_path -vpr_fpga_bitstream_generator -vpr_fpga_verilog_print_autocheck_top_testbench -vpr_fpga_verilog_include_timing -vpr_fpga_verilog_include_signal_init -vpr_fpga_verilog_formal_verification_top_netlist -fix_route_chan_width -vpr_fpga_verilog_include_icarus_simulator -power
echo "Netlists successfully generated and simulated"
exit 0

File diff suppressed because it is too large Load Diff

View File

@ -32,17 +32,17 @@ sub opts_read()
if ($#ARGV == -1){
print "Error: Not enough input argument!\n";
&print_usage();
exit(1);
exit(1);
} else {
for (my $iargv = 0; $iargv < $#ARGV+1; $iargv++){
if ("-i" eq $ARGV[$iargv]){
if ("-i" eq $ARGV[$iargv]){
$arch_file = $ARGV[$iargv+1];
$iargv++;
} elsif ("-o" eq $ARGV[$iargv]){
} elsif ("-o" eq $ARGV[$iargv]){
$new_arch_file = $ARGV[$iargv+1];
$overwrite = "FALSE";
$iargv++;
} elsif ("-k" eq $ARGV[$iargv]){
} elsif ("-k" eq $ARGV[$iargv]){
$keyword = $ARGV[$iargv+1];
$change_to = $ARGV[$iargv+2];
$default_keyword = "FALSE";
@ -77,8 +77,8 @@ sub save_original($)
my ($template) = @_;
my $renamed_template = "$template".".bak";
rename($template, $renamed_template);
return $renamed_template;
return $renamed_template;
}
sub findPath(){
@ -103,7 +103,7 @@ sub rewrite_file($ $)
my ($arch, $template) = @_;
open(IN, '<'.$template);
open(OUT, '>'.$arch);
if($default_keyword eq "TRUE"){
my $myPath = &findPath();
while(<IN>){
@ -125,7 +125,7 @@ sub main()
my $rewrite_needed = &rewriting_required_check($arch_file);
if($rewrite_needed == 1){
if($overwrite eq "TRUE"){
my $template_file = &save_original($arch_file);
my $template_file = &save_original($arch_file);
&rewrite_file($arch_file, $template_file);
} else {
&rewrite_file($new_arch_file, $arch_file);
@ -133,6 +133,6 @@ sub main()
}
return;
}
&main();
exit(0);

1
fpga_flow/tech/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
winbond90nm

2
run_local.bat Executable file
View File

@ -0,0 +1,2 @@
docker run -it --rm -v "%cd%":/localfile -w="/localfile/vpr7_x2p/vpr" goreganesh/open_fpga ./go_ganesh.sh
pause

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,882 @@
<!--
Flagship Heterogeneous Architecture with Carry Chains for VTR 7.0.
- 40 nm technology
- General purpose logic block:
K = 6, N = 10, fracturable 6 LUTs (can operate as one 6-LUT or two 5-LUTs with all 5 inputs shared)
with optionally registered outputs
Each 5-LUT has an arithemtic mode that converts it to a single-bit adder with both inputs driven by 4-LUTs (both 4-LUTs share all 4 inputs)
Carry chain links to vertically adjacent logic blocks
- Memory size 32 Kbits, memory aspect ratios vary from a data width of 1 to data width of 64.
Height = 6, found on every (8n+2)th column
- Multiplier modes: one 36x36, two 18x18, each 18x18 can also operate as two 9x9.
Height = 4, found on every (8n+6)th column
- Routing architecture: L = 4, fc_in = 0.15, Fc_out = 0.1
Details on Modelling:
The electrical design of the architecture described here is NOT from an
optimized, SPICED architecture. Instead, we attempt to create a reasonable
architecture file by using an existing commercial FPGA to approximate the area,
delay, and power of the underlying components. This is combined with a reasonable 40 nm
model of wiring and circuit design for low-level routing components, where available.
The resulting architecture has delays that roughly match a commercial 40 nm FPGA, but also
has wiring electrical parameters that allow the wire lengths and switch patterns to be
modified and you will still get reasonable delay results for the new architecture.
The following describes, in detail, how we obtained the various electrical values for this
architecture.
Rmin for nmos and pmos, routing buffer sizes, and I/O pad delays are from the ifar
architecture created by Ian Kuon: K06 N10 45nm fc 0.15 area-delay optimized architecture.
(n10k06l04.fc15.area1delay1.cmos45nm.bptm.cmos45nm.xml)
This routing architecture was optimized for 45 nm, and we have scaled it linearly to 40 nm to
match the overall target (a 40 nm FPGA).
We obtain delay numbers by measuring delays of routing, soft logic blocks,
memories, and multipliers from test circuits on a Stratix IV GX device
(EP4SGX230DF29C2X, i.e. fastest speed grade). For routing, we took the average delay of H4 and V4
wires. Rmetal and Cmetal values for the routing wires were obtained from work done by Charles
Chiasson. We use a 96 nm half-pitch (corresponding to mid-level metal stack 40 nm routing) and
take the R and C data from the ITRS roadmap.
For the general purpose logic block, we assume that the area and delays of the Stratix IV
crossbar is close enough to the crossbar modelled here. We use 40 inputs and 20 feedback lines in
the cluster and a full crossbar, leading to 53:1 multiplexers in front of each BLE input.
Stratix IV uses 52 inputs and 20 feedback lines, but only a half-populated crossbar, leading to
36:1 multiplexers. We require 60 such multiplexers, while Stratix IV requires 88 for its more
complex fracturable BLEs + the extra control signals. We justify this rough approximation as follows:
The Stratix IV crossbar has more inputs (72 vs. 60) and
outputs (88 vs. 60) than our full crossbar which should increase its area and delay, but the
Stratix IV crossbar is also 50% sparse (each mux is 36:1 instead of 53:1) which should reduce its
area and delay. The total number of crossbar switch points is roughly similar between the two
architectures (3160 for SIV and 3600 for the academic architecture below), so we use the area
& delay of the Stratix IV crossbar as a rough approximation of our crossbar.
For LUTs, we include LUT
delays measured from Stratix IV which is dependant on the input used (ie. some
LUT inputs are faster than others). The CAD tools at the time of VTR 7 does
not consider differences in LUT input delays.
Adder delays obtained as approximate values from a Stratix IV EP4SE230F29C3 device.
Delay obtained by compiling a 256 bit adder (registered inputs and outputs,
all pins except clock virtual) then measuring the delays in chip-planner,
sumout delay = 0.271ns to 0.348 ns, intra-block carry delay = 0.011 ns,
inter-block carry delay = 0.327 ns. Given this data, I will approximate
sumout 0.3 ns, intra-block carry-delay = 0.01 ns, and
inter-block carry-delay = 0.16 ns (since Altera inter-block carry delay has
overhead that we don't have, I'll approximate the delay of a simpler chain at
one half what they have. This is very rough, anything from 0.01ns to 0.327ns
can be justified).
Logic block area numbers obtained by scaling overall tile area of a 65nm
Stratix III device, (as given in Wong, Betz and Rose, FPGA 2011) to 40 nm, then subtracting out
routing area at a channel width of 300. We use a channel width of 300 because it can route
all the VTR 6.0 benchmark circuits with an approximately 20% safety margin, and is also close to the
total channel width of Stratix IV. Hence this channel width is close to the commercial practice of
choosing a width that provides high routability. The architecture can be routed at different channel
widths, but we estimate the tile size and hence the physical length of routing wires assuming
a channel width of 300.
Sanity checks employed:
1. We confirmed the routing buffer delay is ~1/3rd of total routing delay at L = 4. This matches
common electrical design.
Authors: Jason Luu, Jeff Goeders, Vaughn Betz
-->
<architecture>
<!--
ODIN II specific config begins
Describes the types of user-specified netlist blocks (in blif, this corresponds to
".model [type_of_block]") that this architecture supports.
Note: Basic LUTs, I/Os, and flip-flops are not included here as there are
already special structures in blif (.names, .input, .output, and .latch)
that describe them.
-->
<models>
<model name="io">
<input_ports>
<port name="outpad"/>
</input_ports>
<output_ports>
<port name="inpad"/>
</output_ports>
</model>
<model name="adder">
<input_ports>
<port name="a"/>
<port name="b"/>
<port name="cin"/>
</input_ports>
<output_ports>
<port name="cout"/>
<port name="sumout"/>
</output_ports>
</model>
<model name="frac_lut6">
<input_ports>
<port name="in"/>
</input_ports>
<output_ports>
<port name="lut6_out"/>
<port name="lut5_out"/>
<port name="lut4_out"/>
</output_ports>
</model>
</models>
<!-- ODIN II specific config ends -->
<!-- Physical descriptions begin -->
<layout width="2" height="2"/>
<spice_settings>
<parameters>
<options sim_temp="25" post="off" captab="off" fast="on"/>
<monte_carlo mc_sim="off" num_mc_points="2" cmos_variation="off" rram_variation="off">
<cmos abs_variation="0.1" num_sigma="3"/>
<rram abs_variation="0.1" num_sigma="3"/>
</monte_carlo>
<measure sim_num_clock_cycle="auto" accuracy="1e-13" 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="TOP_TT" lib_path="/research/ece/lnis/USERS/tang/tangxifan-eda-tools/branches/subvt_fpga/process/tsmc40nm/toplevel.l" nominal_vdd="0.9" io_vdd="2.5"/>
<transistors pn_ratio="2" model_ref="M">
<nmos model_name="nch" chan_length="40e-9" min_width="140e-9"/>
<pmos model_name="pch" chan_length="40e-9" min_width="140e-9"/>
<io_nmos model_name="nch_25" chan_length="270e-9" min_width="320e-9"/>
<io_pmos model_name="pch_25" chan_length="270e-9" min_width="320e-9"/>
</transistors>
<module_circuit_models>
<circuit_model type="inv_buf" name="inv1" prefix="inv1" is_default="1">
<design_technology type="cmos" topology="inverter" size="1" tapered="off"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="in" out_port="out">
10e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in" out_port="out">
10e-12
</delay_matrix>
</circuit_model>
<circuit_model type="inv_buf" name="buf4" prefix="buf4" 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" size="1"/>
<port type="output" prefix="out" size="1"/>
</circuit_model>
<circuit_model type="inv_buf" name="tap_inv4" prefix="tap_inv4" is_default="0">
<design_technology type="cmos" topology="buffer" size="1" 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"/>
<delay_matrix type="rise" in_port="in sel selb" out_port="out">
10e-12 0e-12 0e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in sel selb" out_port="out">
10e-12 0e-12 0e-12
</delay_matrix>
</circuit_model>
<circuit_model type="gate" name="or2" prefix="or2" is_default="1" verilog_netlist="/research/ece/lnis/USERS/alacchi/clone_github/tangxifan-eda-tools/branches/vpr7_rram/vpr/VerilogNetlists/sram.v/VerilogNetlists/essential_gates.v">
<design_technology type="cmos" topology="OR"/>
<input_buffer exist="off"/>
<output_buffer exist="off"/>
<port type="input" prefix="in" size="2"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="in" out_port="out">
10e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in" out_port="out">
10e-12
</delay_matrix>
</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="101" cap_val="22.5e-15" 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_tree_like" prefix="mux_tree_like" dump_structural_verilog="true">
<design_technology type="cmos" structure="tree-like" add_const_input="true" const_input_val="1"/>
<input_buffer exist="on" circuit_model_name="inv1"/>
<output_buffer exist="on" circuit_model_name="inv1"/>
<!--mux2to1 subckt_name="mux2to1"/-->
<pass_gate_logic circuit_model_name="tgate"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="1"/>
</circuit_model>
<circuit_model type="mux" name="mux_tree_like_tapbuf" prefix="mux_tree_like_tapbuf" dump_structural_verilog="true" is_default="0">
<design_technology type="cmos" structure="tree-like" add_const_input="true" const_input_val="1"/>
<input_buffer exist="on" circuit_model_name="inv1"/>
<output_buffer exist="on" circuit_model_name="tap_inv4"/>
<!--mux2to1 subckt_name="mux2to1"/-->
<pass_gate_logic circuit_model_name="tgate"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="1"/>
</circuit_model>
<circuit_model type="mux" name="mux_1level_tapbuf" prefix="mux_1level_tapbuf" is_default="1" dump_structural_verilog="true">
<design_technology type="cmos" structure="tree-like" add_const_input="true" const_input_val="1"/>
<input_buffer exist="on" circuit_model_name="inv1"/>
<output_buffer exist="on" circuit_model_name="tap_inv4"/>
<!--mux2to1 subckt_name="mux2to1"/-->
<pass_gate_logic circuit_model_name="tgate"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="1"/>
</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="/research/ece/lnis/USERS/alacchi/Current_release/OpenFPGA/vpr7_x2p/vpr/SpiceNetlists/ff.sp" verilog_netlist="/research/ece/lnis/USERS/alacchi/Current_release/OpenFPGA/vpr7_x2p/vpr/VerilogNetlists/ff.v">
<design_technology type="cmos"/>
<input_buffer exist="on" circuit_model_name="inv1"/>
<output_buffer exist="on" circuit_model_name="inv1"/>
<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="1" 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="frac_lut6" prefix="frac_lut6" dump_structural_verilog="true">
<design_technology type="cmos" fracturable_lut="true"/>
<input_buffer exist="on" circuit_model_name="inv1"/>
<output_buffer exist="on" circuit_model_name="inv1"/>
<lut_input_buffer exist="on" circuit_model_name="buf4"/>
<lut_input_inverter exist="on" circuit_model_name="inv1"/>
<pass_gate_logic circuit_model_name="tgate"/>
<port type="input" prefix="in" size="6" tri_state_map="----11" circuit_model_name="or2"/>
<port type="output" prefix="lut4_out" size="4" lut_frac_level="4" lut_output_mask="0,1,2,3"/>
<port type="output" prefix="lut5_out" size="2" lut_frac_level="5" lut_output_mask="0,1"/>
<port type="output" prefix="lut6_out" size="1" lut_output_mask="0"/>
<port type="sram" prefix="sram" size="64"/>
<port type="sram" prefix="mode" size="2" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/>
</circuit_model>
<!--Scan-chain DFF subckt ports should be defined as <D> <Q> <Qb> <CLK> <RESET> <SET> -->
<circuit_model type="sff" name="sc_dff_compact" prefix="scff" spice_netlist="/research/ece/lnis/USERS/alacchi/Current_release/OpenFPGA/vpr7_x2p/vpr/SpiceNetlists/ff.sp" verilog_netlist="/research/ece/lnis/USERS/alacchi/Current_release/OpenFPGA/vpr7_x2p/vpr/VerilogNetlists/ff.v">
<design_technology type="cmos"/>
<input_buffer exist="on" circuit_model_name="inv1"/>
<output_buffer exist="on" circuit_model_name="inv1"/>
<pass_gate_logic circuit_model_name="tgate"/>
<port type="input" prefix="pReset" size="1" is_global="true" default_val="1" is_reset="true" is_prog="true"/>
<port type="input" prefix="pSet" size="1" is_global="true" default_val="0" is_set="true" is_prog="true"/>
<port type="input" prefix="D" size="1"/>
<port type="output" prefix="Q" size="1"/>
<port type="output" prefix="Qb" size="1"/>
<port type="clock" prefix="prog_clk" size="1" is_global="true" default_val="0" is_prog="true"/>
</circuit_model>
<circuit_model type="iopad" name="iopad" prefix="iopad" spice_netlist="/research/ece/lnis/USERS/alacchi/Current_release/OpenFPGA/vpr7_x2p/vpr/SpiceNetlists/io.sp" verilog_netlist="/research/ece/lnis/USERS/alacchi/Current_release/OpenFPGA/vpr7_x2p/vpr/VerilogNetlists/io.v">
<design_technology type="cmos"/>
<input_buffer exist="on" circuit_model_name="inv1"/>
<output_buffer exist="on" circuit_model_name="inv1"/>
<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="sc_dff_compact" default_val="1"/>
<!--port type="sram" prefix="enb" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="0"/-->
<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>
<!-- Hard logic definition for heterogenous blocks -->
<circuit_model type="hard_logic" name="adder_1bit" prefix="adder" spice_netlist="/research/ece/lnis/USERS/alacchi/Current_release/OpenFPGA/vpr7_x2p/vpr/SpiceNetlists/adder.sp" verilog_netlist="/research/ece/lnis/USERS/alacchi/Current_release/OpenFPGA/vpr7_x2p/vpr/VerilogNetlists/adder.v">
<design_technology type="cmos"/>
<input_buffer exist="on" circuit_model_name="inv1"/>
<output_buffer exist="on" circuit_model_name="inv1"/>
<port type="input" prefix="a" size="1"/>
<port type="input" prefix="b" size="1"/>
<port type="input" prefix="cin" size="1"/>
<port type="output" prefix="sumout" size="1"/>
<port type="output" prefix="cout" size="1"/>
</circuit_model>
<circuit_model type="sram" name="sram6T" prefix="sram" spice_netlist="/research/ece/lnis/USERS/alacchi/Current_release/OpenFPGA/vpr7_x2p/vpr/SpiceNetlists/sram.sp" verilog_netlist="/research/ece/lnis/USERS/alacchi/Current_release/OpenFPGA/vpr7_x2p/vpr/VerilogNetlists/sram.v" >
<design_technology type="cmos"/>
<input_buffer exist="on" circuit_model_name="inv1"/>
<output_buffer exist="on" circuit_model_name="inv1"/>
<pass_gate_logic circuit_model_name="tgate"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="2"/>
</circuit_model>
</module_circuit_models>
</spice_settings>
<device>
<!-- VB & JL: Using Ian Kuon's transistor sizing and drive strength data for routing, at 40 nm. Ian used BPTM
models. We are modifying the delay values however, to include metal C and R, which allows more architecture
experimentation. We are also modifying the relative resistance of PMOS to be 1.8x that of NMOS
(vs. Ian's 3x) as 1.8x lines up with Jeff G's data from a 45 nm process (and is more typical of
45 nm in general). I'm upping the Rmin_nmos from Ian's just over 6k to nearly 9k, and dropping
RminW_pmos from 18k to 16k to hit this 1.8x ratio, while keeping the delays of buffers approximately
lined up with Stratix IV.
We are using Jeff G.'s capacitance data for 45 nm (in tech/ptm_45nm).
Jeff's tables list C in for transistors with widths in multiples of the minimum feature size (45 nm).
The minimum contactable transistor is 2.5 * 45 nm, so I need to multiply drive strength sizes in this file
by 2.5x when looking up in Jeff's tables.
The delay values are lined up with Stratix IV, which has an architecture similar to this
proposed FPGA, and which is also 40 nm
C_ipin_cblock: input capacitance of a track buffer, which VPR assumes is a single-stage
4x minimum drive strength buffer. -->
<sizing R_minW_nmos="8926" R_minW_pmos="16067" ipin_mux_trans_size="9"/>
<timing C_ipin_cblock="596e-18" T_ipin_cblock="77.93e-12"/>
<!-- The grid_logic_tile_area below will be used for all blocks that do not explicitly set their own (non-routing)
area; set to 0 since we explicitly set the area of all blocks currently in this architecture file.
-->
<area grid_logic_tile_area="0"/>
<sram area="6">
<verilog organization="scan-chain" circuit_model_name="sc_dff_compact"/>
<!--verilog organization="memory-bank" circuit_model_name="sram6T_blwl"/-->
<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="77.93e-12" mux_trans_size="3" buf_size="63" circuit_model_name="mux_tree_like_tapbuf" structure="tree-like" num_level="2">
</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="105" Cin="596e-18" Cout="0e-15" Tdel="47.2e-12" mux_trans_size="3" buf_size="63" circuit_model_name="mux_tree_like_tapbuf" structure="tree-like" num_level="1">
</switch>
<switch type="mux" name="sb_mux_L2" R="115" Cin="596e-18" Cout="0e-15" Tdel="47.2e-12" mux_trans_size="3" buf_size="63" circuit_model_name="mux_tree_like_tapbuf" structure="tree-like" num_level="1">
</switch>
<switch type="mux" name="sb_mux_L1" R="128" Cin="596e-18" Cout="0e-15" Tdel="47.2e-12" mux_trans_size="3" buf_size="63" circuit_model_name="mux_tree_like_tapbuf" structure="tree-like" 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>
<!--switch_segment_patterns>
<pattern type="unbuf_sb" seg_length="1" seg_type="unidir" pattern_length="2">
<unbuf_mux name="1"/>
<sb type ="pattern">0 1</sb>
</pattern>
</switch_segment_patterns-->
<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="7" 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">
<input name="I" num_pins="40" equivalent="true"/>
<input name="cin" num_pins="1"/>
<output name="O" num_pins="20" equivalent="false"/>
<output name="cout" num_pins="1"/>
<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
-->
<pb_type name="fle" num_pb="10" physical_mode_name="fle_phy" idle_mode_name="n2_lut5">
<input name="in" num_pins="6"/>
<input name="cin" num_pins="1"/>
<output name="out" num_pins="2"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<mode name="fle_phy" disabled_in_packing="true">
<pb_type name="frac_logic" num_pb="1">
<input name="in" num_pins="6"/>
<input name="cin" num_pins="1"/>
<output name="out" num_pins="2"/>
<output name="cout" num_pins="1"/>
<pb_type name="frac_lut6" blif_model=".frac_lut6" mode_bits="11" num_pb="1" circuit_model_name="frac_lut6">
<input name="in" num_pins="6"/>
<output name="lut4_out" num_pins="4"/>
<output name="lut5_out" num_pins="2"/>
<output name="lut6_out" num_pins="1"/>
</pb_type>
<pb_type name="adder_phy" blif_model=".subckt adder" num_pb="2" circuit_model_name="adder_1bit">
<input name="a" num_pins="1"/>
<input name="b" num_pins="1"/>
<input name="cin" num_pins="1"/>
<output name="cout" num_pins="1"/>
<output name="sumout" num_pins="1"/>
</pb_type>
<interconnect>
<direct name="direct_fraclut_in" input="frac_logic.in[5:0]" output="frac_lut6.in[5:0]"/>
<direct name="direct_cin" input="frac_logic.cin" output="adder_phy[0].cin"/>
<direct name="direct_carry" input="adder_phy[0].cout" output="adder_phy[1].cin"/>
<direct name="direct_cout" input="adder_phy[1].cout" output="frac_logic.cout"/>
<direct name="direct_lut4carry0" input="frac_lut6.lut4_out[0]" output="adder_phy[0].a"/>
<direct name="direct_lut4carry1" input="frac_lut6.lut4_out[1]" output="adder_phy[0].b"/>
<direct name="direct_lut4carry2" input="frac_lut6.lut4_out[2]" output="adder_phy[1].a"/>
<direct name="direct_lut4carry3" input="frac_lut6.lut4_out[3]" output="adder_phy[1].b"/>
<mux name="mux1" input="adder_phy[0].sumout frac_lut6.lut5_out[0]" output="frac_logic.out[0]">
<mode_select mode_name="n2_lut5.arithmetic" in_port="adder_phy[0].sumout" out_port="frac_logic.out[0]"/>
<mode_select mode_name="n2_lut5.blut5" in_port="frac_lut6.lut5_out[0]" out_port="frac_logic.out[0]"/>
<mode_select mode_name="n1_lut6" in_port="frac_lut6.lut5_out[0]" out_port="frac_logic.out[0]"/>
</mux>
<mux name="mux2" input="adder_phy[1].sumout frac_lut6.lut5_out[1] frac_lut6.lut6_out[0]" output="frac_logic.out[1]">
<mode_select mode_name="n2_lut5.arithmetic" in_port="adder_phy[1].sumout" out_port="frac_logic.out[1]"/>
<mode_select mode_name="n2_lut5.blut5" in_port="frac_lut6.lut5_out[1]" out_port="frac_logic.out[1]"/>
<mode_select mode_name="n1_lut6" in_port="frac_lut6.lut6_out[0]" out_port="frac_logic.out[1]"/>
</mux>
</interconnect>
</pb_type>
<pb_type name="ff_phy" blif_model=".latch" num_pb="2" 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="66e-12" port="ff_phy.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff_phy.Q" clock="clk"/>
</pb_type>
<interconnect>
<complete name="direct_clk" input="fle.clk" output="ff_phy[1:0].clk"/>
<direct name="direct_in" input="fle.in[5:0]" output="frac_logic.in[5:0]"/>
<direct name="direct_cin" input="fle.cin" output="frac_logic.cin"/>
<direct name="direct_cout" input="frac_logic.cout" output="fle.cout"/>
<direct name="direct_frac_out1" input="frac_logic.out[0]" output="ff_phy[0].D"/>
<direct name="direct_frac_out2" input="frac_logic.out[1]" output="ff_phy[1].D"/>
<mux name="mux1" input="ff_phy[0].Q frac_logic.out[0]" output="fle.out[0]">
</mux>
<mux name="mux2" input="ff_phy[1].Q frac_logic.out[1]" output="fle.out[1]">
</mux>
</interconnect>
</mode>
<mode name="n2_lut5" disabled_in_packing="false">
<!-- multi-mode support -->
<pb_type name="lut5inter" num_pb="1">
<input name="in" num_pins="5"/>
<input name="cin" num_pins="1"/>
<output name="out" num_pins="2"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<pb_type name="ble5" num_pb="2" idle_mode_name="blut5">
<input name="in" num_pins="5"/>
<input name="cin" num_pins="1"/>
<output name="out" num_pins="1"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<mode name="blut5">
<pb_type name="flut5" num_pb="1">
<input name="in" num_pins="5"/>
<output name="out" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- Regular LUT mode -->
<pb_type name="lut5" blif_model=".names" num_pb="1" class="lut" mode_bits="01" physical_pb_type_name="frac_lut6" physical_pb_type_index_factor="0.5">
<input name="in" num_pins="5" port_class="lut_in" physical_mode_pin="in[5:0]"/>
<output name="out" num_pins="1" port_class="lut_out" physical_mode_pin="lut5_out" physical_mode_pin_rotate_offset="1"/>
<!-- LUT timing using delay matrix -->
<!-- These are the physical delay inputs on a Stratix IV LUT but because VPR cannot do LUT rebalancing,
we instead take the average of these numbers to get more stable results
82e-12
173e-12
261e-12
263e-12
398e-12
-->
<delay_matrix type="max" in_port="lut5.in" out_port="lut5.out">
235e-12
235e-12
235e-12
235e-12
235e-12
</delay_matrix>
</pb_type>
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop" physical_pb_type_name="ff_phy">
<input name="D" num_pins="1" port_class="D" physical_mode_pin="D"/>
<output name="Q" num_pins="1" port_class="Q" physical_mode_pin="Q"/>
<clock name="clk" num_pins="1" port_class="clock" physical_mode_pin="clk"/>
<T_setup value="66e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="direct1" input="flut5.in" output="lut5.in"/>
<direct name="direct2" input="lut5.out" output="ff.D">
<pack_pattern name="ble5" in_port="lut5.out" out_port="ff.D"/>
</direct>
<direct name="direct3" input="flut5.clk" output="ff.clk"/>
<mux name="mux1" input="ff.Q lut5.out" output="flut5.out" spice_model_sram_offset="0">
<delay_constant max="25e-12" in_port="lut5.out" out_port="flut5.out" />
<delay_constant max="45e-12" in_port="ff.Q" out_port="flut5.out" />
</mux>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="ble5.in" output="flut5.in"/>
<direct name="direct2" input="ble5.clk" output="flut5.clk"/>
<direct name="direct3" input="flut5.out" output="ble5.out"/>
</interconnect>
</mode>
<mode name="arithmetic">
<pb_type name="arithmetic" num_pb="1">
<input name="in" num_pins="4"/>
<input name="cin" num_pins="1"/>
<output name="out" num_pins="1"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- Special dual-LUT mode that drives adder only -->
<pb_type name="lut4" blif_model=".names" num_pb="2" class="lut" mode_bits="11" physical_pb_type_name="frac_lut6" physical_pb_type_index_factor="0.25">
<input name="in" num_pins="4" port_class="lut_in" physical_mode_pin="in[4:0]"/>
<output name="out" num_pins="1" port_class="lut_out" physical_mode_pin="lut4_out" physical_mode_pin_rotate_offset="1"/>
<!-- LUT timing using delay matrix -->
<!-- These are the physical delay inputs on a Stratix IV LUT but because VPR cannot do LUT rebalancing,
we instead take the average of these numbers to get more stable results
82e-12
173e-12
261e-12
263e-12
-->
<delay_matrix type="max" in_port="lut4.in" out_port="lut4.out">
195e-12
195e-12
195e-12
195e-12
</delay_matrix>
</pb_type>
<pb_type name="adder" blif_model=".subckt adder" num_pb="1" physical_pb_type_name="adder_phy">
<input name="a" num_pins="1" physical_mode_pin="a"/>
<input name="b" num_pins="1" physical_mode_pin="b"/>
<input name="cin" num_pins="1" physical_mode_pin="cin"/>
<output name="cout" num_pins="1" physical_mode_pin="cout"/>
<output name="sumout" num_pins="1" physical_mode_pin="sumout"/>
<delay_constant max="0.3e-9" in_port="adder.a" out_port="adder.sumout"/>
<delay_constant max="0.3e-9" in_port="adder.b" out_port="adder.sumout"/>
<delay_constant max="0.3e-9" in_port="adder.cin" out_port="adder.sumout"/>
<delay_constant max="0.3e-9" in_port="adder.a" out_port="adder.cout"/>
<delay_constant max="0.3e-9" in_port="adder.b" out_port="adder.cout"/>
<delay_constant max="0.01e-9" in_port="adder.cin" out_port="adder.cout"/>
</pb_type>
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop" physical_pb_type_name="ff_phy">
<input name="D" num_pins="1" port_class="D" physical_mode_pin="D"/>
<output name="Q" num_pins="1" port_class="Q" physical_mode_pin="Q"/>
<clock name="clk" num_pins="1" port_class="clock" physical_mode_pin="clk"/>
<T_setup value="66e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="clock" input="arithmetic.clk" output="ff.clk"/>
<direct name="lut_in1" input="arithmetic.in[3:0]" output="lut4[0:0].in[3:0]"/>
<direct name="lut_in2" input="arithmetic.in[3:0]" output="lut4[1:1].in[3:0]"/>
<direct name="lut_to_add1" input="lut4[0:0].out" output="adder.a">
</direct>
<direct name="lut_to_add2" input="lut4[1:1].out" output="adder.b">
</direct>
<direct name="add_to_ff" input="adder.sumout" output="ff.D">
<pack_pattern name="chain" in_port="adder.sumout" out_port="ff.D"/>
</direct>
<direct name="carry_in" input="arithmetic.cin" output="adder.cin">
<pack_pattern name="chain" in_port="arithmetic.cin" out_port="adder.cin"/>
</direct>
<direct name="carry_out" input="adder.cout" output="arithmetic.cout">
<pack_pattern name="chain" in_port="adder.cout" out_port="arithmetic.cout"/>
</direct>
<mux name="sumout" input="ff.Q adder.sumout" output="arithmetic.out">
<delay_constant max="25e-12" in_port="adder.sumout" out_port="arithmetic.out"/>
<delay_constant max="45e-12" in_port="ff.Q" out_port="arithmetic.out" />
</mux>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="ble5.in[3:0]" output="arithmetic.in"/>
<direct name="carry_in" input="ble5.cin" output="arithmetic.cin">
<pack_pattern name="chain" in_port="ble5.cin" out_port="arithmetic.cin"/>
</direct>
<direct name="carry_out" input="arithmetic.cout" output="ble5.cout">
<pack_pattern name="chain" in_port="arithmetic.cout" out_port="ble5.cout"/>
</direct>
<direct name="direct2" input="ble5.clk" output="arithmetic.clk"/>
<direct name="direct3" input="arithmetic.out" output="ble5.out"/>
</interconnect>
</mode>
</pb_type>
<interconnect>
<direct name="direct1" input="lut5inter.in" output="ble5[0:0].in"/>
<direct name="direct2" input="lut5inter.in" output="ble5[1:1].in"/>
<direct name="direct3" input="ble5[1:0].out" output="lut5inter.out"/>
<direct name="carry_in" input="lut5inter.cin" output="ble5[0:0].cin">
<pack_pattern name="chain" in_port="lut5inter.cin" out_port="ble5[0:0].cin"/>
</direct>
<direct name="carry_out" input="ble5[1:1].cout" output="lut5inter.cout">
<pack_pattern name="chain" in_port="ble5[1:1].cout" out_port="lut5inter.cout"/>
</direct>
<direct name="carry_link" input="ble5[0:0].cout" output="ble5[1:1].cin">
<pack_pattern name="chain" in_port="ble5[0:0].cout" out_port="ble5[1:1].cout"/>
</direct>
<complete name="complete1" input="lut5inter.clk" output="ble5[1:0].clk"/>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="fle.in[4:0]" output="lut5inter.in"/>
<direct name="direct2" input="lut5inter.out" output="fle.out"/>
<direct name="direct3" input="fle.clk" output="lut5inter.clk"/>
<direct name="carry_in" input="fle.cin" output="lut5inter.cin">
<pack_pattern name="chain" in_port="fle.cin" out_port="lut5inter.cin"/>
</direct>
<direct name="carry_out" input="lut5inter.cout" output="fle.cout">
<pack_pattern name="chain" in_port="lut5inter.cout" out_port="fle.cout"/>
</direct>
</interconnect>
</mode> <!-- n2_lut5 -->
<mode name="n1_lut6">
<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"/>
<pb_type name="lut6" blif_model=".names" num_pb="1" class="lut" mode_bits="00" physical_pb_type_name="frac_lut6" spice_model_sram_offset="0">
<input name="in" num_pins="6" port_class="lut_in" physical_mode_pin="in[5:0]"/>
<output name="out" num_pins="1" port_class="lut_out" physical_mode_pin="lut6_out[0]"/>
<!-- LUT timing using delay matrix -->
<!-- These are the physical delay inputs on a Stratix IV LUT but because VPR cannot do LUT rebalancing,
we instead take the average of these numbers to get more stable results
82e-12
173e-12
261e-12
263e-12
398e-12
397e-12
-->
<delay_matrix type="max" in_port="lut6.in" out_port="lut6.out">
261e-12
261e-12
261e-12
261e-12
261e-12
261e-12
</delay_matrix>
</pb_type>
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop" physical_pb_type_name="ff_phy" physical_pb_type_index_factor="2" physical_pb_type_index_offset="1">
<input name="D" num_pins="1" port_class="D" physical_mode_pin="D"/>
<output name="Q" num_pins="1" port_class="Q" physical_mode_pin="Q"/>
<clock name="clk" num_pins="1" port_class="clock" physical_mode_pin="clk"/>
<T_setup value="66e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="124e-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">
<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">
<delay_constant max="25e-12" in_port="lut6.out" out_port="ble6.out" />
<delay_constant max="45e-12" 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[1:1]"/>
<direct name="direct3" input="fle.clk" output="ble6.clk"/>
</interconnect>
</mode> <!-- n1_lut6 -->
</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_tree_like">
<delay_constant max="95e-12" in_port="clb.I" out_port="fle[9:0].in" />
<delay_constant max="75e-12" 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]"/>
<!-- Carry chain links -->
<direct name="carry_in" input="clb.cin" output="fle[0:0].cin">
<!-- Put all inter-block carry chain delay on this one edge -->
<delay_constant max="0.16e-9" in_port="clb.cin" out_port="fle[0:0].cin"/>
<pack_pattern name="chain" in_port="clb.cin" out_port="fle[0:0].cin"/>
</direct>
<direct name="carry_out" input="fle[9:9].cout" output="clb.cout">
<pack_pattern name="chain" in_port="fle[9:9].cout" out_port="clb.cout"/>
</direct>
<direct name="carry_link" input="fle[8:0].cout" output="fle[9:1].cin">
<pack_pattern name="chain" in_port="fle[8:0].cout" out_port="fle[9:1].cin"/>
</direct>
</interconnect>
<fc default_in_type="frac" default_in_val="0.15" default_out_type="frac" default_out_val="0.10">
<pin name="cin" fc_type="frac" fc_val="0"/>
<pin name="cout" fc_type="frac" fc_val="0"/>
</fc>
<pinlocations pattern="spread"/>
<gridlocations>
<loc type="fill" priority="1"/>
</gridlocations>
</pb_type>
<!-- Define general purpose logic block (CLB) ends -->
</complexblocklist>
<power>
<local_interconnect C_wire="2.5e-10"/>
<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="2.5e-10"/>
</clocks>
</architecture>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

33
vpr7_x2p/vpr/go_ganesh.sh Executable file
View File

@ -0,0 +1,33 @@
#!/bin/bash
echo "#################################################"
echo "The current shell environment is the following:"
echo $0
echo "#################################################"
# Example of how to run vprset circuit_name = pip_add
#set circuit_name = pip_add
circuit_name=sync_4bits_add
circuit_blif=${PWD}/Circuits/${circuit_name}.blif
arch_file=${PWD}/ARCH/k6_N10_scan_chain_ptm45nm_TT.xml
arch_file_template=${PWD}/ARCH/k6_N10_sram_chain_HC_template.xml
circuit_act=${PWD}/Circuits/${circuit_name}.act
circuit_verilog=${PWD}/Circuits/${circuit_name}.v
spice_output=${PWD}/spice_demo
verilog_output=${PWD}/verilog_demo
modelsim_ini=/uusoc/facility/cad_tools/Mentor/modelsim10.7b/modeltech/modelsim.ini
openfpga_path=${PWD}/../..
# Make sure a clean start
rm -rf ${spice_output}
rm -rf ${verilog_output}
echo "*******************************"
echo "THIS SCRIPT NEEDS TO BE SOURCED"
echo "source ./go.sh"
echo "*******************************"
sed "s:OPENFPGAPATH:${openfpga_path}:g" ${arch_file_template} > ${arch_file}
# Pack, place, and route a heterogeneous FPGA
# Packing uses the AAPack algorithm
./vpr ${arch_file} ${circuit_blif} --full_stats --nodisp --activity_file ${circuit_act} --route_chan_width 30 --fpga_spice --fpga_spice_rename_illegal_port --fpga_spice_dir ${spice_output} --fpga_spice_print_top_testbench