mirror of https://github.com/lnis-uofu/SOFA.git
Merge remote-tracking branch 'origin/master' into ganesh_dev
This commit is contained in:
commit
78e2a242b3
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,265 @@
|
||||||
|
<!-- Architecture annotation for OpenFPGA framework
|
||||||
|
This annotation supports the k4_frac_cc_sky130nm.xml
|
||||||
|
- General purpose logic block
|
||||||
|
- K = 6, N = 10, I = 40
|
||||||
|
- Single mode
|
||||||
|
- Routing architecture
|
||||||
|
- L = 4, fc_in = 0.15, fc_out = 0.1
|
||||||
|
- Skywater 130nm PDK
|
||||||
|
- circuit models are binded to the opensource skywater
|
||||||
|
foundry middle-speed (ms) standard cell library
|
||||||
|
-->
|
||||||
|
<openfpga_architecture>
|
||||||
|
<technology_library>
|
||||||
|
<device_library>
|
||||||
|
<device_model name="logic" type="transistor">
|
||||||
|
<lib type="industry" corner="TOP_TT" ref="M" path="${OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.pm"/>
|
||||||
|
<design vdd="0.9" pn_ratio="2"/>
|
||||||
|
<pmos name="pch" chan_length="40e-9" min_width="140e-9" variation="logic_transistor_var"/>
|
||||||
|
<nmos name="nch" chan_length="40e-9" min_width="140e-9" variation="logic_transistor_var"/>
|
||||||
|
</device_model>
|
||||||
|
<device_model name="io" type="transistor">
|
||||||
|
<lib type="academia" ref="M" path="${OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.pm"/>
|
||||||
|
<design vdd="2.5" pn_ratio="3"/>
|
||||||
|
<pmos name="pch_25" chan_length="270e-9" min_width="320e-9" variation="io_transistor_var"/>
|
||||||
|
<nmos name="nch_25" chan_length="270e-9" min_width="320e-9" variation="io_transistor_var"/>
|
||||||
|
</device_model>
|
||||||
|
</device_library>
|
||||||
|
<variation_library>
|
||||||
|
<variation name="logic_transistor_var" abs_deviation="0.1" num_sigma="3"/>
|
||||||
|
<variation name="io_transistor_var" abs_deviation="0.1" num_sigma="3"/>
|
||||||
|
</variation_library>
|
||||||
|
</technology_library>
|
||||||
|
<circuit_library>
|
||||||
|
<circuit_model type="inv_buf" name="sky130_fd_sc_hd__inv_1" prefix="sky130_fd_sc_hd__inv_1" is_default="true" verilog_netlist="${SKYWATER_OPENFPGA_HOME}/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/inv/sky130_fd_sc_hd__inv_1.v">
|
||||||
|
<design_technology type="cmos" topology="inverter" size="1"/>
|
||||||
|
<device_technology device_model_name="logic"/>
|
||||||
|
<port type="input" prefix="in" lib_name="A" size="1"/>
|
||||||
|
<port type="output" prefix="out" lib_name="Y" 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="sky130_fd_sc_hd__buf_2" prefix="sky130_fd_sc_hd__buf_2" is_default="false" verilog_netlist="${SKYWATER_OPENFPGA_HOME}/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/buf/sky130_fd_sc_hd__buf_2.v">
|
||||||
|
<design_technology type="cmos" topology="buffer" size="1" num_level="2" f_per_stage="2"/>
|
||||||
|
<device_technology device_model_name="logic"/>
|
||||||
|
<port type="input" prefix="in" lib_name="A" size="1"/>
|
||||||
|
<port type="output" prefix="out" lib_name="X" 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="sky130_fd_sc_hd__buf_4" prefix="sky130_fd_sc_hd__buf_4" is_default="false" verilog_netlist="${SKYWATER_OPENFPGA_HOME}/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/buf/sky130_fd_sc_hd__buf_4.v">
|
||||||
|
<design_technology type="cmos" topology="buffer" size="1" num_level="2" f_per_stage="4"/>
|
||||||
|
<device_technology device_model_name="logic"/>
|
||||||
|
<port type="input" prefix="in" lib_name="A" size="1"/>
|
||||||
|
<port type="output" prefix="out" lib_name="X" 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="sky130_fd_sc_hd__inv_2" prefix="sky130_fd_sc_hd__inv_2" is_default="false" verilog_netlist="${SKYWATER_OPENFPGA_HOME}/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/inv/sky130_fd_sc_hd__inv_2.v">
|
||||||
|
<design_technology type="cmos" topology="buffer" size="1"/>
|
||||||
|
<device_technology device_model_name="logic"/>
|
||||||
|
<port type="input" prefix="in" lib_name="A" size="1"/>
|
||||||
|
<port type="output" prefix="out" lib_name="Y" 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="gate" name="sky130_fd_sc_hd__or2_1" prefix="sky130_fd_sc_hd__or2_1" is_default="true" verilog_netlist="${SKYWATER_OPENFPGA_HOME}/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/or2/sky130_fd_sc_hd__or2_1.v">
|
||||||
|
<design_technology type="cmos" topology="OR"/>
|
||||||
|
<device_technology device_model_name="logic"/>
|
||||||
|
<input_buffer exist="false"/>
|
||||||
|
<output_buffer exist="false"/>
|
||||||
|
<port type="input" prefix="a" lib_name="A" size="1"/>
|
||||||
|
<port type="input" prefix="b" lib_name="B" size="1"/>
|
||||||
|
<port type="output" prefix="out" lib_name="X" size="1"/>
|
||||||
|
<delay_matrix type="rise" in_port="a b" out_port="out">
|
||||||
|
10e-12 5e-12
|
||||||
|
</delay_matrix>
|
||||||
|
<delay_matrix type="fall" in_port="a b" out_port="out">
|
||||||
|
10e-12 5e-12
|
||||||
|
</delay_matrix>
|
||||||
|
</circuit_model>
|
||||||
|
<!-- Define a circuit model for the standard cell MUX2
|
||||||
|
OpenFPGA requires the following truth table for the MUX2
|
||||||
|
When the select signal sel is enabled, the first input, i.e., in0
|
||||||
|
will be propagated to the output, i.e., out
|
||||||
|
If your standard cell provider does not offer the exact truth table,
|
||||||
|
you can simply swap the inputs as shown in the example below
|
||||||
|
-->
|
||||||
|
<circuit_model type="gate" name="sky130_fd_sc_hd__mux2_1" prefix="sky130_fd_sc_hd__mux2_1" verilog_netlist="${SKYWATER_OPENFPGA_HOME}/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/mux2/sky130_fd_sc_hd__mux2_1.v">
|
||||||
|
<design_technology type="cmos" topology="MUX2"/>
|
||||||
|
<device_technology device_model_name="logic"/>
|
||||||
|
<input_buffer exist="false"/>
|
||||||
|
<output_buffer exist="false"/>
|
||||||
|
<port type="input" prefix="in0" lib_name="A1" size="1"/>
|
||||||
|
<port type="input" prefix="in1" lib_name="A0" size="1"/>
|
||||||
|
<port type="input" prefix="sel" lib_name="S" size="1"/>
|
||||||
|
<port type="output" prefix="out" lib_name="X" size="1"/>
|
||||||
|
</circuit_model>
|
||||||
|
<circuit_model type="chan_wire" name="chan_segment" prefix="track_seg" is_default="true">
|
||||||
|
<design_technology type="cmos"/>
|
||||||
|
<input_buffer exist="false"/>
|
||||||
|
<output_buffer exist="false"/>
|
||||||
|
<port type="input" prefix="in" size="1"/>
|
||||||
|
<port type="output" prefix="out" size="1"/>
|
||||||
|
<wire_param model_type="pi" R="101" C="22.5e-15" num_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="true">
|
||||||
|
<design_technology type="cmos"/>
|
||||||
|
<input_buffer exist="false"/>
|
||||||
|
<output_buffer exist="false"/>
|
||||||
|
<port type="input" prefix="in" size="1"/>
|
||||||
|
<port type="output" prefix="out" size="1"/>
|
||||||
|
<wire_param model_type="pi" R="0" C="0" num_level="1"/>
|
||||||
|
<!-- model_type could be T, res_val cap_val should be defined -->
|
||||||
|
</circuit_model>
|
||||||
|
<circuit_model type="mux" name="mux_tree" prefix="mux_tree" is_default="true" dump_structural_verilog="true">
|
||||||
|
<design_technology type="cmos" structure="tree" add_const_input="true" const_input_val="1"/>
|
||||||
|
<input_buffer exist="false"/>
|
||||||
|
<output_buffer exist="false"/>
|
||||||
|
<pass_gate_logic circuit_model_name="sky130_fd_sc_hd__mux2_1"/>
|
||||||
|
<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_tapbuf" prefix="mux_tree_tapbuf" dump_structural_verilog="true">
|
||||||
|
<design_technology type="cmos" structure="tree" add_const_input="true" const_input_val="1"/>
|
||||||
|
<input_buffer exist="false"/>
|
||||||
|
<output_buffer exist="true" circuit_model_name="sky130_fd_sc_hd__buf_4"/>
|
||||||
|
<pass_gate_logic circuit_model_name="sky130_fd_sc_hd__mux2_1"/>
|
||||||
|
<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="sky130_fd_sc_hd__sdfrtp_1" prefix="sky130_fd_sc_hd__sdfrtp_1" verilog_netlist="${SKYWATER_OPENFPGA_HOME}/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/sdfrtp/sky130_fd_sc_hd__sdfrtp_1.v">
|
||||||
|
<design_technology type="cmos"/>
|
||||||
|
<input_buffer exist="true" circuit_model_name="sky130_fd_sc_hd__inv_1"/>
|
||||||
|
<output_buffer exist="true" circuit_model_name="sky130_fd_sc_hd__inv_1"/>
|
||||||
|
<port type="input" prefix="D" size="1"/>
|
||||||
|
<port type="input" prefix="DI" lib_name="SCD" size="1"/>
|
||||||
|
<port type="input" prefix="Test_en" lib_name="SCE" size="1" is_global="true" default_val="0"/>
|
||||||
|
<port type="input" prefix="reset" lib_name="RESET_B" size="1" default_val="1"/>
|
||||||
|
<port type="output" prefix="Q" size="1"/>
|
||||||
|
<port type="clock" prefix="clk" lib_name="CLK" size="1" is_global="false" default_val="0" />
|
||||||
|
</circuit_model>
|
||||||
|
<circuit_model type="lut" name="frac_lut4" prefix="frac_lut4" dump_structural_verilog="true">
|
||||||
|
<design_technology type="cmos" fracturable_lut="true"/>
|
||||||
|
<input_buffer exist="false"/>
|
||||||
|
<output_buffer exist="true" circuit_model_name="sky130_fd_sc_hd__buf_2"/>
|
||||||
|
<lut_input_inverter exist="true" circuit_model_name="sky130_fd_sc_hd__inv_1"/>
|
||||||
|
<lut_input_buffer exist="true" circuit_model_name="sky130_fd_sc_hd__buf_2"/>
|
||||||
|
<lut_intermediate_buffer exist="true" circuit_model_name="sky130_fd_sc_hd__buf_2" location_map="-1-"/>
|
||||||
|
<pass_gate_logic circuit_model_name="sky130_fd_sc_hd__mux2_1"/>
|
||||||
|
<port type="input" prefix="in" size="4" tri_state_map="---1" circuit_model_name="sky130_fd_sc_hd__or2_1"/>
|
||||||
|
<port type="output" prefix="lut2_out" size="2" lut_frac_level="2" lut_output_mask="2,3"/>
|
||||||
|
<port type="output" prefix="lut4_out" size="1" lut_output_mask="0"/>
|
||||||
|
<port type="sram" prefix="sram" size="16"/>
|
||||||
|
<port type="sram" prefix="mode" size="1" mode_select="true" circuit_model_name="sky130_fd_sc_hd__dfrtp_1" default_val="1"/>
|
||||||
|
</circuit_model>
|
||||||
|
<!--Scan-chain DFF subckt ports should be defined as <D> <Q> <Qb> <CLK> <RESET> <SET> -->
|
||||||
|
<circuit_model type="ccff" name="sky130_fd_sc_hd__dfrtp_1" prefix="sky130_fd_sc_hd__dfrtp_1" verilog_netlist="${SKYWATER_OPENFPGA_HOME}/PDK/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/dfrtp/sky130_fd_sc_hd__dfrtp_1.v">
|
||||||
|
<design_technology type="cmos"/>
|
||||||
|
<input_buffer exist="true" circuit_model_name="sky130_fd_sc_hd__inv_1"/>
|
||||||
|
<output_buffer exist="true" circuit_model_name="sky130_fd_sc_hd__inv_1"/>
|
||||||
|
<port type="input" prefix="D" size="1"/>
|
||||||
|
<port type="output" prefix="Q" size="1"/>
|
||||||
|
<port type="clock" prefix="prog_clk" lib_name="CLK" size="1" is_global="true" default_val="0" is_prog="true"/>
|
||||||
|
<port type="input" prefix="pReset" lib_name="RESET_B" size="1" is_global="true" default_val="1" is_prog="true" is_reset="true"/>
|
||||||
|
</circuit_model>
|
||||||
|
<circuit_model type="iopad" name="EMBEDDED_IO_HD" prefix="EMBEDDED_IO_HD" is_default="true" verilog_netlist="${SKYWATER_OPENFPGA_HOME}/HDL/common/digital_io_hd.v">
|
||||||
|
<design_technology type="cmos"/>
|
||||||
|
<input_buffer exist="true" circuit_model_name="sky130_fd_sc_hd__inv_1"/>
|
||||||
|
<output_buffer exist="true" circuit_model_name="sky130_fd_sc_hd__inv_1"/>
|
||||||
|
<port type="input" prefix="SOC_IN" lib_name="SOC_IN" size="1" is_global="true" is_io="true" is_data_io="true"/>
|
||||||
|
<port type="output" prefix="SOC_OUT" lib_name="SOC_OUT" size="1" is_global="true" is_io="true" is_data_io="true"/>
|
||||||
|
<port type="output" prefix="SOC_DIR" lib_name="SOC_DIR" size="1" is_global="true" is_io="true"/>
|
||||||
|
<port type="input" prefix="IO_ISOL_N" lib_name="IO_ISOL_N" size="1" is_global="true" default_val="1"/>
|
||||||
|
<port type="output" prefix="inpad" lib_name="FPGA_IN" size="1"/>
|
||||||
|
<port type="input" prefix="outpad" lib_name="FPGA_OUT" size="1"/>
|
||||||
|
<port type="sram" prefix="en" lib_name="FPGA_DIR" size="1" mode_select="true" circuit_model_name="sky130_fd_sc_hd__dfrtp_1" default_val="1"/>
|
||||||
|
</circuit_model>
|
||||||
|
<circuit_model type="hard_logic" name="sky130_fd_sc_hd__mux2_1_wrapper" prefix="sky130_fd_sc_hd__mux2_1_wrapper" verilog_netlist="${SKYWATER_OPENFPGA_HOME}/HDL/common/sky130_fd_sc_hd_wrapper.v">
|
||||||
|
<design_technology type="cmos"/>
|
||||||
|
<device_technology device_model_name="logic"/>
|
||||||
|
<input_buffer exist="false"/>
|
||||||
|
<output_buffer exist="false"/>
|
||||||
|
<port type="input" prefix="a" lib_name="A0" size="1"/>
|
||||||
|
<port type="input" prefix="b" lib_name="A1" size="1"/>
|
||||||
|
<port type="input" prefix="cin" lib_name="S" size="1"/>
|
||||||
|
<port type="output" prefix="cout" lib_name="X" size="1"/>
|
||||||
|
</circuit_model>
|
||||||
|
</circuit_library>
|
||||||
|
<configuration_protocol>
|
||||||
|
<organization type="scan_chain" circuit_model_name="sky130_fd_sc_hd__dfrtp_1" num_regions="1"/>
|
||||||
|
</configuration_protocol>
|
||||||
|
<connection_block>
|
||||||
|
<switch name="ipin_cblock" circuit_model_name="mux_tree_tapbuf"/>
|
||||||
|
</connection_block>
|
||||||
|
<switch_block>
|
||||||
|
<switch name="L1_mux" circuit_model_name="mux_tree_tapbuf"/>
|
||||||
|
<switch name="L2_mux" circuit_model_name="mux_tree_tapbuf"/>
|
||||||
|
<switch name="L4_mux" circuit_model_name="mux_tree_tapbuf"/>
|
||||||
|
</switch_block>
|
||||||
|
<routing_segment>
|
||||||
|
<segment name="L1" circuit_model_name="chan_segment"/>
|
||||||
|
<segment name="L2" circuit_model_name="chan_segment"/>
|
||||||
|
<segment name="L4" circuit_model_name="chan_segment"/>
|
||||||
|
</routing_segment>
|
||||||
|
<direct_connection>
|
||||||
|
<direct name="carry_chain" circuit_model_name="direct_interc"/>
|
||||||
|
<direct name="shift_register" circuit_model_name="direct_interc"/>
|
||||||
|
<direct name="scan_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||||
|
</direct_connection>
|
||||||
|
<tile_annotations>
|
||||||
|
<global_port name="clk" is_clock="true" default_val="0">
|
||||||
|
<tile name="clb" port="clk[0:3]" x="-1" y="-1"/>
|
||||||
|
</global_port>
|
||||||
|
<global_port name="Reset" is_reset="true" default_val="1">
|
||||||
|
<tile name="clb" port="reset" x="-1" y="-1"/>
|
||||||
|
</global_port>
|
||||||
|
</tile_annotations>
|
||||||
|
<pb_type_annotations>
|
||||||
|
<!-- physical pb_type binding in complex block IO -->
|
||||||
|
<pb_type name="io" physical_mode_name="physical" idle_mode_name="inpad"/>
|
||||||
|
<!-- IMPORTANT: must set unused I/Os to operating in INPUT mode !!! -->
|
||||||
|
<pb_type name="io[physical].iopad" circuit_model_name="EMBEDDED_IO_HD" mode_bits="1"/>
|
||||||
|
<pb_type name="io[inpad].inpad" physical_pb_type_name="io[physical].iopad" mode_bits="1"/>
|
||||||
|
<pb_type name="io[outpad].outpad" physical_pb_type_name="io[physical].iopad" mode_bits="0"/>
|
||||||
|
<!-- End physical pb_type binding in complex block IO -->
|
||||||
|
|
||||||
|
<!-- physical pb_type binding in complex block CLB -->
|
||||||
|
<!-- physical mode will be the default mode if not specified -->
|
||||||
|
<pb_type name="clb.fle" physical_mode_name="physical"/>
|
||||||
|
<pb_type name="clb.fle[physical].fabric.frac_logic.frac_lut4" circuit_model_name="frac_lut4" mode_bits="0"/>
|
||||||
|
<pb_type name="clb.fle[physical].fabric.frac_logic.carry_follower" circuit_model_name="sky130_fd_sc_hd__mux2_1_wrapper"/>
|
||||||
|
<pb_type name="clb.fle[physical].fabric.ff" circuit_model_name="sky130_fd_sc_hd__sdfrtp_1"/>
|
||||||
|
<!-- Binding operating pb_type to physical pb_type -->
|
||||||
|
<!-- Binding operating pb_types in mode 'ble4' -->
|
||||||
|
<pb_type name="clb.fle[n1_lut4].ble4.lut4" physical_pb_type_name="clb.fle[physical].fabric.frac_logic.frac_lut4" mode_bits="0">
|
||||||
|
<!-- Binding the lut4 to the first 4 inputs of fracturable lut4 -->
|
||||||
|
<port name="in" physical_mode_port="in[0:3]"/>
|
||||||
|
<port name="out" physical_mode_port="lut4_out"/>
|
||||||
|
</pb_type>
|
||||||
|
<pb_type name="clb.fle[n1_lut4].ble4.ff" physical_pb_type_name="clb.fle[physical].fabric.ff"/>
|
||||||
|
<!-- Binding operating pb_types in mode 'shift_register' -->
|
||||||
|
<pb_type name="clb.fle[shift_register].shift_reg.ff" physical_pb_type_name="clb.fle[physical].fabric.ff"/>
|
||||||
|
<!-- End physical pb_type binding in complex block IO -->
|
||||||
|
</pb_type_annotations>
|
||||||
|
</openfpga_architecture>
|
|
@ -216,7 +216,9 @@
|
||||||
<direct name="scan_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
<direct name="scan_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||||
</direct_connection>
|
</direct_connection>
|
||||||
<tile_annotations>
|
<tile_annotations>
|
||||||
<global_port name="clk" tile_port="clb.clk" is_clock="true" default_val="0"/>
|
<global_port name="clk" is_clock="true" default_val="0">
|
||||||
|
<tile name="clb" port="clk" x="-1" y="-1"/>
|
||||||
|
</global_port>
|
||||||
</tile_annotations>
|
</tile_annotations>
|
||||||
<pb_type_annotations>
|
<pb_type_annotations>
|
||||||
<!-- physical pb_type binding in complex block IO -->
|
<!-- physical pb_type binding in complex block IO -->
|
||||||
|
|
|
@ -217,8 +217,12 @@
|
||||||
<direct name="scan_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
<direct name="scan_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||||
</direct_connection>
|
</direct_connection>
|
||||||
<tile_annotations>
|
<tile_annotations>
|
||||||
<global_port name="clk" tile_port="clb.clk" is_clock="true" default_val="0"/>
|
<global_port name="clk" is_clock="true" default_val="0">
|
||||||
<global_port name="reset" tile_port="clb.reset" is_reset="true" default_val="1"/>
|
<tile name="clb" port="clk" x="-1" y="-1"/>
|
||||||
|
</global_port>
|
||||||
|
<global_port name="Reset" is_reset="true" default_val="1">
|
||||||
|
<tile name="clb" port="reset" x="-1" y="-1"/>
|
||||||
|
</global_port>
|
||||||
</tile_annotations>
|
</tile_annotations>
|
||||||
<pb_type_annotations>
|
<pb_type_annotations>
|
||||||
<!-- physical pb_type binding in complex block IO -->
|
<!-- physical pb_type binding in complex block IO -->
|
||||||
|
|
|
@ -288,8 +288,12 @@
|
||||||
<direct name="scan_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
<direct name="scan_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||||
</direct_connection>
|
</direct_connection>
|
||||||
<tile_annotations>
|
<tile_annotations>
|
||||||
<global_port name="clk" tile_port="clb.clk" is_clock="true" default_val="0"/>
|
<global_port name="clk" is_clock="true" default_val="0">
|
||||||
<global_port name="Reset" tile_port="clb.reset" is_reset="true" default_val="1"/>
|
<tile name="clb" port="clk" x="-1" y="-1"/>
|
||||||
|
</global_port>
|
||||||
|
<global_port name="Reset" is_reset="true" default_val="1">
|
||||||
|
<tile name="clb" port="reset" x="-1" y="-1"/>
|
||||||
|
</global_port>
|
||||||
</tile_annotations>
|
</tile_annotations>
|
||||||
<pb_type_annotations>
|
<pb_type_annotations>
|
||||||
<!-- physical pb_type binding in complex block IO -->
|
<!-- physical pb_type binding in complex block IO -->
|
||||||
|
|
|
@ -229,8 +229,12 @@
|
||||||
<direct name="scan_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
<direct name="scan_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||||
</direct_connection>
|
</direct_connection>
|
||||||
<tile_annotations>
|
<tile_annotations>
|
||||||
<global_port name="clk" tile_port="clb.clk" is_clock="true" default_val="0"/>
|
<global_port name="clk" is_clock="true" default_val="0">
|
||||||
<global_port name="Reset" tile_port="clb.reset" is_reset="true" default_val="1"/>
|
<tile name="clb" port="clk" x="-1" y="-1"/>
|
||||||
|
</global_port>
|
||||||
|
<global_port name="Reset" is_reset="true" default_val="1">
|
||||||
|
<tile name="clb" port="reset" x="-1" y="-1"/>
|
||||||
|
</global_port>
|
||||||
</tile_annotations>
|
</tile_annotations>
|
||||||
<pb_type_annotations>
|
<pb_type_annotations>
|
||||||
<!-- physical pb_type binding in complex block IO -->
|
<!-- physical pb_type binding in complex block IO -->
|
||||||
|
|
|
@ -228,7 +228,9 @@
|
||||||
<direct name="scan_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
<direct name="scan_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
|
||||||
</direct_connection>
|
</direct_connection>
|
||||||
<tile_annotations>
|
<tile_annotations>
|
||||||
<global_port name="clk" tile_port="clb.clk" is_clock="true" default_val="0"/>
|
<global_port name="clk" is_clock="true" default_val="0">
|
||||||
|
<tile name="clb" port="clk" x="-1" y="-1"/>
|
||||||
|
</global_port>
|
||||||
</tile_annotations>
|
</tile_annotations>
|
||||||
<pb_type_annotations>
|
<pb_type_annotations>
|
||||||
<!-- physical pb_type binding in complex block IO -->
|
<!-- physical pb_type binding in complex block IO -->
|
||||||
|
|
|
@ -214,7 +214,9 @@
|
||||||
<direct name="adder_carry" circuit_model_name="direct_interc"/>
|
<direct name="adder_carry" circuit_model_name="direct_interc"/>
|
||||||
</direct_connection>
|
</direct_connection>
|
||||||
<tile_annotations>
|
<tile_annotations>
|
||||||
<global_port name="clk" tile_port="SUPER_LOGIC_CELL.QCK" is_clock="true" default_val="0"/>
|
<global_port name="clk" is_clock="true" default_val="0">
|
||||||
|
<tile name="SUPER_LOGIC_CELL" port="QCK" x="-1" y="-1"/>
|
||||||
|
</global_port>
|
||||||
</tile_annotations>
|
</tile_annotations>
|
||||||
<pb_type_annotations>
|
<pb_type_annotations>
|
||||||
<!-- physical pb_type binding in complex block IO -->
|
<!-- physical pb_type binding in complex block IO -->
|
||||||
|
|
|
@ -0,0 +1,596 @@
|
||||||
|
<!--
|
||||||
|
Low-cost homogeneous FPGA Architecture.
|
||||||
|
|
||||||
|
- Skywater 130 nm technology
|
||||||
|
- General purpose logic block:
|
||||||
|
K = 4, N = 8, fracturable 4 LUTs (can operate as one 4-LUT or two 3-LUTs with all 3 inputs shared)
|
||||||
|
with optionally registered outputs
|
||||||
|
- Routing architecture:
|
||||||
|
- 10% L = 1, fc_in = 0.15, Fc_out = 0.10
|
||||||
|
- 10% L = 2, fc_in = 0.15, Fc_out = 0.10
|
||||||
|
- 80% L = 4, fc_in = 0.15, Fc_out = 0.10
|
||||||
|
- 100 routing tracks per channel
|
||||||
|
|
||||||
|
Authors: Xifan Tang
|
||||||
|
-->
|
||||||
|
<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>
|
||||||
|
<!-- A virtual model for I/O to be used in the physical mode of io block -->
|
||||||
|
<model name="io">
|
||||||
|
<input_ports>
|
||||||
|
<port name="outpad"/>
|
||||||
|
</input_ports>
|
||||||
|
<output_ports>
|
||||||
|
<port name="inpad"/>
|
||||||
|
</output_ports>
|
||||||
|
</model>
|
||||||
|
|
||||||
|
<model name="frac_lut4">
|
||||||
|
<input_ports>
|
||||||
|
<port name="in"/>
|
||||||
|
</input_ports>
|
||||||
|
<output_ports>
|
||||||
|
<port name="lut2_out"/>
|
||||||
|
<port name="lut4_out"/>
|
||||||
|
</output_ports>
|
||||||
|
</model>
|
||||||
|
<model name="carry_follower">
|
||||||
|
<input_ports>
|
||||||
|
<port name="a"/>
|
||||||
|
<port name="b"/>
|
||||||
|
<port name="cin"/>
|
||||||
|
</input_ports>
|
||||||
|
<output_ports>
|
||||||
|
<port name="cout"/>
|
||||||
|
</output_ports>
|
||||||
|
</model>
|
||||||
|
<!-- A virtual model for scan-chain flip-flop to be used in the physical mode of FF -->
|
||||||
|
<model name="scff">
|
||||||
|
<input_ports>
|
||||||
|
<port name="D" clock="clk"/>
|
||||||
|
<port name="DI" clock="clk"/>
|
||||||
|
<port name="reset" clock="clk"/>
|
||||||
|
<port name="clk" is_clock="1"/>
|
||||||
|
</input_ports>
|
||||||
|
<output_ports>
|
||||||
|
<port name="Q" clock="clk"/>
|
||||||
|
</output_ports>
|
||||||
|
</model>
|
||||||
|
</models>
|
||||||
|
<tiles>
|
||||||
|
<!-- Do NOT add clock pins to I/O here!!! VPR does not build clock network in the way that OpenFPGA can support
|
||||||
|
If you need to register the I/O, define clocks in the circuit models
|
||||||
|
These clocks can be handled in back-end
|
||||||
|
-->
|
||||||
|
<!-- Top-side has 1 I/O per tile -->
|
||||||
|
<tile name="io_top" capacity="16" area="0">
|
||||||
|
<equivalent_sites>
|
||||||
|
<site pb_type="io"/>
|
||||||
|
</equivalent_sites>
|
||||||
|
<input name="outpad" num_pins="1"/>
|
||||||
|
<output name="inpad" num_pins="1"/>
|
||||||
|
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10"/>
|
||||||
|
<pinlocations pattern="custom">
|
||||||
|
<loc side="bottom">io_top.outpad io_top.inpad</loc>
|
||||||
|
</pinlocations>
|
||||||
|
</tile>
|
||||||
|
<!-- Right-side has 1 I/O per tile -->
|
||||||
|
<tile name="io_right" capacity="16" area="0">
|
||||||
|
<equivalent_sites>
|
||||||
|
<site pb_type="io"/>
|
||||||
|
</equivalent_sites>
|
||||||
|
<input name="outpad" num_pins="1"/>
|
||||||
|
<output name="inpad" num_pins="1"/>
|
||||||
|
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10"/>
|
||||||
|
<pinlocations pattern="custom">
|
||||||
|
<loc side="left">io_right.outpad io_right.inpad</loc>
|
||||||
|
</pinlocations>
|
||||||
|
</tile>
|
||||||
|
<!-- Bottom-side has 9 I/O per tile -->
|
||||||
|
<tile name="io_bottom" capacity="16" area="0">
|
||||||
|
<equivalent_sites>
|
||||||
|
<site pb_type="io"/>
|
||||||
|
</equivalent_sites>
|
||||||
|
<input name="outpad" num_pins="1"/>
|
||||||
|
<output name="inpad" num_pins="1"/>
|
||||||
|
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10"/>
|
||||||
|
<pinlocations pattern="custom">
|
||||||
|
<loc side="top">io_bottom.outpad io_bottom.inpad</loc>
|
||||||
|
</pinlocations>
|
||||||
|
</tile>
|
||||||
|
<!-- Left-side has 1 I/O per tile -->
|
||||||
|
<tile name="io_left" capacity="16" area="0">
|
||||||
|
<equivalent_sites>
|
||||||
|
<site pb_type="io"/>
|
||||||
|
</equivalent_sites>
|
||||||
|
<input name="outpad" num_pins="1"/>
|
||||||
|
<output name="inpad" num_pins="1"/>
|
||||||
|
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10"/>
|
||||||
|
<pinlocations pattern="custom">
|
||||||
|
<loc side="right">io_left.outpad io_left.inpad</loc>
|
||||||
|
</pinlocations>
|
||||||
|
</tile>
|
||||||
|
<!-- CLB has most pins on the top and right sides -->
|
||||||
|
<tile name="clb" area="53894">
|
||||||
|
<equivalent_sites>
|
||||||
|
<site pb_type="clb"/>
|
||||||
|
</equivalent_sites>
|
||||||
|
<input name="I" num_pins="24" equivalent="full"/>
|
||||||
|
<input name="reg_in" num_pins="1"/>
|
||||||
|
<input name="sc_in" num_pins="1"/>
|
||||||
|
<input name="cin" num_pins="1"/>
|
||||||
|
<input name="reset" num_pins="1" is_non_clock_global="true"/>
|
||||||
|
<output name="O" num_pins="8" equivalent="none"/>
|
||||||
|
<output name="reg_out" num_pins="1"/>
|
||||||
|
<output name="sc_out" num_pins="1"/>
|
||||||
|
<output name="cout" num_pins="1"/>
|
||||||
|
<output name="cout_copy" num_pins="1"/>
|
||||||
|
<clock name="clk" num_pins="4"/>
|
||||||
|
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10">
|
||||||
|
<fc_override port_name="reg_in" fc_type="frac" fc_val="0"/>
|
||||||
|
<fc_override port_name="reg_out" fc_type="frac" fc_val="0"/>
|
||||||
|
<fc_override port_name="sc_in" fc_type="frac" fc_val="0"/>
|
||||||
|
<fc_override port_name="sc_out" fc_type="frac" fc_val="0"/>
|
||||||
|
<fc_override port_name="cin" fc_type="frac" fc_val="0"/>
|
||||||
|
<fc_override port_name="cout" fc_type="frac" fc_val="0"/>
|
||||||
|
<fc_override port_name="clk" fc_type="frac" fc_val="0"/>
|
||||||
|
<fc_override port_name="reset" fc_type="frac" fc_val="0"/>
|
||||||
|
</fc>
|
||||||
|
<!--pinlocations pattern="spread"/-->
|
||||||
|
<pinlocations pattern="custom">
|
||||||
|
<loc side="left">clb.clk clb.reset</loc>
|
||||||
|
<loc side="top">clb.reg_in clb.sc_in clb.cin clb.O[7:0] clb.I[11:0]</loc>
|
||||||
|
<loc side="right">clb.I[23:12]</loc>
|
||||||
|
<loc side="bottom">clb.reg_out clb.sc_out clb.cout clb.cout_copy</loc>
|
||||||
|
</pinlocations>
|
||||||
|
</tile>
|
||||||
|
</tiles>
|
||||||
|
<!-- ODIN II specific config ends -->
|
||||||
|
<!-- Physical descriptions begin -->
|
||||||
|
<layout tileable="true">
|
||||||
|
<auto_layout aspect_ratio="1.0">
|
||||||
|
<!--Perimeter of 'io' blocks with 'EMPTY' blocks at corners-->
|
||||||
|
<row type="io_top" starty="H-1" priority="100"/>
|
||||||
|
<row type="io_bottom" starty="0" priority="100"/>
|
||||||
|
<col type="io_left" startx="0" priority="100"/>
|
||||||
|
<col type="io_right" startx="W-1" priority="100"/>
|
||||||
|
<corners type="EMPTY" priority="101"/>
|
||||||
|
<!--Fill with 'clb'-->
|
||||||
|
<fill type="clb" priority="10"/>
|
||||||
|
</auto_layout>
|
||||||
|
<fixed_layout name="2x2" width="4" height="4">
|
||||||
|
<!--Perimeter of 'io' blocks with 'EMPTY' blocks at corners-->
|
||||||
|
<row type="io_top" starty="H-1" priority="100"/>
|
||||||
|
<row type="io_bottom" starty="0" priority="100"/>
|
||||||
|
<col type="io_left" startx="0" priority="100"/>
|
||||||
|
<col type="io_right" startx="W-1" priority="100"/>
|
||||||
|
<corners type="EMPTY" priority="101"/>
|
||||||
|
<!--Fill with 'clb'-->
|
||||||
|
<fill type="clb" priority="10"/>
|
||||||
|
</fixed_layout>
|
||||||
|
<fixed_layout name="12x12" width="14" height="14">
|
||||||
|
<!--Perimeter of 'io' blocks with 'EMPTY' blocks at corners-->
|
||||||
|
<row type="io_top" starty="H-1" priority="100"/>
|
||||||
|
<row type="io_bottom" starty="0" priority="100"/>
|
||||||
|
<col type="io_left" startx="0" priority="100"/>
|
||||||
|
<col type="io_right" startx="W-1" priority="100"/>
|
||||||
|
<corners type="EMPTY" priority="101"/>
|
||||||
|
<!--Fill with 'clb'-->
|
||||||
|
<fill type="clb" priority="10"/>
|
||||||
|
</fixed_layout>
|
||||||
|
<fixed_layout name="32x32" width="34" height="34">
|
||||||
|
<!--Perimeter of 'io' blocks with 'EMPTY' blocks at corners-->
|
||||||
|
<row type="io_top" starty="H-1" priority="100"/>
|
||||||
|
<row type="io_bottom" starty="0" priority="100"/>
|
||||||
|
<col type="io_left" startx="0" priority="100"/>
|
||||||
|
<col type="io_right" startx="W-1" priority="100"/>
|
||||||
|
<corners type="EMPTY" priority="101"/>
|
||||||
|
<!--Fill with 'clb'-->
|
||||||
|
<fill type="clb" priority="10"/>
|
||||||
|
</fixed_layout>
|
||||||
|
</layout>
|
||||||
|
<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"/>
|
||||||
|
<!-- 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"/>
|
||||||
|
<chan_width_distr>
|
||||||
|
<x distr="uniform" peak="1.000000"/>
|
||||||
|
<y distr="uniform" peak="1.000000"/>
|
||||||
|
</chan_width_distr>
|
||||||
|
<switch_block type="wilton" fs="3" sub_type="subset" sub_fs="3"/>
|
||||||
|
<connection_block input_switch_name="ipin_cblock"/>
|
||||||
|
</device>
|
||||||
|
<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="L1_mux" R="551" Cin=".77e-15" Cout="4e-15" Tdel="58e-12" mux_trans_size="2.630740" buf_size="27.645901"/>
|
||||||
|
<switch type="mux" name="L2_mux" R="551" Cin=".77e-15" Cout="4e-15" Tdel="58e-12" mux_trans_size="2.630740" buf_size="27.645901"/>
|
||||||
|
<switch type="mux" name="L4_mux" R="551" Cin=".77e-15" Cout="4e-15" Tdel="58e-12" mux_trans_size="2.630740" buf_size="27.645901"/>
|
||||||
|
<!--switch ipin_cblock resistance set to yeild for 4x minimum drive strength buffer-->
|
||||||
|
<switch type="mux" name="ipin_cblock" R="2231.5" Cout="0." Cin="1.47e-15" Tdel="7.247000e-11" mux_trans_size="1.222260" buf_size="auto"/>
|
||||||
|
</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. -->
|
||||||
|
<!-- GIVE a specific name for the segment! OpenFPGA appreciate that! -->
|
||||||
|
<segment name="L1" freq="0.20" length="1" type="unidir" Rmetal="101" Cmetal="22.5e-15">
|
||||||
|
<mux name="L1_mux"/>
|
||||||
|
<sb type="pattern">1 1</sb>
|
||||||
|
<cb type="pattern">1</cb>
|
||||||
|
</segment>
|
||||||
|
<segment name="L2" freq="0.10" length="2" type="unidir" Rmetal="101" Cmetal="22.5e-15">
|
||||||
|
<mux name="L2_mux"/>
|
||||||
|
<sb type="pattern">1 1 1</sb>
|
||||||
|
<cb type="pattern">1 1</cb>
|
||||||
|
</segment>
|
||||||
|
<segment name="L4" freq="0.70" length="4" type="unidir" Rmetal="101" Cmetal="22.5e-15">
|
||||||
|
<mux name="L4_mux"/>
|
||||||
|
<sb type="pattern">1 1 1 1 1</sb>
|
||||||
|
<cb type="pattern">1 1 1 1</cb>
|
||||||
|
</segment>
|
||||||
|
</segmentlist>
|
||||||
|
<directlist>
|
||||||
|
<direct name="carry_chain" from_pin="clb.cout" to_pin="clb.cin" x_offset="0" y_offset="-1" z_offset="0"/>
|
||||||
|
<direct name="shift_register" from_pin="clb.reg_out" to_pin="clb.reg_in" x_offset="0" y_offset="-1" z_offset="0"/>
|
||||||
|
<direct name="scan_chain" from_pin="clb.sc_out" to_pin="clb.sc_in" x_offset="0" y_offset="-1" z_offset="0"/>
|
||||||
|
</directlist>
|
||||||
|
<complexblocklist>
|
||||||
|
<!-- Define input pads begin -->
|
||||||
|
<pb_type name="io">
|
||||||
|
<input name="outpad" num_pins="1"/>
|
||||||
|
<output name="inpad" num_pins="1"/>
|
||||||
|
<!-- Do NOT add clock pins to I/O here!!! VPR does not build clock network in the way that OpenFPGA can support
|
||||||
|
If you need to register the I/O, define clocks in the circuit models
|
||||||
|
These clocks can be handled in back-end
|
||||||
|
-->
|
||||||
|
<!-- A mode denotes the physical implementation of an I/O
|
||||||
|
This mode will be not packable but is mainly used for fabric verilog generation
|
||||||
|
-->
|
||||||
|
<mode name="physical" disabled_in_pack="true">
|
||||||
|
<pb_type name="iopad" blif_model=".subckt io" num_pb="1">
|
||||||
|
<input name="outpad" num_pins="1"/>
|
||||||
|
<output name="inpad" num_pins="1"/>
|
||||||
|
</pb_type>
|
||||||
|
<interconnect>
|
||||||
|
<direct name="outpad" input="io.outpad" output="iopad.outpad">
|
||||||
|
<delay_constant max="1.394e-11" in_port="io.outpad" out_port="iopad.outpad"/>
|
||||||
|
</direct>
|
||||||
|
<direct name="inpad" input="iopad.inpad" output="io.inpad">
|
||||||
|
<delay_constant max="4.243e-11" in_port="iopad.inpad" out_port="io.inpad"/>
|
||||||
|
</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">
|
||||||
|
<output name="inpad" num_pins="1"/>
|
||||||
|
</pb_type>
|
||||||
|
<interconnect>
|
||||||
|
<direct name="inpad" input="inpad.inpad" output="io.inpad">
|
||||||
|
<delay_constant max="4.243e-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">
|
||||||
|
<input name="outpad" num_pins="1"/>
|
||||||
|
</pb_type>
|
||||||
|
<interconnect>
|
||||||
|
<direct name="outpad" input="io.outpad" output="outpad.outpad">
|
||||||
|
<delay_constant max="1.394e-11" in_port="io.outpad" out_port="outpad.outpad"/>
|
||||||
|
</direct>
|
||||||
|
</interconnect>
|
||||||
|
</mode>
|
||||||
|
<power method="ignore"/>
|
||||||
|
</pb_type>
|
||||||
|
<!-- Define I/O pads ends -->
|
||||||
|
<!-- Define general purpose logic block (CLB) begin -->
|
||||||
|
<!-- -Due to the absence of local routing,
|
||||||
|
the 4 inputs of fracturable LUT4 are no longer equivalent,
|
||||||
|
because the 4th input can not be switched when the dual-LUT3 modes are used.
|
||||||
|
So pin equivalence should be applied to the first 3 inputs only
|
||||||
|
-->
|
||||||
|
<pb_type name="clb">
|
||||||
|
<input name="I" num_pins="24" equivalent="full"/>
|
||||||
|
<input name="reg_in" num_pins="1"/>
|
||||||
|
<input name="sc_in" num_pins="1"/>
|
||||||
|
<input name="cin" num_pins="1"/>
|
||||||
|
<input name="reset" num_pins="1" is_non_clock_global="true"/>
|
||||||
|
<output name="O" num_pins="8" equivalent="none"/>
|
||||||
|
<output name="reg_out" num_pins="1"/>
|
||||||
|
<output name="sc_out" num_pins="1"/>
|
||||||
|
<output name="cout" num_pins="1"/>
|
||||||
|
<output name="cout_copy" num_pins="1"/>
|
||||||
|
<clock name="clk" num_pins="4"/>
|
||||||
|
<!-- 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="8">
|
||||||
|
<input name="in" num_pins="4"/>
|
||||||
|
<input name="reg_in" num_pins="1"/>
|
||||||
|
<input name="sc_in" num_pins="1"/>
|
||||||
|
<input name="cin" num_pins="1"/>
|
||||||
|
<input name="reset" num_pins="1"/>
|
||||||
|
<output name="out" num_pins="1"/>
|
||||||
|
<output name="reg_out" num_pins="1"/>
|
||||||
|
<output name="sc_out" num_pins="1"/>
|
||||||
|
<output name="cout" num_pins="1"/>
|
||||||
|
<clock name="clk" num_pins="1"/>
|
||||||
|
<!-- Physical mode definition begin (physical implementation of the fle) -->
|
||||||
|
<mode name="physical" disabled_in_pack="true">
|
||||||
|
<pb_type name="fabric" num_pb="1">
|
||||||
|
<input name="in" num_pins="4"/>
|
||||||
|
<input name="reg_in" num_pins="1"/>
|
||||||
|
<input name="sc_in" num_pins="1"/>
|
||||||
|
<input name="cin" num_pins="1"/>
|
||||||
|
<input name="reset" num_pins="1"/>
|
||||||
|
<output name="out" num_pins="1"/>
|
||||||
|
<output name="reg_out" num_pins="1"/>
|
||||||
|
<output name="sc_out" num_pins="1"/>
|
||||||
|
<output name="cout" num_pins="1"/>
|
||||||
|
<clock name="clk" num_pins="1"/>
|
||||||
|
<pb_type name="frac_logic" 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"/>
|
||||||
|
<!-- Define LUT -->
|
||||||
|
<pb_type name="frac_lut4" blif_model=".subckt frac_lut4" num_pb="1">
|
||||||
|
<input name="in" num_pins="4"/>
|
||||||
|
<output name="lut2_out" num_pins="2"/>
|
||||||
|
<output name="lut4_out" num_pins="1"/>
|
||||||
|
</pb_type>
|
||||||
|
<pb_type name="carry_follower" blif_model=".subckt carry_follower" num_pb="1">
|
||||||
|
<input name="a" num_pins="1"/>
|
||||||
|
<input name="b" num_pins="1"/>
|
||||||
|
<input name="cin" num_pins="1"/>
|
||||||
|
<output name="cout" num_pins="1"/>
|
||||||
|
</pb_type>
|
||||||
|
<interconnect>
|
||||||
|
<direct name="direct1" input="frac_logic.in[0:1]" output="frac_lut4.in[0:1]"/>
|
||||||
|
<direct name="direct2" input="frac_logic.in[3:3]" output="frac_lut4.in[3:3]"/>
|
||||||
|
<direct name="direct3" input="frac_logic.cin" output="carry_follower.b"/>
|
||||||
|
<direct name="direct4" input="frac_lut4.lut2_out[1:1]" output="carry_follower.a"/>
|
||||||
|
<direct name="direct5" input="frac_lut4.lut2_out[0:0]" output="carry_follower.cin"/>
|
||||||
|
<direct name="direct6" input="carry_follower.cout" output="frac_logic.cout"/>
|
||||||
|
<!-- Xifan Tang: I use out[0] because the output of lut6 in lut6 mode is wired to the out[0] -->
|
||||||
|
<direct name="direct7" input="frac_lut4.lut4_out" output="frac_logic.out"/>
|
||||||
|
<mux name="mux2" input="frac_logic.cin frac_logic.in[2:2]" output="frac_lut4.in[2:2]"/>
|
||||||
|
</interconnect>
|
||||||
|
</pb_type>
|
||||||
|
<!-- Define flip-flop with scan-chain capability, DI is the scan-chain data input -->
|
||||||
|
<pb_type name="ff" blif_model=".subckt scff" num_pb="1">
|
||||||
|
<input name="D" num_pins="1"/>
|
||||||
|
<input name="DI" num_pins="1"/>
|
||||||
|
<input name="reset" num_pins="1"/>
|
||||||
|
<output name="Q" num_pins="1"/>
|
||||||
|
<clock name="clk" num_pins="1"/>
|
||||||
|
<T_setup value="66e-12" port="ff.D" clock="clk"/>
|
||||||
|
<T_setup value="66e-12" port="ff.DI" clock="clk"/>
|
||||||
|
<T_setup value="66e-12" port="ff.reset" clock="clk"/>
|
||||||
|
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
|
||||||
|
</pb_type>
|
||||||
|
<interconnect>
|
||||||
|
<direct name="direct1" input="fabric.in" output="frac_logic.in"/>
|
||||||
|
<direct name="direct2" input="fabric.sc_in" output="ff.DI"/>
|
||||||
|
<direct name="direct3" input="fabric.cin" output="frac_logic.cin"/>
|
||||||
|
<direct name="direct4" input="ff.Q" output="fabric.sc_out"/>
|
||||||
|
<direct name="direct5" input="ff.Q" output="fabric.reg_out"/>
|
||||||
|
<direct name="direct6" input="frac_logic.cout" output="fabric.cout"/>
|
||||||
|
<complete name="complete1" input="fabric.clk" output="ff.clk"/>
|
||||||
|
<complete name="complete2" input="fabric.reset" output="ff.reset"/>
|
||||||
|
<mux name="mux1" input="frac_logic.out fabric.reg_in" output="ff.D">
|
||||||
|
<delay_constant max="25e-12" in_port="frac_logic.out" out_port="ff.D"/>
|
||||||
|
<delay_constant max="45e-12" in_port="fabric.reg_in" out_port="ff.D"/>
|
||||||
|
</mux>
|
||||||
|
<mux name="mux2" input="ff.Q frac_logic.out" output="fabric.out">
|
||||||
|
<!-- LUT to output is faster than FF to output on a Stratix IV -->
|
||||||
|
<delay_constant max="25e-12" in_port="frac_logic.out" out_port="fabric.out"/>
|
||||||
|
<delay_constant max="45e-12" in_port="ff.Q" out_port="fabric.out"/>
|
||||||
|
</mux>
|
||||||
|
</interconnect>
|
||||||
|
</pb_type>
|
||||||
|
<interconnect>
|
||||||
|
<direct name="direct1" input="fle.in" output="fabric.in"/>
|
||||||
|
<direct name="direct2" input="fle.reg_in" output="fabric.reg_in"/>
|
||||||
|
<direct name="direct3" input="fle.sc_in" output="fabric.sc_in"/>
|
||||||
|
<direct name="direct4" input="fle.cin" output="fabric.cin"/>
|
||||||
|
<direct name="direct5" input="fabric.out" output="fle.out"/>
|
||||||
|
<direct name="direct6" input="fabric.reg_out" output="fle.reg_out"/>
|
||||||
|
<direct name="direct7" input="fabric.sc_out" output="fle.sc_out"/>
|
||||||
|
<direct name="direct8" input="fabric.cout" output="fle.cout"/>
|
||||||
|
<direct name="direct9" input="fle.clk" output="fabric.clk"/>
|
||||||
|
<direct name="direct10" input="fle.reset" output="fabric.reset"/>
|
||||||
|
</interconnect>
|
||||||
|
</mode>
|
||||||
|
<!-- Physical mode definition end (physical implementation of the fle) -->
|
||||||
|
<mode name="n1_lut4">
|
||||||
|
<!-- Define 4-LUT mode -->
|
||||||
|
<pb_type name="ble4" num_pb="1">
|
||||||
|
<input name="in" num_pins="4"/>
|
||||||
|
<output name="out" num_pins="1"/>
|
||||||
|
<clock name="clk" num_pins="1"/>
|
||||||
|
<!-- Define LUT -->
|
||||||
|
<pb_type name="lut4" blif_model=".names" num_pb="1" class="lut">
|
||||||
|
<input name="in" num_pins="4" port_class="lut_in"/>
|
||||||
|
<output name="out" num_pins="1" port_class="lut_out"/>
|
||||||
|
<!-- 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="lut4.in" out_port="lut4.out">
|
||||||
|
261e-12
|
||||||
|
261e-12
|
||||||
|
261e-12
|
||||||
|
261e-12
|
||||||
|
</delay_matrix>
|
||||||
|
</pb_type>
|
||||||
|
<!-- Define flip-flop -->
|
||||||
|
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop">
|
||||||
|
<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.D" clock="clk"/>
|
||||||
|
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
|
||||||
|
</pb_type>
|
||||||
|
<interconnect>
|
||||||
|
<direct name="direct1" input="ble4.in" output="lut4[0:0].in"/>
|
||||||
|
<direct name="direct2" input="lut4.out" output="ff.D">
|
||||||
|
<!-- Advanced user option that tells CAD tool to find LUT+FF pairs in netlist -->
|
||||||
|
<pack_pattern name="ble4" in_port="lut4.out" out_port="ff.D"/>
|
||||||
|
</direct>
|
||||||
|
<direct name="direct3" input="ble4.clk" output="ff.clk"/>
|
||||||
|
<mux name="mux1" input="ff.Q lut4.out" output="ble4.out">
|
||||||
|
<!-- LUT to output is faster than FF to output on a Stratix IV -->
|
||||||
|
<delay_constant max="25e-12" in_port="lut4.out" out_port="ble4.out"/>
|
||||||
|
<delay_constant max="45e-12" in_port="ff.Q" out_port="ble4.out"/>
|
||||||
|
</mux>
|
||||||
|
</interconnect>
|
||||||
|
</pb_type>
|
||||||
|
<interconnect>
|
||||||
|
<direct name="direct1" input="fle.in" output="ble4.in"/>
|
||||||
|
<direct name="direct2" input="ble4.out" output="fle.out"/>
|
||||||
|
<direct name="direct3" input="fle.clk" output="ble4.clk"/>
|
||||||
|
</interconnect>
|
||||||
|
</mode>
|
||||||
|
<!-- 4-LUT mode definition end -->
|
||||||
|
<!-- Define shift register begin -->
|
||||||
|
<mode name="shift_register" disable_packing="true">
|
||||||
|
<pb_type name="shift_reg" num_pb="1">
|
||||||
|
<input name="reg_in" num_pins="1"/>
|
||||||
|
<output name="ff_out" num_pins="1"/>
|
||||||
|
<output name="reg_out" num_pins="1"/>
|
||||||
|
<clock name="clk" num_pins="1"/>
|
||||||
|
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop">
|
||||||
|
<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.D" clock="clk"/>
|
||||||
|
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
|
||||||
|
</pb_type>
|
||||||
|
<interconnect>
|
||||||
|
<direct name="direct1" input="shift_reg.reg_in" output="ff.D"/>
|
||||||
|
<direct name="direct2" input="ff.Q" output="shift_reg.reg_out"/>
|
||||||
|
<direct name="direct3" input="ff.Q" output="shift_reg.ff_out"/>
|
||||||
|
<complete name="complete1" input="shift_reg.clk" output="ff.clk"/>
|
||||||
|
</interconnect>
|
||||||
|
</pb_type>
|
||||||
|
<interconnect>
|
||||||
|
<direct name="direct1" input="fle.reg_in" output="shift_reg.reg_in"/>
|
||||||
|
<direct name="direct2" input="shift_reg.reg_out" output="fle.reg_out"/>
|
||||||
|
<direct name="direct3" input="shift_reg.ff_out" output="fle.out"/>
|
||||||
|
<direct name="direct4" input="fle.clk" output="shift_reg.clk"/>
|
||||||
|
</interconnect>
|
||||||
|
</mode>
|
||||||
|
<!-- Define shift register end -->
|
||||||
|
</pb_type>
|
||||||
|
<interconnect>
|
||||||
|
<!-- We use direct connections to reduce the area to the most
|
||||||
|
The global local routing is going to compensate the loss in routability
|
||||||
|
-->
|
||||||
|
<!-- FIXME: The implicit port definition results in I0[0] connected to
|
||||||
|
in[2]. Such twisted connection is not expected.
|
||||||
|
I[0] should be connected to in[0]
|
||||||
|
-->
|
||||||
|
<complete name="crossbar" input="clb.I fle[7:0].out" output="fle[7:0].in">
|
||||||
|
<!-- TODO: Timing should be backannotated from post-PnR results -->
|
||||||
|
</complete>
|
||||||
|
<complete name="clks" input="clb.clk" output="fle[7:0].clk">
|
||||||
|
</complete>
|
||||||
|
<complete name="resets" input="clb.reset" output="fle[7:0].reset">
|
||||||
|
</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[3:0].out" output="clb.O[3:0]"/>
|
||||||
|
<direct name="clbouts2" input="fle[7:4].out" output="clb.O[7:4]"/>
|
||||||
|
<direct name="cout_copy" input="fle[7:7].cout" output="clb.cout_copy"/>
|
||||||
|
<!-- Shift register chain links -->
|
||||||
|
<direct name="shift_register_in" input="clb.reg_in" output="fle[0:0].reg_in">
|
||||||
|
<!-- Put all inter-block carry chain delay on this one edge -->
|
||||||
|
<delay_constant max="0.16e-9" in_port="clb.reg_in" out_port="fle[0:0].reg_in"/>
|
||||||
|
<!--pack_pattern name="chain" in_port="clb.reg_in" out_port="fle[0:0].reg_in"/-->
|
||||||
|
</direct>
|
||||||
|
<direct name="shift_register_out" input="fle[7:7].reg_out" output="clb.reg_out">
|
||||||
|
<!--pack_pattern name="chain" in_port="fle[7:7].reg_out" out_port="clb.reg_out"/-->
|
||||||
|
</direct>
|
||||||
|
<direct name="shift_register_link" input="fle[6:0].reg_out" output="fle[7:1].reg_in">
|
||||||
|
<!--pack_pattern name="chain" in_port="fle[6:0].reg_out" out_port="fle[7:1].reg_in"/-->
|
||||||
|
</direct>
|
||||||
|
<!-- Scan chain links -->
|
||||||
|
<direct name="scan_chain_in" input="clb.sc_in" output="fle[0:0].sc_in">
|
||||||
|
<!-- Put all inter-block carry chain delay on this one edge -->
|
||||||
|
<delay_constant max="0.16e-9" in_port="clb.sc_in" out_port="fle[0:0].sc_in"/>
|
||||||
|
</direct>
|
||||||
|
<direct name="scan_chain_out" input="fle[7:7].sc_out" output="clb.sc_out">
|
||||||
|
</direct>
|
||||||
|
<direct name="scan_chain_link" input="fle[6:0].sc_out" output="fle[7:1].sc_in">
|
||||||
|
</direct>
|
||||||
|
<!-- Carry chain links -->
|
||||||
|
<direct name="carry_chain_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"/>
|
||||||
|
</direct>
|
||||||
|
<direct name="carry_chain_out" input="fle[7:7].cout" output="clb.cout">
|
||||||
|
</direct>
|
||||||
|
<direct name="carry_chain_link" input="fle[6:0].cout" output="fle[7:1].cin">
|
||||||
|
</direct>
|
||||||
|
</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 -->
|
||||||
|
<!-- Place this general purpose logic block in any unspecified column -->
|
||||||
|
</pb_type>
|
||||||
|
<!-- Define general purpose logic block (CLB) ends -->
|
||||||
|
</complexblocklist>
|
||||||
|
</architecture>
|
|
@ -437,10 +437,12 @@
|
||||||
</pb_type>
|
</pb_type>
|
||||||
<interconnect>
|
<interconnect>
|
||||||
<direct name="direct1" input="fabric.in" output="frac_logic.in"/>
|
<direct name="direct1" input="fabric.in" output="frac_logic.in"/>
|
||||||
<direct name="direct2" input="fabric.sc_in" output="ff[0].DI"/>
|
<direct name="direct2" input="fabric.cin" output="frac_logic.cin"/>
|
||||||
<direct name="direct3" input="ff[0].Q" output="ff[1].DI"/>
|
<direct name="direct3" input="fabric.sc_in" output="ff[0].DI"/>
|
||||||
<direct name="direct4" input="ff[1].Q" output="fabric.sc_out"/>
|
<direct name="direct4" input="ff[0].Q" output="ff[1].DI"/>
|
||||||
<direct name="direct5" input="ff[1].Q" output="fabric.reg_out"/>
|
<direct name="direct5" input="ff[1].Q" output="fabric.sc_out"/>
|
||||||
|
<direct name="direct6" input="ff[1].Q" output="fabric.reg_out"/>
|
||||||
|
<direct name="direct7" input="frac_logic.cout" output="fabric.cout"/>
|
||||||
<complete name="complete1" input="fabric.clk" output="ff[1:0].clk"/>
|
<complete name="complete1" input="fabric.clk" output="ff[1:0].clk"/>
|
||||||
<complete name="complete2" input="fabric.reset" output="ff[1:0].reset"/>
|
<complete name="complete2" input="fabric.reset" output="ff[1:0].reset"/>
|
||||||
<mux name="mux1" input="frac_logic.out[0:0] fabric.reg_in" output="ff[0:0].D">
|
<mux name="mux1" input="frac_logic.out[0:0] fabric.reg_in" output="ff[0:0].D">
|
||||||
|
|
|
@ -429,10 +429,12 @@
|
||||||
</pb_type>
|
</pb_type>
|
||||||
<interconnect>
|
<interconnect>
|
||||||
<direct name="direct1" input="fabric.in" output="frac_logic.in"/>
|
<direct name="direct1" input="fabric.in" output="frac_logic.in"/>
|
||||||
<direct name="direct2" input="fabric.sc_in" output="ff[0].DI"/>
|
<direct name="direct2" input="fabric.cin" output="frac_logic.cin"/>
|
||||||
<direct name="direct3" input="ff[0].Q" output="ff[1].DI"/>
|
<direct name="direct3" input="fabric.sc_in" output="ff[0].DI"/>
|
||||||
<direct name="direct4" input="ff[1].Q" output="fabric.sc_out"/>
|
<direct name="direct4" input="ff[0].Q" output="ff[1].DI"/>
|
||||||
<direct name="direct5" input="ff[1].Q" output="fabric.reg_out"/>
|
<direct name="direct5" input="ff[1].Q" output="fabric.sc_out"/>
|
||||||
|
<direct name="direct6" input="ff[1].Q" output="fabric.reg_out"/>
|
||||||
|
<direct name="direct7" input="frac_logic.cout" output="fabric.cout"/>
|
||||||
<complete name="complete1" input="fabric.clk" output="ff[1:0].clk"/>
|
<complete name="complete1" input="fabric.clk" output="ff[1:0].clk"/>
|
||||||
<mux name="mux1" input="frac_logic.out[0:0] fabric.reg_in" output="ff[0:0].D">
|
<mux name="mux1" input="frac_logic.out[0:0] fabric.reg_in" output="ff[0:0].D">
|
||||||
<delay_constant max="25e-12" in_port="frac_logic.out[0:0]" out_port="ff[0:0].D"/>
|
<delay_constant max="25e-12" in_port="frac_logic.out[0:0]" out_port="ff[0:0].D"/>
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,225 @@
|
||||||
|
`timescale 1ns / 1ps
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Team: Virginia Tech Secure Embedded Systems (SES) Lab
|
||||||
|
// Implementer: Ege Gulcan
|
||||||
|
//
|
||||||
|
// Create Date: 17:21:26 11/13/2013
|
||||||
|
// Design Name:
|
||||||
|
// Module Name: simon_datapath_shiftreg
|
||||||
|
// Project Name:
|
||||||
|
// Target Devices:
|
||||||
|
// Tool versions:
|
||||||
|
// Description:
|
||||||
|
//
|
||||||
|
// Dependencies:
|
||||||
|
//
|
||||||
|
// Revision:
|
||||||
|
// Revision 0.01 - File Created
|
||||||
|
// Additional Comments:
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
module simon_datapath_shiftreg(clk,data_in,data_rdy,key_in,cipher_out,round_counter,bit_counter);
|
||||||
|
|
||||||
|
input clk,data_in,key_in;
|
||||||
|
input [1:0] data_rdy;
|
||||||
|
input round_counter;
|
||||||
|
output cipher_out;
|
||||||
|
output [5:0] bit_counter;
|
||||||
|
|
||||||
|
reg [55:0] shifter1;
|
||||||
|
reg [63:0] shifter2;
|
||||||
|
reg shift_in1,shift_in2;
|
||||||
|
wire shift_out1,shift_out2;
|
||||||
|
reg shifter_enable1,shifter_enable2;
|
||||||
|
|
||||||
|
reg fifo_ff63,fifo_ff62,fifo_ff61,fifo_ff60,fifo_ff59,fifo_ff58,fifo_ff57,fifo_ff56;
|
||||||
|
reg lut_ff63,lut_ff62,lut_ff61,lut_ff60,lut_ff59,lut_ff58,lut_ff57,lut_ff56;
|
||||||
|
|
||||||
|
reg lut_ff_input,fifo_ff_input;
|
||||||
|
reg lut_rol1,lut_rol2,lut_rol8;
|
||||||
|
reg s1,s4,s5,s6,s7;
|
||||||
|
reg [1:0] s3;
|
||||||
|
reg [5:0] bit_counter;
|
||||||
|
wire lut_out;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Shift Register1 FIFO 56x1 Begin
|
||||||
|
// 56x1 Shift register to store the upper word
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
if(shifter_enable1)
|
||||||
|
begin
|
||||||
|
shifter1 <= {shift_in1, shifter1[55:1]};
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign shift_out1 = shifter1[0];
|
||||||
|
// Shift Register1 End
|
||||||
|
|
||||||
|
// Shift Register2 FIFO 64x1 Begin
|
||||||
|
// 64x1 Shift register to store the lower word
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
if(shifter_enable2)
|
||||||
|
begin
|
||||||
|
shifter2 <= {shift_in2, shifter2[63:1]};
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign shift_out2 = shifter2[0];
|
||||||
|
// Shift Register2 End
|
||||||
|
|
||||||
|
|
||||||
|
// 8 Flip-Flops to store the most significant 8 bits of the upper word at even rounds
|
||||||
|
// Denoted as Shift Register Up (SRU) in Figure 5
|
||||||
|
always@(posedge clk)
|
||||||
|
begin
|
||||||
|
if(shifter_enable1)
|
||||||
|
begin
|
||||||
|
fifo_ff63 <= fifo_ff_input;
|
||||||
|
fifo_ff62 <= fifo_ff63;
|
||||||
|
fifo_ff61 <= fifo_ff62;
|
||||||
|
fifo_ff60 <= fifo_ff61;
|
||||||
|
fifo_ff59 <= fifo_ff60;
|
||||||
|
fifo_ff58 <= fifo_ff59;
|
||||||
|
fifo_ff57 <= fifo_ff58;
|
||||||
|
fifo_ff56 <= fifo_ff57;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// 8 Flip-Flops to store the most significant 8 bits of the upper word at odd rounds
|
||||||
|
// Denoted as Shift Register Down (SRD) in Figure 5
|
||||||
|
always@(posedge clk)
|
||||||
|
begin
|
||||||
|
lut_ff63 <= lut_ff_input;
|
||||||
|
lut_ff62 <= lut_ff63;
|
||||||
|
lut_ff61 <= lut_ff62;
|
||||||
|
lut_ff60 <= lut_ff61;
|
||||||
|
lut_ff59 <= lut_ff60;
|
||||||
|
lut_ff58 <= lut_ff59;
|
||||||
|
lut_ff57 <= lut_ff58;
|
||||||
|
lut_ff56 <= lut_ff57;
|
||||||
|
end
|
||||||
|
|
||||||
|
// FIFO 64x1 Input MUX
|
||||||
|
// Input of the lower FIFO is always the output of the upper FIFO
|
||||||
|
always@(*)
|
||||||
|
begin
|
||||||
|
shift_in2 = shift_out1;
|
||||||
|
end
|
||||||
|
|
||||||
|
// FIFO 56x1 Input MUX
|
||||||
|
// Input of the upper FIFO depends on the select line S1
|
||||||
|
always@(*)
|
||||||
|
begin
|
||||||
|
if(s1==0)
|
||||||
|
shift_in1 = lut_ff56;
|
||||||
|
else
|
||||||
|
shift_in1 = fifo_ff56;
|
||||||
|
end
|
||||||
|
|
||||||
|
// FIFO FF Input MUX
|
||||||
|
// The input of FIFO_FF can be the input plaintext, output of 56x1 FIFO or the output of LUT
|
||||||
|
always@(*)
|
||||||
|
begin
|
||||||
|
if(s3==0)
|
||||||
|
fifo_ff_input = data_in;
|
||||||
|
else if(s3==1)
|
||||||
|
fifo_ff_input = shift_out1;
|
||||||
|
else if(s3==2)
|
||||||
|
fifo_ff_input = lut_out;
|
||||||
|
else
|
||||||
|
fifo_ff_input = 1'bx; // Debugging
|
||||||
|
end
|
||||||
|
|
||||||
|
// LUT FF Input MUX
|
||||||
|
// The input of the LUT_FF is either the output of 56x1 FIFO or the output of LUT
|
||||||
|
always@(*)
|
||||||
|
begin
|
||||||
|
if(s5==0)
|
||||||
|
lut_ff_input = shift_out1;
|
||||||
|
else
|
||||||
|
lut_ff_input = lut_out;
|
||||||
|
end
|
||||||
|
|
||||||
|
// LUT Input MUX
|
||||||
|
always@(*)
|
||||||
|
begin
|
||||||
|
if(s7==0)
|
||||||
|
lut_rol1 = fifo_ff63;
|
||||||
|
else
|
||||||
|
lut_rol1 = lut_ff63;
|
||||||
|
|
||||||
|
if(s4==0)
|
||||||
|
lut_rol2 = fifo_ff62;
|
||||||
|
else
|
||||||
|
lut_rol2 = lut_ff62;
|
||||||
|
|
||||||
|
if(s6==0)
|
||||||
|
lut_rol8 = fifo_ff56;
|
||||||
|
else
|
||||||
|
lut_rol8 = lut_ff56;
|
||||||
|
end
|
||||||
|
|
||||||
|
//Selection MUX
|
||||||
|
always@(*)
|
||||||
|
begin
|
||||||
|
// For the first 8 bits of each even round OR for all the bits after the first 8 bits in odd rounds OR loading the plaintext
|
||||||
|
if((round_counter==0 && bit_counter<8)||(round_counter==1 && bit_counter>7)||(data_rdy==1))
|
||||||
|
s1 = 1;
|
||||||
|
else
|
||||||
|
s1 = 0;
|
||||||
|
|
||||||
|
if(data_rdy==1) // Loading plaintext
|
||||||
|
s3 = 0;
|
||||||
|
else if(round_counter==0) // Even rounds
|
||||||
|
s3 = 1;
|
||||||
|
else if(round_counter==1) // Odd rounds
|
||||||
|
s3 = 2;
|
||||||
|
else
|
||||||
|
s3 = 1'bx; // For debugging
|
||||||
|
|
||||||
|
if(round_counter==0) // Even rounds
|
||||||
|
s6 = 0;
|
||||||
|
else
|
||||||
|
s6 = 1;
|
||||||
|
|
||||||
|
s4 = s6;
|
||||||
|
s7 = s6;
|
||||||
|
s5 = ~s6;
|
||||||
|
end
|
||||||
|
|
||||||
|
// SHIFTER ENABLES
|
||||||
|
// Two shift registers are enabled when the plaintext is being loaded (1) or when the block cipher is running (3)
|
||||||
|
always@(*)
|
||||||
|
begin
|
||||||
|
if(data_rdy==1 || data_rdy==3)
|
||||||
|
begin
|
||||||
|
shifter_enable1 = 1;
|
||||||
|
shifter_enable2 = 1;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
shifter_enable1 = 0;
|
||||||
|
shifter_enable2 = 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// The bit_counter value is incremented in each clock cycle when the block cipher is running
|
||||||
|
always@(posedge clk)
|
||||||
|
begin
|
||||||
|
if(data_rdy==0)
|
||||||
|
bit_counter <= 0;
|
||||||
|
else if(data_rdy==3)
|
||||||
|
bit_counter <= bit_counter + 1;
|
||||||
|
else
|
||||||
|
bit_counter <= bit_counter;
|
||||||
|
end
|
||||||
|
|
||||||
|
// The new computed value
|
||||||
|
assign lut_out = (lut_rol1 & lut_rol8) ^ shift_out2 ^ lut_rol2 ^ key_in;
|
||||||
|
|
||||||
|
// The global output that gives the ciphertext value
|
||||||
|
assign cipher_out = lut_out;
|
||||||
|
endmodule
|
|
@ -0,0 +1,241 @@
|
||||||
|
`timescale 1ns / 1ps
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Team: Virginia Tech Secure Embedded Systems (SES) Lab
|
||||||
|
// Implementer: Ege Gulcan
|
||||||
|
//
|
||||||
|
// Create Date: 16:55:06 11/12/2013
|
||||||
|
// Design Name:
|
||||||
|
// Module Name: simon_key_expansion_shiftreg
|
||||||
|
// Project Name:
|
||||||
|
// Target Devices:
|
||||||
|
// Tool versions:
|
||||||
|
// Description:
|
||||||
|
//
|
||||||
|
// Dependencies:
|
||||||
|
//
|
||||||
|
// Revision:
|
||||||
|
// Revision 0.01 - File Created
|
||||||
|
// Additional Comments:
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
module simon_key_expansion_shiftreg(clk,data_in,key_out,data_rdy,bit_counter,round_counter_out);
|
||||||
|
|
||||||
|
input clk;
|
||||||
|
input data_in;
|
||||||
|
input [1:0] data_rdy;
|
||||||
|
input [5:0] bit_counter;
|
||||||
|
output key_out;
|
||||||
|
output round_counter_out;
|
||||||
|
|
||||||
|
|
||||||
|
reg [59:0] shifter1;
|
||||||
|
reg [63:0] shifter2;
|
||||||
|
reg shift_in1,shift_in2;
|
||||||
|
wire shift_out1,shift_out2;
|
||||||
|
reg shifter_enable1,shifter_enable2;
|
||||||
|
|
||||||
|
reg lut_ff_enable,fifo_ff_enable;
|
||||||
|
wire lut_out;
|
||||||
|
reg lut_in3;
|
||||||
|
reg s2,s3;
|
||||||
|
reg [1:0] s1;
|
||||||
|
reg [6:0] round_counter;
|
||||||
|
reg z_value;
|
||||||
|
|
||||||
|
reg fifo_ff0,fifo_ff1,fifo_ff2,fifo_ff3;
|
||||||
|
|
||||||
|
//(* shreg_extract = "no" *)
|
||||||
|
reg lut_ff0,lut_ff1,lut_ff2,lut_ff3;
|
||||||
|
//Constant value Z ROM
|
||||||
|
reg [0:67] Z = 68'b10101111011100000011010010011000101000010001111110010110110011101011;
|
||||||
|
reg c;
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////
|
||||||
|
//// BEGIN CODE ////////////////////////
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
// Least bit of the round counter is sent to the datapath to check if it is even or odd
|
||||||
|
assign round_counter_out = round_counter[0];
|
||||||
|
|
||||||
|
// Shift Register1 FIFO 60x1 Begin
|
||||||
|
// 60x1 shift register storing the 60 most significant bits of the upper word of the key
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
if(shifter_enable1)
|
||||||
|
begin
|
||||||
|
shifter1 <= {shift_in1, shifter1[59:1]};
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign shift_out1 = shifter1[0];
|
||||||
|
// Shift Register1 End
|
||||||
|
|
||||||
|
// Shift Register2 FIFO 64x1 Begin
|
||||||
|
// 64x1 shift register storing the lower word of the key
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
if(shifter_enable2)
|
||||||
|
begin
|
||||||
|
shifter2 <= {shift_in2, shifter2[63:1]};
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign shift_out2 = shifter2[0];
|
||||||
|
// Shift Register2 End
|
||||||
|
|
||||||
|
// 4 flip-flops storing the least significant 4 bits of the upper word in the first round
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
if(fifo_ff_enable)
|
||||||
|
begin
|
||||||
|
fifo_ff3 <= shift_out1;
|
||||||
|
fifo_ff2 <= fifo_ff3;
|
||||||
|
fifo_ff1 <= fifo_ff2;
|
||||||
|
fifo_ff0 <= fifo_ff1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// 4 flip-flops storing the least significant 4 bits of the upper word after the first round
|
||||||
|
always@(posedge clk)
|
||||||
|
begin
|
||||||
|
if(lut_ff_enable)
|
||||||
|
begin
|
||||||
|
lut_ff3 <= lut_out;
|
||||||
|
lut_ff2 <= lut_ff3;
|
||||||
|
lut_ff1 <= lut_ff2;
|
||||||
|
lut_ff0 <= lut_ff1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
//FIFO 64x1 Input MUX
|
||||||
|
always@(*)
|
||||||
|
begin
|
||||||
|
if(data_rdy==2)
|
||||||
|
shift_in2 = fifo_ff0;
|
||||||
|
else if(data_rdy==3 && (round_counter<1 || bit_counter>3))
|
||||||
|
shift_in2 = fifo_ff0;
|
||||||
|
else if(data_rdy==3 && bit_counter<4 && round_counter>0)
|
||||||
|
shift_in2 = lut_ff0;
|
||||||
|
else
|
||||||
|
shift_in2 = 1'bx;
|
||||||
|
end
|
||||||
|
|
||||||
|
//LUT >>3 Input MUX
|
||||||
|
always@(*)
|
||||||
|
begin
|
||||||
|
if(s2==0)
|
||||||
|
lut_in3 = fifo_ff3;
|
||||||
|
else
|
||||||
|
lut_in3 = lut_ff3;
|
||||||
|
end
|
||||||
|
|
||||||
|
//FIFO 60x1 Input MUX
|
||||||
|
always@(*)
|
||||||
|
begin
|
||||||
|
if(s1==0)
|
||||||
|
shift_in1 = fifo_ff0;
|
||||||
|
else if(s1==1)
|
||||||
|
shift_in1 = data_in;
|
||||||
|
else if(s1==2)
|
||||||
|
shift_in1 = lut_out;
|
||||||
|
else if(s1==3)
|
||||||
|
shift_in1 = lut_ff0;
|
||||||
|
else
|
||||||
|
shift_in1 = 1'bx;
|
||||||
|
end
|
||||||
|
|
||||||
|
//S2 MUX
|
||||||
|
always@(*)
|
||||||
|
begin
|
||||||
|
if(bit_counter==0 && round_counter!=0)
|
||||||
|
s2 = 1;
|
||||||
|
else
|
||||||
|
s2 = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
//S1 MUX
|
||||||
|
always@(*)
|
||||||
|
begin
|
||||||
|
if(data_rdy==2)
|
||||||
|
s1 = 1;
|
||||||
|
else if(data_rdy==3 && bit_counter<4 && round_counter==0)
|
||||||
|
s1 = 0;
|
||||||
|
else if(data_rdy==3 && bit_counter<4 && round_counter>0)
|
||||||
|
s1 = 3;
|
||||||
|
else
|
||||||
|
s1 = 2;
|
||||||
|
end
|
||||||
|
|
||||||
|
// LUT FF ENABLE MUX
|
||||||
|
// LUT FFs are used only at the first four clock cycles of each round
|
||||||
|
always@(*)
|
||||||
|
begin
|
||||||
|
if(data_rdy==3 && bit_counter<4)
|
||||||
|
lut_ff_enable = 1;
|
||||||
|
else
|
||||||
|
lut_ff_enable = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
//FIFO FF ENABLE MUX
|
||||||
|
always@(*)
|
||||||
|
begin
|
||||||
|
if(data_rdy==2 || data_rdy==3)
|
||||||
|
fifo_ff_enable = 1;
|
||||||
|
else
|
||||||
|
fifo_ff_enable = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
//SHIFTER ENABLES
|
||||||
|
// Shifters are enabled when the key is loaded or block cipher is running
|
||||||
|
always@(*)
|
||||||
|
begin
|
||||||
|
if(data_rdy==2 || data_rdy==3)
|
||||||
|
shifter_enable1 = 1;
|
||||||
|
else
|
||||||
|
shifter_enable1 = 0;
|
||||||
|
|
||||||
|
if(data_rdy==2 || data_rdy==3)
|
||||||
|
shifter_enable2 = 1;
|
||||||
|
else
|
||||||
|
shifter_enable2 = 0;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
//Round Counter
|
||||||
|
always@(posedge clk)
|
||||||
|
begin
|
||||||
|
if(data_rdy==3 && bit_counter==63)
|
||||||
|
round_counter <= round_counter + 1;
|
||||||
|
else if(data_rdy==0)
|
||||||
|
round_counter <= 0;
|
||||||
|
else
|
||||||
|
round_counter <= round_counter;
|
||||||
|
end
|
||||||
|
|
||||||
|
// The necessary bit of the constant Z is selected by the round counter
|
||||||
|
always @(*)
|
||||||
|
begin
|
||||||
|
if(bit_counter==0)
|
||||||
|
z_value = Z[round_counter];
|
||||||
|
else
|
||||||
|
z_value = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
// The value of c is 1 at the first two cycles of each round only
|
||||||
|
always @(*)
|
||||||
|
begin
|
||||||
|
if(bit_counter==0 || bit_counter==1)
|
||||||
|
c = 0;
|
||||||
|
else
|
||||||
|
c = 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
// New computed key bit
|
||||||
|
assign lut_out = shift_out2 ^ lut_in3 ^ shift_out1 ^ z_value ^ c;
|
||||||
|
|
||||||
|
// Output key bit that is connected to the datapath
|
||||||
|
assign key_out = shift_out2;
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,45 @@
|
||||||
|
`timescale 1ns / 1ps
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Team: Virginia Tech Secure Embedded Systems (SES) Lab
|
||||||
|
// Implementer: Ege Gulcan
|
||||||
|
//
|
||||||
|
// Create Date: 19:14:37 11/13/2013
|
||||||
|
// Design Name:
|
||||||
|
// Module Name: top_module
|
||||||
|
// Project Name:
|
||||||
|
// Target Devices:
|
||||||
|
// Tool versions:
|
||||||
|
// Description:
|
||||||
|
//
|
||||||
|
// Dependencies:
|
||||||
|
//
|
||||||
|
// Revision:
|
||||||
|
// Revision 0.01 - File Created
|
||||||
|
// Additional Comments:
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
module Simon_bit_serial_top(clk,data_in,data_rdy,cipher_out);
|
||||||
|
|
||||||
|
input clk,data_in;
|
||||||
|
input [1:0] data_rdy;
|
||||||
|
output cipher_out;
|
||||||
|
|
||||||
|
wire key;
|
||||||
|
wire [5:0] bit_counter;
|
||||||
|
wire round_counter_out;
|
||||||
|
|
||||||
|
/*
|
||||||
|
data_rdy=0 -> Reset, Idle
|
||||||
|
data_rdy=1 -> Load Plaintext
|
||||||
|
data_rdy=2 -> Load Key
|
||||||
|
data_rdy=3 -> Run (keep at 3 while the block cipher is running)
|
||||||
|
*/
|
||||||
|
|
||||||
|
simon_datapath_shiftreg datapath(.clk(clk), .data_in(data_in), .data_rdy(data_rdy), .key_in(key),
|
||||||
|
. cipher_out(cipher_out), .round_counter(round_counter_out), .bit_counter(bit_counter));
|
||||||
|
|
||||||
|
simon_key_expansion_shiftreg key_exp(.clk(clk), .data_in(data_in), .data_rdy(data_rdy), .key_out(key), .bit_counter(bit_counter),
|
||||||
|
.round_counter_out(round_counter_out));
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,143 @@
|
||||||
|
/*-------------------------------------------------------------------
|
||||||
|
CM_FIFO_1x
|
||||||
|
Communication Manager (CM) FIFO, using 1 RAM block.
|
||||||
|
18-bit write port (512 deep), 9-bit read port (1024 deep).
|
||||||
|
|
||||||
|
The LSB on the write port will be the first byte to appear on
|
||||||
|
the read port.
|
||||||
|
|
||||||
|
Valid data appears on the output data port without first
|
||||||
|
having to do a pop.
|
||||||
|
|
||||||
|
Over-run and under-run protection are both implemented:
|
||||||
|
reads when empty will be ignored and provide invalid data,
|
||||||
|
writes when full will be ignored.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
`timescale 1ns / 10ps
|
||||||
|
|
||||||
|
module CM_FIFO_1x (
|
||||||
|
rst,
|
||||||
|
|
||||||
|
push_clk,
|
||||||
|
push,
|
||||||
|
din,
|
||||||
|
full,
|
||||||
|
push_flag,
|
||||||
|
overflow,
|
||||||
|
|
||||||
|
pop_clk,
|
||||||
|
pop,
|
||||||
|
dout,
|
||||||
|
empty,
|
||||||
|
pop_flag,
|
||||||
|
|
||||||
|
CM_FIFO_1x_din_o ,
|
||||||
|
CM_FIFO_1x_push_int_o ,
|
||||||
|
CM_FIFO_1x_pop_int_o ,
|
||||||
|
CM_FIFO_1x_push_clk_o ,
|
||||||
|
CM_FIFO_1x_pop_clk_o ,
|
||||||
|
CM_FIFO_1x_rst_o ,
|
||||||
|
|
||||||
|
CM_FIFO_1x_almost_full_i ,
|
||||||
|
CM_FIFO_1x_almost_empty_i ,
|
||||||
|
CM_FIFO_1x_push_flag_i ,
|
||||||
|
CM_FIFO_1x_pop_flag_i ,
|
||||||
|
CM_FIFO_1x_dout_i
|
||||||
|
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
input rst;
|
||||||
|
|
||||||
|
input push_clk;
|
||||||
|
input push;
|
||||||
|
input [17:0] din;
|
||||||
|
output full;
|
||||||
|
output [3:0] push_flag;
|
||||||
|
output overflow;
|
||||||
|
|
||||||
|
input pop_clk;
|
||||||
|
input pop;
|
||||||
|
output [8:0] dout;
|
||||||
|
output empty;
|
||||||
|
output [3:0] pop_flag;
|
||||||
|
|
||||||
|
output [17:0] CM_FIFO_1x_din_o ;
|
||||||
|
output CM_FIFO_1x_push_int_o ;
|
||||||
|
output CM_FIFO_1x_pop_int_o ;
|
||||||
|
output CM_FIFO_1x_push_clk_o ;
|
||||||
|
output CM_FIFO_1x_pop_clk_o ;
|
||||||
|
output CM_FIFO_1x_rst_o ;
|
||||||
|
|
||||||
|
input CM_FIFO_1x_almost_full_i ;
|
||||||
|
input CM_FIFO_1x_almost_empty_i ;
|
||||||
|
input [3:0] CM_FIFO_1x_push_flag_i ;
|
||||||
|
input [3:0] CM_FIFO_1x_pop_flag_i ;
|
||||||
|
input [8:0] CM_FIFO_1x_dout_i ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
reg overflow;
|
||||||
|
|
||||||
|
|
||||||
|
wire push_int;
|
||||||
|
wire pop_int;
|
||||||
|
reg pop_r1, pop_r2, pop_r3;
|
||||||
|
|
||||||
|
|
||||||
|
// over-run/under-run protection
|
||||||
|
assign push_int = full ? 1'b0 : push;
|
||||||
|
|
||||||
|
// changed to match the current S2 functionality
|
||||||
|
//assign pop_int = empty ? 1'b0 : pop;
|
||||||
|
assign pop_int = empty ? 1'b0 : (pop_r2 ^ pop_r3);
|
||||||
|
|
||||||
|
|
||||||
|
assign CM_FIFO_1x_din_o = din;
|
||||||
|
assign CM_FIFO_1x_push_int_o = push_int;
|
||||||
|
assign CM_FIFO_1x_pop_int_o = pop_int;
|
||||||
|
assign CM_FIFO_1x_push_clk_o = push_clk;
|
||||||
|
assign CM_FIFO_1x_pop_clk_o = pop_clk;
|
||||||
|
assign CM_FIFO_1x_rst_o = rst;
|
||||||
|
assign almost_full = CM_FIFO_1x_almost_full_i;
|
||||||
|
assign almost_empty = CM_FIFO_1x_almost_empty_i;
|
||||||
|
assign push_flag = CM_FIFO_1x_push_flag_i;
|
||||||
|
assign pop_flag = CM_FIFO_1x_pop_flag_i;
|
||||||
|
assign dout = CM_FIFO_1x_dout_i;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
assign full = (push_flag == 4'h0);
|
||||||
|
assign empty = (pop_flag == 4'h0);
|
||||||
|
|
||||||
|
|
||||||
|
// overflow detection
|
||||||
|
always @(posedge push_clk or posedge rst)
|
||||||
|
if (rst)
|
||||||
|
overflow <= 0;
|
||||||
|
else
|
||||||
|
if (push && full)
|
||||||
|
overflow <= 1;
|
||||||
|
else
|
||||||
|
overflow <= 0;
|
||||||
|
|
||||||
|
/// Synchronize SPI FIFO Read to SPI CLock due to delay
|
||||||
|
always @(posedge pop_clk or posedge rst)
|
||||||
|
if (rst) begin
|
||||||
|
pop_r1 <= 1'b0;
|
||||||
|
pop_r2 <= 1'b0;
|
||||||
|
pop_r3 <= 1'b0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
pop_r1 <= pop;
|
||||||
|
pop_r2 <= pop_r1;
|
||||||
|
pop_r3 <= pop_r2;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,152 @@
|
||||||
|
/*-----------------------------------------------------------------------------
|
||||||
|
CM_FIFO_autodrain
|
||||||
|
This module will auto-drain (read from) the CM FIFO when RingBufferMode
|
||||||
|
is enabled. It will stop on packet boundaries (designated by bit 8 of
|
||||||
|
the FIFO data).
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
`timescale 1ns / 10ps
|
||||||
|
|
||||||
|
|
||||||
|
module CM_FIFO_autodrain (
|
||||||
|
input rst,
|
||||||
|
input FFE_CLK_gclk,
|
||||||
|
|
||||||
|
input RingBufferMode,
|
||||||
|
input [3:0] CM_FIFO_PushFlags,
|
||||||
|
input CM_FIFO_Empty,
|
||||||
|
input CM_FIFO_PopFromTLC,
|
||||||
|
input [8:0] CM_FIFO_ReadData,
|
||||||
|
|
||||||
|
output CM_FIFO_Pop,
|
||||||
|
output busy,
|
||||||
|
output TP1,
|
||||||
|
output TP2
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// state definitions
|
||||||
|
localparam ST_IDLE = 3'b000;
|
||||||
|
localparam ST_SETBUSY1 = 3'b001;
|
||||||
|
localparam ST_SETBUSY2 = 3'b010;
|
||||||
|
localparam ST_WAIT = 3'b011;
|
||||||
|
localparam ST_READ = 3'b100;
|
||||||
|
|
||||||
|
|
||||||
|
wire SOP_Marker;
|
||||||
|
wire FIFO_AutoRead_Threshold;
|
||||||
|
reg RingBufferMode_r1;
|
||||||
|
reg RingBufferMode_r2;
|
||||||
|
reg [2:0] state;
|
||||||
|
reg busy_reg;
|
||||||
|
reg CM_FIFO_PopAutoDrain;
|
||||||
|
|
||||||
|
|
||||||
|
assign SOP_Marker = CM_FIFO_ReadData[8];
|
||||||
|
|
||||||
|
|
||||||
|
/* PUSH_FLAG:
|
||||||
|
0x0: full
|
||||||
|
0x1: empty
|
||||||
|
0x2: room for 1/2 to (full - 1)
|
||||||
|
0x3: room for 1/4 to (1/2 -1)
|
||||||
|
0x4: room for 64 to (1/4 - 1)
|
||||||
|
0xA: room for 32 to 63
|
||||||
|
0xB: room for 16 to 31
|
||||||
|
0xC: room for 8 to 15
|
||||||
|
0xD: room for 4 to 7
|
||||||
|
0xE: room for 2 to 3
|
||||||
|
0xF: room for 1
|
||||||
|
others: reserved */
|
||||||
|
|
||||||
|
assign FIFO_AutoRead_Threshold = ((CM_FIFO_PushFlags == 4'h0) || (CM_FIFO_PushFlags[3])); // full or (63 or less) 16-bit words
|
||||||
|
|
||||||
|
|
||||||
|
// sync RingBufferMode to the FFE clk
|
||||||
|
always @(posedge rst or posedge FFE_CLK_gclk)
|
||||||
|
if (rst) begin
|
||||||
|
RingBufferMode_r1 <= 0;
|
||||||
|
RingBufferMode_r2 <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
RingBufferMode_r1 <= RingBufferMode;
|
||||||
|
RingBufferMode_r2 <= RingBufferMode_r1;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// state machine
|
||||||
|
always @(posedge rst or posedge FFE_CLK_gclk)
|
||||||
|
if (rst)
|
||||||
|
state <= ST_IDLE;
|
||||||
|
else
|
||||||
|
case (state)
|
||||||
|
ST_IDLE: if (RingBufferMode_r2)
|
||||||
|
state <= ST_SETBUSY1;
|
||||||
|
else
|
||||||
|
state <= ST_IDLE;
|
||||||
|
|
||||||
|
ST_SETBUSY1: state <= ST_SETBUSY2; // allow time for the FIFO read clock to switch safely
|
||||||
|
|
||||||
|
ST_SETBUSY2: state <= ST_WAIT;
|
||||||
|
|
||||||
|
ST_WAIT: if (!RingBufferMode_r2)
|
||||||
|
state <= ST_IDLE;
|
||||||
|
else
|
||||||
|
state <= ST_READ;
|
||||||
|
|
||||||
|
ST_READ: if (SOP_Marker && !RingBufferMode_r2)
|
||||||
|
state <= ST_SETBUSY1; // goto ST_SETBUSY1 to allow time to switch to SPI_SCLK
|
||||||
|
else
|
||||||
|
state <= ST_READ;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
|
||||||
|
// busy
|
||||||
|
wire busy_reg_reset;
|
||||||
|
assign busy_reg_reset = rst || !RingBufferMode;
|
||||||
|
always @(posedge busy_reg_reset or posedge FFE_CLK_gclk)
|
||||||
|
if (busy_reg_reset)
|
||||||
|
busy_reg <= 0;
|
||||||
|
else
|
||||||
|
case (busy_reg)
|
||||||
|
1'b0: if ((state == ST_IDLE) && (RingBufferMode_r2))
|
||||||
|
busy_reg <= 1;
|
||||||
|
else
|
||||||
|
busy_reg <= 0;
|
||||||
|
1'b1: if (((state == ST_SETBUSY1) && !RingBufferMode_r2) || (state == ST_IDLE))
|
||||||
|
busy_reg <= 0;
|
||||||
|
else
|
||||||
|
busy_reg <= 1;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// FIFO Read control
|
||||||
|
always @(*)
|
||||||
|
if (state == ST_READ) // pop only allowed in ST_READ state...
|
||||||
|
if (!CM_FIFO_Empty) // ...and FIFO not empty
|
||||||
|
if (!SOP_Marker) // if not on SOP marker, keep reading
|
||||||
|
CM_FIFO_PopAutoDrain <= 1;
|
||||||
|
else // (SOP_Marker)
|
||||||
|
if (FIFO_AutoRead_Threshold && RingBufferMode_r2) // if SOP marker, read next packet if FIFO is at or past threshold and RingBufferMode still on
|
||||||
|
CM_FIFO_PopAutoDrain <= 1;
|
||||||
|
else
|
||||||
|
CM_FIFO_PopAutoDrain <= 0; // else pop=0
|
||||||
|
else // (CM_FIFO_Empty)
|
||||||
|
CM_FIFO_PopAutoDrain <= 0;
|
||||||
|
else // (state != ST_READ)
|
||||||
|
CM_FIFO_PopAutoDrain <= 0;
|
||||||
|
|
||||||
|
|
||||||
|
assign CM_FIFO_Pop = busy_reg ? CM_FIFO_PopAutoDrain : CM_FIFO_PopFromTLC;
|
||||||
|
|
||||||
|
assign busy = busy_reg;
|
||||||
|
|
||||||
|
|
||||||
|
assign TP1 = FIFO_AutoRead_Threshold;
|
||||||
|
assign TP2 = 0;
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,291 @@
|
||||||
|
|
||||||
|
// 4k deep CM
|
||||||
|
// This module bypasses the FFEControlMememoryMux since the addressing of the individual RAM blocks
|
||||||
|
// is not the same when coming from the TLC vs. FFE, and dynamic code updates must be supported for
|
||||||
|
// the fabric RAM's.
|
||||||
|
|
||||||
|
// Note: in order for this to work correctly, RdClk and WrClk must be the same (tied together externally).
|
||||||
|
|
||||||
|
|
||||||
|
`timescale 1ns / 10ps
|
||||||
|
|
||||||
|
`include "ulpsh_rtl_defines.v"
|
||||||
|
|
||||||
|
module FFEControlMemory_4k (
|
||||||
|
// General Interface
|
||||||
|
input ResetIn,
|
||||||
|
input SPI_clk,
|
||||||
|
input TLC_FFE_clk2x_muxed, // already muxed based on UseFastClock from TLC
|
||||||
|
|
||||||
|
input MemSelect_en, // MemorySelect and enable from TLC
|
||||||
|
input [2:0] MemSelect,
|
||||||
|
|
||||||
|
input FFE_clock_halfperiod,
|
||||||
|
|
||||||
|
input [11:0] Address_TLC, // TLC address is used for both TLC reads and writes
|
||||||
|
|
||||||
|
input [35:0] MemoryMux_in,
|
||||||
|
output [35:0] MemoryMux_out,
|
||||||
|
|
||||||
|
//Read Interface
|
||||||
|
input [11:0] ReadAddress_FFE,
|
||||||
|
output [35:0] ReadData,
|
||||||
|
input ReadEnable_TLC,
|
||||||
|
input ReadEnable_FFE,
|
||||||
|
|
||||||
|
//Write Interface
|
||||||
|
input [35:0] WriteData_TLC,
|
||||||
|
input WriteEnable_TLC,
|
||||||
|
|
||||||
|
// ASSP RAM interface - left bank
|
||||||
|
output assp_lb_ram0_clk,
|
||||||
|
output [8:0] assp_lb_ram0_addr,
|
||||||
|
output [35:0] assp_lb_ram0_wr_data,
|
||||||
|
input [35:0] assp_lb_ram0_rd_data,
|
||||||
|
output assp_lb_ram0_wr_en,
|
||||||
|
output assp_lb_ram0_rd_en,
|
||||||
|
output [3:0] assp_lb_ram0_wr_be,
|
||||||
|
|
||||||
|
// ASSP RAM interface - right bank
|
||||||
|
output assp_rb_ram1_clk,
|
||||||
|
output [8:0] assp_rb_ram1_addr,
|
||||||
|
output [35:0] assp_rb_ram1_wr_data,
|
||||||
|
input [35:0] assp_rb_ram1_rd_data,
|
||||||
|
output assp_rb_ram1_wr_en,
|
||||||
|
output assp_rb_ram1_rd_en,
|
||||||
|
output [3:0] assp_rb_ram1_wr_be,
|
||||||
|
|
||||||
|
// ASSP RAM interface - 8k - left bank
|
||||||
|
output assp_lb_ram8k_clk,
|
||||||
|
output [11:0] assp_lb_ram8k_addr,
|
||||||
|
output [16:0] assp_lb_ram8k_wr_data,
|
||||||
|
input [16:0] assp_lb_ram8k_rd_data,
|
||||||
|
output assp_lb_ram8k_wr_en,
|
||||||
|
output assp_lb_ram8k_rd_en,
|
||||||
|
output [1:0] assp_lb_ram8k_wr_be,
|
||||||
|
|
||||||
|
//AP2
|
||||||
|
output [8:0] FFEControlMemory_4k_Address_TLC_o ,
|
||||||
|
output [8:0] FFEControlMemory_4k_ReadAddress_muxed_o ,
|
||||||
|
output FFEControlMemory_4k_ram5_wr_en_o,
|
||||||
|
output FFEControlMemory_4k_ram5_rd_en_o,
|
||||||
|
output FFEControlMemory_4k_SPI_clk_o,
|
||||||
|
output FFEControlMemory_4k_TLC_FFE_clk2x_muxed_o,
|
||||||
|
output [35:0] FFEControlMemory_4k_WriteData_TLC_o ,
|
||||||
|
input [35:0] FFEControlMemory_4k_ram5_rd_data_i ,
|
||||||
|
output FFEControlMemory_4k_ram4_wr_en_o ,
|
||||||
|
output FFEControlMemory_4k_ram4_rd_en_o,
|
||||||
|
input [35:0] FFEControlMemory_4k_ram4_rd_data_i,
|
||||||
|
output [9:0] FFEControlMemory_4k_fabric_ram1Kx9_addr_o,
|
||||||
|
output FFEControlMemory_4k_ram1_wr_en_o ,
|
||||||
|
output FFEControlMemory_4k_ram1_rd_en_o ,
|
||||||
|
input [8:0] FFEControlMemory_4k_ram1_rd_data_i
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
wire [11:0] ReadAddress_muxed;
|
||||||
|
|
||||||
|
wire Select_from_TLC;
|
||||||
|
|
||||||
|
wire ram0_wr_en;
|
||||||
|
wire ram1_wr_en;
|
||||||
|
wire ram2_wr_en;
|
||||||
|
wire ram3_wr_en;
|
||||||
|
wire ram4_wr_en;
|
||||||
|
wire ram5_wr_en;
|
||||||
|
|
||||||
|
wire ram0_rd_en;
|
||||||
|
wire ram1_rd_en;
|
||||||
|
wire ram2_rd_en;
|
||||||
|
wire ram3_rd_en;
|
||||||
|
wire ram4_rd_en;
|
||||||
|
wire ram5_rd_en;
|
||||||
|
|
||||||
|
wire [11:0] assp_ram8k_addr;
|
||||||
|
wire [9:0] fabric_ram1Kx9_addr;
|
||||||
|
|
||||||
|
wire [16:0] ram0_rd_data;
|
||||||
|
wire [8:0] ram1_rd_data;
|
||||||
|
wire [35:0] ram2_rd_data;
|
||||||
|
wire [35:0] ram3_rd_data;
|
||||||
|
wire [35:0] ram4_rd_data;
|
||||||
|
wire [35:0] ram5_rd_data;
|
||||||
|
reg [35:0] lower2k_rd_data;
|
||||||
|
reg [16:0] lower2k_rd_data_phase0, lower2k_rd_data_phase1;
|
||||||
|
reg ReadAddress_muxed_bit0_r1;
|
||||||
|
|
||||||
|
reg [2:0] ram_rd_select;
|
||||||
|
reg [35:0] ram_rd_data;
|
||||||
|
wire [8:0] assp_ram_addr;
|
||||||
|
|
||||||
|
|
||||||
|
// RAM blocks are arranged as follows:
|
||||||
|
// RAM 0: 0-2k: 4Kx17 (double-clocked to create the lower 34 bits of each uInstruction)
|
||||||
|
// RAM 1: 0-2k: 1024x9 (one-half of the 1024x9 word is used for the remaining 2 bits of each uInstruction)
|
||||||
|
// RAM 2,3: 2k-3k: ASSP RAM's (formerly 0k-1k in the 2k CM)
|
||||||
|
// RAM 4,5: 3k-4k: fabric RAM's (formerly 1k-2k in the 2k CM)
|
||||||
|
|
||||||
|
|
||||||
|
assign Select_from_TLC = (MemSelect_en && (MemSelect == 3'h0 || MemSelect == 3'h4 || MemSelect == 3'h5));
|
||||||
|
|
||||||
|
// memory mux to pass data back to TLC
|
||||||
|
assign MemoryMux_out = Select_from_TLC ? ReadData : MemoryMux_in;
|
||||||
|
|
||||||
|
|
||||||
|
// mux between the TLC and FFE control signals
|
||||||
|
assign ReadAddress_muxed = Select_from_TLC ? Address_TLC : ReadAddress_FFE;
|
||||||
|
assign ReadEnable_muxed = Select_from_TLC ? ReadEnable_TLC : ReadEnable_FFE;
|
||||||
|
|
||||||
|
|
||||||
|
// generate the read address for the 4Kx17 ASSP RAM
|
||||||
|
assign assp_ram8k_addr = Select_from_TLC ? Address_TLC : {ReadAddress_FFE[10:0], FFE_clock_halfperiod};
|
||||||
|
|
||||||
|
/// generate the read address for the 1Kx9 fabric RAM
|
||||||
|
assign fabric_ram1Kx9_addr = Select_from_TLC ? Address_TLC : ReadAddress_FFE[10:1];
|
||||||
|
|
||||||
|
// write enables for each RAM block
|
||||||
|
// note: fabric RAM's cannot use MemSelect_en since these RAM's may be updated during run-time.
|
||||||
|
assign ram0_wr_en = (MemSelect_en && MemSelect == 3'h4 && WriteEnable_TLC);
|
||||||
|
assign ram1_wr_en = (MemSelect_en && MemSelect == 3'h5 && WriteEnable_TLC);
|
||||||
|
assign ram2_wr_en = (MemSelect_en && MemSelect == 3'h0 && WriteEnable_TLC && Address_TLC[10:9] == 2'b00);
|
||||||
|
assign ram3_wr_en = (MemSelect_en && MemSelect == 3'h0 && WriteEnable_TLC && Address_TLC[10:9] == 2'b01);
|
||||||
|
assign ram4_wr_en = ( MemSelect == 3'h0 && WriteEnable_TLC && Address_TLC[10:9] == 2'b10);
|
||||||
|
assign ram5_wr_en = ( MemSelect == 3'h0 && WriteEnable_TLC && Address_TLC[10:9] == 2'b11);
|
||||||
|
|
||||||
|
// read enables for each RAM block
|
||||||
|
assign ram0_rd_en = (MemSelect_en && MemSelect == 3'h4) ? ReadEnable_TLC : (ReadEnable_FFE && ReadAddress_FFE[11] == 1'b0);
|
||||||
|
assign ram1_rd_en = (MemSelect_en && MemSelect == 3'h5) ? ReadEnable_TLC : (ReadEnable_FFE && ReadAddress_FFE[11] == 1'b0 && FFE_clock_halfperiod);
|
||||||
|
assign ram2_rd_en = (MemSelect_en && MemSelect == 3'h0) ? (ReadEnable_TLC && Address_TLC[10:9] == 2'b00) : (ReadEnable_FFE && FFE_clock_halfperiod && ReadAddress_FFE[11:9] == 3'b100 && FFE_clock_halfperiod);
|
||||||
|
assign ram3_rd_en = (MemSelect_en && MemSelect == 3'h0) ? (ReadEnable_TLC && Address_TLC[10:9] == 2'b01) : (ReadEnable_FFE && FFE_clock_halfperiod && ReadAddress_FFE[11:9] == 3'b101 && FFE_clock_halfperiod);
|
||||||
|
assign ram4_rd_en = (MemSelect_en && MemSelect == 3'h0) ? (ReadEnable_TLC && Address_TLC[10:9] == 2'b10) : (ReadEnable_FFE && FFE_clock_halfperiod && ReadAddress_FFE[11:9] == 3'b110 && FFE_clock_halfperiod);
|
||||||
|
assign ram5_rd_en = (MemSelect_en && MemSelect == 3'h0) ? (ReadEnable_TLC && Address_TLC[10:9] == 2'b11) : (ReadEnable_FFE && FFE_clock_halfperiod && ReadAddress_FFE[11:9] == 3'b111 && FFE_clock_halfperiod);
|
||||||
|
|
||||||
|
|
||||||
|
// RAM 5 (fabric)
|
||||||
|
assign FFEControlMemory_4k_Address_TLC_o[8:0] = Address_TLC[8:0];
|
||||||
|
assign FFEControlMemory_4k_ReadAddress_muxed_o[8:0] = ReadAddress_muxed[8:0];
|
||||||
|
assign FFEControlMemory_4k_ram5_wr_en_o = ram5_wr_en ;
|
||||||
|
assign FFEControlMemory_4k_ram5_rd_en_o = ram5_rd_en;
|
||||||
|
assign FFEControlMemory_4k_SPI_clk_o = SPI_clk;
|
||||||
|
assign FFEControlMemory_4k_TLC_FFE_clk2x_muxed_o = TLC_FFE_clk2x_muxed;
|
||||||
|
assign FFEControlMemory_4k_WriteData_TLC_o = WriteData_TLC;
|
||||||
|
assign ram5_rd_data = FFEControlMemory_4k_ram5_rd_data_i;
|
||||||
|
|
||||||
|
|
||||||
|
assign FFEControlMemory_4k_ram4_wr_en_o = ram4_wr_en ;
|
||||||
|
assign FFEControlMemory_4k_ram4_rd_en_o = ram4_rd_en;
|
||||||
|
assign ram4_rd_data = FFEControlMemory_4k_ram4_rd_data_i;
|
||||||
|
|
||||||
|
|
||||||
|
// mappings to the ASSP RAM's
|
||||||
|
|
||||||
|
assign assp_ram_addr = (MemSelect_en && MemSelect == 3'h0) ? Address_TLC[8:0] : ReadAddress_muxed[8:0];
|
||||||
|
|
||||||
|
// RAM 3 (ASSP right bank)
|
||||||
|
// note: the port names are still called "ram1" to maintain compatibility with the 2k CM variant
|
||||||
|
assign assp_rb_ram1_clk = TLC_FFE_clk2x_muxed;
|
||||||
|
assign assp_rb_ram1_addr = assp_ram_addr;
|
||||||
|
assign assp_rb_ram1_wr_data = WriteData_TLC;
|
||||||
|
assign ram3_rd_data = assp_rb_ram1_rd_data;
|
||||||
|
assign assp_rb_ram1_wr_en = ram3_wr_en;
|
||||||
|
assign assp_rb_ram1_rd_en = ram3_rd_en;
|
||||||
|
assign assp_rb_ram1_wr_be = 4'b1111;
|
||||||
|
|
||||||
|
// RAM 2 (ASSP left bank)
|
||||||
|
// note: the port names are still called "ram0" to maintain compatibility with the 2k CM variant
|
||||||
|
assign assp_lb_ram0_clk = TLC_FFE_clk2x_muxed;
|
||||||
|
assign assp_lb_ram0_addr = assp_ram_addr;
|
||||||
|
assign assp_lb_ram0_wr_data = WriteData_TLC;
|
||||||
|
assign ram2_rd_data = assp_lb_ram0_rd_data;
|
||||||
|
assign assp_lb_ram0_wr_en = ram2_wr_en;
|
||||||
|
assign assp_lb_ram0_rd_en = ram2_rd_en;
|
||||||
|
assign assp_lb_ram0_wr_be = 4'b1111;
|
||||||
|
|
||||||
|
assign FFEControlMemory_4k_fabric_ram1Kx9_addr_o = fabric_ram1Kx9_addr;
|
||||||
|
assign FFEControlMemory_4k_ram1_wr_en_o = ram1_wr_en ;
|
||||||
|
assign FFEControlMemory_4k_ram1_rd_en_o = ram1_rd_en;
|
||||||
|
assign FFEControlMemory_4k_SPI_clk_o = SPI_clk;
|
||||||
|
assign ram1_rd_data = FFEControlMemory_4k_ram1_rd_data_i;
|
||||||
|
|
||||||
|
|
||||||
|
// RAM 0 (ASSP 8k left bank)
|
||||||
|
assign assp_lb_ram8k_clk = TLC_FFE_clk2x_muxed;
|
||||||
|
assign assp_lb_ram8k_addr = assp_ram8k_addr;
|
||||||
|
assign assp_lb_ram8k_wr_data = WriteData_TLC;
|
||||||
|
assign ram0_rd_data = assp_lb_ram8k_rd_data;
|
||||||
|
assign assp_lb_ram8k_wr_en = ram0_wr_en;
|
||||||
|
assign assp_lb_ram8k_rd_en = ram0_rd_en;
|
||||||
|
assign assp_lb_ram8k_wr_be = 2'b11;
|
||||||
|
|
||||||
|
|
||||||
|
// latch the 4Kx17 read data
|
||||||
|
always @(posedge TLC_FFE_clk2x_muxed) begin
|
||||||
|
if (FFE_clock_halfperiod)
|
||||||
|
lower2k_rd_data_phase0 <= ram0_rd_data;
|
||||||
|
if (!FFE_clock_halfperiod)
|
||||||
|
lower2k_rd_data_phase1 <= ram0_rd_data;
|
||||||
|
if (FFE_clock_halfperiod)
|
||||||
|
ReadAddress_muxed_bit0_r1 <= ReadAddress_muxed[0];
|
||||||
|
end
|
||||||
|
|
||||||
|
// assemble the read data for the lower 2k (ram0/ram1)
|
||||||
|
always @(*)
|
||||||
|
if (FFE_clock_halfperiod == 0)
|
||||||
|
if (ReadAddress_muxed_bit0_r1 == 0)
|
||||||
|
lower2k_rd_data <= {ram1_rd_data[1:0], ram0_rd_data[16:0], lower2k_rd_data_phase0[16:0]};
|
||||||
|
else
|
||||||
|
lower2k_rd_data <= {ram1_rd_data[3:2], ram0_rd_data[16:0], lower2k_rd_data_phase0[16:0]};
|
||||||
|
else
|
||||||
|
if (ReadAddress_muxed_bit0_r1 == 0)
|
||||||
|
lower2k_rd_data <= {ram1_rd_data[1:0], lower2k_rd_data_phase1[16:0], lower2k_rd_data_phase0[16:0]};
|
||||||
|
else
|
||||||
|
lower2k_rd_data <= {ram1_rd_data[3:2], lower2k_rd_data_phase1[16:0], lower2k_rd_data_phase0[16:0]};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// mux the read data from each RAM block, for the FFE
|
||||||
|
always @(posedge TLC_FFE_clk2x_muxed)
|
||||||
|
if (FFE_clock_halfperiod)
|
||||||
|
ram_rd_select <= ReadAddress_muxed[11:9];
|
||||||
|
|
||||||
|
always @(*)
|
||||||
|
if (MemSelect_en)
|
||||||
|
// TLC is reading
|
||||||
|
if (MemSelect == 3'h0)
|
||||||
|
case (ram_rd_select[1:0])
|
||||||
|
2'b00: ram_rd_data <= ram2_rd_data;
|
||||||
|
2'b01: ram_rd_data <= ram3_rd_data;
|
||||||
|
2'b10: ram_rd_data <= ram4_rd_data;
|
||||||
|
2'b11: ram_rd_data <= ram5_rd_data;
|
||||||
|
endcase
|
||||||
|
else
|
||||||
|
if (MemSelect == 3'h4)
|
||||||
|
ram_rd_data <= ram0_rd_data;
|
||||||
|
else
|
||||||
|
// assume select=5 to reduce logic
|
||||||
|
|
||||||
|
//if (MemSelect == 3'h5)
|
||||||
|
ram_rd_data <= ram1_rd_data;
|
||||||
|
//else
|
||||||
|
// ram_rd_data <= 0;
|
||||||
|
else
|
||||||
|
// FFE is reading
|
||||||
|
if (ram_rd_select[2])
|
||||||
|
// upper 2k
|
||||||
|
case(ram_rd_select[1:0])
|
||||||
|
2'b00: ram_rd_data <= ram2_rd_data;
|
||||||
|
2'b01: ram_rd_data <= ram3_rd_data;
|
||||||
|
2'b10: ram_rd_data <= ram4_rd_data;
|
||||||
|
2'b11: ram_rd_data <= ram5_rd_data;
|
||||||
|
endcase
|
||||||
|
else
|
||||||
|
// lower 2k
|
||||||
|
ram_rd_data <= lower2k_rd_data;
|
||||||
|
|
||||||
|
assign ReadData = ram_rd_data;
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
`timescale 1ns / 10ps
|
||||||
|
|
||||||
|
module FFEDataMemoryMux (
|
||||||
|
input Select,
|
||||||
|
|
||||||
|
input [9:0] ReadAddressIn0,
|
||||||
|
input [9:0] ReadAddressIn1,
|
||||||
|
output[9:0] ReadAddressOut,
|
||||||
|
|
||||||
|
input [9:0] WriteAddressIn0,
|
||||||
|
input [9:0] WriteAddressIn1,
|
||||||
|
output[9:0] WriteAddressOut,
|
||||||
|
|
||||||
|
input [35:0] DataToMemoryIn0,
|
||||||
|
input [35:0] DataToMemoryIn1,
|
||||||
|
output[35:0] DataToMemoryOut,
|
||||||
|
|
||||||
|
input [35:0] DataFromMemoryIn0,
|
||||||
|
input [35:0] DataFromMemoryIn1,
|
||||||
|
output[35:0] DataFromMemoryOut,
|
||||||
|
|
||||||
|
input ReadEnable0,
|
||||||
|
input ReadEnable1,
|
||||||
|
output ReadEnable,
|
||||||
|
|
||||||
|
input WriteEnable0,
|
||||||
|
input WriteEnable1,
|
||||||
|
output WriteEnable
|
||||||
|
);
|
||||||
|
|
||||||
|
assign ReadAddressOut = (Select) ? ReadAddressIn1 : ReadAddressIn0;
|
||||||
|
assign WriteAddressOut = (Select) ? WriteAddressIn1 : WriteAddressIn0;
|
||||||
|
assign DataToMemoryOut = (Select) ? DataToMemoryIn1 : DataToMemoryIn0;
|
||||||
|
assign DataFromMemoryOut = (Select) ? DataFromMemoryIn1 : DataFromMemoryIn0;
|
||||||
|
assign ReadEnable = (Select) ? ReadEnable1 : ReadEnable0;
|
||||||
|
assign WriteEnable = (Select) ? WriteEnable1 : WriteEnable0;
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,476 @@
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// title : FFE_ALU.v
|
||||||
|
// project : ULP Sensor Hub
|
||||||
|
// description : 32-bit ALU
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// copyright (c) 2013, QuickLogic Corporation
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// History :
|
||||||
|
// date version author description
|
||||||
|
//
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// date version author description
|
||||||
|
// 10-31-2013 1.1 Anthony Le Add AND function to code
|
||||||
|
// Details:
|
||||||
|
// 1. Add new bus signal xT30 as 32-bit for output of AND function
|
||||||
|
// 2. Assign a temporary 32bit bus to hold the concatenation of MailBox bit:
|
||||||
|
// Mailbox32bit = {8'b0, MailBox[7:0], 16'h0};
|
||||||
|
// 3. Add code to perform AND function between Mailbox32bit and xT23
|
||||||
|
// 4. Add mux function between xT30 and MailBox in using signal[38]
|
||||||
|
// 5. Expected the Synthesis to remove all unused logics
|
||||||
|
//
|
||||||
|
// 11-29-2013 1.2 Anthony Le Add additional comparison functions
|
||||||
|
// Details:
|
||||||
|
// 1. Current system supports only three jump functions:
|
||||||
|
// a. JMP: jump
|
||||||
|
// b. JMPNEZ: jump when result is not equal to zero
|
||||||
|
// c. JMPGEZ: jump when result is greater or equal to zero
|
||||||
|
// 2. Add four more compriason jump functions
|
||||||
|
// a. JMPEQZ: jump when result is equal to zero
|
||||||
|
// b. JMPLTZ: jump when result is less than zero
|
||||||
|
// c. JMPLEZ: jump when result is less than or equal to zero
|
||||||
|
// d. JMPGTZ: jump when result is greater than zero
|
||||||
|
// 3. Re-use the three control signals[19:17]
|
||||||
|
// 4. Use an 8-to-1 mux for JUMP logic
|
||||||
|
// 5. Update xJumpFlag from wire to reg type
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1ns / 10ps
|
||||||
|
|
||||||
|
`include "ulpsh_rtl_defines.v"
|
||||||
|
|
||||||
|
module FFE_ALU (
|
||||||
|
input [31:0] xReadData1,
|
||||||
|
input [31:0] xReadData2,
|
||||||
|
input [63:0] signals,
|
||||||
|
input ClockIn,
|
||||||
|
input Clock_x2In,
|
||||||
|
input FFE_clock_halfperiod,
|
||||||
|
input [15:0] TimeStampIn,
|
||||||
|
input [31:0] MailboxIn,
|
||||||
|
input [3:0] SM_InterruptIn,
|
||||||
|
input MultClockIn,
|
||||||
|
input [3:0] MultStateIn,
|
||||||
|
output [8:0] xIndexRegister,
|
||||||
|
output [31:0] xWriteData,
|
||||||
|
output reg xJumpFlag,
|
||||||
|
input Save_BG_registers,
|
||||||
|
input Restore_BG_registers,
|
||||||
|
|
||||||
|
output [31:0] mult_in1,
|
||||||
|
output [31:0] mult_in2,
|
||||||
|
output mult_enable,
|
||||||
|
input [63:0] mult_out
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
wire [31:0] xT0, xT1, xT2;
|
||||||
|
//wire [31:0] xT3; // defined below, depending on the multiplier implementation
|
||||||
|
wire [31:0] xT4;
|
||||||
|
reg [31:0] xT5;
|
||||||
|
wire [31:0] xT6, xT7, xT8, xT9;
|
||||||
|
wire [31:0] xT10, xT11, xT12, xT13, xT14, xT15, xT16, xT17, xT18, xT19, xT20, xT21, xT22;
|
||||||
|
reg [31:0] xT23;
|
||||||
|
wire [31:0] xT24, xT25;
|
||||||
|
wire [8:0] xT26, xT27, xT28;
|
||||||
|
reg [8:0] xT29;
|
||||||
|
wire [31:0] xT30;
|
||||||
|
wire signed [31:0] xT12_signed;
|
||||||
|
wire f0;
|
||||||
|
reg f2, f5, f2_BG, f5_BG;
|
||||||
|
wire f3, f6;
|
||||||
|
reg f2_latched, f2_BG_latched;
|
||||||
|
reg [31:0] xT5_latched;
|
||||||
|
reg f5_latched, f5_BG_latched;
|
||||||
|
reg [8:0] xT29_latched;
|
||||||
|
|
||||||
|
// compiler options, from rtl_defines.v
|
||||||
|
// ENABLE_FFE_F0_EXTENDED_DM
|
||||||
|
// ENABLE_FFE_F0_SINGLE_DM
|
||||||
|
// ENABLE_FFE_F0_PROGRAMMABLE_SEG0_OFFSET
|
||||||
|
// FFE_F0_SEG0_OFFSET [value]
|
||||||
|
|
||||||
|
// compiler directives related to CM size:
|
||||||
|
// ENABLE_FFE_F0_CM_SIZE_2K
|
||||||
|
// ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
// ENABLE_FFE_F0_CM_SIZE_3K (future support if needed)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// select the multiplier implementation
|
||||||
|
`define ASSP_MULT
|
||||||
|
|
||||||
|
`ifdef FullSingleCycle
|
||||||
|
wire [63:0] xT3;
|
||||||
|
wire [63:0] xT1extended, xT2extended;
|
||||||
|
|
||||||
|
assign xT1extended[63:0] = { {32{xT1[31]}}, xT1[31:0] };
|
||||||
|
assign xT2extended[63:0] = { {32{xT2[31]}}, xT2[31:0] };
|
||||||
|
assign xT3 = xT1extended * xT2extended;
|
||||||
|
assign xT4 = (xT3 >> 16);
|
||||||
|
|
||||||
|
`elsif Handicapped
|
||||||
|
wire [31:0] xT3;
|
||||||
|
assign xT3 = xT1 + xT2; // replace multiplier with adder
|
||||||
|
assign xT4 = xT3;
|
||||||
|
|
||||||
|
`elsif MultiCycle
|
||||||
|
wire [31:0] xT3;
|
||||||
|
Multiplier Multiplier_1 (
|
||||||
|
.ClockIn ( MultClockIn ),
|
||||||
|
.StateIn ( MultStateIn ),
|
||||||
|
.Arg1In ( xT1 ),
|
||||||
|
.Arg2In ( xT2 ),
|
||||||
|
.ResultOut ( xT3 )
|
||||||
|
);
|
||||||
|
assign xT4 = xT3;
|
||||||
|
|
||||||
|
`elsif ASSP_MULT
|
||||||
|
wire [63:0] xT3;
|
||||||
|
|
||||||
|
assign xT3 = mult_out;
|
||||||
|
assign xT4 = (xT3 >> 16);
|
||||||
|
|
||||||
|
`else
|
||||||
|
wire [31:0] xT3;
|
||||||
|
|
||||||
|
assign xT3 = 0;
|
||||||
|
assign xT4 = 0;
|
||||||
|
|
||||||
|
`endif
|
||||||
|
|
||||||
|
|
||||||
|
// drive the outputs for the ASSP multiplier
|
||||||
|
assign mult_in1 = xT1;
|
||||||
|
assign mult_in2 = xT2;
|
||||||
|
assign mult_enable = signals[5];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
assign xT22 = signals[2] ? (xReadData1<<16) : xReadData1;
|
||||||
|
|
||||||
|
always @(*)
|
||||||
|
case (signals[1:0])
|
||||||
|
2'b00: xT23 <= xReadData2;
|
||||||
|
2'b01: xT23 <= MailboxIn;
|
||||||
|
2'b10: xT23 <= {TimeStampIn[15:0], 16'b0};
|
||||||
|
2'b11: xT23 <= {7'b0, xT29[8:0], 16'b0}; // IndexReg
|
||||||
|
endcase
|
||||||
|
|
||||||
|
assign xT24 = signals[3] ? {12'b0, SM_InterruptIn[3:0], 16'b0} : xT23;
|
||||||
|
assign xT30 = xReadData1 & xT24;
|
||||||
|
assign xT9 = signals[38] ? xT30 : xT24;
|
||||||
|
assign xT21 = xReadData1 | xT24;
|
||||||
|
assign xT25 = signals[39] ? xT21 : xT9;
|
||||||
|
|
||||||
|
assign xT0 = signals[4] ? xT25 : xT22;
|
||||||
|
|
||||||
|
assign xT12_signed = xT12;
|
||||||
|
// remove these muxes to save space
|
||||||
|
//assign xT1 = signals[5] ? xT0 : xT1; // this mux (latch) keeps the multiplier inputs stable, to save power
|
||||||
|
//assign xT2 = signals[5] ? xT25 : xT2; // this mux (latch) keeps the multiplier inputs stable, to save power
|
||||||
|
assign xT1 = xT0;
|
||||||
|
assign xT2 = xT25;
|
||||||
|
|
||||||
|
assign xT7 = signals[5] ? xT4 : xT25;
|
||||||
|
assign xT10 = signals[8] ? ~xT7 : xT7;
|
||||||
|
assign xT11 = signals[8] ? 32'b1 : 32'b0;
|
||||||
|
assign xT13 = signals[9] ? xT7 : xT10;
|
||||||
|
assign xT6 = signals[6] ? xT22 : xT5;
|
||||||
|
assign xT8 = signals[7] ? xT6 : 32'b0;
|
||||||
|
assign xT12 = xT8 + xT10 + xT11;
|
||||||
|
assign xT14 = (xT12_signed >>> 1);
|
||||||
|
assign xT16 = signals[11] ? xT14 : xT12;
|
||||||
|
assign xT19 = signals[12] ? xT16 : xT6;
|
||||||
|
assign f0 = xT12[31];
|
||||||
|
|
||||||
|
// Sign bit
|
||||||
|
`ifndef ENABLE_FFE_F0_SINGLE_DM
|
||||||
|
// double DM, default behavior
|
||||||
|
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
// 4k CM
|
||||||
|
always @(posedge Clock_x2In) begin
|
||||||
|
if (FFE_clock_halfperiod) begin
|
||||||
|
if (Restore_BG_registers)
|
||||||
|
f2 <= f2_BG;
|
||||||
|
else
|
||||||
|
f2 <= signals[10] ? f0 : f2;
|
||||||
|
|
||||||
|
if (Save_BG_registers)
|
||||||
|
f2_BG <= f2;
|
||||||
|
else
|
||||||
|
f2_BG <= f2_BG;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
`else
|
||||||
|
// 2k CM
|
||||||
|
always @(posedge ClockIn) begin
|
||||||
|
if (Restore_BG_registers)
|
||||||
|
f2 <= f2_BG;
|
||||||
|
else
|
||||||
|
f2 <= signals[10] ? f0 : f2;
|
||||||
|
|
||||||
|
if (Save_BG_registers)
|
||||||
|
f2_BG <= f2;
|
||||||
|
else
|
||||||
|
f2_BG <= f2_BG;
|
||||||
|
end
|
||||||
|
|
||||||
|
`endif
|
||||||
|
|
||||||
|
`else
|
||||||
|
// single DM
|
||||||
|
|
||||||
|
always @(posedge Clock_x2In) begin
|
||||||
|
if (!FFE_clock_halfperiod) begin
|
||||||
|
if (Restore_BG_registers)
|
||||||
|
f2_latched <= f2_BG;
|
||||||
|
else
|
||||||
|
f2_latched <= signals[10] ? f0 : f2;
|
||||||
|
|
||||||
|
if (Save_BG_registers)
|
||||||
|
f2_BG_latched <= f2;
|
||||||
|
else
|
||||||
|
f2_BG_latched <= f2_BG;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
always @(posedge Clock_x2In) begin
|
||||||
|
if (FFE_clock_halfperiod) begin
|
||||||
|
f2 <= f2_latched;
|
||||||
|
f2_BG <= f2_BG_latched;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
`else
|
||||||
|
always @(posedge ClockIn) begin
|
||||||
|
f2 <= f2_latched;
|
||||||
|
f2_BG <= f2_BG_latched;
|
||||||
|
end
|
||||||
|
`endif
|
||||||
|
|
||||||
|
`endif
|
||||||
|
|
||||||
|
|
||||||
|
assign f6 = signals[33] ? (f2) : (f0);
|
||||||
|
assign f3 = signals[35] ? !f5 : f6;
|
||||||
|
|
||||||
|
assign xT15 = (f3) ? xT13 : xT19;
|
||||||
|
assign xT17 = signals[13] ? xT15 : xT16;
|
||||||
|
assign xT18 = (xT17 << 1);
|
||||||
|
assign xT20 = signals[14] ? xT18 : xT17;
|
||||||
|
|
||||||
|
assign xWriteData = xT20;
|
||||||
|
|
||||||
|
// accumulator
|
||||||
|
`ifndef ENABLE_FFE_F0_SINGLE_DM
|
||||||
|
// double DM, default behavior
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
always @(posedge Clock_x2In) begin
|
||||||
|
if (FFE_clock_halfperiod)
|
||||||
|
xT5 <= signals[16] ? xT20 : xT5;
|
||||||
|
end
|
||||||
|
`else
|
||||||
|
always @(posedge ClockIn) begin
|
||||||
|
xT5 <= signals[16] ? xT20 : xT5;
|
||||||
|
end
|
||||||
|
`endif
|
||||||
|
`else
|
||||||
|
// single DM
|
||||||
|
always @(posedge Clock_x2In) begin
|
||||||
|
if (!FFE_clock_halfperiod)
|
||||||
|
xT5_latched <= signals[16] ? xT20 : xT5;
|
||||||
|
end
|
||||||
|
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
always @(posedge Clock_x2In)
|
||||||
|
if (FFE_clock_halfperiod)
|
||||||
|
xT5 <= xT5_latched;
|
||||||
|
`else
|
||||||
|
always @(posedge ClockIn)
|
||||||
|
xT5 <= xT5_latched;
|
||||||
|
`endif
|
||||||
|
`endif
|
||||||
|
|
||||||
|
|
||||||
|
// NEZ flag
|
||||||
|
`ifndef ENABLE_FFE_F0_SINGLE_DM
|
||||||
|
// double DM, default behavior
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
always @(posedge Clock_x2In) begin
|
||||||
|
if (FFE_clock_halfperiod) begin
|
||||||
|
if (Restore_BG_registers)
|
||||||
|
f5 <= f5_BG;
|
||||||
|
else
|
||||||
|
f5 <= signals[15] ? f5 : (xT20 != 32'b0);
|
||||||
|
|
||||||
|
if (Save_BG_registers)
|
||||||
|
f5_BG <= f5;
|
||||||
|
else
|
||||||
|
f5_BG <= f5_BG;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
`else
|
||||||
|
always @(posedge ClockIn) begin
|
||||||
|
if (Restore_BG_registers)
|
||||||
|
f5 <= f5_BG;
|
||||||
|
else
|
||||||
|
f5 <= signals[15] ? f5 : (xT20 != 32'b0);
|
||||||
|
|
||||||
|
if (Save_BG_registers)
|
||||||
|
f5_BG <= f5;
|
||||||
|
else
|
||||||
|
f5_BG <= f5_BG;
|
||||||
|
end
|
||||||
|
`endif
|
||||||
|
`else
|
||||||
|
// single DM
|
||||||
|
always @(posedge Clock_x2In) begin
|
||||||
|
if (!FFE_clock_halfperiod) begin
|
||||||
|
if (Restore_BG_registers)
|
||||||
|
f5_latched <= f5_BG;
|
||||||
|
//f5_latched <= f5_BG_latched;
|
||||||
|
else
|
||||||
|
f5_latched <= signals[15] ? f5 : (xT20 != 32'b0);
|
||||||
|
//f5_latched <= signals[15] ? f5_latched : (xT20 != 32'b0);
|
||||||
|
|
||||||
|
if (Save_BG_registers)
|
||||||
|
f5_BG_latched <= f5;
|
||||||
|
//f5_BG_latched <= f5_latched;
|
||||||
|
else
|
||||||
|
f5_BG_latched <= f5_BG;
|
||||||
|
//f5_BG_latched <= f5_BG_latched;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
always @(posedge Clock_x2In) begin
|
||||||
|
if (FFE_clock_halfperiod) begin
|
||||||
|
f5 <= f5_latched;
|
||||||
|
f5_BG <= f5_BG_latched;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
`else
|
||||||
|
always @(posedge ClockIn) begin
|
||||||
|
f5 <= f5_latched;
|
||||||
|
f5_BG <= f5_BG_latched;
|
||||||
|
end
|
||||||
|
`endif
|
||||||
|
`endif
|
||||||
|
|
||||||
|
|
||||||
|
always @(*)
|
||||||
|
begin
|
||||||
|
case ({signals[19], signals[18], signals[17]})
|
||||||
|
3'b000: xJumpFlag = 1'b0; // no jump
|
||||||
|
3'b001: xJumpFlag = 1'b1; // JMP (unconditional jump)
|
||||||
|
3'b010: xJumpFlag = f5; // JMPNEZ (jump if NEZflag)
|
||||||
|
3'b011: xJumpFlag = !f5; // JMPEQZ (jump if !NEZflag)
|
||||||
|
3'b100: xJumpFlag = !f2; // JMPGEZ (jump if !SignBit)
|
||||||
|
3'b101: xJumpFlag = f2; // JMPLTZ (jump if SignBit)
|
||||||
|
3'b110: xJumpFlag = !(!f2 && f5); // JMPLEZ (jump if SignBit or !NEZflag)
|
||||||
|
3'b111: xJumpFlag = !f2 && f5; // JMPGTZ (jump if !SignBit and NEZflag)
|
||||||
|
default: xJumpFlag = 1'b0;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// Index register code
|
||||||
|
assign xT26 = xT29 + 1;
|
||||||
|
assign xT27 = signals[24] ? xT26 : 9'b0;
|
||||||
|
assign xT28 = signals[26] ? xT20[24:16] : xT27; // assign the integer portion of xT20, or xT27
|
||||||
|
|
||||||
|
// Index Register
|
||||||
|
`ifndef ENABLE_FFE_F0_SINGLE_DM
|
||||||
|
// double DM, default behavior
|
||||||
|
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
always @(posedge Clock_x2In) begin
|
||||||
|
if (FFE_clock_halfperiod) begin
|
||||||
|
if (signals[25])
|
||||||
|
xT29 <= xT28;
|
||||||
|
else
|
||||||
|
xT29 <= xT29;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
`else
|
||||||
|
always @(posedge ClockIn) begin
|
||||||
|
if (signals[25])
|
||||||
|
xT29 <= xT28;
|
||||||
|
else
|
||||||
|
xT29 <= xT29;
|
||||||
|
end
|
||||||
|
`endif
|
||||||
|
`else
|
||||||
|
// single DM
|
||||||
|
|
||||||
|
always @(posedge Clock_x2In) begin
|
||||||
|
if (!FFE_clock_halfperiod) begin
|
||||||
|
if (signals[25])
|
||||||
|
xT29_latched <= xT28;
|
||||||
|
else
|
||||||
|
xT29_latched <= xT29;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
always @(posedge Clock_x2In)
|
||||||
|
if (FFE_clock_halfperiod)
|
||||||
|
xT29 <= xT29_latched;
|
||||||
|
`else
|
||||||
|
always @(posedge ClockIn)
|
||||||
|
xT29 <= xT29_latched;
|
||||||
|
`endif
|
||||||
|
|
||||||
|
`endif
|
||||||
|
|
||||||
|
assign xIndexRegister = xT29;
|
||||||
|
|
||||||
|
|
||||||
|
// prevent logic duplication
|
||||||
|
//pragma attribute xT0 preserve_driver true
|
||||||
|
//pragma attribute xT1 preserve_driver true
|
||||||
|
//pragma attribute xT2 preserve_driver true
|
||||||
|
//pragma attribute xT3 preserve_driver true
|
||||||
|
//pragma attribute xT4 preserve_driver true
|
||||||
|
//pragma attribute xT5 preserve_driver true
|
||||||
|
//pragma attribute xT6 preserve_driver true
|
||||||
|
//pragma attribute xT7 preserve_driver true
|
||||||
|
//pragma attribute xT8 preserve_driver true
|
||||||
|
//pragma attribute xT9 preserve_driver true
|
||||||
|
//pragma attribute xT10 preserve_driver true
|
||||||
|
//pragma attribute xT11 preserve_driver true
|
||||||
|
//pragma attribute xT12 preserve_driver true
|
||||||
|
//pragma attribute xT13 preserve_driver true
|
||||||
|
//pragma attribute xT14 preserve_driver true
|
||||||
|
//pragma attribute xT15 preserve_driver true
|
||||||
|
//pragma attribute xT16 preserve_driver true
|
||||||
|
//pragma attribute xT17 preserve_driver true
|
||||||
|
//pragma attribute xT18 preserve_driver true
|
||||||
|
//pragma attribute xT19 preserve_driver true
|
||||||
|
//pragma attribute xT20 preserve_driver true
|
||||||
|
//pragma attribute xT20 preserve_driver true
|
||||||
|
//pragma attribute xT21 preserve_driver true
|
||||||
|
//pragma attribute xT22 preserve_driver true
|
||||||
|
//pragma attribute xT23 preserve_driver true
|
||||||
|
//pragma attribute xT24 preserve_driver true
|
||||||
|
//pragma attribute xT25 preserve_driver true
|
||||||
|
//pragma attribute xT26 preserve_driver true
|
||||||
|
//pragma attribute xT27 preserve_driver true
|
||||||
|
//pragma attribute xT28 preserve_driver true
|
||||||
|
//pragma attribute xT29 preserve_driver true
|
||||||
|
//pragma attribute xT30 preserve_driver true
|
||||||
|
//pragma attribute xT12_signed preserve_driver true
|
||||||
|
//pragma attribute f0 preserve_driver true
|
||||||
|
//pragma attribute f2 preserve_driver true
|
||||||
|
//pragma attribute f5 preserve_driver true
|
||||||
|
//pragma attribute f3 preserve_driver true
|
||||||
|
//pragma attribute f6 preserve_driver true
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,964 @@
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
title : FlexFusionEngine Control
|
||||||
|
project : Jim-Bob Hardware Sensor Hub
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
platform : Alabama test chip
|
||||||
|
standard : Verilog 2001
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
description: Module for controlling the FlexFusionEngine
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
copyright (c) 2013, QuickLogic Corporation
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
History :
|
||||||
|
Date Version Author Description
|
||||||
|
2013/03/21 1.0 Jason Lew Created
|
||||||
|
2013/05/02 1.1 Jason Lew Migrated from FFEAT v21d
|
||||||
|
2013/06/14 1.2 Randy O. Corrected assignment to DataMemReadAddr's b/c it wasn't using IndexReg properly.
|
||||||
|
Corrected assignment to MemReadData's b/c it shouldn't use IndexReg.
|
||||||
|
2013/06/26 1.3 Randy O. Made the Signals bus 64 bits wide instead of 32, since it needs to be at least as wide as the one in microopdecodes.v
|
||||||
|
2013/07/01 1.4 Randy O. Cosmetic changes to improve readability.
|
||||||
|
Removed DataMem1WriteData_int & DataMem2WriteData_int since they were unused.
|
||||||
|
2013/07/08 1.5 Randy O. Added unit delays to aid in functional sim.
|
||||||
|
2014/05/21 1.6 Glen G. Added ability to read/write expanded Sensor Manager Memory
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
Comments: This solution is specifically for implementing into the Alabama
|
||||||
|
test chip. Verification will be done using the Jim-Bob Sensor Board
|
||||||
|
------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
`include "ulpsh_rtl_defines.v"
|
||||||
|
|
||||||
|
|
||||||
|
`timescale 1ns / 10ps
|
||||||
|
|
||||||
|
module FFE_Control ( // named RunFlexFusionEngine in C source
|
||||||
|
input ClockIn,
|
||||||
|
input Clock_x2In,
|
||||||
|
input ResetIn,
|
||||||
|
input StartIn,
|
||||||
|
output StartSMOut,
|
||||||
|
input [15:0] TimeStampIn,
|
||||||
|
input [31:0] MailboxIn,
|
||||||
|
input [3:0] SM_InterruptIn,
|
||||||
|
output [11:0] ControlMemAddressOut,
|
||||||
|
output reg ControlMemReadEnableOut,
|
||||||
|
output [9:0] SensorMemReadAddressOut, // Expanded for Rel 0 on 6/18
|
||||||
|
output SensorMemReadEnableOut,
|
||||||
|
output [9:0] SensorMemWriteAddressOut, // New for Rel 0 on 6/18
|
||||||
|
output SensorMemWriteEnableOut, // New for Rel 0 on 6/18
|
||||||
|
input [35:0] ControlMemDataIn,
|
||||||
|
input [35:0] Mem1ReadData,
|
||||||
|
input [35:0] Mem2ReadData,
|
||||||
|
input [17:0] SensorMemReadDataIn,
|
||||||
|
input SensorMemBusyIn,
|
||||||
|
|
||||||
|
output [8:0] SensorMemWriteDataOut, // New for Rel 0 on 6/18
|
||||||
|
output BusyOut,
|
||||||
|
output DataMem1ReadEnable,
|
||||||
|
output DataMem2ReadEnable,
|
||||||
|
output DataMem1WriteEnable,
|
||||||
|
output DataMem2WriteEnable,
|
||||||
|
output [9:0] DataMem1ReadAddressOut,
|
||||||
|
output [9:0] DataMem1WriteAddressOut,
|
||||||
|
output [35:0] DataMem1WriteDataOut,
|
||||||
|
output [9:0] DataMem2ReadAddressOut,
|
||||||
|
output [9:0] DataMem2WriteAddressOut,
|
||||||
|
output [35:0] DataMem2WriteDataOut,
|
||||||
|
|
||||||
|
output reg FFE_clock_halfperiod,
|
||||||
|
|
||||||
|
input MultClockIn,
|
||||||
|
input [3:0] MultStateIn,
|
||||||
|
|
||||||
|
// Status data
|
||||||
|
input SMBusyIn,
|
||||||
|
output reg SMOverrunOut,
|
||||||
|
|
||||||
|
// CM FIFO controls
|
||||||
|
output [17:0] CMWriteDataOut,
|
||||||
|
output CMWriteEnableOut,
|
||||||
|
|
||||||
|
output [7:0] InterruptMsgOut,
|
||||||
|
|
||||||
|
// interface to ASSP multiplier
|
||||||
|
output [31:0] mult_in1,
|
||||||
|
output [31:0] mult_in2,
|
||||||
|
output mult_enable,
|
||||||
|
input [63:0] mult_out,
|
||||||
|
|
||||||
|
|
||||||
|
output TP1,
|
||||||
|
output TP2,
|
||||||
|
output TP3
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// compiler directives related to CM size:
|
||||||
|
// ENABLE_FFE_F0_CM_SIZE_2K
|
||||||
|
// ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
// ENABLE_FFE_F0_CM_SIZE_3K (future support if needed)
|
||||||
|
|
||||||
|
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
// 4k CM
|
||||||
|
reg [11:0] xPC;
|
||||||
|
wire [11:0] xJumpAddress;
|
||||||
|
reg [11:0] PC_BG;
|
||||||
|
`else
|
||||||
|
// 2k CM (3k CM support may be added in the future)
|
||||||
|
reg [10:0] xPC;
|
||||||
|
wire [10:0] xJumpAddress;
|
||||||
|
reg [10:0] PC_BG;
|
||||||
|
`endif
|
||||||
|
|
||||||
|
|
||||||
|
reg BusyOut_reg, BusyOut_r1;
|
||||||
|
|
||||||
|
reg Start_r1, Start_r2, Start_r3;
|
||||||
|
wire [31:0] Mem1ReadDataToALU;
|
||||||
|
wire [31:0] Mem2ReadDataToALU;
|
||||||
|
wire [8:0] MicroOpCode;
|
||||||
|
wire [63:0] Signals; // the width of Signals is defined to be way larger than it needs to be (today), extra bits should get optimized out.
|
||||||
|
wire [8:0] xIndexRegister;
|
||||||
|
wire [31:0] xWriteData;
|
||||||
|
wire xJumpFlag;
|
||||||
|
wire [35:0] Mem1ReadDataX;
|
||||||
|
wire [35:0] Mem2ReadDataX;
|
||||||
|
|
||||||
|
reg [7:0] InterruptMsg_reg;
|
||||||
|
reg StartSM_reg;
|
||||||
|
|
||||||
|
reg [15:0] TimeStamp_r1, TimeStamp_r2, TimeStamp_synced;
|
||||||
|
|
||||||
|
|
||||||
|
reg f5_BG;
|
||||||
|
reg f2_BG;
|
||||||
|
reg BGcontinue_pending;
|
||||||
|
reg BGsave_pending;
|
||||||
|
reg BGstop_pending;
|
||||||
|
reg BG_active;
|
||||||
|
reg Start_pending;
|
||||||
|
wire Start_detected;
|
||||||
|
wire Save_BG_registers;
|
||||||
|
wire Restore_BG_registers;
|
||||||
|
wire Clear_PC;
|
||||||
|
wire Disable_DataMem_WrEn;
|
||||||
|
|
||||||
|
reg [2:0] Thread_switch_cnt;
|
||||||
|
parameter [2:0] THREAD_SWITCH_CNT_DONE = 3'b111;
|
||||||
|
|
||||||
|
|
||||||
|
// standard-depth DM addresses (9 bits)
|
||||||
|
wire [8:0] DataMem1ReadAddressOut_std;
|
||||||
|
wire [8:0] DataMem1WriteAddressOut_std;
|
||||||
|
wire [8:0] DataMem2ReadAddressOut_std;
|
||||||
|
wire [8:0] DataMem2WriteAddressOut_std;
|
||||||
|
|
||||||
|
wire [9:0] DataMem1WriteAddressOut_trans;
|
||||||
|
wire [9:0] DataMem2WriteAddressOut_trans;
|
||||||
|
wire [9:0] DataMem1ReadAddressOut_trans;
|
||||||
|
wire [9:0] DataMem2ReadAddressOut_trans;
|
||||||
|
reg [9:0] DataMem2ReadAddressOut_trans_hold;
|
||||||
|
reg DataMem1ReadAddressOut_trans_MSB_r1;
|
||||||
|
|
||||||
|
wire [9:0] DataMem1WriteAddressOut_mux;
|
||||||
|
wire [9:0] DataMem1ReadAddressOut_mux;
|
||||||
|
|
||||||
|
wire DataMem1ReadEnable_mux;
|
||||||
|
wire DataMem1WriteEnable_mux;
|
||||||
|
|
||||||
|
wire [9:0] DataMem1WriteAddressOut_split;
|
||||||
|
wire [9:0] DataMem2WriteAddressOut_split;
|
||||||
|
wire [9:0] DataMem1ReadAddressOut_split;
|
||||||
|
wire [9:0] DataMem2ReadAddressOut_split;
|
||||||
|
|
||||||
|
wire DataMem1ReadEnable_split;
|
||||||
|
wire DataMem1WriteEnable_split;
|
||||||
|
wire DataMem2ReadEnable_split;
|
||||||
|
wire DataMem2WriteEnable_split;
|
||||||
|
|
||||||
|
//reg FFE_clock_halfperiod;
|
||||||
|
|
||||||
|
wire DataMem1ReadEnable_std;
|
||||||
|
wire DataMem2ReadEnable_std;
|
||||||
|
reg DataMem2ReadEnable_std_hold;
|
||||||
|
wire DataMem1WriteEnable_std;
|
||||||
|
wire DataMem2WriteEnable_std;
|
||||||
|
|
||||||
|
reg [31:0] Mem1ReadData_latched;
|
||||||
|
reg [31:0] Mem2ReadData_latched;
|
||||||
|
|
||||||
|
wire ClockIn_dly1;
|
||||||
|
wire ClockIn_dly2;
|
||||||
|
wire ClockIn_dly3;
|
||||||
|
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
reg SensorMemReadEnable_reg;
|
||||||
|
reg SensorMemWriteEnable_reg;
|
||||||
|
reg [9:0] SensorMemReadAddress_reg;
|
||||||
|
reg [9:0] SensorMemWriteAddress_reg;
|
||||||
|
reg CMWriteEnable_reg;
|
||||||
|
`endif
|
||||||
|
|
||||||
|
// compiler options, from rtl_defines.v
|
||||||
|
// ENABLE_FFE_F0_EXTENDED_DM
|
||||||
|
// ENABLE_FFE_F0_SINGLE_DM
|
||||||
|
// ENABLE_FFE_F0_PROGRAMMABLE_SEG0_OFFSET
|
||||||
|
// FFE_F0_SEG0_OFFSET [value]
|
||||||
|
|
||||||
|
`ifdef FFE_F0_SEG0_OFFSET
|
||||||
|
parameter [8:0] Segment0_offset = `FFE_F0_SEG0_OFFSET;
|
||||||
|
`endif
|
||||||
|
|
||||||
|
`ifdef ENABLE_FFE_F0_EXTENDED_DM
|
||||||
|
reg [9:0] CurrentSegment_offset;
|
||||||
|
reg DataMem2ReadAddress_MSB_r1;
|
||||||
|
`endif
|
||||||
|
|
||||||
|
`ifdef ENABLE_FFE_F0_SINGLE_DM
|
||||||
|
reg [31:16] WriteData_latched;
|
||||||
|
reg sig37_latched;
|
||||||
|
`endif
|
||||||
|
|
||||||
|
|
||||||
|
// sync the timestamp to this clock domain
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
always @(posedge Clock_x2In) begin
|
||||||
|
`else
|
||||||
|
always @(posedge ClockIn) begin
|
||||||
|
`endif
|
||||||
|
TimeStamp_r1 <= TimeStampIn;
|
||||||
|
TimeStamp_r2 <= TimeStamp_r1;
|
||||||
|
if (TimeStamp_r1 == TimeStamp_r2)
|
||||||
|
TimeStamp_synced <= TimeStamp_r2;
|
||||||
|
else
|
||||||
|
TimeStamp_synced <= TimeStamp_synced;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
FFE_ALU u_FFE_ALU (
|
||||||
|
.xReadData1 ( Mem1ReadDataToALU[31:0] ),
|
||||||
|
.xReadData2 ( Mem2ReadDataToALU[31:0] ),
|
||||||
|
.signals ( Signals ),
|
||||||
|
.ClockIn ( ClockIn ),
|
||||||
|
.Clock_x2In ( Clock_x2In ),
|
||||||
|
.FFE_clock_halfperiod ( FFE_clock_halfperiod ),
|
||||||
|
.MultClockIn ( MultClockIn ),
|
||||||
|
.MultStateIn ( MultStateIn ),
|
||||||
|
.TimeStampIn ( TimeStamp_synced ),
|
||||||
|
.MailboxIn ( MailboxIn ),
|
||||||
|
.SM_InterruptIn ( SM_InterruptIn ),
|
||||||
|
.xIndexRegister ( xIndexRegister ),
|
||||||
|
.xWriteData ( xWriteData ),
|
||||||
|
.xJumpFlag ( xJumpFlag ),
|
||||||
|
.Save_BG_registers ( Save_BG_registers ),
|
||||||
|
.Restore_BG_registers ( Restore_BG_registers ),
|
||||||
|
|
||||||
|
.mult_in1 ( mult_in1 ),
|
||||||
|
.mult_in2 ( mult_in2 ),
|
||||||
|
.mult_enable ( mult_enable ),
|
||||||
|
.mult_out ( mult_out )
|
||||||
|
);
|
||||||
|
|
||||||
|
decodeMicroOpCode U_decodeMicroOpCode (
|
||||||
|
.MicroOpCode ( MicroOpCode ),
|
||||||
|
.Signals ( Signals )
|
||||||
|
);
|
||||||
|
|
||||||
|
// Fetch Micro OpCode from Control Memory
|
||||||
|
// then needs to be decoded for the various control signals to the ALU (these are called 'signals')
|
||||||
|
assign MicroOpCode = BusyOut_reg ? ControlMemDataIn[8:0] : 9'b0; // xMicroOpCode (hold at zero if FFE is not running because of single port ASSP RAMs
|
||||||
|
|
||||||
|
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
// 4k CM
|
||||||
|
assign xJumpAddress = ControlMemDataIn[20:9];
|
||||||
|
`else
|
||||||
|
// 2k CM
|
||||||
|
assign xJumpAddress = ControlMemDataIn[19:9];
|
||||||
|
`endif
|
||||||
|
|
||||||
|
|
||||||
|
// standard (legacy) control/address signals for the DM's
|
||||||
|
|
||||||
|
assign DataMem1ReadEnable_std = Signals[20];
|
||||||
|
assign DataMem2ReadEnable_std = Signals[21];
|
||||||
|
assign DataMem1WriteEnable_std = Disable_DataMem_WrEn ? 1'b0 : (Signals[22] && BusyOut_reg);
|
||||||
|
assign DataMem2WriteEnable_std = Disable_DataMem_WrEn ? 1'b0 : (Signals[23] && BusyOut_reg);
|
||||||
|
|
||||||
|
assign DataMem1WriteAddressOut_std = Signals[34] ? (ControlMemDataIn[17:9] + xIndexRegister) : ControlMemDataIn[17:9];
|
||||||
|
assign DataMem2WriteAddressOut_std = Signals[34] ? (ControlMemDataIn[17:9] + xIndexRegister) : ControlMemDataIn[17:9];
|
||||||
|
assign DataMem1ReadAddressOut_std = Signals[28] ? (ControlMemDataIn[26:18] + xIndexRegister) : ControlMemDataIn[26:18];
|
||||||
|
assign DataMem2ReadAddressOut_std = Signals[29] ? (ControlMemDataIn[35:27] + xIndexRegister) : ControlMemDataIn[35:27];
|
||||||
|
|
||||||
|
|
||||||
|
// translate DM read/write addresses if an extended-length DM is specified
|
||||||
|
`ifdef ENABLE_FFE_F0_EXTENDED_DM
|
||||||
|
// extended-length DM
|
||||||
|
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
always @(posedge Clock_x2In or posedge ResetIn)
|
||||||
|
if (ResetIn)
|
||||||
|
CurrentSegment_offset <= 0;
|
||||||
|
else
|
||||||
|
if (Signals[44] && FFE_clock_halfperiod) // seg_offset being written
|
||||||
|
CurrentSegment_offset <= ControlMemDataIn[32:23];
|
||||||
|
`else
|
||||||
|
always @(posedge ClockIn or posedge ResetIn)
|
||||||
|
if (ResetIn)
|
||||||
|
CurrentSegment_offset <= 0;
|
||||||
|
else
|
||||||
|
if (Signals[44]) // seg_offset being written
|
||||||
|
CurrentSegment_offset <= ControlMemDataIn[32:23];
|
||||||
|
`endif
|
||||||
|
|
||||||
|
// translate addresses to handle extended data memory(ies)
|
||||||
|
assign DataMem1WriteAddressOut_trans = (DataMem1WriteAddressOut_std < Segment0_offset) ?
|
||||||
|
{1'b0, DataMem1WriteAddressOut_std[8:0]} :
|
||||||
|
({1'b0, DataMem1WriteAddressOut_std} + {1'b0, CurrentSegment_offset});
|
||||||
|
assign DataMem2WriteAddressOut_trans = (DataMem2WriteAddressOut_std < Segment0_offset) ?
|
||||||
|
{1'b0, DataMem2WriteAddressOut_std[8:0]} :
|
||||||
|
({1'b0, DataMem2WriteAddressOut_std} + {1'b0, CurrentSegment_offset});
|
||||||
|
assign DataMem1ReadAddressOut_trans = (DataMem1ReadAddressOut_std < Segment0_offset) ?
|
||||||
|
{1'b0, DataMem1ReadAddressOut_std[8:0]} :
|
||||||
|
({1'b0, DataMem1ReadAddressOut_std} + {1'b0, CurrentSegment_offset});
|
||||||
|
assign DataMem2ReadAddressOut_trans = (DataMem2ReadAddressOut_std < Segment0_offset) ?
|
||||||
|
{1'b0, DataMem2ReadAddressOut_std[8:0]} :
|
||||||
|
({1'b0, DataMem2ReadAddressOut_std} + {1'b0, CurrentSegment_offset});
|
||||||
|
|
||||||
|
`else
|
||||||
|
// standard-length DM (could be single or double)
|
||||||
|
|
||||||
|
assign DataMem1WriteAddressOut_trans = {1'b0, DataMem1WriteAddressOut_std};
|
||||||
|
assign DataMem2WriteAddressOut_trans = {1'b0, DataMem2WriteAddressOut_std};
|
||||||
|
assign DataMem1ReadAddressOut_trans = {1'b0, DataMem1ReadAddressOut_std};
|
||||||
|
assign DataMem2ReadAddressOut_trans = {1'b0, DataMem2ReadAddressOut_std};
|
||||||
|
|
||||||
|
`endif
|
||||||
|
|
||||||
|
|
||||||
|
// mux the DM1/DM2 addresses into a single logical DM1 address if a single-DM design is specified
|
||||||
|
`ifdef ENABLE_FFE_F0_SINGLE_DM
|
||||||
|
// single DM
|
||||||
|
|
||||||
|
// keep track of the half-period (0 or 1) within a single FFE clock, by using the 2x FFE clock.
|
||||||
|
// FFE_clock_halfperiod should be 0 when the 1x clock is low, 1 when the 1x clock is high (it's registered here to help eliminate timing issues).
|
||||||
|
buff buff_clockin_dly1 (.A(ClockIn), .Q(ClockIn_dly1));
|
||||||
|
buff buff_clockin_dly2 (.A(ClockIn_dly1), .Q(ClockIn_dly2));
|
||||||
|
buff buff_clockin_dly3 (.A(ClockIn_dly2), .Q(ClockIn_dly3));
|
||||||
|
//pragma attribute buff_clockin_dly1 dont_touch true
|
||||||
|
//pragma attribute buff_clockin_dly2 dont_touch true
|
||||||
|
//pragma attribute buff_clockin_dly3 dont_touch true
|
||||||
|
assign #3 ClockIn_dly4 = ClockIn_dly3;
|
||||||
|
always @(posedge Clock_x2In or posedge ResetIn)
|
||||||
|
if (ResetIn)
|
||||||
|
FFE_clock_halfperiod <= 0;
|
||||||
|
else
|
||||||
|
FFE_clock_halfperiod <= #1 ClockIn_dly4;
|
||||||
|
/*
|
||||||
|
if (BusyOut_reg)
|
||||||
|
FFE_clock_halfperiod <= !FFE_clock_halfperiod;
|
||||||
|
else
|
||||||
|
FFE_clock_halfperiod <= 0;
|
||||||
|
*/
|
||||||
|
|
||||||
|
always @(posedge Clock_x2In or posedge ResetIn)
|
||||||
|
if (ResetIn) begin
|
||||||
|
DataMem2ReadAddressOut_trans_hold <= 0;
|
||||||
|
DataMem2ReadEnable_std_hold <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (!FFE_clock_halfperiod) begin
|
||||||
|
DataMem2ReadAddressOut_trans_hold <= DataMem2ReadAddressOut_trans;
|
||||||
|
DataMem2ReadEnable_std_hold <= DataMem2ReadEnable_std;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// on half-period 0, drive the DM1 read address and read enable
|
||||||
|
// on half-period 1, drive the DM2 read address and read enable
|
||||||
|
// drive the write address on both half-periods, and the write enable on half-period 0
|
||||||
|
assign DataMem1ReadAddressOut_mux = FFE_clock_halfperiod ? DataMem2ReadAddressOut_trans_hold : DataMem1ReadAddressOut_trans;
|
||||||
|
assign DataMem1ReadEnable_mux = FFE_clock_halfperiod ? DataMem2ReadEnable_std_hold : DataMem1ReadEnable_std;
|
||||||
|
assign DataMem1WriteAddressOut_mux = DataMem1WriteAddressOut_trans; // note: DM1 write address = DM2 write address
|
||||||
|
assign DataMem1WriteEnable_mux = FFE_clock_halfperiod ? 0 : DataMem1WriteEnable_std;
|
||||||
|
|
||||||
|
`else
|
||||||
|
// double DM
|
||||||
|
|
||||||
|
// FFE_clock_halfperiod should never be used in this case. Assign it to 0.
|
||||||
|
always @(*)
|
||||||
|
FFE_clock_halfperiod <= 0;
|
||||||
|
`endif
|
||||||
|
|
||||||
|
|
||||||
|
// split the muxed RAM control signals across both physical memories if an extended-depth DM is specified.
|
||||||
|
// (if an extended-depth DM is specified, it must also be a single DM)
|
||||||
|
`ifdef ENABLE_FFE_F0_EXTENDED_DM
|
||||||
|
// extended-length DM
|
||||||
|
// note that the DM2 "_mux" signals are not defined, since it's assumed that an extended-length DM is also a single-DM
|
||||||
|
|
||||||
|
assign DataMem1ReadAddressOut_split = DataMem1ReadAddressOut_mux;
|
||||||
|
assign DataMem1ReadEnable_split = (DataMem1ReadAddressOut_mux[9] == 1'b0) ? DataMem1ReadEnable_mux : 1'b0;
|
||||||
|
assign DataMem1WriteAddressOut_split = DataMem1WriteAddressOut_mux;
|
||||||
|
// assign DataMem1WriteEnable_split = (DataMem1WriteAddressOut_mux[9] == 1'b0) ? DataMem1WriteEnable_split : 1'b0; // original
|
||||||
|
assign DataMem1WriteEnable_split = (DataMem1WriteAddressOut_mux[9] == 1'b0) ? DataMem1WriteEnable_mux : 1'b0; // Anthony Le 11-01-2014
|
||||||
|
|
||||||
|
assign DataMem2ReadAddressOut_split = DataMem1ReadAddressOut_mux;
|
||||||
|
assign DataMem2ReadEnable_split = (DataMem1ReadAddressOut_mux[9] == 1'b1) ? DataMem1ReadEnable_mux : 1'b0;
|
||||||
|
assign DataMem2WriteAddressOut_split = DataMem1WriteAddressOut_mux;
|
||||||
|
// assign DataMem2WriteEnable_split = (DataMem1WriteAddressOut_mux[9] == 1'b1) ? DataMem1WriteEnable_split : 1'b0; // original
|
||||||
|
assign DataMem2WriteEnable_split = (DataMem1WriteAddressOut_mux[9] == 1'b1) ? DataMem1WriteEnable_mux : 1'b0; // Anthony Le 11-01-2014
|
||||||
|
`endif
|
||||||
|
|
||||||
|
|
||||||
|
// drive the outputs for the DM control/address
|
||||||
|
`ifdef ENABLE_FFE_F0_EXTENDED_DM
|
||||||
|
// extended-length DM (must be single DM as well)
|
||||||
|
|
||||||
|
// must use the translated then muxed then split signals...
|
||||||
|
|
||||||
|
assign DataMem1ReadEnable = DataMem1ReadEnable_split;
|
||||||
|
assign DataMem1WriteEnable = DataMem1WriteEnable_split;
|
||||||
|
assign DataMem1WriteAddressOut = DataMem1WriteAddressOut_split;
|
||||||
|
assign DataMem1ReadAddressOut = DataMem1ReadAddressOut_split;
|
||||||
|
|
||||||
|
assign DataMem2ReadEnable = DataMem2ReadEnable_split;
|
||||||
|
assign DataMem2WriteEnable = DataMem2WriteEnable_split;
|
||||||
|
assign DataMem2WriteAddressOut = DataMem2WriteAddressOut_split;
|
||||||
|
assign DataMem2ReadAddressOut = DataMem2ReadAddressOut_split;
|
||||||
|
|
||||||
|
`else
|
||||||
|
// standard-length DM
|
||||||
|
|
||||||
|
`ifdef ENABLE_FFE_F0_SINGLE_DM
|
||||||
|
// standard-length single DM
|
||||||
|
|
||||||
|
// must use the non-translated then muxed signals
|
||||||
|
// note that physical DM2 is unused, so those outputs are grounded.
|
||||||
|
|
||||||
|
assign DataMem1ReadEnable = DataMem1ReadEnable_mux;
|
||||||
|
assign DataMem1WriteEnable = DataMem1WriteEnable_mux;
|
||||||
|
assign DataMem1WriteAddressOut = DataMem1WriteAddressOut_mux;
|
||||||
|
assign DataMem1ReadAddressOut = DataMem1ReadAddressOut_mux;
|
||||||
|
|
||||||
|
assign DataMem2ReadEnable = 0;
|
||||||
|
assign DataMem2WriteEnable = 0;
|
||||||
|
assign DataMem2WriteAddressOut = 0;
|
||||||
|
assign DataMem2ReadAddressOut = 0;
|
||||||
|
|
||||||
|
`else
|
||||||
|
// standard-length double DM (legacy)
|
||||||
|
|
||||||
|
// use the standard signals
|
||||||
|
|
||||||
|
assign DataMem1WriteAddressOut = {1'b0, DataMem1WriteAddressOut_std};
|
||||||
|
assign DataMem2WriteAddressOut = {1'b0, DataMem2WriteAddressOut_std};
|
||||||
|
assign DataMem1ReadAddressOut = {1'b0, DataMem1ReadAddressOut_std};
|
||||||
|
assign DataMem2ReadAddressOut = {1'b0, DataMem2ReadAddressOut_std};
|
||||||
|
|
||||||
|
assign DataMem1ReadEnable = DataMem1ReadEnable_std;
|
||||||
|
assign DataMem2ReadEnable = DataMem2ReadEnable_std;
|
||||||
|
assign DataMem1WriteEnable = DataMem1WriteEnable_std;
|
||||||
|
assign DataMem2WriteEnable = DataMem2WriteEnable_std;
|
||||||
|
|
||||||
|
`endif
|
||||||
|
|
||||||
|
`endif
|
||||||
|
|
||||||
|
|
||||||
|
`ifdef ENABLE_FFE_F0_SINGLE_DM
|
||||||
|
// single DM, extended or standard length
|
||||||
|
|
||||||
|
// hold the write data so it can be written to the CM FIFO or SM Mem correctly, when a single DM is used
|
||||||
|
always @(posedge Clock_x2In or posedge ResetIn)
|
||||||
|
if (ResetIn) begin
|
||||||
|
WriteData_latched <= 0;
|
||||||
|
sig37_latched <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (!FFE_clock_halfperiod) begin
|
||||||
|
sig37_latched <= Signals[37];
|
||||||
|
//if (!FFE_clock_halfperiod && (CMWriteEnableOut || SensorMemWriteEnableOut || Signals[36]))
|
||||||
|
if (Signals[30] || Signals[40] || Signals[36]) // CM write or SM write or Interrupt msg write
|
||||||
|
WriteData_latched <= xWriteData[31:16];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
//assign CMWriteDataOut = {1'b0, WriteData_latched[31:24], Signals[37], WriteData_latched[23:16]};
|
||||||
|
assign CMWriteDataOut = {1'b0, WriteData_latched[31:24], sig37_latched, WriteData_latched[23:16]};
|
||||||
|
assign SensorMemWriteDataOut = WriteData_latched[24:16];
|
||||||
|
|
||||||
|
`else
|
||||||
|
// double DM (legacy)
|
||||||
|
|
||||||
|
assign CMWriteDataOut = {1'b0, xWriteData[31:24], Signals[37], xWriteData[23:16]};
|
||||||
|
assign SensorMemWriteDataOut = xWriteData[24:16];
|
||||||
|
`endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
// 4k CM
|
||||||
|
|
||||||
|
// this is done to make sure that all of these signals are stable when the 1x clock occurs.
|
||||||
|
always @(posedge Clock_x2In or posedge ResetIn)
|
||||||
|
if (ResetIn) begin
|
||||||
|
SensorMemReadEnable_reg <= 0;
|
||||||
|
SensorMemWriteEnable_reg <= 0;
|
||||||
|
SensorMemReadAddress_reg <= 0;
|
||||||
|
SensorMemWriteAddress_reg <= 0;
|
||||||
|
CMWriteEnable_reg <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (!FFE_clock_halfperiod ) begin
|
||||||
|
SensorMemReadEnable_reg <= DataMem1ReadEnable_std;
|
||||||
|
SensorMemWriteEnable_reg <= Disable_DataMem_WrEn ? 1'b0 : (Signals[40] && BusyOut_reg);
|
||||||
|
SensorMemReadAddress_reg <= Signals[28] ? (ControlMemDataIn[27:18] + xIndexRegister) : ControlMemDataIn[27:18];
|
||||||
|
SensorMemWriteAddress_reg <= Signals[34] ? (ControlMemDataIn[18:9] + xIndexRegister) : ControlMemDataIn[18:9];
|
||||||
|
CMWriteEnable_reg <= Disable_DataMem_WrEn ? 1'b0 : (Signals[30] && BusyOut_reg); // Write enable to CM FIFO
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign SensorMemReadEnableOut = SensorMemReadEnable_reg;
|
||||||
|
assign SensorMemWriteEnableOut = SensorMemWriteEnable_reg;
|
||||||
|
assign SensorMemReadAddressOut = SensorMemReadAddress_reg;
|
||||||
|
assign SensorMemWriteAddressOut = SensorMemWriteAddress_reg;
|
||||||
|
assign CMWriteEnableOut = CMWriteEnable_reg;
|
||||||
|
|
||||||
|
`else
|
||||||
|
// 2k CM
|
||||||
|
|
||||||
|
assign SensorMemReadEnableOut = DataMem1ReadEnable_std;
|
||||||
|
assign SensorMemWriteEnableOut = Disable_DataMem_WrEn ? 1'b0 : (Signals[40] && BusyOut_reg);
|
||||||
|
assign SensorMemReadAddressOut = (Signals[28] ? (ControlMemDataIn[27:18] + xIndexRegister) : ControlMemDataIn[27:18]);
|
||||||
|
assign SensorMemWriteAddressOut = Signals[34] ? (ControlMemDataIn[18:9] + xIndexRegister) : ControlMemDataIn[18:9];
|
||||||
|
|
||||||
|
assign CMWriteEnableOut = Disable_DataMem_WrEn ? 1'b0 : (Signals[30] && BusyOut_reg); // Write enable to CM FIFO
|
||||||
|
`endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
// 4k CM
|
||||||
|
assign ControlMemAddressOut = xPC;
|
||||||
|
`else
|
||||||
|
// 2k CM
|
||||||
|
assign ControlMemAddressOut = {1'b0, xPC};
|
||||||
|
`endif
|
||||||
|
|
||||||
|
assign DataMem1WriteDataOut = {4'b0000,xWriteData};
|
||||||
|
assign DataMem2WriteDataOut = {4'b0000,xWriteData};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// latch the read data from the DM(s)
|
||||||
|
`ifdef ENABLE_FFE_F0_SINGLE_DM
|
||||||
|
`ifdef ENABLE_FFE_F0_EXTENDED_DM
|
||||||
|
// extended-length single-DM
|
||||||
|
|
||||||
|
always @(posedge Clock_x2In or posedge ResetIn)
|
||||||
|
if (ResetIn)
|
||||||
|
DataMem1ReadAddressOut_trans_MSB_r1 <= 0;
|
||||||
|
else
|
||||||
|
if (!FFE_clock_halfperiod)
|
||||||
|
DataMem1ReadAddressOut_trans_MSB_r1 <= DataMem1ReadAddressOut_trans[9];
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge Clock_x2In or posedge ResetIn)
|
||||||
|
if (ResetIn)
|
||||||
|
Mem1ReadData_latched <= 0;
|
||||||
|
else
|
||||||
|
if (FFE_clock_halfperiod)
|
||||||
|
Mem1ReadData_latched <= DataMem1ReadAddressOut_trans_MSB_r1 ? Mem2ReadData : Mem1ReadData; // read from the correct physical DM
|
||||||
|
|
||||||
|
// store the (logical) DM2 read address' MSB, so it can be used on the following clock to select the correct physical DM
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
always @(posedge Clock_x2In or posedge ResetIn)
|
||||||
|
if (ResetIn)
|
||||||
|
DataMem2ReadAddress_MSB_r1 <= 0;
|
||||||
|
else
|
||||||
|
if (FFE_clock_halfperiod)
|
||||||
|
DataMem2ReadAddress_MSB_r1 <= DataMem2ReadAddressOut_trans[9];
|
||||||
|
`else
|
||||||
|
always @(posedge ClockIn or posedge ResetIn)
|
||||||
|
if (ResetIn)
|
||||||
|
DataMem2ReadAddress_MSB_r1 <= 0;
|
||||||
|
else
|
||||||
|
DataMem2ReadAddress_MSB_r1 <= DataMem2ReadAddressOut_trans[9];
|
||||||
|
`endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
always @(*)
|
||||||
|
Mem2ReadData_latched <= DataMem2ReadAddress_MSB_r1 ? Mem2ReadData : Mem1ReadData; // read from the correct physical DM
|
||||||
|
// note that Mem2ReadData_latched will only be valid on the first half-period
|
||||||
|
// note that ReadData2 can be registered as well, to make FFE clock-to-clock timing easier (at the cost of more FFs).
|
||||||
|
|
||||||
|
`else
|
||||||
|
// standard-length single-DM, latch & hold at the appropriate half-periods
|
||||||
|
always @(posedge Clock_x2In or posedge ResetIn)
|
||||||
|
if (ResetIn)
|
||||||
|
Mem1ReadData_latched <= 0;
|
||||||
|
else
|
||||||
|
if (FFE_clock_halfperiod)
|
||||||
|
Mem1ReadData_latched <= Mem1ReadData;
|
||||||
|
else
|
||||||
|
Mem1ReadData_latched <= Mem1ReadData_latched;
|
||||||
|
|
||||||
|
always @(*)
|
||||||
|
Mem2ReadData_latched <= Mem1ReadData;
|
||||||
|
// note that ReadData2 can be registered as well, to make FFE clock-to-clock timing easier (at the cost of more FFs).
|
||||||
|
`endif
|
||||||
|
|
||||||
|
`else
|
||||||
|
// standard-length double-DM, pass-thru
|
||||||
|
always @(*) begin
|
||||||
|
Mem1ReadData_latched <= Mem1ReadData;
|
||||||
|
Mem2ReadData_latched <= Mem2ReadData;
|
||||||
|
end
|
||||||
|
`endif
|
||||||
|
|
||||||
|
|
||||||
|
assign Mem1ReadDataX = Mem1ReadData_latched[31:0];
|
||||||
|
//a mux that switches between data read from FFEDM2 or SMSM
|
||||||
|
assign Mem2ReadDataX = Signals[27] ? {SensorMemReadDataIn[16:9], SensorMemReadDataIn[7:0], 16'b0} : Mem2ReadData_latched[31:0];
|
||||||
|
|
||||||
|
|
||||||
|
assign Mem1ReadDataToALU = Mem1ReadDataX;
|
||||||
|
assign Mem2ReadDataToALU = Mem2ReadDataX;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// toggle StartSM each time Signals[31] is active
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
always @(posedge Clock_x2In or posedge ResetIn)
|
||||||
|
if (ResetIn)
|
||||||
|
StartSM_reg <= 0;
|
||||||
|
else
|
||||||
|
if (FFE_clock_halfperiod && Signals[31])
|
||||||
|
StartSM_reg <= !StartSM_reg;
|
||||||
|
else
|
||||||
|
StartSM_reg <= StartSM_reg;
|
||||||
|
|
||||||
|
`else
|
||||||
|
always @(posedge ClockIn or posedge ResetIn)
|
||||||
|
if (ResetIn)
|
||||||
|
StartSM_reg <= 0;
|
||||||
|
else
|
||||||
|
if (Signals[31])
|
||||||
|
StartSM_reg <= !StartSM_reg;
|
||||||
|
else
|
||||||
|
StartSM_reg <= StartSM_reg;
|
||||||
|
|
||||||
|
`endif
|
||||||
|
|
||||||
|
assign StartSMOut = StartSM_reg;
|
||||||
|
|
||||||
|
|
||||||
|
// de-glitch the interrupt msg signal since it comes out of the decoder and data mem
|
||||||
|
`ifdef ENABLE_FFE_F0_SINGLE_DM
|
||||||
|
// single DM
|
||||||
|
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
// 4k CM
|
||||||
|
always @(posedge Clock_x2In)
|
||||||
|
InterruptMsg_reg <= (FFE_clock_halfperiod && Signals[36]) ? WriteData_latched[23:16] : 8'b0;
|
||||||
|
`else
|
||||||
|
// 2k CM
|
||||||
|
always @(posedge ClockIn)
|
||||||
|
InterruptMsg_reg <= Signals[36] ? WriteData_latched[23:16] : 8'b0;
|
||||||
|
`endif
|
||||||
|
|
||||||
|
`else
|
||||||
|
// double DM, legacy behavior
|
||||||
|
always @(posedge ClockIn)
|
||||||
|
InterruptMsg_reg <= Signals[36] ? xWriteData[23:16] : 8'b0;
|
||||||
|
`endif
|
||||||
|
|
||||||
|
assign InterruptMsgOut = InterruptMsg_reg;
|
||||||
|
|
||||||
|
|
||||||
|
// sync to local clock
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
always @(posedge Clock_x2In) begin
|
||||||
|
`else
|
||||||
|
always @(posedge ClockIn) begin
|
||||||
|
`endif
|
||||||
|
Start_r1 <= StartIn;
|
||||||
|
Start_r2 <= Start_r1;
|
||||||
|
Start_r3 <= Start_r2;
|
||||||
|
end
|
||||||
|
|
||||||
|
assign Start_detected = (Start_r1 != Start_r2) || (Start_r2 != Start_r3);
|
||||||
|
|
||||||
|
|
||||||
|
// Program Counter to step through the Control Memory
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
always @(posedge Clock_x2In or posedge ResetIn) begin
|
||||||
|
`else
|
||||||
|
always @(posedge ClockIn or posedge ResetIn) begin
|
||||||
|
`endif
|
||||||
|
|
||||||
|
if (ResetIn) begin
|
||||||
|
xPC <= 0;
|
||||||
|
BusyOut_reg <= 1'b0;
|
||||||
|
BusyOut_r1 <= 1'b0;
|
||||||
|
ControlMemReadEnableOut <= 1'b0;
|
||||||
|
SMOverrunOut <= 1'b0;
|
||||||
|
end else
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
if (FFE_clock_halfperiod)
|
||||||
|
`endif
|
||||||
|
begin
|
||||||
|
BusyOut_r1 <= BusyOut_reg;
|
||||||
|
if (BusyOut_reg && BusyOut_r1) begin // make sure the 1st control word appears on the RAM outputs... requires one clock cycle after the read enable is turned on.
|
||||||
|
if (!Signals[32]) begin // !Signals[32] = continue running = !STOP
|
||||||
|
if (Restore_BG_registers)
|
||||||
|
xPC <= PC_BG;
|
||||||
|
else
|
||||||
|
if (Clear_PC)
|
||||||
|
xPC <= 0;
|
||||||
|
else
|
||||||
|
// hold the PC while switching threads
|
||||||
|
if (BG_active &&
|
||||||
|
((Start_detected || BGsave_pending) ||
|
||||||
|
(BGcontinue_pending && (Thread_switch_cnt != THREAD_SWITCH_CNT_DONE))))
|
||||||
|
xPC <= xPC;
|
||||||
|
else
|
||||||
|
if (xJumpFlag)
|
||||||
|
xPC <= xJumpAddress;
|
||||||
|
else
|
||||||
|
xPC <= xPC + 1;
|
||||||
|
end else begin // Signals[32] = STOP
|
||||||
|
xPC <= 0;
|
||||||
|
if (!BG_active) begin // FG mode
|
||||||
|
BusyOut_reg <= 1'b0;
|
||||||
|
ControlMemReadEnableOut <= 1'b0;
|
||||||
|
end else begin // BG mode
|
||||||
|
ControlMemReadEnableOut <= 1'b1;
|
||||||
|
if (BGstop_pending && (Thread_switch_cnt == THREAD_SWITCH_CNT_DONE) && !Start_pending && !Start_detected)
|
||||||
|
BusyOut_reg <= 1'b0;
|
||||||
|
else
|
||||||
|
BusyOut_reg <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end else // new start condition not detected, keep running
|
||||||
|
if (Start_detected) begin
|
||||||
|
if (SMBusyIn) begin
|
||||||
|
SMOverrunOut <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
BusyOut_reg <= 1'b1;
|
||||||
|
ControlMemReadEnableOut <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign BusyOut = BusyOut_reg;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --- BG thread support
|
||||||
|
|
||||||
|
// Signals[42] = SetBGflag (instruction modifier)
|
||||||
|
// Signals[43] = BGcontinue (instruction)
|
||||||
|
|
||||||
|
|
||||||
|
// Start_pending, flag to latch the start event, in case it happens right as we're switching to the BG thread or while running the BG thread.
|
||||||
|
// This needs to be latched so the FG thread can be started immediately once we've switched out of the BG thread.
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
always @(posedge Clock_x2In or posedge ResetIn)
|
||||||
|
`else
|
||||||
|
always @(posedge ClockIn or posedge ResetIn)
|
||||||
|
`endif
|
||||||
|
if (ResetIn)
|
||||||
|
Start_pending <= 0;
|
||||||
|
else
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
if (FFE_clock_halfperiod)
|
||||||
|
`endif
|
||||||
|
case (Start_pending)
|
||||||
|
1'b0: if (Start_detected && // start detected AND...
|
||||||
|
(Signals[42] || // ...SetBGflag active (about to start or continue BG)...OR...
|
||||||
|
BG_active)) // ...BG active (switching to BG, running BG, about to stop/end BG, stopping BG)
|
||||||
|
Start_pending <= 1;
|
||||||
|
1'b1: if (!BG_active) // clear this flag when BG_active goes away
|
||||||
|
Start_pending <= 0;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
|
||||||
|
// BG_pending counter, used instead of individual state machines for each type of context switch
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
always @(posedge Clock_x2In or posedge ResetIn)
|
||||||
|
`else
|
||||||
|
always @(posedge ClockIn or posedge ResetIn)
|
||||||
|
`endif
|
||||||
|
if (ResetIn)
|
||||||
|
Thread_switch_cnt <= 0;
|
||||||
|
else
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
if (FFE_clock_halfperiod)
|
||||||
|
`endif
|
||||||
|
if (BGsave_pending || BGcontinue_pending || BGstop_pending)
|
||||||
|
if (Thread_switch_cnt == THREAD_SWITCH_CNT_DONE)
|
||||||
|
Thread_switch_cnt <= 0;
|
||||||
|
else
|
||||||
|
Thread_switch_cnt <= Thread_switch_cnt + 1;
|
||||||
|
else
|
||||||
|
Thread_switch_cnt <= 0;
|
||||||
|
|
||||||
|
|
||||||
|
// BGcontinue_pending, flag that goes active while resuming the BG thread (BGcontinue instruction)
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
always @(posedge Clock_x2In or posedge ResetIn)
|
||||||
|
`else
|
||||||
|
always @(posedge ClockIn or posedge ResetIn)
|
||||||
|
`endif
|
||||||
|
if (ResetIn)
|
||||||
|
BGcontinue_pending <= 0;
|
||||||
|
else
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
if (FFE_clock_halfperiod)
|
||||||
|
`endif
|
||||||
|
case (BGcontinue_pending)
|
||||||
|
1'b0: if (Signals[43])
|
||||||
|
BGcontinue_pending <= 1;
|
||||||
|
1'b1: if (Thread_switch_cnt == THREAD_SWITCH_CNT_DONE)
|
||||||
|
BGcontinue_pending <= 0;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
|
||||||
|
// BGsave_pending, flag that goes active while saving the state of the BG thread (BG_continue or BG thread interrupted by the sample timer)
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
always @(posedge Clock_x2In or posedge ResetIn)
|
||||||
|
`else
|
||||||
|
always @(posedge ClockIn or posedge ResetIn)
|
||||||
|
`endif
|
||||||
|
if (ResetIn)
|
||||||
|
BGsave_pending <= 0;
|
||||||
|
else
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
if (FFE_clock_halfperiod)
|
||||||
|
`endif
|
||||||
|
case (BGsave_pending)
|
||||||
|
1'b0: if (BG_active && // in the BG thread...AND...
|
||||||
|
(Start_detected || // ...started detected...OR...
|
||||||
|
(BGcontinue_pending && (Thread_switch_cnt == THREAD_SWITCH_CNT_DONE) && Start_pending))) // ...about to complete BGcontinue AND start was detected
|
||||||
|
BGsave_pending <= 1;
|
||||||
|
1'b1: if (Thread_switch_cnt == THREAD_SWITCH_CNT_DONE)
|
||||||
|
BGsave_pending <= 0;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
|
||||||
|
// BGstop_pending, flag that goes active while stopping the BG thread (normal completion)
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
always @(posedge Clock_x2In or posedge ResetIn)
|
||||||
|
`else
|
||||||
|
always @(posedge ClockIn or posedge ResetIn)
|
||||||
|
`endif
|
||||||
|
if (ResetIn)
|
||||||
|
BGstop_pending <= 0;
|
||||||
|
else
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
if (FFE_clock_halfperiod)
|
||||||
|
`endif
|
||||||
|
case (BGstop_pending)
|
||||||
|
1'b0: if (BG_active && Signals[32])
|
||||||
|
BGstop_pending <= 1;
|
||||||
|
1'b1: if (Thread_switch_cnt == THREAD_SWITCH_CNT_DONE)
|
||||||
|
BGstop_pending <= 0;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// BG_active, flag that is active while switching to, in, or switching from, the BG thread
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
always @(posedge Clock_x2In or posedge ResetIn)
|
||||||
|
`else
|
||||||
|
always @(posedge ClockIn or posedge ResetIn)
|
||||||
|
`endif
|
||||||
|
if (ResetIn)
|
||||||
|
BG_active <= 0;
|
||||||
|
else
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
if (FFE_clock_halfperiod)
|
||||||
|
`endif
|
||||||
|
case (BG_active)
|
||||||
|
1'b0: if (Signals[42]) // SetBGactive (entering BG mode, either via start BG or continue BG)
|
||||||
|
BG_active <= 1;
|
||||||
|
1'b1: if ((BGsave_pending || BGstop_pending) && (Thread_switch_cnt == THREAD_SWITCH_CNT_DONE)) // done switching out of BG mode
|
||||||
|
BG_active <= 0;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
|
||||||
|
// Control signal used to save the BG copy of the PC and ALU flags
|
||||||
|
assign Save_BG_registers = (BGsave_pending && (Thread_switch_cnt == 1));
|
||||||
|
// clock-by-clock sequence of events:
|
||||||
|
// {BGsave_pending,Thread_switch_cnt}
|
||||||
|
// 0,0 - Start detected, last BG instruction, hold PC
|
||||||
|
// 1,0 - hold PC, disable DataMemWrEn
|
||||||
|
// 1,1 - hold PC, save PC & flags (Save_BG_registers active), disable DataMemWrEn
|
||||||
|
// 1,2 - clear PC, disable DataMemWrEn
|
||||||
|
// 1,3 - hold PC (driving into CodeMem), disable DataMemWrEn
|
||||||
|
// 1,4 - hold PC (CodeMem available, driving DataMem), disable DataMemWrEn
|
||||||
|
// 1,5 - hold PC (DataMem available), disable DataMemWrEn
|
||||||
|
// 1,6 - hold PC (extraneous), disable DataMemWrEn
|
||||||
|
// 1,7 - hold PC (extraneous), disable DataMemWrEn
|
||||||
|
// 0,0 - continue running normally (now in FG thread)
|
||||||
|
|
||||||
|
// Control signal used to restore the BG state of the PC and ALU flags
|
||||||
|
assign Restore_BG_registers = (BGcontinue_pending && (Thread_switch_cnt == 1));
|
||||||
|
// clock-by-clock sequence of events:
|
||||||
|
// {BGcontinue_pending,Thread_switch_cnt} - action(s)
|
||||||
|
// 0,0 - BGcontinue();
|
||||||
|
// 1,0 - NOP;, disable DataMemWrEn
|
||||||
|
// 1,1 - load PC & flags (Restore_BG_registers active), disable DataMemWrEn
|
||||||
|
// 1,2 - hold PC (driving into CodeMem), disable DataMemWrEn
|
||||||
|
// 1,3 - hold PC (CodeMem available, driving DataMem), disable DataMemWrEn
|
||||||
|
// 1,4 - hold PC (DataMem available), disable DataMemWrEn
|
||||||
|
// 1,5 - hold PC (extraneous), disable DataMemWrEn
|
||||||
|
// 1,6 - hold PC (extraneous), disable DataMemWrEn
|
||||||
|
// 1,7 - increment PC, disable DataMemWrEn
|
||||||
|
// 0,0 - continue running normally (now in BG thread)
|
||||||
|
|
||||||
|
|
||||||
|
// Control signal used to reset the PC (during BGstop or BGsave)
|
||||||
|
assign Clear_PC = ((BGsave_pending && (Thread_switch_cnt == 2)) || (BGstop_pending));
|
||||||
|
|
||||||
|
// Control signal used to disable the FFE DataMem write enable, while resuming the BG thread
|
||||||
|
assign Disable_DataMem_WrEn = (BGcontinue_pending);
|
||||||
|
|
||||||
|
|
||||||
|
// BG copy of the PC
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
always @(posedge Clock_x2In or posedge ResetIn)
|
||||||
|
`else
|
||||||
|
always @(posedge ClockIn or posedge ResetIn)
|
||||||
|
`endif
|
||||||
|
if (ResetIn)
|
||||||
|
PC_BG <= 0;
|
||||||
|
else
|
||||||
|
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||||
|
if (FFE_clock_halfperiod)
|
||||||
|
`endif
|
||||||
|
if (Save_BG_registers)
|
||||||
|
PC_BG <= xPC;
|
||||||
|
else
|
||||||
|
PC_BG <= PC_BG;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// test points
|
||||||
|
assign TP1 = 0;
|
||||||
|
assign TP2 = 0;
|
||||||
|
assign TP3 = 0;
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
`timescale 1ns / 10ps
|
||||||
|
// algorithm file = 'ulpsh_s2_main_JB4_BMI160_AK09911_PD.alg'
|
||||||
|
// UlpshType = S2_1KDM
|
||||||
|
|
||||||
|
module decodeMicroOpCode (MicroOpCode, Signals);
|
||||||
|
|
||||||
|
input [8:0] MicroOpCode;
|
||||||
|
output [45:0] Signals;
|
||||||
|
wire [45:0] Signals;
|
||||||
|
|
||||||
|
assign Signals[0] = (MicroOpCode == 9'h00e) || 0;
|
||||||
|
assign Signals[1] = (MicroOpCode == 9'h012) || (MicroOpCode == 9'h013) || 0;
|
||||||
|
assign Signals[2] = 0;
|
||||||
|
assign Signals[3] = 0;
|
||||||
|
assign Signals[4] = (MicroOpCode == 9'h038) || 0;
|
||||||
|
assign Signals[5] = (MicroOpCode == 9'h016) || (MicroOpCode == 9'h017) || (MicroOpCode == 9'h021) || (MicroOpCode == 9'h034) || (MicroOpCode == 9'h035) || (MicroOpCode == 9'h036) || (MicroOpCode == 9'h038) || (MicroOpCode == 9'h040) || (MicroOpCode == 9'h041) || (MicroOpCode == 9'h042) || (MicroOpCode == 9'h045) || (MicroOpCode == 9'h04a) || (MicroOpCode == 9'h04e) || (MicroOpCode == 9'h04f) || 0;
|
||||||
|
assign Signals[6] = (MicroOpCode == 9'h00a) || (MicroOpCode == 9'h014) || (MicroOpCode == 9'h020) || (MicroOpCode == 9'h024) || (MicroOpCode == 9'h026) || (MicroOpCode == 9'h027) || (MicroOpCode == 9'h028) || (MicroOpCode == 9'h02d) || (MicroOpCode == 9'h033) || (MicroOpCode == 9'h037) || (MicroOpCode == 9'h038) || (MicroOpCode == 9'h039) || (MicroOpCode == 9'h03e) || (MicroOpCode == 9'h03f) || (MicroOpCode == 9'h044) || (MicroOpCode == 9'h047) || (MicroOpCode == 9'h049) || (MicroOpCode == 9'h04b) || (MicroOpCode == 9'h04c) || (MicroOpCode == 9'h050) || 0;
|
||||||
|
assign Signals[7] = (MicroOpCode == 9'h00a) || (MicroOpCode == 9'h014) || (MicroOpCode == 9'h020) || (MicroOpCode == 9'h024) || (MicroOpCode == 9'h026) || (MicroOpCode == 9'h027) || (MicroOpCode == 9'h028) || (MicroOpCode == 9'h02d) || (MicroOpCode == 9'h033) || (MicroOpCode == 9'h035) || (MicroOpCode == 9'h036) || (MicroOpCode == 9'h037) || (MicroOpCode == 9'h038) || (MicroOpCode == 9'h039) || (MicroOpCode == 9'h03e) || (MicroOpCode == 9'h03f) || (MicroOpCode == 9'h044) || (MicroOpCode == 9'h049) || (MicroOpCode == 9'h04a) || (MicroOpCode == 9'h050) || 0;
|
||||||
|
assign Signals[8] = (MicroOpCode == 9'h00a) || (MicroOpCode == 9'h024) || (MicroOpCode == 9'h026) || (MicroOpCode == 9'h033) || (MicroOpCode == 9'h037) || (MicroOpCode == 9'h038) || (MicroOpCode == 9'h03b) || (MicroOpCode == 9'h03f) || (MicroOpCode == 9'h043) || (MicroOpCode == 9'h047) || (MicroOpCode == 9'h049) || (MicroOpCode == 9'h04a) || (MicroOpCode == 9'h04b) || (MicroOpCode == 9'h04c) || 0;
|
||||||
|
assign Signals[9] = (MicroOpCode == 9'h027) || (MicroOpCode == 9'h028) || (MicroOpCode == 9'h039) || (MicroOpCode == 9'h03b) || (MicroOpCode == 9'h03e) || (MicroOpCode == 9'h043) || (MicroOpCode == 9'h044) || (MicroOpCode == 9'h047) || (MicroOpCode == 9'h04b) || (MicroOpCode == 9'h04c) || 0;
|
||||||
|
assign Signals[10] = (MicroOpCode == 9'h007) || (MicroOpCode == 9'h008) || (MicroOpCode == 9'h009) || (MicroOpCode == 9'h00a) || (MicroOpCode == 9'h00d) || (MicroOpCode == 9'h00e) || (MicroOpCode == 9'h010) || (MicroOpCode == 9'h012) || (MicroOpCode == 9'h013) || (MicroOpCode == 9'h014) || (MicroOpCode == 9'h020) || (MicroOpCode == 9'h022) || (MicroOpCode == 9'h024) || (MicroOpCode == 9'h025) || (MicroOpCode == 9'h026) || (MicroOpCode == 9'h036) || (MicroOpCode == 9'h038) || (MicroOpCode == 9'h03a) || (MicroOpCode == 9'h03c) || (MicroOpCode == 9'h03d) || (MicroOpCode == 9'h03f) || (MicroOpCode == 9'h040) || (MicroOpCode == 9'h041) || (MicroOpCode == 9'h042) || (MicroOpCode == 9'h046) || (MicroOpCode == 9'h047) || (MicroOpCode == 9'h049) || (MicroOpCode == 9'h04a) || (MicroOpCode == 9'h04e) || (MicroOpCode == 9'h04f) || (MicroOpCode == 9'h050) || 0;
|
||||||
|
assign Signals[11] = (MicroOpCode == 9'h037) || (MicroOpCode == 9'h049) || 0;
|
||||||
|
assign Signals[12] = (MicroOpCode == 9'h03b) || (MicroOpCode == 9'h043) || (MicroOpCode == 9'h047) || (MicroOpCode == 9'h04b) || (MicroOpCode == 9'h04c) || 0;
|
||||||
|
assign Signals[13] = (MicroOpCode == 9'h027) || (MicroOpCode == 9'h028) || (MicroOpCode == 9'h039) || (MicroOpCode == 9'h03b) || (MicroOpCode == 9'h03e) || (MicroOpCode == 9'h043) || (MicroOpCode == 9'h044) || (MicroOpCode == 9'h047) || (MicroOpCode == 9'h04b) || (MicroOpCode == 9'h04c) || 0;
|
||||||
|
assign Signals[14] = 0;
|
||||||
|
assign Signals[15] = (MicroOpCode == 9'h038) || (MicroOpCode == 9'h039) || (MicroOpCode == 9'h04a) || 0;
|
||||||
|
assign Signals[16] = (MicroOpCode == 9'h034) || (MicroOpCode == 9'h035) || (MicroOpCode == 9'h048) || 0;
|
||||||
|
assign Signals[17] = (MicroOpCode == 9'h00f) || (MicroOpCode == 9'h011) || (MicroOpCode == 9'h015) || (MicroOpCode == 9'h01c) || (MicroOpCode == 9'h029) || 0;
|
||||||
|
assign Signals[18] = (MicroOpCode == 9'h00b) || (MicroOpCode == 9'h00f) || (MicroOpCode == 9'h01f) || (MicroOpCode == 9'h029) || 0;
|
||||||
|
assign Signals[19] = (MicroOpCode == 9'h015) || (MicroOpCode == 9'h01f) || (MicroOpCode == 9'h029) || (MicroOpCode == 9'h031) || 0;
|
||||||
|
assign Signals[20] = (MicroOpCode == 9'h001) || (MicroOpCode == 9'h002) || (MicroOpCode == 9'h009) || (MicroOpCode == 9'h00c) || (MicroOpCode == 9'h016) || (MicroOpCode == 9'h020) || (MicroOpCode == 9'h025) || (MicroOpCode == 9'h026) || (MicroOpCode == 9'h02c) || (MicroOpCode == 9'h02d) || (MicroOpCode == 9'h032) || (MicroOpCode == 9'h033) || (MicroOpCode == 9'h034) || (MicroOpCode == 9'h035) || (MicroOpCode == 9'h037) || (MicroOpCode == 9'h038) || (MicroOpCode == 9'h03c) || (MicroOpCode == 9'h03f) || (MicroOpCode == 9'h042) || (MicroOpCode == 9'h043) || (MicroOpCode == 9'h044) || (MicroOpCode == 9'h047) || (MicroOpCode == 9'h048) || (MicroOpCode == 9'h049) || (MicroOpCode == 9'h04a) || (MicroOpCode == 9'h04b) || (MicroOpCode == 9'h04d) || (MicroOpCode == 9'h04f) || 0;
|
||||||
|
assign Signals[21] = (MicroOpCode == 9'h004) || (MicroOpCode == 9'h008) || (MicroOpCode == 9'h009) || (MicroOpCode == 9'h00c) || (MicroOpCode == 9'h010) || (MicroOpCode == 9'h013) || (MicroOpCode == 9'h016) || (MicroOpCode == 9'h019) || (MicroOpCode == 9'h01b) || (MicroOpCode == 9'h020) || (MicroOpCode == 9'h023) || (MicroOpCode == 9'h026) || (MicroOpCode == 9'h028) || (MicroOpCode == 9'h02a) || (MicroOpCode == 9'h02c) || (MicroOpCode == 9'h02d) || (MicroOpCode == 9'h02e) || (MicroOpCode == 9'h030) || (MicroOpCode == 9'h032) || (MicroOpCode == 9'h033) || (MicroOpCode == 9'h034) || (MicroOpCode == 9'h035) || (MicroOpCode == 9'h037) || (MicroOpCode == 9'h038) || (MicroOpCode == 9'h03a) || (MicroOpCode == 9'h03c) || (MicroOpCode == 9'h03d) || (MicroOpCode == 9'h03f) || (MicroOpCode == 9'h041) || (MicroOpCode == 9'h042) || (MicroOpCode == 9'h043) || (MicroOpCode == 9'h044) || (MicroOpCode == 9'h045) || (MicroOpCode == 9'h047) || (MicroOpCode == 9'h048) || (MicroOpCode == 9'h049) || (MicroOpCode == 9'h04a) || (MicroOpCode == 9'h04b) || (MicroOpCode == 9'h04d) || (MicroOpCode == 9'h04f) || (MicroOpCode == 9'h050) || 0;
|
||||||
|
assign Signals[22] = (MicroOpCode == 9'h002) || (MicroOpCode == 9'h003) || (MicroOpCode == 9'h007) || (MicroOpCode == 9'h008) || (MicroOpCode == 9'h009) || (MicroOpCode == 9'h00d) || (MicroOpCode == 9'h00e) || (MicroOpCode == 9'h010) || (MicroOpCode == 9'h012) || (MicroOpCode == 9'h013) || (MicroOpCode == 9'h014) || (MicroOpCode == 9'h016) || (MicroOpCode == 9'h017) || (MicroOpCode == 9'h020) || (MicroOpCode == 9'h022) || (MicroOpCode == 9'h024) || (MicroOpCode == 9'h025) || (MicroOpCode == 9'h027) || (MicroOpCode == 9'h028) || (MicroOpCode == 9'h02a) || (MicroOpCode == 9'h02b) || (MicroOpCode == 9'h02c) || (MicroOpCode == 9'h02d) || (MicroOpCode == 9'h02e) || (MicroOpCode == 9'h02f) || (MicroOpCode == 9'h030) || (MicroOpCode == 9'h032) || (MicroOpCode == 9'h033) || (MicroOpCode == 9'h036) || (MicroOpCode == 9'h037) || (MicroOpCode == 9'h039) || (MicroOpCode == 9'h03a) || (MicroOpCode == 9'h03b) || (MicroOpCode == 9'h03c) || (MicroOpCode == 9'h03d) || (MicroOpCode == 9'h03e) || (MicroOpCode == 9'h03f) || (MicroOpCode == 9'h040) || (MicroOpCode == 9'h041) || (MicroOpCode == 9'h042) || (MicroOpCode == 9'h043) || (MicroOpCode == 9'h044) || (MicroOpCode == 9'h045) || (MicroOpCode == 9'h047) || (MicroOpCode == 9'h049) || (MicroOpCode == 9'h04b) || (MicroOpCode == 9'h04c) || (MicroOpCode == 9'h04e) || (MicroOpCode == 9'h04f) || (MicroOpCode == 9'h050) || 0;
|
||||||
|
assign Signals[23] = 0;
|
||||||
|
assign Signals[24] = 0;
|
||||||
|
assign Signals[25] = (MicroOpCode == 9'h021) || 0;
|
||||||
|
assign Signals[26] = (MicroOpCode == 9'h021) || 0;
|
||||||
|
assign Signals[27] = (MicroOpCode == 9'h002) || (MicroOpCode == 9'h003) || 0;
|
||||||
|
assign Signals[28] = (MicroOpCode == 9'h04d) || 0;
|
||||||
|
assign Signals[29] = (MicroOpCode == 9'h023) || (MicroOpCode == 9'h02e) || (MicroOpCode == 9'h03d) || (MicroOpCode == 9'h04d) || 0;
|
||||||
|
assign Signals[30] = (MicroOpCode == 9'h018) || (MicroOpCode == 9'h019) || (MicroOpCode == 9'h01a) || (MicroOpCode == 9'h01b) || 0;
|
||||||
|
assign Signals[31] = (MicroOpCode == 9'h006) || 0;
|
||||||
|
assign Signals[32] = (MicroOpCode == 9'h01e) || 0;
|
||||||
|
assign Signals[33] = (MicroOpCode == 9'h039) || (MicroOpCode == 9'h03e) || (MicroOpCode == 9'h044) || (MicroOpCode == 9'h04b) || (MicroOpCode == 9'h04c) || 0;
|
||||||
|
assign Signals[34] = (MicroOpCode == 9'h022) || (MicroOpCode == 9'h02a) || (MicroOpCode == 9'h02b) || (MicroOpCode == 9'h02c) || (MicroOpCode == 9'h03a) || (MicroOpCode == 9'h03c) || (MicroOpCode == 9'h03d) || (MicroOpCode == 9'h04e) || (MicroOpCode == 9'h04f) || 0;
|
||||||
|
assign Signals[35] = (MicroOpCode == 9'h027) || (MicroOpCode == 9'h028) || 0;
|
||||||
|
assign Signals[36] = (MicroOpCode == 9'h01d) || 0;
|
||||||
|
assign Signals[37] = (MicroOpCode == 9'h018) || (MicroOpCode == 9'h019) || 0;
|
||||||
|
assign Signals[38] = (MicroOpCode == 9'h00d) || (MicroOpCode == 9'h00e) || (MicroOpCode == 9'h010) || 0;
|
||||||
|
assign Signals[39] = 0;
|
||||||
|
assign Signals[40] = (MicroOpCode == 9'h005) || 0;
|
||||||
|
assign Signals[41] = 0;
|
||||||
|
assign Signals[42] = 0;
|
||||||
|
assign Signals[43] = 0;
|
||||||
|
assign Signals[44] = (MicroOpCode == 9'h01c) || 0;
|
||||||
|
assign Signals[45] = 0;
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// title : Sensor Manager Memory Module
|
||||||
|
// project : ULP Sensor Hub
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// file : SMEMemoryMux.v
|
||||||
|
// author : OCTO
|
||||||
|
// company : QuickLogic Corp
|
||||||
|
// created : 2012/??/??
|
||||||
|
// last update : 2014/05/20
|
||||||
|
// platform : PolarPro III
|
||||||
|
// standard : Verilog 2001
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// description: The Sensor Manger Memory Mux selects between several sources
|
||||||
|
// for passing both read and write information.
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// copyright (c) 2013
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// revisions :
|
||||||
|
// date version author description
|
||||||
|
// 2014/05/20 1.0 Glen Gomes Updated -> Added support for a second
|
||||||
|
// memory block by adding
|
||||||
|
// address bits.
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Comments: This solution is specifically for use with the QuickLogic
|
||||||
|
// PolarPro III S2 device.
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1ns / 10ps
|
||||||
|
|
||||||
|
module SMEMemoryMux (
|
||||||
|
input Select,
|
||||||
|
|
||||||
|
input [9:0] ReadAddressIn0, // Expanded for Rel 0 on 6/18
|
||||||
|
input [9:0] ReadAddressIn1, // Expanded for Rel 0 on 6/18
|
||||||
|
output[9:0] ReadAddressOut, // Expanded for Rel 0 on 6/18
|
||||||
|
|
||||||
|
input [9:0] WriteAddressIn0,
|
||||||
|
input [9:0] WriteAddressIn1,
|
||||||
|
output[9:0] WriteAddressOut,
|
||||||
|
|
||||||
|
input [8:0] DataToMemoryIn0,
|
||||||
|
input [8:0] DataToMemoryIn1,
|
||||||
|
output[8:0] DataToMemoryOut,
|
||||||
|
|
||||||
|
input [17:0] DataFromMemoryIn0,
|
||||||
|
input [17:0] DataFromMemoryIn1,
|
||||||
|
output[17:0] DataFromMemoryOut,
|
||||||
|
|
||||||
|
input ReadEnableIn0,
|
||||||
|
input ReadEnableIn1,
|
||||||
|
output ReadEnableOut,
|
||||||
|
|
||||||
|
input WriteEnableIn0,
|
||||||
|
input WriteEnableIn1,
|
||||||
|
output WriteEnableOut,
|
||||||
|
|
||||||
|
input ReadClockIn0,
|
||||||
|
input ReadClockIn1,
|
||||||
|
output ReadClockOut
|
||||||
|
);
|
||||||
|
|
||||||
|
assign ReadAddressOut = (Select) ? ReadAddressIn1 : ReadAddressIn0;
|
||||||
|
assign WriteAddressOut = (Select) ? WriteAddressIn1 : WriteAddressIn0;
|
||||||
|
assign DataToMemoryOut = (Select) ? DataToMemoryIn1 : DataToMemoryIn0;
|
||||||
|
assign DataFromMemoryOut = (Select) ? DataFromMemoryIn1 : DataFromMemoryIn0;
|
||||||
|
assign ReadEnableOut = (Select) ? ReadEnableIn1 : ReadEnableIn0;
|
||||||
|
assign WriteEnableOut = (Select) ? WriteEnableIn1 : WriteEnableIn0;
|
||||||
|
assign ReadClockOut = (Select) ? ReadClockIn1 : ReadClockIn0;
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,112 @@
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// title : Sensor Manager Memory Module
|
||||||
|
// project : ULP Sensor Hub
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// file : SMMemory.v
|
||||||
|
// author : OCTO
|
||||||
|
// company : QuickLogic Corp
|
||||||
|
// created : 2012/??/??
|
||||||
|
// last update : 2014/05/20
|
||||||
|
// platform : PolarPro III
|
||||||
|
// standard : Verilog 2001
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// description: The Sensor Manger Memory performs several tasks. These include
|
||||||
|
// storing Sensor Manager Instructions, Sensor Data, and FFE mail
|
||||||
|
// box data. This memory consists of several physical memory
|
||||||
|
// blocks.
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// copyright (c) 2013
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// revisions :
|
||||||
|
// date version author description
|
||||||
|
// 2014/05/20 1.0 Glen Gomes Updated -> Added a second memory block
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Comments: This solution is specifically for use with the QuickLogic
|
||||||
|
// PolarPro III S2 device.
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1ns / 10ps
|
||||||
|
|
||||||
|
module SMMemory (
|
||||||
|
// General Interface
|
||||||
|
input ResetIn,
|
||||||
|
input SMBusyIn,
|
||||||
|
|
||||||
|
//Read Interface
|
||||||
|
input [9:0] ReadAddressIn,
|
||||||
|
output [17:0] ReadDataOut,
|
||||||
|
input ReadSelectIn,
|
||||||
|
input ReadClockIn,
|
||||||
|
|
||||||
|
//Write Interface
|
||||||
|
input [9:0] WriteAddressIn,
|
||||||
|
input [8:0] WriteDataIn,
|
||||||
|
input WriteSelectIn,
|
||||||
|
|
||||||
|
input [9:0] WriteAddressIn_TLC,
|
||||||
|
input [8:0] WriteDataIn_TLC,
|
||||||
|
input WriteSelectIn_TLC,
|
||||||
|
|
||||||
|
input WriteClockIn,
|
||||||
|
|
||||||
|
output [9:0] SMMemory_WriteAddressIn_TLC_o,
|
||||||
|
output [8:0] SMMemory_ReadAddressIn_o,
|
||||||
|
output SMMemory_WriteSelectIn_TLC_o,
|
||||||
|
output SMMemory_ReadSelect_RAM0_o,
|
||||||
|
output SMMemory_WriteClockIn_o,
|
||||||
|
output SMMemory_ReadClockIn_o,
|
||||||
|
output [8:0] SMMemory_WriteDataIn_TLC_o,
|
||||||
|
input [17:0] SMMemory_ReadDataOut_SRAM_i,
|
||||||
|
output [9:0] SMMemory_WriteAddressIn_o,
|
||||||
|
output SMMemory_WriteSelectIn_o,
|
||||||
|
output SMMemory_ReadSelect_RAM1_o,
|
||||||
|
output SMMemory_WriteDataIn_o,
|
||||||
|
input [17:0] SMMemory_ReadDataOut_SRAM1_i
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
// Define local variables
|
||||||
|
//
|
||||||
|
wire [17:0] ReadDataOut_SRAM;
|
||||||
|
wire [17:0] ReadDataOut_SRAM_1;
|
||||||
|
|
||||||
|
reg ReadDataSel;
|
||||||
|
wire ReadSelect_RAM0;
|
||||||
|
wire ReadSelect_RAM1;
|
||||||
|
wire SMMemoryBankSelect;
|
||||||
|
|
||||||
|
|
||||||
|
// generate individual read enables
|
||||||
|
assign ReadSelect_RAM0 = ReadSelectIn && !ReadAddressIn[9];
|
||||||
|
assign ReadSelect_RAM1 = ReadSelectIn && ReadAddressIn[9];
|
||||||
|
|
||||||
|
|
||||||
|
// Mux the read data
|
||||||
|
always @(posedge ReadClockIn)
|
||||||
|
ReadDataSel <= ReadAddressIn[9];
|
||||||
|
|
||||||
|
assign SMMemoryBankSelect = SMBusyIn ? ReadAddressIn[9] : ReadDataSel;
|
||||||
|
assign ReadDataOut = SMMemoryBankSelect ? ReadDataOut_SRAM_1: ReadDataOut_SRAM;
|
||||||
|
|
||||||
|
|
||||||
|
// Instantiate the Memory Blocks
|
||||||
|
//
|
||||||
|
assign SMMemory_WriteAddressIn_TLC_o = WriteAddressIn_TLC;
|
||||||
|
assign SMMemory_ReadAddressIn_o[8:0] = ReadAddressIn[8:0];
|
||||||
|
assign SMMemory_WriteSelectIn_TLC_o = WriteSelectIn_TLC;
|
||||||
|
assign SMMemory_ReadSelect_RAM0_o = ReadSelect_RAM0;
|
||||||
|
assign SMMemory_WriteClockIn_o = WriteClockIn;
|
||||||
|
assign SMMemory_ReadClockIn_o = ReadClockIn;
|
||||||
|
assign SMMemory_WriteDataIn_TLC_o = WriteDataIn_TLC;
|
||||||
|
assign ReadDataOut_SRAM = SMMemory_ReadDataOut_SRAM_i;
|
||||||
|
|
||||||
|
assign SMMemory_WriteAddressIn_o = WriteAddressIn;
|
||||||
|
assign SMMemory_WriteSelectIn_o = WriteSelectIn;
|
||||||
|
assign SMMemory_ReadSelect_RAM1_o = ReadSelect_RAM1;
|
||||||
|
assign SMMemory_WriteDataIn_o = WriteDataIn;
|
||||||
|
assign ReadDataOut_SRAM1 = SMMemory_ReadDataOut_SRAM1_i;
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,292 @@
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
SPI_slave
|
||||||
|
SPI slave interface, designed for the ULP Sensor Hub.
|
||||||
|
This module is designed to be as small and simple as possible, while
|
||||||
|
supporting the ULP Sensor Hub. Only supports SPI Mode 0 (CPOL=CPHA=0)...
|
||||||
|
which means that input data is latched on the positive edge of SPI_SCLK,
|
||||||
|
and driven out on the negative edge of SPI_SCLK, with the base value of
|
||||||
|
SPI_SCLK being 0.
|
||||||
|
|
||||||
|
|
||||||
|
SPI Protocol:
|
||||||
|
Writes: MOSI: A0 + D0 + D1 + ... + Dn
|
||||||
|
MISO: xx + xx + xx + ... + xx
|
||||||
|
|
||||||
|
Reads: MOSI: A0 + xx + xx + ... + xx
|
||||||
|
MISO: xx + xx + D0 + ... + Dn
|
||||||
|
|
||||||
|
A0 = [1-bit R/W: 1=write, 0=read] + [7-bit address]
|
||||||
|
Dn = valid data byte
|
||||||
|
xx = don't-care data byte
|
||||||
|
|
||||||
|
It is assumed that the MSb is transmitted first, and the LSb last.
|
||||||
|
|
||||||
|
The address is latched, and auto-incremented to support burst reads/writes.
|
||||||
|
The address, when 0d11, jumps back to 0d07, to support repeated (burst)
|
||||||
|
reads to/from the memory data port. The logic to re-map addresses above
|
||||||
|
0d11, that previously was in TLC.v, can now be removed. New registers
|
||||||
|
above 0d11 may now be added if needed.
|
||||||
|
|
||||||
|
This SPI slave requires extra edges on SPI_SCLK to complete any write
|
||||||
|
operation. This may be accomplished in any one of several ways:
|
||||||
|
1. A (non-destructive) read should be performed following the last
|
||||||
|
write operation.
|
||||||
|
2. SPI_SCLK should be toggled after SPI_SS goes inactive
|
||||||
|
(a free-running SPI_SCLK would accomplish this).
|
||||||
|
3. A few extra bits (totaling less than a full byte) should be
|
||||||
|
transmitted by the master. These extra bits will be ignored by
|
||||||
|
this core, but will provide the clocks needed to generated the
|
||||||
|
wr_data_valid pulse.
|
||||||
|
4. A "null" transaction should be performed following the last
|
||||||
|
write transaction, during which the address byte is transmitted
|
||||||
|
by the SPI master followed by 0 bytes of read/write data.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
`timescale 1ns / 1ns
|
||||||
|
|
||||||
|
`include "SensorHubDefines.v"
|
||||||
|
|
||||||
|
|
||||||
|
module SPI_slave (
|
||||||
|
input rst, // system/global reset (active-high)
|
||||||
|
|
||||||
|
// SPI interface
|
||||||
|
input SPI_SCLK, // base value 0 (mode 0)
|
||||||
|
input SPI_MOSI, // master out, slave in
|
||||||
|
output SPI_MISO, // master in, slave out
|
||||||
|
input SPI_SS, // slave select (active-low)
|
||||||
|
|
||||||
|
// internal interface
|
||||||
|
output [6:0] addr,
|
||||||
|
output [7:0] wr_data,
|
||||||
|
output wr_data_valid, // active high
|
||||||
|
input [7:0] rd_data,
|
||||||
|
output rd_data_ack
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
parameter WR = 1'b1;
|
||||||
|
parameter RD = 1'b0;
|
||||||
|
|
||||||
|
|
||||||
|
wire rst_int;
|
||||||
|
|
||||||
|
reg [7:0] shift_in;
|
||||||
|
reg [7:0] shift_out;
|
||||||
|
|
||||||
|
reg [2:0] bit_cnt, bit_cnt_neg;
|
||||||
|
|
||||||
|
reg rcv_byte_valid;
|
||||||
|
reg addr_has_been_latched;
|
||||||
|
reg first_data_has_been_latched;
|
||||||
|
reg [6:0] addr_reg;
|
||||||
|
reg write_readn;
|
||||||
|
reg [7:0] write_data_reg;
|
||||||
|
reg wr_data_valid_reg;
|
||||||
|
reg write_pending;
|
||||||
|
reg rd_data_ack_reg;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// rst_int is active when the global rst occurs or when the SPI interface is idle.
|
||||||
|
// Some logic needs to remain active after a SPI transaction occurs, so rst will be used in those cases.
|
||||||
|
assign rst_int = rst || SPI_SS;
|
||||||
|
|
||||||
|
// input shift register
|
||||||
|
always @(posedge rst_int or posedge SPI_SCLK)
|
||||||
|
if (rst_int)
|
||||||
|
shift_in <= 8'b0;
|
||||||
|
else
|
||||||
|
if (!SPI_SS)
|
||||||
|
shift_in <= {shift_in[6:0], SPI_MOSI};
|
||||||
|
else
|
||||||
|
shift_in <= shift_in;
|
||||||
|
|
||||||
|
|
||||||
|
// bit counter
|
||||||
|
always @(posedge rst_int or posedge SPI_SCLK)
|
||||||
|
if (rst_int)
|
||||||
|
bit_cnt <= 3'b0;
|
||||||
|
else
|
||||||
|
if (!SPI_SS)
|
||||||
|
bit_cnt <= bit_cnt + 1;
|
||||||
|
else
|
||||||
|
bit_cnt <= 3'b0;
|
||||||
|
|
||||||
|
|
||||||
|
// byte valid, active for 1 clk every time a full byte has been received from the master
|
||||||
|
always @(posedge rst_int or posedge SPI_SCLK)
|
||||||
|
if (rst_int)
|
||||||
|
rcv_byte_valid <= 1'b0;
|
||||||
|
else
|
||||||
|
if (rcv_byte_valid) // added to guarantee that rcv_byte_valid is only active for 1 clock
|
||||||
|
rcv_byte_valid <= 1'b0;
|
||||||
|
else
|
||||||
|
if (!SPI_SS && (bit_cnt == 3'b111))
|
||||||
|
rcv_byte_valid <= 1'b1;
|
||||||
|
else
|
||||||
|
rcv_byte_valid <= 1'b0;
|
||||||
|
|
||||||
|
|
||||||
|
// flags for keeping track of the address byte and 1st data byte
|
||||||
|
always @(posedge rst_int or posedge SPI_SCLK)
|
||||||
|
if (rst_int) begin
|
||||||
|
addr_has_been_latched <= 1'b0; // flag that gets set after the addr has been received (and latched)
|
||||||
|
first_data_has_been_latched <= 1'b0; // flag that gets set after the 1st data byte has been received (and latched)
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
|
||||||
|
// if (SPI_SS) // if SPI interface is idle
|
||||||
|
// addr_has_been_latched <= 1'b0;
|
||||||
|
// else
|
||||||
|
// the above is not necessary since the async rst includes SPI_SS
|
||||||
|
if (rcv_byte_valid)
|
||||||
|
addr_has_been_latched <= 1'b1; // set flag after first byte (the address) is received, keep at 1 until transaction is over
|
||||||
|
else
|
||||||
|
addr_has_been_latched <= addr_has_been_latched;
|
||||||
|
|
||||||
|
// if (SPI_SS) // if SPI interface is idle
|
||||||
|
// first_data_has_been_latched <= 1'b0;
|
||||||
|
// else
|
||||||
|
// the above is not necessary since the async rst includes SPI_SS
|
||||||
|
if (addr_has_been_latched && rcv_byte_valid)
|
||||||
|
first_data_has_been_latched <= 1'b1;
|
||||||
|
else
|
||||||
|
first_data_has_been_latched <= first_data_has_been_latched;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// address register, direction control flag
|
||||||
|
always @(posedge rst or posedge SPI_SCLK) // don't use rst_int so these signals will remain active even after SPI_SS has gone inactive
|
||||||
|
if (rst) begin
|
||||||
|
addr_reg <= 7'b0;
|
||||||
|
write_readn <= 1'b0; // flag that signifies a write vs. read transaction
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
|
||||||
|
if (!addr_has_been_latched && rcv_byte_valid)
|
||||||
|
write_readn <= shift_in[7]; // the direction (r/w) flag is in the MSb of the address byte.
|
||||||
|
else
|
||||||
|
write_readn <= write_readn;
|
||||||
|
|
||||||
|
if (!addr_has_been_latched)
|
||||||
|
if (rcv_byte_valid)
|
||||||
|
addr_reg <= shift_in[6:0]; // latch the new address, located in the lowest 7 bits of the address byte.
|
||||||
|
else
|
||||||
|
addr_reg <= addr_reg;
|
||||||
|
else // addr_has_been_latched
|
||||||
|
|
||||||
|
// if (((write_readn == WR) && wr_data_valid_reg) || ((write_readn == RD) && rcv_byte_valid))
|
||||||
|
// addr_reg <= addr_reg + 1;
|
||||||
|
// else
|
||||||
|
// addr_reg <= addr_reg;
|
||||||
|
|
||||||
|
// during writes, make addr_reg wrap back to MemDataByte0 after MemDataByte4
|
||||||
|
if ((write_readn == WR) && wr_data_valid_reg)
|
||||||
|
if (addr_reg == `MemDataByte4)
|
||||||
|
addr_reg <= `MemDataByte0;
|
||||||
|
else
|
||||||
|
addr_reg <= addr_reg + 1;
|
||||||
|
else
|
||||||
|
// during reads, do not increment addr_reg when accessing CM_FIFO_Data
|
||||||
|
//if ((write_readn == RD) && rcv_byte_valid)
|
||||||
|
if ((write_readn == RD) && rd_data_ack_reg)
|
||||||
|
if (addr_reg == `CM_FIFO_Data)
|
||||||
|
addr_reg <= addr_reg;
|
||||||
|
else
|
||||||
|
addr_reg <= addr_reg + 1;
|
||||||
|
else
|
||||||
|
addr_reg <= addr_reg;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// write_pending flag, so writes eventually get sent to the internal interface when more SPI_SCLK edges occur
|
||||||
|
always @(posedge rst or posedge SPI_SCLK) // don't use rst_int since this may need to stay active after SPI_SS goes inactive
|
||||||
|
if (rst)
|
||||||
|
write_pending <= 1'b0;
|
||||||
|
else
|
||||||
|
if (wr_data_valid_reg)
|
||||||
|
write_pending <= 1'b0;
|
||||||
|
else
|
||||||
|
if ((write_readn == WR) && !SPI_SS && addr_has_been_latched && (bit_cnt == 3'b111)) // can't use rcv_byte_valid since there may not be extra clocks after this byte is being written
|
||||||
|
write_pending <= 1'b1;
|
||||||
|
else
|
||||||
|
write_pending <= write_pending;
|
||||||
|
|
||||||
|
|
||||||
|
// write data valid signal
|
||||||
|
always @(posedge rst or posedge SPI_SCLK) // don't use rst_int since this may need to be set after SPI_SS goes inactive
|
||||||
|
if (rst)
|
||||||
|
wr_data_valid_reg <= 1'b0;
|
||||||
|
else
|
||||||
|
if (wr_data_valid_reg)
|
||||||
|
wr_data_valid_reg <= 1'b0;
|
||||||
|
else
|
||||||
|
if (write_pending)
|
||||||
|
wr_data_valid_reg <= 1'b1;
|
||||||
|
else
|
||||||
|
wr_data_valid_reg <= wr_data_valid_reg;
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge rst or posedge SPI_SCLK) // don't use rst_int since this needs to stay valid after SPI_SS goes inactive
|
||||||
|
if (rst)
|
||||||
|
write_data_reg <= 8'b0;
|
||||||
|
else
|
||||||
|
if (!SPI_SS && (bit_cnt == 3'b111))
|
||||||
|
write_data_reg <= {shift_in[6:0], SPI_MOSI};
|
||||||
|
else
|
||||||
|
write_data_reg <= write_data_reg;
|
||||||
|
|
||||||
|
|
||||||
|
// output shift register
|
||||||
|
always @(posedge rst_int or negedge SPI_SCLK)
|
||||||
|
if (rst_int) begin
|
||||||
|
bit_cnt_neg <= 3'b0;
|
||||||
|
shift_out <= 8'b0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (!SPI_SS) begin
|
||||||
|
bit_cnt_neg <= bit_cnt_neg + 1;
|
||||||
|
|
||||||
|
if (addr_has_been_latched && (bit_cnt_neg == 7))
|
||||||
|
shift_out <= rd_data;
|
||||||
|
else
|
||||||
|
shift_out <= {shift_out[6:0], 1'b0};
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
bit_cnt_neg <= 3'b0;
|
||||||
|
shift_out <= shift_out;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// read data acknowledge. this is required to pop data from the CM FIFO
|
||||||
|
always @(posedge rst_int or posedge SPI_SCLK)
|
||||||
|
if (rst_int)
|
||||||
|
rd_data_ack_reg <= 1'b0;
|
||||||
|
else
|
||||||
|
//if ( addr_has_been_latched && (write_readn == RD) && (bit_cnt == 3'b111) )
|
||||||
|
if ( addr_has_been_latched && (write_readn == RD) && rcv_byte_valid)
|
||||||
|
rd_data_ack_reg <= 1'b1;
|
||||||
|
else
|
||||||
|
rd_data_ack_reg <= 1'b0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// assignments to the outputs
|
||||||
|
//assign SPI_MISO = SPI_SS ? 1'bz : shift_out[7];
|
||||||
|
assign SPI_MISO = shift_out[7];//AP2 doesn't support tristate
|
||||||
|
assign addr = addr_reg;
|
||||||
|
assign wr_data = write_data_reg;
|
||||||
|
assign wr_data_valid = wr_data_valid_reg;
|
||||||
|
assign rd_data_ack = rd_data_ack_reg;
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
|
||||||
|
`ifndef SensorHub_Definitions
|
||||||
|
|
||||||
|
`define SensorHub_Definitions
|
||||||
|
|
||||||
|
// Communication Manager register offsets
|
||||||
|
`define CommandReg 7'h00
|
||||||
|
`define StatusReg 7'h01
|
||||||
|
`define milSecSample 7'h02
|
||||||
|
`define InterruptCtrl 7'h03
|
||||||
|
`define InterruptStat 7'h04
|
||||||
|
`define CalValueLow 7'h05
|
||||||
|
`define CalValueHi 7'h06
|
||||||
|
`define Reserved_10 7'h07
|
||||||
|
`define Reserved_11 7'h08
|
||||||
|
`define Reserved_12 7'h09
|
||||||
|
`define Reserved_13 7'h0A
|
||||||
|
`define Reserved_14 7'h0B
|
||||||
|
`define CM_FIFO_Data 7'h0C
|
||||||
|
`define CM_Control 7'h0D
|
||||||
|
`define CM_Status 7'h0E
|
||||||
|
`define CM_FIFO_Flags_0 7'h0F
|
||||||
|
`define Reserved_1 7'h10 /* reserved for CM_FIFO_Flags_23 */
|
||||||
|
`define MailboxToFFE_0 7'h11
|
||||||
|
`define MailboxToFFE_1 7'h12
|
||||||
|
`define MailboxToFFE_2 7'h13
|
||||||
|
`define MailboxToFFE_3 7'h14
|
||||||
|
`define InterruptFFEMsg 7'h15
|
||||||
|
`define Reserved_5 7'h16
|
||||||
|
`define Reserved_6 7'h17
|
||||||
|
`define Reserved_7 7'h18
|
||||||
|
`define RunTimeAdrReg 7'h19
|
||||||
|
`define DemoLedCtrlReg 7'h1A /* Register to control demo LEDs */
|
||||||
|
`define ClocksControl 7'h1B
|
||||||
|
`define SleepControl 7'h1C
|
||||||
|
`define RunTimeAdrReg_Upr 7'h1D /* New for Rel 0 on 6/18 */
|
||||||
|
`define MemAddrLow 7'h20
|
||||||
|
`define MemAddrHigh 7'h21
|
||||||
|
`define MemSelect 7'h22
|
||||||
|
`define MemDataByte0 7'h28
|
||||||
|
`define MemDataByte1 7'h29
|
||||||
|
`define MemDataByte2 7'h2A
|
||||||
|
`define MemDataByte3 7'h2B
|
||||||
|
`define MemDataByte4 7'h2C
|
||||||
|
|
||||||
|
|
||||||
|
`define CtrlSensorManager 8'h00
|
||||||
|
`define CtrlReceiveAddress 8'h01
|
||||||
|
`define CtrlRunTimeAddress 8'h02
|
||||||
|
`define MasterPreLo 8'h08
|
||||||
|
`define MasterPreHi 8'h09
|
||||||
|
`define MasterCTR 8'h0A
|
||||||
|
`define MasterTXR 8'h0B
|
||||||
|
`define MasterCR 8'h0C
|
||||||
|
|
||||||
|
|
||||||
|
`define CR_START 8'b1000_0000
|
||||||
|
`define CR_STOP 8'b0100_0000
|
||||||
|
`define CR_READ 8'b0010_0000
|
||||||
|
`define CR_WRITE 8'b0001_0000
|
||||||
|
`define CR_NAK 8'b0000_1000
|
||||||
|
// `define CR_POLL 8'b0000_0100
|
||||||
|
`define CR_IACK 8'b0000_0001
|
||||||
|
|
||||||
|
`endif
|
|
@ -0,0 +1,960 @@
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// title : Sensor Manager Main Routine
|
||||||
|
// project : ULP Sensor Hub
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// file : SensorManager.v
|
||||||
|
// author : OCTO
|
||||||
|
// company : QuickLogic Corp
|
||||||
|
// created : 2012/??/??
|
||||||
|
// last update : 2013/12/06
|
||||||
|
// platform : PolarPro III
|
||||||
|
// standard : Verilog 2001
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// description: The Sensor Manger is responsible for controlling various
|
||||||
|
// external sensors and storing the resulting data in Sensor
|
||||||
|
// Manager Memory. These include performing transfers between
|
||||||
|
// Sensor Memory and various registers.
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// copyright (c) 2013
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// revisions :
|
||||||
|
// date version author description
|
||||||
|
// 2013/12/06 1.0 Glen Gomes Updated -> Mostly re-written
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Comments: This solution is specifically for use with the QuickLogic
|
||||||
|
// PolarPro III device.
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1ns / 10ps
|
||||||
|
|
||||||
|
module SensorManager (
|
||||||
|
|
||||||
|
// General interface
|
||||||
|
ClockIn,
|
||||||
|
ResetIn,
|
||||||
|
StartFromFFE,
|
||||||
|
StartFromTLC,
|
||||||
|
BusyOut,
|
||||||
|
TimeStamp_Delta_i,
|
||||||
|
TimeStamp_Delta_Tog_i,
|
||||||
|
SensorInterrupt_0_i,
|
||||||
|
SensorInterrupt_1_i,
|
||||||
|
SensorInterrupt_2_i,
|
||||||
|
SensorInterrupt_3_i,
|
||||||
|
SensorInterrupt_0_o,
|
||||||
|
SensorInterrupt_1_o,
|
||||||
|
SensorInterrupt_2_o,
|
||||||
|
SensorInterrupt_3_o,
|
||||||
|
CtrlRunTimeAddressSM,
|
||||||
|
CtrlRunTimeAddressOut,
|
||||||
|
CtrlRunTimeAddressReg,
|
||||||
|
MemReadAddressOut,
|
||||||
|
MemReadEnableOut,
|
||||||
|
MemReadDataIn,
|
||||||
|
MemWriteAddressOut,
|
||||||
|
MemWriteEnableOut,
|
||||||
|
MemWriteDataOut,
|
||||||
|
MemClockOut,
|
||||||
|
I2C_wb_adr_o,
|
||||||
|
I2C_wb_dat_o,
|
||||||
|
I2C_wb_dat_i,
|
||||||
|
I2C_wb_we_o,
|
||||||
|
I2C_wb_stb_o,
|
||||||
|
I2C_wb_cyc_o,
|
||||||
|
I2C_wb_ack_i,
|
||||||
|
I2C_tip_i,
|
||||||
|
TP1,
|
||||||
|
TP2,
|
||||||
|
TP3,
|
||||||
|
SmClockSelect_o
|
||||||
|
);
|
||||||
|
|
||||||
|
//-----Port Signals--------------------
|
||||||
|
//
|
||||||
|
|
||||||
|
input ClockIn;
|
||||||
|
input ResetIn;
|
||||||
|
input StartFromFFE;
|
||||||
|
input StartFromTLC;
|
||||||
|
output BusyOut;
|
||||||
|
input [15:0] TimeStamp_Delta_i;
|
||||||
|
input TimeStamp_Delta_Tog_i;
|
||||||
|
input SensorInterrupt_0_i;
|
||||||
|
input SensorInterrupt_1_i;
|
||||||
|
input SensorInterrupt_2_i;
|
||||||
|
input SensorInterrupt_3_i;
|
||||||
|
output SensorInterrupt_0_o;
|
||||||
|
output SensorInterrupt_1_o;
|
||||||
|
output SensorInterrupt_2_o;
|
||||||
|
output SensorInterrupt_3_o;
|
||||||
|
input CtrlRunTimeAddressSM;
|
||||||
|
input [9:0] CtrlRunTimeAddressOut;
|
||||||
|
output [9:0] CtrlRunTimeAddressReg;
|
||||||
|
output [9:0] MemReadAddressOut; // Expanded for Rel 0 on 6/18
|
||||||
|
output MemReadEnableOut;
|
||||||
|
input [17:0] MemReadDataIn;
|
||||||
|
output [9:0] MemWriteAddressOut;
|
||||||
|
output MemWriteEnableOut;
|
||||||
|
output [8:0] MemWriteDataOut;
|
||||||
|
output MemClockOut;
|
||||||
|
output [2:0] I2C_wb_adr_o;
|
||||||
|
output [7:0] I2C_wb_dat_o;
|
||||||
|
input [7:0] I2C_wb_dat_i;
|
||||||
|
output I2C_wb_we_o;
|
||||||
|
output I2C_wb_stb_o;
|
||||||
|
output I2C_wb_cyc_o;
|
||||||
|
input I2C_wb_ack_i;
|
||||||
|
input I2C_tip_i;
|
||||||
|
output TP1;
|
||||||
|
output TP2;
|
||||||
|
output TP3;
|
||||||
|
output SmClockSelect_o;
|
||||||
|
|
||||||
|
|
||||||
|
wire ClockIn;
|
||||||
|
wire ResetIn;
|
||||||
|
wire StartFromFFE;
|
||||||
|
wire StartFromTLC;
|
||||||
|
wire BusyOut;
|
||||||
|
wire [15:0] TimeStamp_Delta_i;
|
||||||
|
wire TimeStamp_Delta_Tog_i;
|
||||||
|
wire SensorInterrupt_0_i;
|
||||||
|
wire SensorInterrupt_1_i;
|
||||||
|
wire SensorInterrupt_2_i;
|
||||||
|
wire SensorInterrupt_3_i;
|
||||||
|
reg SensorInterrupt_0_o;
|
||||||
|
reg SensorInterrupt_1_o;
|
||||||
|
reg SensorInterrupt_2_o;
|
||||||
|
reg SensorInterrupt_3_o;
|
||||||
|
wire CtrlRunTimeAddressSM;
|
||||||
|
wire [9:0] CtrlRunTimeAddressOut;
|
||||||
|
reg [9:0] CtrlRunTimeAddressReg;
|
||||||
|
wire [9:0] MemReadAddressOut; // Expanded for Rel 0 on 6/18
|
||||||
|
wire MemReadEnableOut;
|
||||||
|
wire [17:0] MemReadDataIn;
|
||||||
|
wire [9:0] MemWriteAddressOut;
|
||||||
|
wire MemWriteEnableOut;
|
||||||
|
reg [8:0] MemWriteDataOut;
|
||||||
|
wire [2:0] I2C_wb_adr_o;
|
||||||
|
wire [7:0] I2C_wb_dat_o;
|
||||||
|
wire [7:0] I2C_wb_dat_i;
|
||||||
|
wire I2C_wb_we_o;
|
||||||
|
wire I2C_wb_stb_o;
|
||||||
|
wire I2C_wb_cyc_o;
|
||||||
|
wire I2C_wb_ack_i;
|
||||||
|
wire I2C_tip_i;
|
||||||
|
wire MemClockOut;
|
||||||
|
wire TP1;
|
||||||
|
wire TP2;
|
||||||
|
wire TP3;
|
||||||
|
reg SmClockSelect_o;
|
||||||
|
|
||||||
|
|
||||||
|
//-----Internal Signals--------------------
|
||||||
|
//
|
||||||
|
|
||||||
|
wire wb_cyc;
|
||||||
|
|
||||||
|
wire wb_we;
|
||||||
|
wire wb_stb;
|
||||||
|
|
||||||
|
wire wb_ack;
|
||||||
|
reg wb_ack_sm;
|
||||||
|
|
||||||
|
wire wb_busy_poll;
|
||||||
|
|
||||||
|
reg [9:0] CtrlReceiveAddressReg;
|
||||||
|
|
||||||
|
reg [5:0] CtrlMailBoxSegmentCtr;
|
||||||
|
reg CtrlMailBoxSegmentCtr_ce;
|
||||||
|
|
||||||
|
reg [9:2] CtrlMailBoxTablePtr;
|
||||||
|
|
||||||
|
reg [9:0] CtrlMailBoxJumpInstPtr;
|
||||||
|
|
||||||
|
reg CtrlMailBoxJumpInstCycle;
|
||||||
|
reg CtrlMailBoxJumpInstCycle_ce;
|
||||||
|
|
||||||
|
wire [9:0] StateMachineCtrlMemAddr;
|
||||||
|
wire [7:0] i2c_masterDataToMem;
|
||||||
|
|
||||||
|
wire save_reg_2_mem;
|
||||||
|
|
||||||
|
wire control_sensor_manager_reg_dcd;
|
||||||
|
wire control_receive_reg_dcd;
|
||||||
|
wire control_runtime_reg_dcd;
|
||||||
|
wire control_jump_reg_dcd;
|
||||||
|
wire control_mailbox_tbl_ptr_dcd;
|
||||||
|
wire control_mailbox_jump_inst_ptr_dcd;
|
||||||
|
|
||||||
|
reg RunSM;
|
||||||
|
wire BusySM;
|
||||||
|
|
||||||
|
wire StartIn_stb;
|
||||||
|
|
||||||
|
reg StartFromFFE_1ff;
|
||||||
|
reg StartFromFFE_2ff;
|
||||||
|
reg StartFromFFE_3ff;
|
||||||
|
reg StartFromFFE_4ff;
|
||||||
|
reg StartFromFFE_5ff;
|
||||||
|
reg StartFromFFE_6ff;
|
||||||
|
|
||||||
|
reg StartFromTLC_1ff;
|
||||||
|
reg StartFromTLC_2ff;
|
||||||
|
|
||||||
|
reg CtrlRunTimeAddressSM_1ff;
|
||||||
|
reg CtrlRunTimeAddressSM_2ff;
|
||||||
|
|
||||||
|
reg s1_BusyOut, s2_BusyOut;
|
||||||
|
|
||||||
|
// Define write enable controls for each TimeStamp register
|
||||||
|
//
|
||||||
|
wire SensorInterrupt_event_reg_we_dcd;
|
||||||
|
|
||||||
|
wire SensorInterrupt_event_mask_we_dcd;
|
||||||
|
|
||||||
|
reg SensorInterrupt_event_mask_0;
|
||||||
|
reg SensorInterrupt_event_mask_1;
|
||||||
|
reg SensorInterrupt_event_mask_2;
|
||||||
|
reg SensorInterrupt_event_mask_3;
|
||||||
|
|
||||||
|
|
||||||
|
// Delta Time Stamp registers for each sensor
|
||||||
|
//
|
||||||
|
reg [7:0] TimeStamp_Delta_sensor_0;
|
||||||
|
reg [7:0] TimeStamp_Delta_sensor_1;
|
||||||
|
reg [7:0] TimeStamp_Delta_sensor_2;
|
||||||
|
reg [7:0] TimeStamp_Delta_sensor_3;
|
||||||
|
|
||||||
|
reg [15:0] TimeStamp_Delta_capt;
|
||||||
|
reg [15:0] TimeStamp_Delta_readback;
|
||||||
|
|
||||||
|
reg TimeStamp_Delta_Tog_1ff;
|
||||||
|
reg TimeStamp_Delta_Tog_2ff;
|
||||||
|
reg TimeStamp_Delta_Tog_3ff;
|
||||||
|
|
||||||
|
// Meta-state registers for each sensor interrupt
|
||||||
|
//
|
||||||
|
reg SensorInterrupt_0_1ff;
|
||||||
|
reg SensorInterrupt_0_2ff;
|
||||||
|
reg SensorInterrupt_0_3ff;
|
||||||
|
|
||||||
|
reg SensorInterrupt_1_1ff;
|
||||||
|
reg SensorInterrupt_1_2ff;
|
||||||
|
reg SensorInterrupt_1_3ff;
|
||||||
|
|
||||||
|
reg SensorInterrupt_2_1ff;
|
||||||
|
reg SensorInterrupt_2_2ff;
|
||||||
|
reg SensorInterrupt_2_3ff;
|
||||||
|
|
||||||
|
reg SensorInterrupt_3_1ff;
|
||||||
|
reg SensorInterrupt_3_2ff;
|
||||||
|
reg SensorInterrupt_3_3ff;
|
||||||
|
|
||||||
|
|
||||||
|
// Wait Instruction Registers
|
||||||
|
//
|
||||||
|
wire control_wait_instr_reg_dcd;
|
||||||
|
|
||||||
|
reg [12:0] control_wait_instr_cntr;
|
||||||
|
reg [12:0] control_wait_instr_cntr_nxt;
|
||||||
|
|
||||||
|
reg control_wait_instr_cntr_tc;
|
||||||
|
reg control_wait_instr_cntr_tc_nxt;
|
||||||
|
|
||||||
|
reg control_wait_instr_busy;
|
||||||
|
wire control_wait_instr_busy_nxt;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//------Define Parameters---------
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define the various address spaces
|
||||||
|
//
|
||||||
|
// Note: These correspond to bits [7:3] of the register address field.
|
||||||
|
//
|
||||||
|
parameter SENSOR_MANAGER_ADR = 5'h0;
|
||||||
|
parameter I2C_MASTER_ADR = 5'h1;
|
||||||
|
parameter TIMESTAMP_DELTA_ADR = 5'h2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define the available registers in the Sensor Manager
|
||||||
|
//
|
||||||
|
// Note: These correspond to bits [2:0] of the register address field.
|
||||||
|
//
|
||||||
|
parameter CONTROL_SENSOR_MANAGER_ADDRESS = 3'h0;
|
||||||
|
parameter CONTROL_RECEIVE_ADDRESS = 3'h1;
|
||||||
|
parameter CONTROL_RUNTIME_ADDRESS = 3'h2;
|
||||||
|
parameter CONTROL_WAIT_INSTR_ADDRESS = 3'h4;
|
||||||
|
parameter CONTROL_MAILBOX_TABLE_PTR = 3'h5;
|
||||||
|
parameter CONTROL_MAILBOX_JUMP_INST_PTR = 3'h6;
|
||||||
|
parameter CONTROL_JUMP_ADDRESS = 3'h7;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define the key registers in the I2C Master IP
|
||||||
|
//
|
||||||
|
// Note: These correspond to bits [2:0] of the register address field.
|
||||||
|
//
|
||||||
|
parameter I2C_MASTER_PRELO = 3'h0;
|
||||||
|
parameter I2C_MASTER_PREHI = 3'h1;
|
||||||
|
parameter I2C_MASTER_CTR = 3'h2;
|
||||||
|
parameter I2C_MASTER_TXR = 3'h3;
|
||||||
|
parameter I2C_MASTER_CR = 3'h4;
|
||||||
|
|
||||||
|
|
||||||
|
// Define the available registers in the TimeStamp Logic
|
||||||
|
//
|
||||||
|
// Note: These correspond to bits [2:0] of the register address field.
|
||||||
|
//
|
||||||
|
parameter TIMESTAMP_DELTA_SENSOR_0 = 3'h0;
|
||||||
|
parameter TIMESTAMP_DELTA_SENSOR_1 = 3'h1;
|
||||||
|
parameter TIMESTAMP_DELTA_SENSOR_2 = 3'h2;
|
||||||
|
parameter TIMESTAMP_DELTA_SENSOR_3 = 3'h3;
|
||||||
|
parameter TIMESTAMP_DELTA_GENERIC_LSB = 3'h4;
|
||||||
|
parameter TIMESTAMP_DELTA_GENERIC_MSB = 3'h5;
|
||||||
|
parameter TIMESTAMP_DELTA_INT_EVENT = 3'h6;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define the default location of the Mail Box structure in SM Memory
|
||||||
|
//
|
||||||
|
parameter MAILBOX_SM_ADDRESS = 8'hFF; // Note: This is "3FC" shifted by two to the right
|
||||||
|
|
||||||
|
//------Logic Operations----------
|
||||||
|
//
|
||||||
|
|
||||||
|
// I2C Interface to the Right Bank ASSP
|
||||||
|
//
|
||||||
|
assign I2C_wb_dat_o = MemReadDataIn[15:8];
|
||||||
|
assign i2c_masterDataToMem = I2C_wb_dat_i;
|
||||||
|
assign I2C_wb_we_o = wb_we;
|
||||||
|
assign I2C_wb_stb_o = wb_stb;
|
||||||
|
|
||||||
|
// Decode the Wishbone bus address space(s)
|
||||||
|
//
|
||||||
|
assign I2C_wb_cyc_o = (MemReadDataIn[7:3] == I2C_MASTER_ADR) & wb_cyc & ~CtrlMailBoxJumpInstCycle;
|
||||||
|
|
||||||
|
|
||||||
|
// Define the write enables controls for each register
|
||||||
|
//
|
||||||
|
assign control_sensor_manager_reg_dcd = (MemReadDataIn[7:0] == {SENSOR_MANAGER_ADR, CONTROL_SENSOR_MANAGER_ADDRESS}) & wb_cyc & wb_stb & wb_we & ~wb_ack_sm & ~CtrlMailBoxJumpInstCycle;
|
||||||
|
assign control_runtime_reg_dcd = (MemReadDataIn[7:0] == {SENSOR_MANAGER_ADR, CONTROL_RUNTIME_ADDRESS}) & wb_cyc & wb_stb & wb_we & ~wb_ack_sm & ~CtrlMailBoxJumpInstCycle;
|
||||||
|
|
||||||
|
assign control_wait_instr_reg_dcd = (MemReadDataIn[7:0] == {SENSOR_MANAGER_ADR, CONTROL_WAIT_INSTR_ADDRESS}) & wb_cyc & wb_stb & wb_we & ~wb_ack_sm & ~CtrlMailBoxJumpInstCycle;
|
||||||
|
|
||||||
|
assign control_receive_reg_dcd = ((MemReadDataIn[7:0] == { SENSOR_MANAGER_ADR, CONTROL_RECEIVE_ADDRESS})
|
||||||
|
| (MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_SENSOR_0})
|
||||||
|
| (MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_SENSOR_1})
|
||||||
|
| (MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_SENSOR_2})
|
||||||
|
| (MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_SENSOR_3})
|
||||||
|
| (MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_GENERIC_MSB})
|
||||||
|
| (MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_GENERIC_LSB})) & wb_cyc & wb_stb & wb_we & ~wb_ack_sm & ~CtrlMailBoxJumpInstCycle;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Define the write enable for the Interrupt event of the Time Stamp Logic
|
||||||
|
//
|
||||||
|
// Note: This write occurs after the write of interrupt data to SM Memory
|
||||||
|
//
|
||||||
|
assign SensorInterrupt_event_reg_we_dcd = (MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_INT_EVENT}) & wb_cyc & wb_stb & ~wb_we & wb_ack_sm & ~CtrlMailBoxJumpInstCycle;
|
||||||
|
assign SensorInterrupt_event_mask_we_dcd = (MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_INT_EVENT}) & wb_cyc & wb_stb & wb_we & ~wb_ack_sm & ~CtrlMailBoxJumpInstCycle;
|
||||||
|
assign TimeStamp_Delta_lsb_reg_we_dcd = (MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_GENERIC_LSB}) & wb_cyc & wb_stb & wb_we & ~wb_ack_sm & ~CtrlMailBoxJumpInstCycle;
|
||||||
|
|
||||||
|
|
||||||
|
// Deterimine if the current cycle is a write to the instruction pointer.
|
||||||
|
//
|
||||||
|
// Note: This only happens during the "jump" instruction
|
||||||
|
//
|
||||||
|
// This signals the Sensor Manager Statemachine that the current cycle
|
||||||
|
// is a "jump" and to load the register data value into the instruction
|
||||||
|
// pointer at the end of the current "register write" instruction.
|
||||||
|
//
|
||||||
|
assign control_jump_reg_dcd = (MemReadDataIn[7:0] == {SENSOR_MANAGER_ADR, CONTROL_JUMP_ADDRESS}) & ~CtrlMailBoxJumpInstCycle;
|
||||||
|
|
||||||
|
|
||||||
|
// Determine if the current cycle is the start of a Mail Box based Jump
|
||||||
|
// sequence.
|
||||||
|
//
|
||||||
|
// Note: The value of the bits in the Mail Box region of SM Memory determine
|
||||||
|
// if the current jump address should be loaded into the instruction
|
||||||
|
// pointer or if it should be ignored.
|
||||||
|
//
|
||||||
|
assign control_mailbox_tbl_ptr_dcd = (MemReadDataIn[7:0] == {SENSOR_MANAGER_ADR, CONTROL_MAILBOX_TABLE_PTR}) & wb_cyc & wb_stb & wb_we & ~wb_ack_sm & ~CtrlMailBoxJumpInstCycle;
|
||||||
|
assign control_mailbox_jump_inst_ptr_dcd = (MemReadDataIn[7:0] == {SENSOR_MANAGER_ADR, CONTROL_MAILBOX_JUMP_INST_PTR}) & wb_cyc & wb_stb & wb_we & wb_ack_sm & ~CtrlMailBoxJumpInstCycle;
|
||||||
|
|
||||||
|
|
||||||
|
// Determine if the current address should include a write to the Sensor Manager's Memory
|
||||||
|
//
|
||||||
|
// Note: There is currently only one address but this may expand with, for
|
||||||
|
// example, a TimeStamp function.
|
||||||
|
//
|
||||||
|
assign save_reg_2_mem = ((MemReadDataIn[7:0] == { I2C_MASTER_ADR, I2C_MASTER_CR}) & MemReadDataIn[13] & ~CtrlMailBoxJumpInstCycle)
|
||||||
|
| ((MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_SENSOR_0}) & ~CtrlMailBoxJumpInstCycle)
|
||||||
|
| ((MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_SENSOR_1}) & ~CtrlMailBoxJumpInstCycle)
|
||||||
|
| ((MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_SENSOR_2}) & ~CtrlMailBoxJumpInstCycle)
|
||||||
|
| ((MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_SENSOR_3}) & ~CtrlMailBoxJumpInstCycle)
|
||||||
|
| ((MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_GENERIC_LSB}) & ~CtrlMailBoxJumpInstCycle)
|
||||||
|
| ((MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_GENERIC_MSB}) & ~CtrlMailBoxJumpInstCycle)
|
||||||
|
| ((MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_INT_EVENT}) & ~CtrlMailBoxJumpInstCycle);
|
||||||
|
|
||||||
|
|
||||||
|
// Determine if the Wishbone device requires monitoring its busy signal
|
||||||
|
//
|
||||||
|
// Note: The only device currently supported is the I2C Master IP. This IP
|
||||||
|
// will generate a I2C bus cycle when the "read" or "write"
|
||||||
|
// bits are set in the control register.
|
||||||
|
//
|
||||||
|
assign wb_busy_poll = ((MemReadDataIn[7:0] == {I2C_MASTER_ADR, I2C_MASTER_CR }) & (MemReadDataIn[12] | MemReadDataIn[13]) & ~CtrlMailBoxJumpInstCycle)
|
||||||
|
| ((MemReadDataIn[7:0] == {SENSOR_MANAGER_ADR, CONTROL_WAIT_INSTR_ADDRESS}) & ~CtrlMailBoxJumpInstCycle);
|
||||||
|
|
||||||
|
|
||||||
|
// Determine when to start the Sensor Manager Statemachine
|
||||||
|
//
|
||||||
|
// Note: Use double-rank synchronization to resolve meta-stability issues.
|
||||||
|
//
|
||||||
|
// Simulation shows these signals toggle from TLC.v clock domain to
|
||||||
|
// the Sensor Manager's.
|
||||||
|
//
|
||||||
|
assign StartIn_stb = (StartFromFFE_5ff ^ StartFromFFE_6ff)
|
||||||
|
| (StartFromTLC_1ff ^ StartFromTLC_2ff);
|
||||||
|
|
||||||
|
|
||||||
|
// Define the Sensor Manager Control Registers
|
||||||
|
//
|
||||||
|
always @(posedge ClockIn or posedge ResetIn)
|
||||||
|
begin
|
||||||
|
if (ResetIn)
|
||||||
|
begin
|
||||||
|
wb_ack_sm <= 1'b0;
|
||||||
|
|
||||||
|
StartFromFFE_1ff <= 1'b0;
|
||||||
|
StartFromFFE_2ff <= 1'b0;
|
||||||
|
StartFromFFE_3ff <= 1'b0;
|
||||||
|
StartFromFFE_4ff <= 1'b0;
|
||||||
|
StartFromFFE_5ff <= 1'b0;
|
||||||
|
StartFromFFE_6ff <= 1'b0;
|
||||||
|
|
||||||
|
StartFromTLC_1ff <= 1'b0;
|
||||||
|
StartFromTLC_2ff <= 1'b0;
|
||||||
|
|
||||||
|
RunSM <= 1'b0;
|
||||||
|
|
||||||
|
CtrlReceiveAddressReg <= 10'h0;
|
||||||
|
CtrlRunTimeAddressReg <= 10'h0;
|
||||||
|
|
||||||
|
CtrlRunTimeAddressSM_1ff <= 1'b0;
|
||||||
|
CtrlRunTimeAddressSM_2ff <= 1'b0;
|
||||||
|
|
||||||
|
TimeStamp_Delta_sensor_0 <= 8'h0;
|
||||||
|
TimeStamp_Delta_sensor_1 <= 8'h0;
|
||||||
|
TimeStamp_Delta_sensor_2 <= 8'h0;
|
||||||
|
TimeStamp_Delta_sensor_3 <= 8'h0;
|
||||||
|
|
||||||
|
SensorInterrupt_0_1ff <= 4'h0;
|
||||||
|
SensorInterrupt_0_2ff <= 4'h0;
|
||||||
|
SensorInterrupt_0_3ff <= 4'h0;
|
||||||
|
|
||||||
|
SensorInterrupt_1_1ff <= 4'h0;
|
||||||
|
SensorInterrupt_1_2ff <= 4'h0;
|
||||||
|
SensorInterrupt_1_3ff <= 4'h0;
|
||||||
|
|
||||||
|
SensorInterrupt_2_1ff <= 4'h0;
|
||||||
|
SensorInterrupt_2_2ff <= 4'h0;
|
||||||
|
SensorInterrupt_2_3ff <= 4'h0;
|
||||||
|
|
||||||
|
SensorInterrupt_3_1ff <= 4'h0;
|
||||||
|
SensorInterrupt_3_2ff <= 4'h0;
|
||||||
|
SensorInterrupt_3_3ff <= 4'h0;
|
||||||
|
|
||||||
|
SensorInterrupt_0_o <= 1'b0;
|
||||||
|
SensorInterrupt_1_o <= 1'b0;
|
||||||
|
SensorInterrupt_2_o <= 1'b0;
|
||||||
|
SensorInterrupt_3_o <= 1'b0;
|
||||||
|
|
||||||
|
SensorInterrupt_event_mask_0 <= 1'b0;
|
||||||
|
SensorInterrupt_event_mask_1 <= 1'b0;
|
||||||
|
SensorInterrupt_event_mask_2 <= 1'b0;
|
||||||
|
SensorInterrupt_event_mask_3 <= 1'b0;
|
||||||
|
|
||||||
|
TimeStamp_Delta_capt <= 16'h0;
|
||||||
|
TimeStamp_Delta_readback <= 16'h0;
|
||||||
|
|
||||||
|
TimeStamp_Delta_Tog_1ff <= 1'b0;
|
||||||
|
TimeStamp_Delta_Tog_2ff <= 1'b0;
|
||||||
|
TimeStamp_Delta_Tog_3ff <= 1'b0;
|
||||||
|
|
||||||
|
CtrlMailBoxSegmentCtr <= 6'h0;
|
||||||
|
CtrlMailBoxSegmentCtr_ce <= 1'b0;
|
||||||
|
|
||||||
|
CtrlMailBoxTablePtr <= MAILBOX_SM_ADDRESS;
|
||||||
|
CtrlMailBoxJumpInstPtr <= 10'h0;
|
||||||
|
|
||||||
|
CtrlMailBoxJumpInstCycle <= 1'b0;
|
||||||
|
CtrlMailBoxJumpInstCycle_ce <= 1'b0;
|
||||||
|
|
||||||
|
control_wait_instr_cntr <= 13'h0;
|
||||||
|
control_wait_instr_cntr_tc <= 1'b0;
|
||||||
|
control_wait_instr_busy <= 1'b0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
wb_ack_sm <= ((MemReadDataIn[7:3] == SENSOR_MANAGER_ADR )
|
||||||
|
| (MemReadDataIn[7:3] == TIMESTAMP_DELTA_ADR)
|
||||||
|
| (CtrlMailBoxJumpInstCycle)) & wb_cyc & wb_stb & ~wb_ack_sm;
|
||||||
|
|
||||||
|
// Double-rank synchronization between clock domains to avoid meta-state issues
|
||||||
|
//
|
||||||
|
|
||||||
|
StartFromFFE_1ff <= StartFromFFE;
|
||||||
|
StartFromFFE_2ff <= StartFromFFE_1ff;
|
||||||
|
StartFromFFE_3ff <= StartFromFFE_2ff;
|
||||||
|
StartFromFFE_4ff <= StartFromFFE_3ff;
|
||||||
|
StartFromFFE_5ff <= StartFromFFE_4ff;
|
||||||
|
StartFromFFE_6ff <= StartFromFFE_5ff;
|
||||||
|
|
||||||
|
StartFromTLC_1ff <= StartFromTLC;
|
||||||
|
StartFromTLC_2ff <= StartFromTLC_1ff;
|
||||||
|
|
||||||
|
CtrlRunTimeAddressSM_1ff <= CtrlRunTimeAddressSM;
|
||||||
|
CtrlRunTimeAddressSM_2ff <= CtrlRunTimeAddressSM_1ff;
|
||||||
|
|
||||||
|
// Define the Sensor Manager Control Register
|
||||||
|
//
|
||||||
|
// Note: A write of "0" to bit "0" of Sensor Manager Register "0" stops execution.
|
||||||
|
//
|
||||||
|
// The remaining bits of the "control" register can be used for other purposes.
|
||||||
|
//
|
||||||
|
if (StartIn_stb)
|
||||||
|
RunSM <= 1'b1;
|
||||||
|
else if (control_sensor_manager_reg_dcd)
|
||||||
|
RunSM <= MemReadDataIn[8];
|
||||||
|
|
||||||
|
// Define the Sensor Manager Receive Address Register
|
||||||
|
//
|
||||||
|
if (control_receive_reg_dcd)
|
||||||
|
CtrlReceiveAddressReg <= MemReadDataIn[17:8];
|
||||||
|
|
||||||
|
// Define the Sensor Manager Run-time Address Register
|
||||||
|
//
|
||||||
|
if (control_runtime_reg_dcd)
|
||||||
|
CtrlRunTimeAddressReg <= MemReadDataIn[17:8];
|
||||||
|
else if ( CtrlRunTimeAddressSM_1ff ^ CtrlRunTimeAddressSM_2ff)
|
||||||
|
CtrlRunTimeAddressReg <= CtrlRunTimeAddressOut;
|
||||||
|
|
||||||
|
|
||||||
|
// Synchronize the interrupt inputs to avoid meta-state issues
|
||||||
|
//
|
||||||
|
SensorInterrupt_0_1ff <= SensorInterrupt_0_i;
|
||||||
|
SensorInterrupt_0_2ff <= SensorInterrupt_0_1ff;
|
||||||
|
SensorInterrupt_0_3ff <= SensorInterrupt_0_2ff;
|
||||||
|
|
||||||
|
SensorInterrupt_1_1ff <= SensorInterrupt_1_i;
|
||||||
|
SensorInterrupt_1_2ff <= SensorInterrupt_1_1ff;
|
||||||
|
SensorInterrupt_1_3ff <= SensorInterrupt_1_2ff;
|
||||||
|
|
||||||
|
SensorInterrupt_2_1ff <= SensorInterrupt_2_i;
|
||||||
|
SensorInterrupt_2_2ff <= SensorInterrupt_2_1ff;
|
||||||
|
SensorInterrupt_2_3ff <= SensorInterrupt_2_2ff;
|
||||||
|
|
||||||
|
SensorInterrupt_3_1ff <= SensorInterrupt_3_i;
|
||||||
|
SensorInterrupt_3_2ff <= SensorInterrupt_3_1ff;
|
||||||
|
SensorInterrupt_3_3ff <= SensorInterrupt_3_2ff;
|
||||||
|
|
||||||
|
TimeStamp_Delta_Tog_1ff <= TimeStamp_Delta_Tog_i;
|
||||||
|
TimeStamp_Delta_Tog_2ff <= TimeStamp_Delta_Tog_1ff;
|
||||||
|
TimeStamp_Delta_Tog_3ff <= TimeStamp_Delta_Tog_2ff;
|
||||||
|
|
||||||
|
|
||||||
|
// Capture the external TimeStamp from the Communication Manager.
|
||||||
|
//
|
||||||
|
// Note: The Communication Manager uses the 32KHz clock for the
|
||||||
|
// TimeStamp function. In the current application, this is not
|
||||||
|
// the same clock used for the Sensor Manager. However, the
|
||||||
|
// Sensor Manager's clock is currently significantly faster than
|
||||||
|
// the 32KHz clock and can capture the TimeStamp value reliably
|
||||||
|
// when is receives the TimeStamp toggle signal from the
|
||||||
|
// Communication Manager.
|
||||||
|
//
|
||||||
|
// This scheme may need to be revisted if the clock assignments
|
||||||
|
// change on future designs.
|
||||||
|
//
|
||||||
|
if (TimeStamp_Delta_Tog_2ff ^ TimeStamp_Delta_Tog_3ff)
|
||||||
|
TimeStamp_Delta_capt <= TimeStamp_Delta_i;
|
||||||
|
|
||||||
|
// Capture the TimeStamp Value for a "generic" TimeStamp write to SM
|
||||||
|
// Memory.
|
||||||
|
//
|
||||||
|
// Note: The entire TimeStamp value is captured when a write of the
|
||||||
|
// LSB value to SM Memory is triggered. This allows for the
|
||||||
|
// writting of the MSB bits without the danger of the TimeStamp
|
||||||
|
// value changing between writes of each TimeStamp byte to
|
||||||
|
// SM Memory.
|
||||||
|
//
|
||||||
|
if (TimeStamp_Delta_lsb_reg_we_dcd)
|
||||||
|
TimeStamp_Delta_readback <= TimeStamp_Delta_capt;
|
||||||
|
|
||||||
|
|
||||||
|
// Capture the time stamp delta when an interrupt is detected.
|
||||||
|
//
|
||||||
|
// Note: See below for the definition of the bit operations.
|
||||||
|
//
|
||||||
|
if (SensorInterrupt_0_2ff && (!SensorInterrupt_0_3ff))
|
||||||
|
TimeStamp_Delta_sensor_0 <= TimeStamp_Delta_capt;
|
||||||
|
|
||||||
|
|
||||||
|
if (SensorInterrupt_1_2ff && (!SensorInterrupt_1_3ff))
|
||||||
|
TimeStamp_Delta_sensor_1 <= TimeStamp_Delta_capt;
|
||||||
|
|
||||||
|
|
||||||
|
if (SensorInterrupt_2_2ff && (!SensorInterrupt_2_3ff))
|
||||||
|
TimeStamp_Delta_sensor_2 <= TimeStamp_Delta_capt;
|
||||||
|
|
||||||
|
|
||||||
|
if (SensorInterrupt_3_2ff && (!SensorInterrupt_3_3ff))
|
||||||
|
TimeStamp_Delta_sensor_3 <= TimeStamp_Delta_capt;
|
||||||
|
|
||||||
|
// Set the Interrupt Status Mask bits
|
||||||
|
//
|
||||||
|
// Note: These bits are used "ANDed" with the write signal to clear
|
||||||
|
// individual status bits.
|
||||||
|
//
|
||||||
|
// The alternate way is to write the interrupt status once
|
||||||
|
// at the end of a series of SM code segments. However, there
|
||||||
|
// may be a significant amount of time between TimeStamp value
|
||||||
|
// capture and a single status being written to memory. This
|
||||||
|
// can allow the interrupt status to change after the TimeStamp
|
||||||
|
// is written to memory. This could result in the assumption
|
||||||
|
// of a good TimeStamp when, in fact, the TimeStamp is not
|
||||||
|
// valid.
|
||||||
|
//
|
||||||
|
if (SensorInterrupt_event_mask_we_dcd)
|
||||||
|
begin
|
||||||
|
SensorInterrupt_event_mask_0 <= MemReadDataIn[8];
|
||||||
|
SensorInterrupt_event_mask_1 <= MemReadDataIn[9];
|
||||||
|
SensorInterrupt_event_mask_2 <= MemReadDataIn[10];
|
||||||
|
SensorInterrupt_event_mask_3 <= MemReadDataIn[11];
|
||||||
|
end
|
||||||
|
|
||||||
|
// Set the interrupt event bit for each sensor when an interrupt is
|
||||||
|
// detected.
|
||||||
|
//
|
||||||
|
// Note: Without this "interrupt event bit" is may not be possible to
|
||||||
|
// know for certain if an interrupt happened. For example,
|
||||||
|
// a value of "0" may be correct given the right
|
||||||
|
// sampling period.
|
||||||
|
//
|
||||||
|
// These status bits assume a positive (i.e. low-to-high)
|
||||||
|
// interrupt assertion.
|
||||||
|
//
|
||||||
|
// All interrupts are cleared when this register is read.
|
||||||
|
//
|
||||||
|
if (SensorInterrupt_event_reg_we_dcd && SensorInterrupt_event_mask_0)
|
||||||
|
SensorInterrupt_0_o <= 1'h0;
|
||||||
|
else if (SensorInterrupt_0_2ff && (!SensorInterrupt_0_3ff))
|
||||||
|
SensorInterrupt_0_o <= 1'h1;
|
||||||
|
|
||||||
|
|
||||||
|
if (SensorInterrupt_event_reg_we_dcd && SensorInterrupt_event_mask_1)
|
||||||
|
SensorInterrupt_1_o <= 1'h0;
|
||||||
|
else if (SensorInterrupt_1_2ff && (!SensorInterrupt_1_3ff))
|
||||||
|
SensorInterrupt_1_o <= 1'h1;
|
||||||
|
|
||||||
|
|
||||||
|
if (SensorInterrupt_event_reg_we_dcd && SensorInterrupt_event_mask_2)
|
||||||
|
SensorInterrupt_2_o <= 1'h0;
|
||||||
|
else if (SensorInterrupt_2_2ff && (!SensorInterrupt_2_3ff))
|
||||||
|
SensorInterrupt_2_o <= 1'h1;
|
||||||
|
|
||||||
|
|
||||||
|
if (SensorInterrupt_event_reg_we_dcd && SensorInterrupt_event_mask_3)
|
||||||
|
SensorInterrupt_3_o <= 1'h0;
|
||||||
|
else if (SensorInterrupt_3_2ff && (!SensorInterrupt_3_3ff))
|
||||||
|
SensorInterrupt_3_o <= 1'h1;
|
||||||
|
|
||||||
|
|
||||||
|
// Mail Box Bit Counter
|
||||||
|
//
|
||||||
|
// Note: Reset Bit Counter between SM Sessions.
|
||||||
|
//
|
||||||
|
// This counter selects the Mail Box bits corresponding to each
|
||||||
|
// SM code segment.
|
||||||
|
//
|
||||||
|
if (!BusySM)
|
||||||
|
CtrlMailBoxSegmentCtr <= 6'h0;
|
||||||
|
else if (CtrlMailBoxSegmentCtr_ce)
|
||||||
|
CtrlMailBoxSegmentCtr <= CtrlMailBoxSegmentCtr + 1'b1;
|
||||||
|
|
||||||
|
CtrlMailBoxSegmentCtr_ce <= wb_cyc & wb_stb & wb_we & ~wb_ack_sm & CtrlMailBoxJumpInstCycle;
|
||||||
|
|
||||||
|
// Mail Box Table Address Pointer
|
||||||
|
//
|
||||||
|
// Note: This is the location in SM Memory where the Mail Box is
|
||||||
|
// located. Typically, the mail box will be in the last four
|
||||||
|
// 18-bit words in SM Memory.
|
||||||
|
//
|
||||||
|
// This value can be dynamically changed by instructions in SM
|
||||||
|
// memory.
|
||||||
|
//
|
||||||
|
if (control_mailbox_tbl_ptr_dcd)
|
||||||
|
CtrlMailBoxTablePtr <= MemReadDataIn[17:10];
|
||||||
|
|
||||||
|
// Mail Box Jump Address
|
||||||
|
//
|
||||||
|
// Note: This address must be temporarily storged while the Mail Box
|
||||||
|
// bits are being read from SM Memory.
|
||||||
|
//
|
||||||
|
// Based on the Mail Box bit for the current code segment, this
|
||||||
|
// jump address may or may not be used for a jump.
|
||||||
|
//
|
||||||
|
if (control_mailbox_jump_inst_ptr_dcd)
|
||||||
|
CtrlMailBoxJumpInstPtr <= MemReadDataIn[17:8];
|
||||||
|
|
||||||
|
// Mail Box Jump Decode Cycle Flag
|
||||||
|
//
|
||||||
|
// Note: This flags that the current SM write cycle is a Mail Box Jump
|
||||||
|
// decode operation.
|
||||||
|
//
|
||||||
|
// The data from SM Memory consist of Mail Box bits and should
|
||||||
|
// not be decoded as a SM "write" instruction would.
|
||||||
|
//
|
||||||
|
// The decode consists of selecting the correct bit from the
|
||||||
|
// Mail Box for the current SM code segment. Based on the state
|
||||||
|
// of this bit (i.e. 0 - No Jump; 1 - Jump), the SM instruction
|
||||||
|
// pointer will either proceed with the next instruction address
|
||||||
|
// or jump to a new code segment.
|
||||||
|
//
|
||||||
|
if (control_mailbox_jump_inst_ptr_dcd)
|
||||||
|
CtrlMailBoxJumpInstCycle <= 1'b1;
|
||||||
|
else if (CtrlMailBoxJumpInstCycle_ce)
|
||||||
|
CtrlMailBoxJumpInstCycle <= 1'b0;
|
||||||
|
|
||||||
|
CtrlMailBoxJumpInstCycle_ce <= wb_cyc & wb_stb & wb_we & wb_ack_sm & ~control_mailbox_jump_inst_ptr_dcd;
|
||||||
|
|
||||||
|
|
||||||
|
// Wait Instruction Register
|
||||||
|
//
|
||||||
|
if (control_wait_instr_reg_dcd || control_wait_instr_busy)
|
||||||
|
begin
|
||||||
|
control_wait_instr_cntr <= control_wait_instr_cntr_nxt;
|
||||||
|
control_wait_instr_cntr_tc <= control_wait_instr_cntr_tc_nxt;
|
||||||
|
end
|
||||||
|
|
||||||
|
control_wait_instr_busy <= control_wait_instr_busy_nxt;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// Define the Wait Instruction Busy signal
|
||||||
|
//
|
||||||
|
// Note: This busy starts with the first write and ends when the counter is done.
|
||||||
|
//
|
||||||
|
// This is an N-1 counter. Therefore, a value of "0" means an "N" of "1".
|
||||||
|
// Therefore, there should be one cycle of busy even with a value of "0".
|
||||||
|
//
|
||||||
|
assign control_wait_instr_busy_nxt = (~control_wait_instr_busy & control_wait_instr_reg_dcd)
|
||||||
|
| ( control_wait_instr_busy & ~control_wait_instr_cntr_tc);
|
||||||
|
|
||||||
|
|
||||||
|
// Define the operation of the Wait Instruction Counter
|
||||||
|
//
|
||||||
|
always @(MemReadDataIn or
|
||||||
|
control_wait_instr_busy or
|
||||||
|
control_wait_instr_cntr
|
||||||
|
)
|
||||||
|
begin
|
||||||
|
|
||||||
|
case({control_wait_instr_busy, MemReadDataIn[17]})
|
||||||
|
2'b00: // MSB == 0 then count 1-to-1
|
||||||
|
begin
|
||||||
|
control_wait_instr_cntr_nxt <= {4'h0, MemReadDataIn[16:8] };
|
||||||
|
control_wait_instr_cntr_tc_nxt <= ( MemReadDataIn[16:8] == 9'h0);
|
||||||
|
end
|
||||||
|
2'b01: // MSB == 1 then count 16-to-1
|
||||||
|
begin
|
||||||
|
control_wait_instr_cntr_nxt <= { MemReadDataIn[16:8], 4'hF}; // Remember: N-1 means that "0" should be one wait period
|
||||||
|
control_wait_instr_cntr_tc_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
2'b10: // Normal Count
|
||||||
|
begin
|
||||||
|
control_wait_instr_cntr_nxt <= control_wait_instr_cntr - 13'h1;
|
||||||
|
control_wait_instr_cntr_tc_nxt <= (control_wait_instr_cntr == 13'h1);
|
||||||
|
end
|
||||||
|
2'b11: // Normal Count - The value was shift << 4 so it is already 16x larger at loading time
|
||||||
|
begin
|
||||||
|
control_wait_instr_cntr_nxt <= control_wait_instr_cntr - 13'h1;
|
||||||
|
control_wait_instr_cntr_tc_nxt <= (control_wait_instr_cntr == 13'h1);
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// Use the "run" bit to signal when the statemachine is "busy" in addition to
|
||||||
|
// the statemachine busy bit.
|
||||||
|
//
|
||||||
|
assign BusyOut = RunSM | BusySM;
|
||||||
|
|
||||||
|
|
||||||
|
// Define the Sensor Manager Memory's read address
|
||||||
|
//
|
||||||
|
// Note: StateMachine is allowed to read all of SensorManager Memory
|
||||||
|
//
|
||||||
|
// The Sensor Manager Memory's "read" port is 10-bits (i.e. [9:0])
|
||||||
|
//
|
||||||
|
// Select the Mail Box Address pointer during Mail Box Jump operations.
|
||||||
|
// The location pointed to contains Mail Box Jump enable bits AND NOT
|
||||||
|
// SM instructions.
|
||||||
|
//
|
||||||
|
assign MemReadAddressOut = CtrlMailBoxJumpInstCycle ? {CtrlMailBoxTablePtr, CtrlMailBoxSegmentCtr[5:4]}
|
||||||
|
: StateMachineCtrlMemAddr ;
|
||||||
|
|
||||||
|
|
||||||
|
// Limit the register write function to the upper half of the Sensor Manager's Memory space
|
||||||
|
//
|
||||||
|
// Note: The Sensor Manager Memory's "write" port address is 10-bits (i.e. [9:0])
|
||||||
|
//
|
||||||
|
assign MemWriteAddressOut = CtrlReceiveAddressReg;
|
||||||
|
|
||||||
|
|
||||||
|
// Define the Data to be written to Sensor Memory
|
||||||
|
//
|
||||||
|
// Note: The I2C Master IP only outputs byte wide values
|
||||||
|
//
|
||||||
|
// For the current design, the following are read back:
|
||||||
|
// - I2C Master IP is read back
|
||||||
|
// - TimeStamp registers for four sensors
|
||||||
|
// - TimeSTamp related interrupt event register
|
||||||
|
//
|
||||||
|
// Only the I2C Master IP was supported in previous designs
|
||||||
|
//
|
||||||
|
always @(MemReadDataIn or
|
||||||
|
MemWriteDataOut or
|
||||||
|
i2c_masterDataToMem or
|
||||||
|
TimeStamp_Delta_sensor_0 or
|
||||||
|
TimeStamp_Delta_sensor_1 or
|
||||||
|
TimeStamp_Delta_sensor_2 or
|
||||||
|
TimeStamp_Delta_sensor_3 or
|
||||||
|
TimeStamp_Delta_readback or
|
||||||
|
SensorInterrupt_0_o or
|
||||||
|
SensorInterrupt_1_o or
|
||||||
|
SensorInterrupt_2_o or
|
||||||
|
SensorInterrupt_3_o
|
||||||
|
)
|
||||||
|
begin
|
||||||
|
case(MemReadDataIn[7:3])
|
||||||
|
I2C_MASTER_ADR: MemWriteDataOut <= {1'b0, i2c_masterDataToMem};
|
||||||
|
TIMESTAMP_DELTA_ADR:
|
||||||
|
begin
|
||||||
|
case(MemReadDataIn[2:0])
|
||||||
|
TIMESTAMP_DELTA_SENSOR_0 : MemWriteDataOut <= {1'b0, TimeStamp_Delta_sensor_0};
|
||||||
|
TIMESTAMP_DELTA_SENSOR_1 : MemWriteDataOut <= {1'b0, TimeStamp_Delta_sensor_1};
|
||||||
|
TIMESTAMP_DELTA_SENSOR_2 : MemWriteDataOut <= {1'b0, TimeStamp_Delta_sensor_2};
|
||||||
|
TIMESTAMP_DELTA_SENSOR_3 : MemWriteDataOut <= {1'b0, TimeStamp_Delta_sensor_3};
|
||||||
|
TIMESTAMP_DELTA_GENERIC_LSB : MemWriteDataOut <= {1'b0, TimeStamp_Delta_readback[7:0]};
|
||||||
|
TIMESTAMP_DELTA_GENERIC_MSB : MemWriteDataOut <= {1'b0, TimeStamp_Delta_readback[15:8]};
|
||||||
|
TIMESTAMP_DELTA_INT_EVENT : MemWriteDataOut <= {4'h0, SensorInterrupt_3_o,
|
||||||
|
SensorInterrupt_2_o,
|
||||||
|
SensorInterrupt_1_o,
|
||||||
|
SensorInterrupt_0_o};
|
||||||
|
default: MemWriteDataOut <= {1'b0, i2c_masterDataToMem};
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
default: MemWriteDataOut <= {1'b0, i2c_masterDataToMem};
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// Define the Sensor Manager Memory's clock
|
||||||
|
//
|
||||||
|
// Note: This is currently a flow through but this may change in future designs.
|
||||||
|
//
|
||||||
|
assign MemClockOut = ClockIn;
|
||||||
|
|
||||||
|
|
||||||
|
// Combine all Wishbone bus acknowledges
|
||||||
|
//
|
||||||
|
// Note: Only one acknowledge should happen at a time.
|
||||||
|
//
|
||||||
|
assign wb_ack = wb_ack_sm | I2C_wb_ack_i;
|
||||||
|
|
||||||
|
|
||||||
|
// Multiplex the address to the I2C Master IP when performing an I2C read
|
||||||
|
//
|
||||||
|
// Note: The address must be switched from the I2C "Control" Register to the I2C "Transmit/Receive" data address.
|
||||||
|
//
|
||||||
|
// This only affects the I2C Master IP and does not affect any other device on the Wishbone bus.
|
||||||
|
//
|
||||||
|
assign I2C_wb_adr_o = ((MemReadDataIn[7:0] == {I2C_MASTER_ADR, I2C_MASTER_CR}) & MemReadDataIn[13] & (~wb_we))
|
||||||
|
? I2C_MASTER_TXR : MemReadDataIn[2:0];
|
||||||
|
|
||||||
|
|
||||||
|
//------Instantiate Modules----------------
|
||||||
|
//
|
||||||
|
|
||||||
|
// Instantiate the Sensor Manager Statemachine
|
||||||
|
//
|
||||||
|
StateMachine StateMachine_inst (
|
||||||
|
|
||||||
|
.CLK_IN ( ClockIn ),
|
||||||
|
.RESET_IN ( ResetIn ),
|
||||||
|
|
||||||
|
.RUNTIME_ADDRESS ( CtrlRunTimeAddressReg ),
|
||||||
|
.CONTROL_JUMP_REG_DCD ( control_jump_reg_dcd ),
|
||||||
|
.SAVE_REG_2_MEM ( save_reg_2_mem ),
|
||||||
|
|
||||||
|
.MAILBOX_JUMP_INST_CYCLE (CtrlMailBoxJumpInstCycle ),
|
||||||
|
.MAILBOX_JUMP_INST_PTR (CtrlMailBoxJumpInstPtr ),
|
||||||
|
.MAILBOX_SEGMENT_CTR (CtrlMailBoxSegmentCtr[3:0] ),
|
||||||
|
|
||||||
|
.WB_ACK_I ( wb_ack ),
|
||||||
|
.WB_BUSY_I ( I2C_tip_i | control_wait_instr_busy ),
|
||||||
|
.WB_BUSY_POLL_I ( wb_busy_poll ),
|
||||||
|
|
||||||
|
.WB_WE_O ( wb_we ),
|
||||||
|
.WB_STB_O ( wb_stb ),
|
||||||
|
.WB_CYC_O ( wb_cyc ),
|
||||||
|
|
||||||
|
.SM_CNTL_REG_RUN ( RunSM ),
|
||||||
|
.SM_READ_DATA ( MemReadDataIn ), // Data "Byte" is MemReadDataIn[17:8]
|
||||||
|
|
||||||
|
.SM_INSTR_PTR ( StateMachineCtrlMemAddr ),
|
||||||
|
.SM_READ_SELECT ( MemReadEnableOut ),
|
||||||
|
|
||||||
|
.SM_WRITE_SELECT ( MemWriteEnableOut ),
|
||||||
|
.SM_BUSY ( BusySM )
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// test points
|
||||||
|
//
|
||||||
|
assign TP1 = I2C_tip_i;
|
||||||
|
assign TP2 = BusyOut;
|
||||||
|
assign TP3 = 0;
|
||||||
|
|
||||||
|
// Logic to generate SmClockSelect_o
|
||||||
|
wire d_SmClockSelect;
|
||||||
|
|
||||||
|
always @(posedge ClockIn or posedge ResetIn)
|
||||||
|
begin
|
||||||
|
if (ResetIn)
|
||||||
|
begin
|
||||||
|
s1_BusyOut <= 1'b0;
|
||||||
|
s2_BusyOut <= 1'b0;
|
||||||
|
SmClockSelect_o <= 1'b0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
s1_BusyOut <= BusyOut;
|
||||||
|
s2_BusyOut <= s1_BusyOut;
|
||||||
|
SmClockSelect_o <= d_SmClockSelect;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign d_SmClockSelect = SmClockSelect_o ? ((!s1_BusyOut && s2_BusyOut) ? 1'b0 : 1'b1) : ((StartFromFFE_1ff ^ StartFromFFE_2ff) ? 1'b1: 1'b0);
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,608 @@
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// title : Sensor Manager Statemachine
|
||||||
|
// project : ULP Sensor Hub
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// file : StateMachine.v
|
||||||
|
// author : Glen Gomes
|
||||||
|
// company : QuickLogic Corp
|
||||||
|
// created : 2013/12/06
|
||||||
|
// last update : 2013/12/06
|
||||||
|
// platform : PolarPro III
|
||||||
|
// standard : Verilog 2001
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// description: The Sensor Manger Statemachine is responsible for controlling the
|
||||||
|
// operations of the Sensor Manager. These include performing
|
||||||
|
// transfers between Sensor Memory and various registers.
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// copyright (c) 2013
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// revisions :
|
||||||
|
// date version author description
|
||||||
|
// 2013/12/06 1.0 Glen Gomes created
|
||||||
|
// 2014/05/27 1.1 Glen Gomes Updated for Tay
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Comments: This solution is specifically for use with the QuickLogic
|
||||||
|
// PolarPro III device.
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1ns/10ps
|
||||||
|
|
||||||
|
module StateMachine (
|
||||||
|
|
||||||
|
CLK_IN,
|
||||||
|
RESET_IN,
|
||||||
|
|
||||||
|
RUNTIME_ADDRESS,
|
||||||
|
CONTROL_JUMP_REG_DCD,
|
||||||
|
SAVE_REG_2_MEM,
|
||||||
|
|
||||||
|
MAILBOX_JUMP_INST_CYCLE,
|
||||||
|
MAILBOX_JUMP_INST_PTR,
|
||||||
|
MAILBOX_SEGMENT_CTR,
|
||||||
|
|
||||||
|
WB_ACK_I,
|
||||||
|
WB_BUSY_I,
|
||||||
|
WB_BUSY_POLL_I,
|
||||||
|
|
||||||
|
WB_WE_O,
|
||||||
|
WB_STB_O,
|
||||||
|
WB_CYC_O,
|
||||||
|
|
||||||
|
SM_CNTL_REG_RUN,
|
||||||
|
SM_READ_DATA,
|
||||||
|
|
||||||
|
SM_INSTR_PTR,
|
||||||
|
SM_READ_SELECT,
|
||||||
|
|
||||||
|
SM_WRITE_SELECT,
|
||||||
|
|
||||||
|
SM_BUSY
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//-----Port Signals--------------------
|
||||||
|
//
|
||||||
|
|
||||||
|
input CLK_IN;
|
||||||
|
input RESET_IN;
|
||||||
|
|
||||||
|
input [9:0] RUNTIME_ADDRESS;
|
||||||
|
input CONTROL_JUMP_REG_DCD;
|
||||||
|
input SAVE_REG_2_MEM;
|
||||||
|
|
||||||
|
input MAILBOX_JUMP_INST_CYCLE;
|
||||||
|
input [9:0] MAILBOX_JUMP_INST_PTR;
|
||||||
|
input [3:0] MAILBOX_SEGMENT_CTR;
|
||||||
|
|
||||||
|
input WB_ACK_I;
|
||||||
|
input WB_BUSY_I;
|
||||||
|
input WB_BUSY_POLL_I;
|
||||||
|
|
||||||
|
output WB_WE_O;
|
||||||
|
output WB_STB_O;
|
||||||
|
output WB_CYC_O;
|
||||||
|
|
||||||
|
input SM_CNTL_REG_RUN;
|
||||||
|
input [17:0] SM_READ_DATA;
|
||||||
|
|
||||||
|
output [9:0] SM_INSTR_PTR;
|
||||||
|
output SM_READ_SELECT;
|
||||||
|
|
||||||
|
output SM_WRITE_SELECT;
|
||||||
|
|
||||||
|
output SM_BUSY;
|
||||||
|
|
||||||
|
|
||||||
|
wire CLK_IN;
|
||||||
|
wire RESET_IN;
|
||||||
|
|
||||||
|
wire [9:0] RUNTIME_ADDRESS;
|
||||||
|
wire CONTROL_JUMP_REG_DCD;
|
||||||
|
wire SAVE_REG_2_MEM;
|
||||||
|
|
||||||
|
wire MAILBOX_JUMP_INST_CYCLE;
|
||||||
|
wire [9:0] MAILBOX_JUMP_INST_PTR;
|
||||||
|
wire [3:0] MAILBOX_SEGMENT_CTR;
|
||||||
|
|
||||||
|
wire WB_ACK_I;
|
||||||
|
wire WB_BUSY_I;
|
||||||
|
wire WB_BUSY_POLL_I;
|
||||||
|
|
||||||
|
reg WB_WE_O;
|
||||||
|
reg wb_we_o_nxt;
|
||||||
|
|
||||||
|
reg WB_STB_O;
|
||||||
|
reg wb_stb_o_nxt;
|
||||||
|
|
||||||
|
reg WB_CYC_O;
|
||||||
|
reg wb_cyc_o_nxt;
|
||||||
|
|
||||||
|
wire SM_CNTL_REG_RUN;
|
||||||
|
wire [17:0] SM_READ_DATA;
|
||||||
|
|
||||||
|
reg [9:0] SM_INSTR_PTR;
|
||||||
|
reg [9:0] sm_instr_ptr_nxt;
|
||||||
|
|
||||||
|
reg SM_READ_SELECT;
|
||||||
|
reg sm_read_select_nxt;
|
||||||
|
|
||||||
|
reg SM_WRITE_SELECT;
|
||||||
|
reg sm_write_select_nxt;
|
||||||
|
|
||||||
|
reg SM_BUSY;
|
||||||
|
reg sm_busy_nxt;
|
||||||
|
|
||||||
|
//-----Internal Signals--------------------
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define the Statemachine registers
|
||||||
|
//
|
||||||
|
reg [3:0] sensor_manager_sm;
|
||||||
|
reg [3:0] sensor_manager_sm_nxt;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define the Instruction Pointer variables
|
||||||
|
//
|
||||||
|
|
||||||
|
reg sm_instr_ptr_ce;
|
||||||
|
reg sm_instr_ptr_ce_nxt;
|
||||||
|
|
||||||
|
reg sm_instr_ptr_ld;
|
||||||
|
reg sm_instr_ptr_ld_nxt;
|
||||||
|
|
||||||
|
//reg sm_instr_ptr_sel;
|
||||||
|
//reg sm_instr_ptr_sel_nxt;
|
||||||
|
|
||||||
|
reg mailbox_jump_inst_ptr_ld;
|
||||||
|
|
||||||
|
|
||||||
|
//------Define Parameters---------
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define the Sensor Manager Statemachine States
|
||||||
|
//
|
||||||
|
// Note: These states are chosen to allow for overlap of various signals
|
||||||
|
// during operation. This overlap should help reduce timing
|
||||||
|
// dependancies.
|
||||||
|
//
|
||||||
|
parameter SM_IDLE = 4'h0;
|
||||||
|
parameter SM_INC_PTR = 4'h1;
|
||||||
|
parameter SM_INST_RD = 4'h2;
|
||||||
|
//parameter SM_INST_DCD = 4'h3; // Note: Will be used for TimeStamp Support in a future design
|
||||||
|
parameter SM_REG_WR = 4'h4;
|
||||||
|
parameter SM_REG_RD = 4'h5;
|
||||||
|
parameter SM_WAIT_BUSY_ON = 4'h6;
|
||||||
|
parameter SM_WAIT_BUSY_OFF = 4'h7;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Sensor Manager Initialization Start Address
|
||||||
|
//
|
||||||
|
// Note: The previous IP used the reset of the "RuntimeAddress" register to
|
||||||
|
// select the sensor initialization code. This value explicity selects
|
||||||
|
// the value for the start (or re-start) of initialization.
|
||||||
|
//
|
||||||
|
parameter SM_INIT_INSTR_ADR = 10'h0; // Address for the start in initialization instructions
|
||||||
|
|
||||||
|
|
||||||
|
//------Logic Operations----------
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define the Instruction Pointer
|
||||||
|
//
|
||||||
|
// Note: This pointer can start at either the sensor initialization code start
|
||||||
|
// address or the run-time code start address.
|
||||||
|
//
|
||||||
|
always @( SM_INSTR_PTR or
|
||||||
|
sm_instr_ptr_ld or
|
||||||
|
sm_instr_ptr_ce or
|
||||||
|
SM_READ_DATA or
|
||||||
|
CONTROL_JUMP_REG_DCD or
|
||||||
|
RUNTIME_ADDRESS or
|
||||||
|
MAILBOX_JUMP_INST_CYCLE or
|
||||||
|
MAILBOX_JUMP_INST_PTR
|
||||||
|
)
|
||||||
|
begin
|
||||||
|
case({sm_instr_ptr_ld, sm_instr_ptr_ce})
|
||||||
|
2'b00: sm_instr_ptr_nxt <= SM_INSTR_PTR; // Hold Current Value
|
||||||
|
2'b01: sm_instr_ptr_nxt <= SM_INSTR_PTR + 1'b1; // Increment to the next address
|
||||||
|
2'b10:
|
||||||
|
begin
|
||||||
|
case({MAILBOX_JUMP_INST_CYCLE, CONTROL_JUMP_REG_DCD})
|
||||||
|
2'b00: sm_instr_ptr_nxt <= RUNTIME_ADDRESS; // Run-time Code Address
|
||||||
|
2'b01: sm_instr_ptr_nxt <= SM_READ_DATA[17:8]; // Jump Address
|
||||||
|
default: sm_instr_ptr_nxt <= MAILBOX_JUMP_INST_PTR; // Mail Box Jump Address
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
2'b11: sm_instr_ptr_nxt <= SM_INSTR_PTR; // Hold Current Value
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// Select the Mail Box Jump Enable Bit
|
||||||
|
//
|
||||||
|
// Note: Mail Box Jump enable bits are spread over 16-bits of the 18-bits from
|
||||||
|
// SM Memory.
|
||||||
|
//
|
||||||
|
always @( MAILBOX_SEGMENT_CTR or
|
||||||
|
SM_READ_DATA or
|
||||||
|
mailbox_jump_inst_ptr_ld
|
||||||
|
)
|
||||||
|
begin
|
||||||
|
case(MAILBOX_SEGMENT_CTR)
|
||||||
|
4'h0: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[0];
|
||||||
|
4'h1: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[1];
|
||||||
|
4'h2: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[2];
|
||||||
|
4'h3: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[3];
|
||||||
|
4'h4: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[4];
|
||||||
|
4'h5: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[5];
|
||||||
|
4'h6: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[6];
|
||||||
|
4'h7: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[7];
|
||||||
|
4'h8: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[9];
|
||||||
|
4'h9: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[10];
|
||||||
|
4'hA: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[11];
|
||||||
|
4'hB: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[12];
|
||||||
|
4'hC: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[13];
|
||||||
|
4'hD: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[14];
|
||||||
|
4'hE: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[15];
|
||||||
|
4'hF: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[16];
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// Define the registers associated with the Sensor Manager Statemachine
|
||||||
|
//
|
||||||
|
always @(posedge CLK_IN or posedge RESET_IN)
|
||||||
|
begin
|
||||||
|
if (RESET_IN)
|
||||||
|
begin
|
||||||
|
sensor_manager_sm <= SM_IDLE;
|
||||||
|
|
||||||
|
SM_INSTR_PTR <= 10'h0;
|
||||||
|
sm_instr_ptr_ce <= 1'b0;
|
||||||
|
sm_instr_ptr_ld <= 1'b0;
|
||||||
|
|
||||||
|
WB_WE_O <= 1'b0;
|
||||||
|
WB_STB_O <= 1'b0;
|
||||||
|
WB_CYC_O <= 1'b0;
|
||||||
|
|
||||||
|
SM_READ_SELECT <= 1'b0;
|
||||||
|
SM_WRITE_SELECT <= 1'b0;
|
||||||
|
|
||||||
|
SM_BUSY <= 1'b0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
sensor_manager_sm <= sensor_manager_sm_nxt;
|
||||||
|
|
||||||
|
SM_INSTR_PTR <= sm_instr_ptr_nxt;
|
||||||
|
sm_instr_ptr_ce <= sm_instr_ptr_ce_nxt;
|
||||||
|
sm_instr_ptr_ld <= sm_instr_ptr_ld_nxt;
|
||||||
|
|
||||||
|
WB_WE_O <= wb_we_o_nxt;
|
||||||
|
WB_STB_O <= wb_stb_o_nxt;
|
||||||
|
WB_CYC_O <= wb_cyc_o_nxt;
|
||||||
|
|
||||||
|
SM_READ_SELECT <= sm_read_select_nxt;
|
||||||
|
SM_WRITE_SELECT <= sm_write_select_nxt;
|
||||||
|
|
||||||
|
SM_BUSY <= sm_busy_nxt;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// Define the Sensor Manager Statemachine
|
||||||
|
//
|
||||||
|
always @( sensor_manager_sm or
|
||||||
|
SM_CNTL_REG_RUN or
|
||||||
|
CONTROL_JUMP_REG_DCD or
|
||||||
|
SAVE_REG_2_MEM or
|
||||||
|
WB_BUSY_I or
|
||||||
|
WB_BUSY_POLL_I or
|
||||||
|
WB_ACK_I or
|
||||||
|
MAILBOX_JUMP_INST_CYCLE or
|
||||||
|
mailbox_jump_inst_ptr_ld
|
||||||
|
)
|
||||||
|
begin
|
||||||
|
case(sensor_manager_sm)
|
||||||
|
SM_IDLE:
|
||||||
|
begin
|
||||||
|
|
||||||
|
case(SM_CNTL_REG_RUN)
|
||||||
|
1'b0: // No Activity
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_IDLE;
|
||||||
|
|
||||||
|
sm_busy_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
1'b1: // Start at the Sensor Run-Time Code
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_INC_PTR;
|
||||||
|
|
||||||
|
sm_busy_nxt <= 1'b1;
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b1;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_read_select_nxt <= 1'b0;
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b0;
|
||||||
|
wb_stb_o_nxt <= 1'b0;
|
||||||
|
wb_cyc_o_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
SM_INC_PTR:
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_INST_RD;
|
||||||
|
|
||||||
|
sm_busy_nxt <= 1'b1;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_read_select_nxt <= 1'b1;
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b0;
|
||||||
|
wb_stb_o_nxt <= 1'b0;
|
||||||
|
wb_cyc_o_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
SM_INST_RD:
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_REG_WR;
|
||||||
|
|
||||||
|
sm_busy_nxt <= 1'b1;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_read_select_nxt <= 1'b0;
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b1;
|
||||||
|
wb_stb_o_nxt <= 1'b1;
|
||||||
|
wb_cyc_o_nxt <= 1'b1;
|
||||||
|
end
|
||||||
|
SM_REG_WR:
|
||||||
|
begin
|
||||||
|
|
||||||
|
sm_read_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
case(SM_CNTL_REG_RUN)
|
||||||
|
1'b0: // A write of "0" to bit "0" of the Command register at address "0" turns off
|
||||||
|
// the Sensor Manager's Statemachine
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_IDLE;
|
||||||
|
|
||||||
|
sm_busy_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b0;
|
||||||
|
wb_stb_o_nxt <= 1'b0;
|
||||||
|
wb_cyc_o_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
1'b1: // Sensor Manager Statemachine is not stopped; continue processing
|
||||||
|
begin
|
||||||
|
sm_busy_nxt <= 1'b1;
|
||||||
|
|
||||||
|
case({WB_BUSY_POLL_I, WB_ACK_I})
|
||||||
|
2'b00: // Wait for Wish Bone Acknowledge and no need to wait for transfer complete
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_REG_WR;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b1;
|
||||||
|
wb_stb_o_nxt <= 1'b1;
|
||||||
|
wb_cyc_o_nxt <= 1'b1;
|
||||||
|
end
|
||||||
|
2'b01: // Wish Bone Acknowledge Received and no need to wait for transfer complete
|
||||||
|
begin
|
||||||
|
case(SAVE_REG_2_MEM)
|
||||||
|
1'b0:
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_INC_PTR;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= CONTROL_JUMP_REG_DCD
|
||||||
|
| (MAILBOX_JUMP_INST_CYCLE & mailbox_jump_inst_ptr_ld);
|
||||||
|
|
||||||
|
sm_instr_ptr_ce_nxt <= ~ CONTROL_JUMP_REG_DCD
|
||||||
|
& ~ MAILBOX_JUMP_INST_CYCLE;
|
||||||
|
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b0;
|
||||||
|
wb_stb_o_nxt <= 1'b0;
|
||||||
|
wb_cyc_o_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
1'b1:
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_REG_RD;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_write_select_nxt <= 1'b1;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b0;
|
||||||
|
wb_stb_o_nxt <= 1'b1;
|
||||||
|
wb_cyc_o_nxt <= 1'b1;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
2'b10: // Wait for Wish Bone Acknowledge and will need to wait for transfer complete
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_REG_WR;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b1;
|
||||||
|
wb_stb_o_nxt <= 1'b1;
|
||||||
|
wb_cyc_o_nxt <= 1'b1;
|
||||||
|
end
|
||||||
|
2'b11: // Acknowledge received but need to wait for transfer complete
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_WAIT_BUSY_ON;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b0;
|
||||||
|
wb_stb_o_nxt <= 1'b0;
|
||||||
|
wb_cyc_o_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
SM_REG_RD:
|
||||||
|
begin
|
||||||
|
sm_busy_nxt <= 1'b1;
|
||||||
|
|
||||||
|
sm_read_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b0;
|
||||||
|
|
||||||
|
case(WB_ACK_I)
|
||||||
|
1'b0: // Waiting for Wish Bone Acknowledge
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_REG_RD;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_write_select_nxt <= 1'b1;
|
||||||
|
|
||||||
|
wb_stb_o_nxt <= 1'b1;
|
||||||
|
wb_cyc_o_nxt <= 1'b1;
|
||||||
|
end
|
||||||
|
1'b1: // Got Wish Bone Acknowledge
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_INC_PTR;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= CONTROL_JUMP_REG_DCD;
|
||||||
|
sm_instr_ptr_ce_nxt <= ~CONTROL_JUMP_REG_DCD;
|
||||||
|
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_stb_o_nxt <= 1'b0;
|
||||||
|
wb_cyc_o_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
SM_WAIT_BUSY_ON:
|
||||||
|
begin
|
||||||
|
sm_busy_nxt <= 1'b1;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_read_select_nxt <= 1'b0;
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b0;
|
||||||
|
wb_stb_o_nxt <= 1'b0;
|
||||||
|
wb_cyc_o_nxt <= 1'b0;
|
||||||
|
|
||||||
|
case(WB_BUSY_I)
|
||||||
|
1'b0: sensor_manager_sm_nxt <= SM_WAIT_BUSY_ON; // Wait for Busy from I/F
|
||||||
|
1'b1: sensor_manager_sm_nxt <= SM_WAIT_BUSY_OFF; // Got Busy from I/F
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
SM_WAIT_BUSY_OFF:
|
||||||
|
begin
|
||||||
|
sm_busy_nxt <= 1'b1;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_read_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b0;
|
||||||
|
|
||||||
|
case({SAVE_REG_2_MEM, WB_BUSY_I})
|
||||||
|
2'b00: // Wishbone transfer complete; no need to write anything to Sensor Manager Memory
|
||||||
|
//
|
||||||
|
// Note: Writes to the command register do not enter this state.
|
||||||
|
// Therefore, there is no need to check for the end of processing.
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_INC_PTR;
|
||||||
|
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b1;
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_stb_o_nxt <= 1'b0;
|
||||||
|
wb_cyc_o_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
2'b01: // Wait for Wishbone transfer to complete
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_WAIT_BUSY_OFF;
|
||||||
|
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_stb_o_nxt <= 1'b0;
|
||||||
|
wb_cyc_o_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
2'b10: // Wishbone transfer complete; Write resulting register value to Sensor Manager Memory
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_REG_RD;
|
||||||
|
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
sm_write_select_nxt <= 1'b1;
|
||||||
|
|
||||||
|
wb_stb_o_nxt <= 1'b1;
|
||||||
|
wb_cyc_o_nxt <= 1'b1;
|
||||||
|
end
|
||||||
|
2'b11: // Wait for Wishbone transfer to complete
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_WAIT_BUSY_OFF;
|
||||||
|
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_stb_o_nxt <= 1'b0;
|
||||||
|
wb_cyc_o_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
default:
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_IDLE;
|
||||||
|
|
||||||
|
sm_busy_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_read_select_nxt <= 1'b0;
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b0;
|
||||||
|
wb_stb_o_nxt <= 1'b0;
|
||||||
|
wb_cyc_o_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,128 @@
|
||||||
|
|
||||||
|
`timescale 1ns / 10ps
|
||||||
|
|
||||||
|
module SystemClockControl (
|
||||||
|
OperatingClockRef_i,
|
||||||
|
Clock32KIn_i,
|
||||||
|
SPIClock_i,
|
||||||
|
ResetIn_i,
|
||||||
|
|
||||||
|
FfeClkSelect_i,
|
||||||
|
SmClkSelect_i,
|
||||||
|
SmSpeedSelect_i,
|
||||||
|
SpiClkSelect_i,
|
||||||
|
ClkSourceSelect_i,
|
||||||
|
Clk32KhzEnable_i,
|
||||||
|
MainClkEnable_i,
|
||||||
|
FfeClkEnable_i,
|
||||||
|
CM_AutoDrain_Busy,
|
||||||
|
|
||||||
|
SmClock_o,
|
||||||
|
FfeClock_o,
|
||||||
|
FfeClock_x2_o,
|
||||||
|
clock_32KHz_o,
|
||||||
|
multiplierClk_o,
|
||||||
|
ClockGen_State_o,
|
||||||
|
CM_FIFO_ReadClk,
|
||||||
|
|
||||||
|
clk_ringosc_i,
|
||||||
|
clk_ringosc_x2_i,
|
||||||
|
enable_i,
|
||||||
|
clk_cal_value_o,
|
||||||
|
assp_ringosc_en_o
|
||||||
|
);
|
||||||
|
|
||||||
|
// IO Declaration
|
||||||
|
input OperatingClockRef_i;
|
||||||
|
input Clock32KIn_i;
|
||||||
|
input SPIClock_i;
|
||||||
|
input ResetIn_i;
|
||||||
|
|
||||||
|
input [2:0] FfeClkSelect_i;
|
||||||
|
input [2:0] SmClkSelect_i;
|
||||||
|
input SmSpeedSelect_i;
|
||||||
|
input SpiClkSelect_i;
|
||||||
|
input ClkSourceSelect_i;
|
||||||
|
input Clk32KhzEnable_i;
|
||||||
|
input MainClkEnable_i;
|
||||||
|
input FfeClkEnable_i;
|
||||||
|
input CM_AutoDrain_Busy;
|
||||||
|
|
||||||
|
output SmClock_o;
|
||||||
|
output FfeClock_o;
|
||||||
|
output FfeClock_x2_o;
|
||||||
|
output clock_32KHz_o;
|
||||||
|
output multiplierClk_o;
|
||||||
|
output [3:0] ClockGen_State_o;
|
||||||
|
output CM_FIFO_ReadClk;
|
||||||
|
|
||||||
|
input clk_ringosc_i;
|
||||||
|
input clk_ringosc_x2_i;
|
||||||
|
input enable_i;
|
||||||
|
output [15:0] clk_cal_value_o;
|
||||||
|
output assp_ringosc_en_o;
|
||||||
|
|
||||||
|
reg multiplierClk_o;
|
||||||
|
wire [3:0] ClockGen_State_o;
|
||||||
|
wire CM_FIFO_ReadClk;
|
||||||
|
wire assp_ringosc_en_o;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Internal Signals Declaration
|
||||||
|
wire highSpeedClock, highSpeedClock_buff, highSpeedClock_x2_buff;
|
||||||
|
reg [6:0] ClockDiv;
|
||||||
|
wire FfeClock;
|
||||||
|
reg SmClock;
|
||||||
|
wire RingOscEnable;
|
||||||
|
wire ring_osc_clk;
|
||||||
|
wire OperatingClockRef;
|
||||||
|
|
||||||
|
|
||||||
|
// Operations
|
||||||
|
|
||||||
|
// Gating the enternal osc
|
||||||
|
// assign OperatingClockRef = OperatingClockRef_i && MainClkEnable_i;
|
||||||
|
assign OperatingClockRef = OperatingClockRef_i;
|
||||||
|
|
||||||
|
// CM FIFO AutoDrain Read Clock
|
||||||
|
// assign CM_FIFO_ReadClk = CM_AutoDrain_Busy ? (FfeClock && FfeClkEnable_i): SPIClock_i;
|
||||||
|
assign CM_FIFO_ReadClk = CM_AutoDrain_Busy ? highSpeedClock_buff : SPIClock_i;
|
||||||
|
|
||||||
|
// Ring Osclilator enable when the when weither FFE or SM is busy
|
||||||
|
// assign RingOscEnable = !ResetIn_i && MainClkEnable_i && ClkSourceSelect_i;
|
||||||
|
|
||||||
|
// Logic to gate 32KHz clock when the ULPSH goes to sleep
|
||||||
|
// Only static power consumption
|
||||||
|
assign clock_32KHz_o = Clock32KIn_i && Clk32KhzEnable_i;
|
||||||
|
|
||||||
|
// Logic to select between the external high speed clock and the internal ring oscillation
|
||||||
|
// and main clock division
|
||||||
|
// assign highSpeedClock = ClkSourceSelect_i ? ring_osc_clk : OperatingClockRef;
|
||||||
|
buff buff_highSpeedClock (.A(clk_ringosc_i), .Q(highSpeedClock_buff)); // don't use a clock network for this
|
||||||
|
//pragma attribute buff_highSpeedClock dont_touch true
|
||||||
|
|
||||||
|
buff buff_highSpeedClock_x2 (.A(clk_ringosc_x2_i), .Q(highSpeedClock_x2_buff)); // don't use a clock network for this
|
||||||
|
//pragma attribute buff_highSpeedClock_x2 dont_touch true
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// FFE CLK and SM CLK select and masking
|
||||||
|
// assign FfeClock_o = SpiClkSelect_i ? SPIClock_i : FfeClock && FfeClkEnable_i;
|
||||||
|
// assign SmClock_o = SmSpeedSelect_i ? SmClock : (SpiClkSelect_i ? SPIClock_i : FfeClock);
|
||||||
|
assign FfeClock_o = SpiClkSelect_i ? SPIClock_i : highSpeedClock_buff;
|
||||||
|
assign FfeClock_x2_o = SpiClkSelect_i ? SPIClock_i : highSpeedClock_x2_buff;
|
||||||
|
assign SmClock_o = SpiClkSelect_i ? SPIClock_i : highSpeedClock_buff;
|
||||||
|
|
||||||
|
|
||||||
|
ring_osc_adjust ring_osc_adjust_1 (
|
||||||
|
.reset_i ( ResetIn_i ),
|
||||||
|
.clk_ringosc_i ( clk_ringosc_i ),
|
||||||
|
.clk_32khz_i ( Clock32KIn_i ),
|
||||||
|
.enable_i ( enable_i ),
|
||||||
|
.cal_val_o ( clk_cal_value_o )
|
||||||
|
);
|
||||||
|
|
||||||
|
assign assp_ringosc_en_o = ClkSourceSelect_i || MainClkEnable_i;
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,731 @@
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------------------
|
||||||
|
Title: TLC.v
|
||||||
|
Description:
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------------------
|
||||||
|
Revision History:
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------------------
|
||||||
|
To Do:
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
`timescale 1ns / 10ps
|
||||||
|
|
||||||
|
`include "SensorHubDefines.v"
|
||||||
|
`include "ulpsh_rtl_defines.v"
|
||||||
|
|
||||||
|
module TLC (
|
||||||
|
// General interface
|
||||||
|
input SPI_SCLK,
|
||||||
|
input FFE_Clock,
|
||||||
|
input Clock32KIn,
|
||||||
|
input ResetIn,
|
||||||
|
output SW_Reset,
|
||||||
|
|
||||||
|
output reg RingOsc_cal_en,
|
||||||
|
output reg [2:0] RingOsc_select,
|
||||||
|
input [15:0] RingOsc_cal_value,
|
||||||
|
|
||||||
|
input I2C_Master_Error,
|
||||||
|
input FFEBusyIn,
|
||||||
|
input SMBusyIn,
|
||||||
|
input SMOverrunIn,
|
||||||
|
output StartFFEOut,
|
||||||
|
// output InitSMOut, // Removed for Rel 0 on 6/18
|
||||||
|
output StartSMOut,
|
||||||
|
output reg [15:0] TimeStampOut,
|
||||||
|
output reg TimeStampOut_Tog,
|
||||||
|
output UseFastClockOut,
|
||||||
|
|
||||||
|
input [7:0] InterruptMsgFromFFEIn,
|
||||||
|
output InterruptPinOut,
|
||||||
|
input SensorInterruptIn,
|
||||||
|
|
||||||
|
output [31:0] FFE_Mailbox_Out,
|
||||||
|
|
||||||
|
input [9:0] CtrlRunTimeAddressReg, // Expanded for Rel 0 on 6/18
|
||||||
|
output reg [9:0] CtrlRunTimeAddressOut, // Expanded for Rel 0 on 6/18
|
||||||
|
output reg CtrlRunTimeAddressSM,
|
||||||
|
|
||||||
|
// Interface to SPI Slave
|
||||||
|
input [6:0] RegAddrIn,
|
||||||
|
input [7:0] RegDataIn,
|
||||||
|
output reg [7:0] RegDataOut,
|
||||||
|
input RegWriteEnableIn,
|
||||||
|
input RegReadDataAckIn,
|
||||||
|
|
||||||
|
// Interface to memories
|
||||||
|
output TLCDrivingFFEControlMem,
|
||||||
|
output TLCDrivingFFEDataMem1,
|
||||||
|
output TLCDrivingFFEDataMem2,
|
||||||
|
output TLCDrivingSMMem,
|
||||||
|
output TLCDrivingCMMem,
|
||||||
|
output MemorySelect_en,
|
||||||
|
output [2:0] MemorySelect,
|
||||||
|
output [11:0] MemoryAddressOut,
|
||||||
|
output [35:0] MemoryDataOut,
|
||||||
|
input [35:0] MemoryDataIn,
|
||||||
|
output reg MemoryReadEnableOut,
|
||||||
|
output reg MemoryWriteEnableOut,
|
||||||
|
output MemoryClockOut,
|
||||||
|
|
||||||
|
// Interface to Communication Manager FIFO
|
||||||
|
output reg CM_FIFO_ReadEnable,
|
||||||
|
input [8:0] CM_FIFO_ReadData,
|
||||||
|
input [3:0] CM_FIFO_PopFlags,
|
||||||
|
input [3:0] CM_FIFO_PushFlags,
|
||||||
|
input CM_FIFO_Overflow,
|
||||||
|
output CM_RingBufferMode,
|
||||||
|
input CM_AutoDrain_Busy,
|
||||||
|
|
||||||
|
// test points
|
||||||
|
output TP1,
|
||||||
|
output TP2,
|
||||||
|
|
||||||
|
// LEDs ON/OFF Control
|
||||||
|
output reg [2:0] leds_off_o,
|
||||||
|
|
||||||
|
// FFE CLock ENable
|
||||||
|
output reg FFE_CLK_Enable_o,
|
||||||
|
output reg ClockEnable_o,
|
||||||
|
output reg clock_32KHz_Enable_o,
|
||||||
|
output reg [2:0] FFE_Clock_Control_o,
|
||||||
|
output reg [2:0] SM_Clock_Control_o,
|
||||||
|
output reg ClkSourceSelect_o
|
||||||
|
);
|
||||||
|
|
||||||
|
parameter CYCLES_PER_MSEC = 33; // number of 32.768KHz clock cycles per millisecond
|
||||||
|
|
||||||
|
reg [7:0] CommandReg;
|
||||||
|
reg [7:0] msecs_per_sample_reg;
|
||||||
|
reg [7:0] MemSelect_reg;
|
||||||
|
reg [7:0] MemAddrLow;
|
||||||
|
reg [7:0] MemAddrHigh;
|
||||||
|
reg [7:0] MemDataByte0;
|
||||||
|
reg [7:0] MemDataByte1;
|
||||||
|
reg [7:0] MemDataByte2;
|
||||||
|
reg [7:0] MemDataByte3;
|
||||||
|
reg [3:0] MemDataByte4;
|
||||||
|
reg [7:0] CM_Control_reg;
|
||||||
|
reg WaitForMemRead;
|
||||||
|
reg WaitForMemWrite;
|
||||||
|
reg IncrementMemAddr;
|
||||||
|
reg StartFFE_32K, StartFFE_Clkin;
|
||||||
|
// reg InitSM_Clkin; // Removed for Rel 0 on 6/18
|
||||||
|
reg StartSM_Clkin;
|
||||||
|
|
||||||
|
reg [7:0] clock32K_count; // this needs to be wide enough to accomodate the CYCLES_PER_MSEC constant
|
||||||
|
reg [7:0] count_msecs;
|
||||||
|
wire pulse_1ms;
|
||||||
|
wire pulse_sample_period;
|
||||||
|
reg pulse_sample_period_reg;
|
||||||
|
wire FFE_Holdoff; // Used to ensure a full count on the First FFE run
|
||||||
|
reg FFE_Holdoff_reset;
|
||||||
|
reg FFE_Holdoff_preset;
|
||||||
|
|
||||||
|
wire RunFFEContinuously;
|
||||||
|
//wire RunFFEOnce;
|
||||||
|
//wire RunSMOnce;
|
||||||
|
//wire RunSensorInit;
|
||||||
|
|
||||||
|
wire CM_FIFO_Overflow_reg;
|
||||||
|
reg [3:0] CM_FIFO_PopFlags_r1;
|
||||||
|
reg [3:0] CM_FIFO_PopFlags_r2;
|
||||||
|
reg [3:0] CM_FIFO_PopFlags_sync;
|
||||||
|
|
||||||
|
wire I2C_Master_Error_reg;
|
||||||
|
|
||||||
|
reg [7:0] InterruptCtrl_reg;
|
||||||
|
reg [7:0] InterruptFFEMsg_clear;
|
||||||
|
wire Interrupt_En_0;
|
||||||
|
wire [7:0] InterruptFFEMsg_latched;
|
||||||
|
wire InterruptFFEMsg_ORed;
|
||||||
|
|
||||||
|
reg SW_Reset_Start;
|
||||||
|
reg SW_Reset_r1;
|
||||||
|
reg SW_Reset_r2;
|
||||||
|
|
||||||
|
reg RunFFEContinuously_r1;
|
||||||
|
reg RunFFEContinuously_r2;
|
||||||
|
|
||||||
|
reg FFEOverrun;
|
||||||
|
reg [31:0] FFE_Mailbox_reg;
|
||||||
|
|
||||||
|
wire i_StartFFEOut;
|
||||||
|
reg s1_StartFFEOut, s2_StartFFEOut;
|
||||||
|
reg s3_FFEBusyIn, s2_FFEBusyIn, s1_FFEBusyIn;
|
||||||
|
reg d_FFE_CLK_Enable;
|
||||||
|
reg s1_SMBusyIn, s2_SMBusyIn, s3_SMBusyIn;
|
||||||
|
wire d_ClockEnable;
|
||||||
|
wire smInit_enable;
|
||||||
|
// reg s1_InitSM_Clkin, s2_InitSM_Clkin, s3_InitSM_Clkin, s4_InitSM_Clkin, s5_InitSM_Clkin, s6_InitSM_Clkin; // Removed for Rel 0 on 6/18
|
||||||
|
reg s1_StartSM_Clkin, s2_StartSM_Clkin, s3_StartSM_Clkin, s4_StartSM_Clkin, s5_StartSM_Clkin, s6_StartSM_Clkin;
|
||||||
|
wire [2:0] FFE_SET, SM_SET;
|
||||||
|
wire clkSourceSelect;
|
||||||
|
reg SleepMode, IntInputLevel;
|
||||||
|
reg sensorInterrupt_s1, sensorInterrupt_s2, sensorInterrupt_s3;
|
||||||
|
wire sleepModeSet, sleepReset;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
assign FFE_Mailbox_Out = {FFE_Mailbox_reg[15:0], FFE_Mailbox_reg[31:16]};
|
||||||
|
assign MemoryClockOut = SPI_SCLK;
|
||||||
|
|
||||||
|
assign RunFFEContinuously = CommandReg[0];
|
||||||
|
//assign RunFFEOnce = CommandReg[1];
|
||||||
|
//assign RunSMOnce = CommandReg[2];
|
||||||
|
//assign RunSensorInit = CommandReg[3];
|
||||||
|
//assign SW_Reset = CommandReg[6];
|
||||||
|
assign UseFastClockOut = CommandReg[7];
|
||||||
|
|
||||||
|
assign Interrupt_En_0 = InterruptCtrl_reg[0];
|
||||||
|
assign Interrupt_En_1 = InterruptCtrl_reg[1];
|
||||||
|
|
||||||
|
assign TLCDrivingFFEControlMem = MemSelect_reg[7] ? (MemSelect_reg[2:0] == 3'b000) : 1'b0;
|
||||||
|
assign TLCDrivingFFEDataMem1 = MemSelect_reg[7] ? (MemSelect_reg[2:0] == 3'b001) : 1'b0;
|
||||||
|
assign TLCDrivingFFEDataMem2 = MemSelect_reg[7] ? (MemSelect_reg[2:0] == 3'b010) : 1'b0;
|
||||||
|
assign TLCDrivingSMMem = MemSelect_reg[7] ? (MemSelect_reg[2:0] == 3'b011) : 1'b0;
|
||||||
|
assign TLCDrivingCMMem = 1'b0; // should be removed, since the CMMem is now the CM FIFO
|
||||||
|
assign MemorySelect_en = MemSelect_reg[7];
|
||||||
|
assign MemorySelect = MemSelect_reg[2:0];
|
||||||
|
|
||||||
|
assign MemoryAddressOut = {MemAddrHigh[3:0],MemAddrLow};
|
||||||
|
assign MemoryDataOut = {MemDataByte4[3:0],MemDataByte3,MemDataByte2,MemDataByte1,MemDataByte0};
|
||||||
|
|
||||||
|
assign CM_RingBufferMode = CM_Control_reg[0];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// requests to run FFE and Sensor Manager
|
||||||
|
|
||||||
|
assign pulse_1ms = (clock32K_count == (CYCLES_PER_MSEC - 1)); // 1-clock pulse each time 1ms has elapsed
|
||||||
|
assign pulse_sample_period = (pulse_1ms && (count_msecs == 1)); // 1-clock pulse @ each sample period
|
||||||
|
|
||||||
|
assign StartFFEOut = s2_StartFFEOut;
|
||||||
|
// Delay starting FFE
|
||||||
|
always @(posedge Clock32KIn or posedge ResetIn)
|
||||||
|
begin
|
||||||
|
if (ResetIn)
|
||||||
|
begin
|
||||||
|
s1_StartFFEOut <= 1'b0;
|
||||||
|
s2_StartFFEOut <= 1'b0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
s1_StartFFEOut <= i_StartFFEOut;
|
||||||
|
s2_StartFFEOut <= s1_StartFFEOut;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// Synchronized FFE Busy input
|
||||||
|
// & logic to generate FFE_CLK_Enable (active when timer starts and off when busy end)
|
||||||
|
always @(posedge Clock32KIn or posedge ResetIn)
|
||||||
|
begin
|
||||||
|
if (ResetIn)
|
||||||
|
begin
|
||||||
|
s1_FFEBusyIn <= 0;
|
||||||
|
s2_FFEBusyIn <= 0;
|
||||||
|
s3_FFEBusyIn <= 0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
s1_FFEBusyIn <= FFEBusyIn;
|
||||||
|
s2_FFEBusyIn <= s1_FFEBusyIn;
|
||||||
|
s3_FFEBusyIn <= s2_FFEBusyIn;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @*
|
||||||
|
begin
|
||||||
|
if (!FFE_CLK_Enable_o)
|
||||||
|
d_FFE_CLK_Enable = s1_StartFFEOut ^ i_StartFFEOut;
|
||||||
|
else
|
||||||
|
if (s3_FFEBusyIn && !s2_FFEBusyIn)
|
||||||
|
d_FFE_CLK_Enable = 1'b0;
|
||||||
|
else
|
||||||
|
d_FFE_CLK_Enable = FFE_CLK_Enable_o;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge Clock32KIn or posedge ResetIn)
|
||||||
|
begin
|
||||||
|
if (ResetIn)
|
||||||
|
begin
|
||||||
|
FFE_CLK_Enable_o <= 0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
FFE_CLK_Enable_o <= d_FFE_CLK_Enable;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge Clock32KIn or posedge ResetIn) begin
|
||||||
|
if (ResetIn) begin
|
||||||
|
clock32K_count <= 0;
|
||||||
|
count_msecs <= 1; // reset to 1 (sample period = 0 does not make sense, and should be invalid)
|
||||||
|
pulse_sample_period_reg <= 0;
|
||||||
|
TimeStampOut <= 0;
|
||||||
|
TimeStampOut_Tog <= 0;
|
||||||
|
StartFFE_32K <= 0;
|
||||||
|
FFEOverrun <= 0;
|
||||||
|
end else begin
|
||||||
|
|
||||||
|
pulse_sample_period_reg <= pulse_sample_period; // de-glitch the pulse_sample_period signal, since it's used to asynchronously reset FFE_Holdoff
|
||||||
|
|
||||||
|
if (pulse_1ms) begin
|
||||||
|
clock32K_count <= 0;
|
||||||
|
TimeStampOut <= TimeStampOut + 1; // the timestamp increments @ 1ms
|
||||||
|
TimeStampOut_Tog <= ~TimeStampOut_Tog; // the timestamp increments @ 1ms
|
||||||
|
end else begin
|
||||||
|
clock32K_count <= clock32K_count + 1;
|
||||||
|
TimeStampOut <= TimeStampOut;
|
||||||
|
TimeStampOut_Tog <= TimeStampOut_Tog;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (pulse_sample_period) // sample period boundary
|
||||||
|
count_msecs <= msecs_per_sample_reg; // reset the msec counter back to the register value
|
||||||
|
else
|
||||||
|
if (pulse_1ms)
|
||||||
|
count_msecs <= count_msecs - 1; // decrement by 1 @ the 1ms boundary
|
||||||
|
else
|
||||||
|
count_msecs <= count_msecs;
|
||||||
|
|
||||||
|
|
||||||
|
//if ((clock32K_count == (CYCLES_PER_MSEC - 1)) && (count_msecs == 1)) begin // msec counter about to be reset back to the register value
|
||||||
|
if (pulse_sample_period && !SleepMode) begin // msec counter about to be reset back to the register value
|
||||||
|
if (RunFFEContinuously && !FFE_Holdoff) begin // trigger a run only if FFE_Holdoff has been deactivated
|
||||||
|
if (FFEBusyIn) begin
|
||||||
|
FFEOverrun <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
StartFFE_32K <= ~StartFFE_32K;
|
||||||
|
//CMBufferBeingWrittenOut <= CMBufferBeingWrittenOut + 1;
|
||||||
|
//if (!AlternateI2CIsActiveIn) begin // If Alternate I2C is active, then we are reading the buffer
|
||||||
|
// CMBufferBeingRead <= CMBufferBeingWrittenOut;
|
||||||
|
//end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// software-controlled reset, 1-2 clock pulses wide @ the 32K clock
|
||||||
|
|
||||||
|
// generate a one-clock pulse @ the SPI_SCLK, to be used to preset a flop running in the 32K clock domain
|
||||||
|
always @(posedge SPI_SCLK)
|
||||||
|
if (RegWriteEnableIn && (RegAddrIn == `CommandReg) && RegDataIn[6]) // SW Reset control bit is being written
|
||||||
|
SW_Reset_Start <= 1;
|
||||||
|
else
|
||||||
|
SW_Reset_Start <= 0;
|
||||||
|
|
||||||
|
// 32K clock domain, the r1 flop gets preset by the SPI clock pulse above, and only gets deactivated after another 32K clock period (using the r2 flop)
|
||||||
|
always @(posedge Clock32KIn or posedge SW_Reset_Start)
|
||||||
|
if (SW_Reset_Start)
|
||||||
|
SW_Reset_r1 <= 1;
|
||||||
|
else
|
||||||
|
if (SW_Reset_r1 && !SW_Reset_r2)
|
||||||
|
SW_Reset_r1 <= 1;
|
||||||
|
else
|
||||||
|
SW_Reset_r1 <= 0;
|
||||||
|
|
||||||
|
// r2 flop, used to stretch the generated reset pulse
|
||||||
|
always @(posedge Clock32KIn)
|
||||||
|
SW_Reset_r2 <= SW_Reset_r1;
|
||||||
|
|
||||||
|
|
||||||
|
assign SW_Reset = SW_Reset_r2;
|
||||||
|
|
||||||
|
|
||||||
|
// When running the FFE continuously, this logic prevents the FFE from running until the start of a sample period
|
||||||
|
|
||||||
|
always @(posedge SPI_SCLK or posedge ResetIn)
|
||||||
|
if (ResetIn)
|
||||||
|
FFE_Holdoff_preset <= 0;
|
||||||
|
else
|
||||||
|
if (RegWriteEnableIn && (RegAddrIn == `CommandReg) && RegDataIn[0]) // Run FFE Continuously control bit is being written...
|
||||||
|
FFE_Holdoff_preset <= 1; // ... assert FFE_Holdoff
|
||||||
|
else
|
||||||
|
FFE_Holdoff_preset <= 0;
|
||||||
|
|
||||||
|
always @(posedge Clock32KIn or posedge ResetIn)
|
||||||
|
if (ResetIn)
|
||||||
|
FFE_Holdoff_reset <= 0;
|
||||||
|
else
|
||||||
|
if (pulse_sample_period_reg && RunFFEContinuously && FFE_Holdoff) // reset FFE_Holdoff when the first timer expiration occurs, to ensure a full first run
|
||||||
|
FFE_Holdoff_reset <= 1;
|
||||||
|
else
|
||||||
|
FFE_Holdoff_reset <= 0;
|
||||||
|
|
||||||
|
dff_pre_clr dff_pre_clr_FFE_Holdoff ( .CLK(1'b0) , .CLR(FFE_Holdoff_reset), .D(1'b0), .PRE(FFE_Holdoff_preset), .Q(FFE_Holdoff) );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// latch the I2C Master Error signal
|
||||||
|
dff_pre_clr dff_pre_clr_I2C_Master_Error ( .CLK(1'b0) , .CLR(ResetIn), .D(1'b0), .PRE(I2C_Master_Error), .Q(I2C_Master_Error_reg) );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// interrupt logic
|
||||||
|
|
||||||
|
// note: InterruptMsgFromFFEIn should be de-glitched externally (currently de-glitched in FFE_Control.v)
|
||||||
|
|
||||||
|
// logic to clear the FFE msg interrupts
|
||||||
|
always @(posedge SPI_SCLK)
|
||||||
|
if (RegWriteEnableIn && (RegAddrIn == `InterruptFFEMsg))
|
||||||
|
InterruptFFEMsg_clear <= RegDataIn[7:0];
|
||||||
|
else
|
||||||
|
InterruptFFEMsg_clear <= 8'b0;
|
||||||
|
|
||||||
|
// latch the interrupt msg from the FFE, clear when the InterruptFFEMsg register is being written
|
||||||
|
dff_pre_clr dff_pre_clr_InterruptFFEMsg_0 ( .CLK(1'b0) , .CLR(InterruptFFEMsg_clear[0]), .D(1'b0), .PRE(InterruptMsgFromFFEIn[0]), .Q(InterruptFFEMsg_latched[0]) );
|
||||||
|
dff_pre_clr dff_pre_clr_InterruptFFEMsg_1 ( .CLK(1'b0) , .CLR(InterruptFFEMsg_clear[1]), .D(1'b0), .PRE(InterruptMsgFromFFEIn[1]), .Q(InterruptFFEMsg_latched[1]) );
|
||||||
|
dff_pre_clr dff_pre_clr_InterruptFFEMsg_2 ( .CLK(1'b0) , .CLR(InterruptFFEMsg_clear[2]), .D(1'b0), .PRE(InterruptMsgFromFFEIn[2]), .Q(InterruptFFEMsg_latched[2]) );
|
||||||
|
dff_pre_clr dff_pre_clr_InterruptFFEMsg_3 ( .CLK(1'b0) , .CLR(InterruptFFEMsg_clear[3]), .D(1'b0), .PRE(InterruptMsgFromFFEIn[3]), .Q(InterruptFFEMsg_latched[3]) );
|
||||||
|
dff_pre_clr dff_pre_clr_InterruptFFEMsg_4 ( .CLK(1'b0) , .CLR(InterruptFFEMsg_clear[4]), .D(1'b0), .PRE(InterruptMsgFromFFEIn[4]), .Q(InterruptFFEMsg_latched[4]) );
|
||||||
|
dff_pre_clr dff_pre_clr_InterruptFFEMsg_5 ( .CLK(1'b0) , .CLR(InterruptFFEMsg_clear[5]), .D(1'b0), .PRE(InterruptMsgFromFFEIn[5]), .Q(InterruptFFEMsg_latched[5]) );
|
||||||
|
dff_pre_clr dff_pre_clr_InterruptFFEMsg_6 ( .CLK(1'b0) , .CLR(InterruptFFEMsg_clear[6]), .D(1'b0), .PRE(InterruptMsgFromFFEIn[6]), .Q(InterruptFFEMsg_latched[6]) );
|
||||||
|
dff_pre_clr dff_pre_clr_InterruptFFEMsg_7 ( .CLK(1'b0) , .CLR(InterruptFFEMsg_clear[7]), .D(1'b0), .PRE(InterruptMsgFromFFEIn[7]), .Q(InterruptFFEMsg_latched[7]) );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
assign InterruptFFEMsg_ORed = |InterruptFFEMsg_latched[7:0];
|
||||||
|
|
||||||
|
// drive the interrupt output pin: active-high, level sensitive
|
||||||
|
assign InterruptPinOut = (Interrupt_En_0 && InterruptFFEMsg_ORed) ||
|
||||||
|
(Interrupt_En_1 && (I2C_Master_Error_reg || SMOverrunIn || FFEOverrun));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// overflow detection bit
|
||||||
|
|
||||||
|
dff_pre_clr dff_pre_clr_overflow ( .CLK(1'b0) , .CLR(ResetIn), .D(1'b0), .PRE(CM_FIFO_Overflow), .Q(CM_FIFO_Overflow_reg) );
|
||||||
|
|
||||||
|
|
||||||
|
// sync the FIFO flags to the SPI clock domain
|
||||||
|
always @(posedge SPI_SCLK) begin
|
||||||
|
CM_FIFO_PopFlags_r1 <= CM_FIFO_PopFlags;
|
||||||
|
CM_FIFO_PopFlags_r2 <= CM_FIFO_PopFlags_r1;
|
||||||
|
if (CM_FIFO_PopFlags_r1 == CM_FIFO_PopFlags_r2)
|
||||||
|
CM_FIFO_PopFlags_sync <= CM_FIFO_PopFlags_r2;
|
||||||
|
else
|
||||||
|
CM_FIFO_PopFlags_sync <= CM_FIFO_PopFlags_sync;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
//Registers for controlling the FFE and memories
|
||||||
|
always @(posedge SPI_SCLK or posedge ResetIn) begin
|
||||||
|
if (ResetIn) begin
|
||||||
|
RegDataOut <= 0;
|
||||||
|
MemoryReadEnableOut <= 0;
|
||||||
|
MemoryWriteEnableOut <= 0;
|
||||||
|
WaitForMemRead <= 0;
|
||||||
|
WaitForMemWrite <= 0;
|
||||||
|
IncrementMemAddr <= 0;
|
||||||
|
CommandReg <= 0;
|
||||||
|
msecs_per_sample_reg <= 1; // default value is 1 (sample period = 0 should be invalid)
|
||||||
|
InterruptCtrl_reg <= 0;
|
||||||
|
MemSelect_reg <= 0;
|
||||||
|
MemAddrLow <= 0;
|
||||||
|
MemAddrHigh <= 0;
|
||||||
|
MemDataByte0 <= 0;
|
||||||
|
MemDataByte1 <= 0;
|
||||||
|
MemDataByte2 <= 0;
|
||||||
|
MemDataByte3 <= 0;
|
||||||
|
MemDataByte4 <= 0;
|
||||||
|
StartFFE_Clkin <= 0;
|
||||||
|
// InitSM_Clkin <= 0; // Removed for Rel 0 on 6/18
|
||||||
|
StartSM_Clkin <= 0;
|
||||||
|
CM_FIFO_ReadEnable <= 0;
|
||||||
|
CM_Control_reg <= 0;
|
||||||
|
FFE_Mailbox_reg <= 0;
|
||||||
|
CtrlRunTimeAddressOut <= 0;
|
||||||
|
CtrlRunTimeAddressSM <= 0;
|
||||||
|
leds_off_o <= 3'b111;
|
||||||
|
ClkSourceSelect_o <= 1'b0;
|
||||||
|
clock_32KHz_Enable_o <= 1'b1;
|
||||||
|
FFE_Clock_Control_o <= FFE_SET;
|
||||||
|
SM_Clock_Control_o <= SM_SET;
|
||||||
|
RingOsc_cal_en <= 0;
|
||||||
|
RingOsc_select <= 3'h7;
|
||||||
|
end else begin
|
||||||
|
if (MemoryWriteEnableOut) begin
|
||||||
|
if(WaitForMemWrite == 0) begin
|
||||||
|
WaitForMemWrite <= 1;
|
||||||
|
end else begin
|
||||||
|
MemoryWriteEnableOut <= 0;
|
||||||
|
WaitForMemWrite <= 0;
|
||||||
|
IncrementMemAddr <= 1;
|
||||||
|
end
|
||||||
|
end // if (MemoryWriteEnableOut)
|
||||||
|
|
||||||
|
if (IncrementMemAddr) begin
|
||||||
|
IncrementMemAddr <= 0;
|
||||||
|
{MemAddrHigh[3:0],MemAddrLow} <= {MemAddrHigh[3:0],MemAddrLow} + 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (MemoryReadEnableOut) begin
|
||||||
|
if (WaitForMemRead == 0) begin
|
||||||
|
WaitForMemRead <= 1;
|
||||||
|
end else begin
|
||||||
|
MemoryReadEnableOut <= 0;
|
||||||
|
WaitForMemRead <= 0;
|
||||||
|
MemDataByte4 <= MemoryDataIn[35:32];
|
||||||
|
MemDataByte3 <= MemoryDataIn[31:24];
|
||||||
|
MemDataByte2 <= MemoryDataIn[23:16];
|
||||||
|
MemDataByte1 <= MemoryDataIn[15:8];
|
||||||
|
MemDataByte0 <= MemoryDataIn[7:0];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// CM FIFO read control
|
||||||
|
///// Old Code
|
||||||
|
/*
|
||||||
|
if (CM_FIFO_ReadEnable)
|
||||||
|
CM_FIFO_ReadEnable <= 0;
|
||||||
|
else
|
||||||
|
if (RegAddrIn == `CM_FIFO_Data && RegReadDataAckIn)
|
||||||
|
CM_FIFO_ReadEnable <= 1;
|
||||||
|
else
|
||||||
|
CM_FIFO_ReadEnable <= 0;
|
||||||
|
*/
|
||||||
|
//// New Code
|
||||||
|
if (RegAddrIn == `CM_FIFO_Data && RegReadDataAckIn)
|
||||||
|
CM_FIFO_ReadEnable <= !CM_FIFO_ReadEnable;
|
||||||
|
else
|
||||||
|
CM_FIFO_ReadEnable <= CM_FIFO_ReadEnable;
|
||||||
|
|
||||||
|
if (RegWriteEnableIn) begin
|
||||||
|
case (RegAddrIn)
|
||||||
|
`CommandReg: begin
|
||||||
|
CommandReg <= RegDataIn;
|
||||||
|
//FFE_Holdoff <= 1;
|
||||||
|
end
|
||||||
|
`milSecSample: msecs_per_sample_reg <= RegDataIn;
|
||||||
|
`InterruptCtrl: InterruptCtrl_reg <= RegDataIn;
|
||||||
|
//`InterruptStat: // currently writes to this register does nothing, adding more interrupts may change this.
|
||||||
|
`MemSelect: MemSelect_reg <= RegDataIn;
|
||||||
|
`MemAddrLow: MemAddrLow <= RegDataIn;
|
||||||
|
`MemAddrHigh: begin
|
||||||
|
MemAddrHigh <= RegDataIn;
|
||||||
|
WaitForMemRead <= 0; // this is assigned in separate 'if' statements, the logic should be combined into 1.
|
||||||
|
MemoryReadEnableOut <= 1;
|
||||||
|
end
|
||||||
|
`MemDataByte0: MemDataByte0 <= RegDataIn;
|
||||||
|
`MemDataByte1: MemDataByte1 <= RegDataIn;
|
||||||
|
`MemDataByte2: MemDataByte2 <= RegDataIn;
|
||||||
|
`MemDataByte3: MemDataByte3 <= RegDataIn;
|
||||||
|
`MemDataByte4: begin
|
||||||
|
MemDataByte4 <= RegDataIn[3:0];
|
||||||
|
MemoryWriteEnableOut <= 1;
|
||||||
|
WaitForMemWrite <= 0; // this is assigned in separate 'if' statements, the logic should be combined into 1.
|
||||||
|
end
|
||||||
|
`CM_Control: CM_Control_reg <= RegDataIn;
|
||||||
|
`MailboxToFFE_0: FFE_Mailbox_reg[7:0] <= RegDataIn;
|
||||||
|
`MailboxToFFE_1: FFE_Mailbox_reg[15:8] <= RegDataIn;
|
||||||
|
`MailboxToFFE_2: FFE_Mailbox_reg[23:16] <= RegDataIn;
|
||||||
|
`MailboxToFFE_3: FFE_Mailbox_reg[31:24] <= RegDataIn;
|
||||||
|
`RunTimeAdrReg: begin
|
||||||
|
CtrlRunTimeAddressOut[7:0] <= RegDataIn; // Expanded for Rel 0 on 6/18
|
||||||
|
CtrlRunTimeAddressSM <= ~CtrlRunTimeAddressSM;
|
||||||
|
end
|
||||||
|
`DemoLedCtrlReg: begin
|
||||||
|
leds_off_o <= RegDataIn[2:0];
|
||||||
|
end
|
||||||
|
`ClocksControl: begin
|
||||||
|
FFE_Clock_Control_o <= RegDataIn[2:0];
|
||||||
|
SM_Clock_Control_o <= RegDataIn[5:3];
|
||||||
|
ClkSourceSelect_o <= RegDataIn[6];
|
||||||
|
clock_32KHz_Enable_o <= RegDataIn[7];
|
||||||
|
end
|
||||||
|
`RunTimeAdrReg_Upr: begin
|
||||||
|
CtrlRunTimeAddressOut[9:8] <= RegDataIn[1:0]; // New for Rel 0 on 6/18
|
||||||
|
end
|
||||||
|
`SleepControl: begin
|
||||||
|
RingOsc_cal_en <= RegDataIn[7];
|
||||||
|
RingOsc_select <= RegDataIn[6:4];
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
|
||||||
|
if ((RegAddrIn == `CommandReg) && RegDataIn[1]) // run FFE once
|
||||||
|
StartFFE_Clkin <= ~StartFFE_Clkin;
|
||||||
|
|
||||||
|
//the SM control signals come as a pair because only one should be toggled at a time if both bits are written to in CommandReg
|
||||||
|
//Initialization takes precedense over Start
|
||||||
|
// if ((RegAddrIn == `CommandReg) && RegDataIn[3]) // Removed for Rel 0 on 6/18
|
||||||
|
// InitSM_Clkin <= ~InitSM_Clkin; // Removed for Rel 0 on 6/18
|
||||||
|
// else if ((RegAddrIn == `CommandReg) && RegDataIn[2]) // Updated for Rel 0 on 6/18
|
||||||
|
if ((RegAddrIn == `CommandReg) && RegDataIn[2])
|
||||||
|
StartSM_Clkin <= ~StartSM_Clkin;
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
case (RegAddrIn)
|
||||||
|
|
||||||
|
`CommandReg: RegDataOut <= { CommandReg[7], // UseFastClk
|
||||||
|
1'b0, // SW_Reset, self-clearing
|
||||||
|
1'b0, // reserved
|
||||||
|
1'b0, // reserved
|
||||||
|
1'b0, // RunSensorInit, self-clearing
|
||||||
|
1'b0, // RunSMOnce, self-clearing
|
||||||
|
1'b0, // RunFFEOnce, self-clearing
|
||||||
|
CommandReg[0] // RunFFEContinuously
|
||||||
|
};
|
||||||
|
|
||||||
|
`StatusReg: RegDataOut <= { 3'b0,
|
||||||
|
I2C_Master_Error_reg,
|
||||||
|
SMOverrunIn,
|
||||||
|
FFEOverrun,
|
||||||
|
SMBusyIn,
|
||||||
|
FFEBusyIn
|
||||||
|
}; // Status Reg
|
||||||
|
|
||||||
|
`milSecSample: RegDataOut <= msecs_per_sample_reg;
|
||||||
|
`InterruptCtrl: RegDataOut <= {6'b0, Interrupt_En_1, Interrupt_En_0};
|
||||||
|
`InterruptStat: RegDataOut <= {7'b0, InterruptFFEMsg_ORed};
|
||||||
|
`MemSelect: RegDataOut <= {MemSelect_reg[7], 4'b0, MemSelect_reg[2:0]};
|
||||||
|
`MemAddrLow: RegDataOut <= MemAddrLow;
|
||||||
|
`MemAddrHigh: RegDataOut <= MemAddrHigh;
|
||||||
|
`MemDataByte0: RegDataOut <= MemoryDataIn[7:0]; // MemDataByte0;
|
||||||
|
`MemDataByte1: RegDataOut <= MemoryDataIn[15:8]; // MemDataByte1;
|
||||||
|
`MemDataByte2: RegDataOut <= MemoryDataIn[23:16]; // MemDataByte2;
|
||||||
|
`MemDataByte3: RegDataOut <= MemoryDataIn[31:24]; // MemDataByte3;
|
||||||
|
`MemDataByte4: RegDataOut <= MemoryDataIn[35:32]; // MemDataByte4;
|
||||||
|
`CM_FIFO_Data: RegDataOut <= CM_FIFO_ReadData[7:0];
|
||||||
|
`CM_Control: RegDataOut <= {7'b0, CM_RingBufferMode};
|
||||||
|
`CM_Status: RegDataOut <= {6'b0, CM_FIFO_Overflow_reg, CM_AutoDrain_Busy};
|
||||||
|
`CM_FIFO_Flags_0: RegDataOut <= {4'b0, CM_FIFO_PopFlags_sync};
|
||||||
|
`MailboxToFFE_0: RegDataOut <= FFE_Mailbox_reg[7:0];
|
||||||
|
`MailboxToFFE_1: RegDataOut <= FFE_Mailbox_reg[15:8];
|
||||||
|
`MailboxToFFE_2: RegDataOut <= FFE_Mailbox_reg[23:16];
|
||||||
|
`MailboxToFFE_3: RegDataOut <= FFE_Mailbox_reg[31:24];
|
||||||
|
`InterruptFFEMsg: RegDataOut <= InterruptFFEMsg_latched;
|
||||||
|
`RunTimeAdrReg: RegDataOut <= CtrlRunTimeAddressReg[7:0]; // Expanded for Rel 0 on 6/18
|
||||||
|
`DemoLedCtrlReg: RegDataOut <= {5'b0, leds_off_o};
|
||||||
|
`ClocksControl: RegDataOut <= {clock_32KHz_Enable_o, ClkSourceSelect_o, SM_Clock_Control_o[2:0], FFE_Clock_Control_o[2:0]};
|
||||||
|
`SleepControl: RegDataOut <= {RingOsc_cal_en, RingOsc_select[2:0], 1'b0, sleepModeSet, IntInputLevel, SleepMode};
|
||||||
|
`RunTimeAdrReg_Upr: RegDataOut <= {6'h0, CtrlRunTimeAddressReg[9:8]}; // New for Rel 0 on 6/18
|
||||||
|
`CalValueLow: RegDataOut <= RingOsc_cal_value[7:0];
|
||||||
|
`CalValueHi: RegDataOut <= RingOsc_cal_value[15:8];
|
||||||
|
default: RegDataOut <= 8'h21;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end // if (ResetIn)
|
||||||
|
end // Always
|
||||||
|
|
||||||
|
|
||||||
|
assign i_StartFFEOut = StartFFE_32K ^ StartFFE_Clkin;
|
||||||
|
//assign InitSMOut = s6_InitSM_Clkin; // Removed for Rel 0 on 6/18
|
||||||
|
assign StartSMOut = s6_StartSM_Clkin;
|
||||||
|
|
||||||
|
// test points
|
||||||
|
assign TP1 = FFE_Mailbox_reg[0];
|
||||||
|
assign TP2 = RegWriteEnableIn;
|
||||||
|
|
||||||
|
// Logic to drive RIng Osc Clock Enable / Disable
|
||||||
|
|
||||||
|
//assign smInit_enable = (s2_InitSM_Clkin ^ s3_InitSM_Clkin) || (s2_StartSM_Clkin ^ s3_StartSM_Clkin); // Removed for Rel 0 on 6/18
|
||||||
|
assign smInit_enable = (s2_StartSM_Clkin ^ s3_StartSM_Clkin); // Updated for Rel 0 on 6/18
|
||||||
|
|
||||||
|
assign d_ClockEnable = ClockEnable_o ? ((!s2_SMBusyIn && s3_SMBusyIn) ? 1'b0 : 1'b1) : (( d_FFE_CLK_Enable || smInit_enable ) ? 1'b1 : 1'b0);
|
||||||
|
always @(posedge Clock32KIn or posedge ResetIn)
|
||||||
|
begin
|
||||||
|
if (ResetIn)
|
||||||
|
begin
|
||||||
|
s1_SMBusyIn <= 0;
|
||||||
|
s2_SMBusyIn <= 0;
|
||||||
|
s3_SMBusyIn <= 0;
|
||||||
|
ClockEnable_o <= 0;
|
||||||
|
// s1_InitSM_Clkin <= 0;
|
||||||
|
// s2_InitSM_Clkin <= 0;
|
||||||
|
// s3_InitSM_Clkin <= 0;
|
||||||
|
// s4_InitSM_Clkin <= 0;
|
||||||
|
// s5_InitSM_Clkin <= 0;
|
||||||
|
// s6_InitSM_Clkin <= 0;
|
||||||
|
s1_StartSM_Clkin <= 0;
|
||||||
|
s2_StartSM_Clkin <= 0;
|
||||||
|
s3_StartSM_Clkin <= 0;
|
||||||
|
s4_StartSM_Clkin <= 0;
|
||||||
|
s5_StartSM_Clkin <= 0;
|
||||||
|
s6_StartSM_Clkin <= 0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
s1_SMBusyIn <= (SMBusyIn || FFEBusyIn);
|
||||||
|
s2_SMBusyIn <= s1_SMBusyIn;
|
||||||
|
s3_SMBusyIn <= s2_SMBusyIn;
|
||||||
|
ClockEnable_o <= d_ClockEnable;
|
||||||
|
// s1_InitSM_Clkin <= InitSM_Clkin;
|
||||||
|
// s2_InitSM_Clkin <= s1_InitSM_Clkin;
|
||||||
|
// s3_InitSM_Clkin <= s2_InitSM_Clkin;
|
||||||
|
// s4_InitSM_Clkin <= s3_InitSM_Clkin;
|
||||||
|
// s5_InitSM_Clkin <= s4_InitSM_Clkin;
|
||||||
|
// s6_InitSM_Clkin <= s5_InitSM_Clkin;
|
||||||
|
s1_StartSM_Clkin <= StartSM_Clkin;
|
||||||
|
s2_StartSM_Clkin <= s1_StartSM_Clkin;
|
||||||
|
s3_StartSM_Clkin <= s2_StartSM_Clkin;
|
||||||
|
s4_StartSM_Clkin <= s3_StartSM_Clkin;
|
||||||
|
s5_StartSM_Clkin <= s4_StartSM_Clkin;
|
||||||
|
s6_StartSM_Clkin <= s5_StartSM_Clkin;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// Logic to select default reset values for the SM and FFE CLK selection
|
||||||
|
assign FFE_SET[0] = (`FFE1CLK_FREQ_SLT == 8'b00000001) || (`FFE1CLK_FREQ_SLT == 8'b00000010) || (`FFE1CLK_FREQ_SLT == 8'b00000100) || (`FFE1CLK_FREQ_SLT == 8'b00001000) ||
|
||||||
|
(`FFE1CLK_FREQ_SLT == 8'b00010000) || (`FFE1CLK_FREQ_SLT == 8'b01000000);
|
||||||
|
assign FFE_SET[1] = (`FFE1CLK_FREQ_SLT == 8'b00000001) || (`FFE1CLK_FREQ_SLT == 8'b00000010) || (`FFE1CLK_FREQ_SLT == 8'b00000100) || (`FFE1CLK_FREQ_SLT == 8'b00001000) ||
|
||||||
|
(`FFE1CLK_FREQ_SLT == 8'b00100000) || (`FFE1CLK_FREQ_SLT == 8'b01000000);
|
||||||
|
assign FFE_SET[2] = (`FFE1CLK_FREQ_SLT == 8'b10000000);
|
||||||
|
|
||||||
|
assign SM_SET[0] = (`SM1CLK_FREQ_SLT == 8'b00000010) || (`SM1CLK_FREQ_SLT == 8'b00001000) || (`SM1CLK_FREQ_SLT == 8'b00100000) || (`SM1CLK_FREQ_SLT == 8'b10000000);
|
||||||
|
assign SM_SET[1] = (`SM1CLK_FREQ_SLT == 8'b00000100) || (`SM1CLK_FREQ_SLT == 8'b00001000) || (`SM1CLK_FREQ_SLT == 8'b01000000) || (`SM1CLK_FREQ_SLT == 8'b10000000);
|
||||||
|
assign SM_SET[2] = (`SM1CLK_FREQ_SLT == 8'b00010000) || (`SM1CLK_FREQ_SLT == 8'b00100000) || (`SM1CLK_FREQ_SLT == 8'b01000000) || (`SM1CLK_FREQ_SLT == 8'b10000000);
|
||||||
|
|
||||||
|
// Logic for Sleep Mode
|
||||||
|
// Sensor interrupt input is double ring to check for transtion from low to high
|
||||||
|
// Once detected, the design will enable the sampling period
|
||||||
|
assign sleepModeSet = sensorInterrupt_s2 && !sensorInterrupt_s3;
|
||||||
|
always @(posedge Clock32KIn or posedge ResetIn)
|
||||||
|
begin
|
||||||
|
if (ResetIn)
|
||||||
|
begin
|
||||||
|
sensorInterrupt_s1 <= 0;
|
||||||
|
sensorInterrupt_s2 <= 0;
|
||||||
|
sensorInterrupt_s3 <= 0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
sensorInterrupt_s1 <= (SensorInterruptIn ~^ IntInputLevel) && SleepMode;
|
||||||
|
sensorInterrupt_s2 <= sensorInterrupt_s1;
|
||||||
|
sensorInterrupt_s3 <= sensorInterrupt_s2;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign sleepReset = ResetIn || sleepModeSet;
|
||||||
|
always @(posedge SPI_SCLK or posedge sleepReset) begin
|
||||||
|
if (sleepReset)
|
||||||
|
begin
|
||||||
|
SleepMode <= 1'b0;
|
||||||
|
end
|
||||||
|
else if ((RegAddrIn == `SleepControl) && RegWriteEnableIn)
|
||||||
|
begin
|
||||||
|
SleepMode <= RegDataIn[0];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge SPI_SCLK or posedge ResetIn) begin
|
||||||
|
if (ResetIn)
|
||||||
|
begin
|
||||||
|
IntInputLevel <= 1'b1;
|
||||||
|
end
|
||||||
|
else if ((RegAddrIn == `SleepControl) && RegWriteEnableIn)
|
||||||
|
begin
|
||||||
|
IntInputLevel <= RegDataIn[1];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,126 @@
|
||||||
|
/***************************************************
|
||||||
|
Vendor : QuickLogic Corp.
|
||||||
|
Aurora Version : AU 1.0.0
|
||||||
|
File Name : primtive_macros.v
|
||||||
|
Author : Kishor Kumar
|
||||||
|
Description : Verilog Netlist File (For Synthesis/Pre-Layout Simulation)
|
||||||
|
*****************************************************/
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------------
|
||||||
|
MODULE NAME : ck_buff
|
||||||
|
DESCRIPTION : Clock tree buffer
|
||||||
|
--------------------------------------------------------------------------------*/
|
||||||
|
`ifdef ck_buff
|
||||||
|
`else
|
||||||
|
`define ck_buff
|
||||||
|
module ck_buff ( A , Q )/* synthesis black_box black_box_pad_pin = "A" */;
|
||||||
|
input A/* synthesis syn_isclock=1 */;
|
||||||
|
output Q;
|
||||||
|
//pragma synthesis_off
|
||||||
|
//pragma synthesis_on
|
||||||
|
endmodule /* ck buff */
|
||||||
|
`endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------------
|
||||||
|
MODULE NAME : gclkbuff
|
||||||
|
DESCRIPTION : Global clock buffer
|
||||||
|
--------------------------------------------------------------------------------*/
|
||||||
|
`ifdef GCLKBUFF
|
||||||
|
`else
|
||||||
|
`define GCLKBUFF
|
||||||
|
module GCLKBUFF ( A , Z )/* synthesis black_box */;
|
||||||
|
input A;
|
||||||
|
output Z;
|
||||||
|
//pragma synthesis_off
|
||||||
|
//pragma synthesis_on
|
||||||
|
endmodule /* gclk buff */
|
||||||
|
`endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------------
|
||||||
|
MODULE NAME : in_buff
|
||||||
|
DESCRIPTION : Input buffer
|
||||||
|
--------------------------------------------------------------------------------*/
|
||||||
|
`ifdef in_buff
|
||||||
|
`else
|
||||||
|
`define in_buff
|
||||||
|
module in_buff ( A , Q )/* synthesis black_box */;
|
||||||
|
input A;
|
||||||
|
output Q;
|
||||||
|
//pragma synthesis_off
|
||||||
|
//pragma synthesis_on
|
||||||
|
endmodule /* in buff */
|
||||||
|
`endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------------
|
||||||
|
MODULE NAME : out_buff
|
||||||
|
DESCRIPTION : Output buffer
|
||||||
|
--------------------------------------------------------------------------------*/
|
||||||
|
`ifdef out_buff
|
||||||
|
`else
|
||||||
|
`define out_buff
|
||||||
|
module out_buff ( A , Q )/* synthesis black_box */;
|
||||||
|
input A;
|
||||||
|
output Q;
|
||||||
|
//pragma synthesis_off
|
||||||
|
//pragma synthesis_on
|
||||||
|
endmodule /* out buff */
|
||||||
|
`endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------------
|
||||||
|
MODULE NAME : inv
|
||||||
|
DESCRIPTION : Inverter
|
||||||
|
--------------------------------------------------------------------------------*/
|
||||||
|
`ifdef inv
|
||||||
|
`else
|
||||||
|
`define inv
|
||||||
|
module inv ( A , Q )/* synthesis black_box */;
|
||||||
|
input A;
|
||||||
|
output Q;
|
||||||
|
//pragma synthesis_off
|
||||||
|
//pragma synthesis_on
|
||||||
|
endmodule /*inverter*/
|
||||||
|
`endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------------
|
||||||
|
MODULE NAME : buff
|
||||||
|
DESCRIPTION : Buffer
|
||||||
|
--------------------------------------------------------------------------------*/
|
||||||
|
`ifdef buff
|
||||||
|
`else
|
||||||
|
`define buff
|
||||||
|
module buff ( A , Q )/* synthesis black_box */;
|
||||||
|
input A;
|
||||||
|
output Q;
|
||||||
|
//pragma synthesis_off
|
||||||
|
//pragma synthesis_on
|
||||||
|
endmodule /*buffer*/
|
||||||
|
`endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------------
|
||||||
|
MODULE NAME : mux2x0
|
||||||
|
DESCRIPTION : Basic Mux 2:1
|
||||||
|
--------------------------------------------------------------------------------*/
|
||||||
|
`ifdef mux2x0
|
||||||
|
`else
|
||||||
|
`define mux2x0
|
||||||
|
module mux2x0 ( A , B, S, Q )/* synthesis black_box */;
|
||||||
|
input A, B, S;
|
||||||
|
output Q;
|
||||||
|
//pragma synthesis_off
|
||||||
|
//pragma synthesis_on
|
||||||
|
endmodule /*mux2x0*/
|
||||||
|
`endif
|
||||||
|
|
||||||
|
`ifdef LOGIC_Cell
|
||||||
|
`else
|
||||||
|
`define LOGIC_Cell
|
||||||
|
module LOGIC_Cell (T0I0, T0I1, T0I2, T0I3, B0I0, B0I1, B0I2, B0I3,
|
||||||
|
TB0S, Q0DI, CD0S, Q0EN, QST, QRT, QCK, QCKS, C0Z, Q0Z, B0Z)/* synthesis black_box */;
|
||||||
|
input T0I0, T0I1, T0I2, T0I3, B0I0, B0I1, B0I2, B0I3;
|
||||||
|
input TB0S, Q0DI, CD0S, Q0EN;
|
||||||
|
input QST, QRT, QCK, QCKS;
|
||||||
|
output C0Z, B0Z, Q0Z;
|
||||||
|
//pragma synthesis_off
|
||||||
|
//pragma synthesis_on
|
||||||
|
endmodule /*LOGIC_Cell*/
|
||||||
|
`endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,17 @@
|
||||||
|
|
||||||
|
`timescale 1ns / 1ns
|
||||||
|
|
||||||
|
module clock_buffer (
|
||||||
|
input A,
|
||||||
|
output Z
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GCLKBUFF gclkbuff_0 (.A(A), .Z(Z));
|
||||||
|
//pragma attribute gclkbuff_0 ql_pack 1
|
||||||
|
//pragma attribute gclkbuff_0 hierarchy preserve
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
|
||||||
|
`timescale 1ns / 1ns
|
||||||
|
|
||||||
|
|
||||||
|
module dff_pre_clr (
|
||||||
|
input CLK,
|
||||||
|
input CLR,
|
||||||
|
input D,
|
||||||
|
input PRE,
|
||||||
|
output Q
|
||||||
|
);
|
||||||
|
|
||||||
|
dffpc dffpc_0 ( .CLK(CLK) , .CLR(CLR), .D(D), .PRE(PRE), .Q(Q) )/* synthesis black_box */;
|
||||||
|
//pragma attribute dffpc_0 dont_touch true
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,301 @@
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------
|
||||||
|
ring_osc_adjust.v
|
||||||
|
|
||||||
|
Control logic to keep the ring oscillator's frequency within the
|
||||||
|
desired range.
|
||||||
|
|
||||||
|
divider values from ClockDivider_rev2.pdf:
|
||||||
|
|
||||||
|
SEL sysclk_x2 sysclk
|
||||||
|
--------------------------------
|
||||||
|
000 ? ?
|
||||||
|
001 2 4
|
||||||
|
010 3 6
|
||||||
|
011 4 8
|
||||||
|
100 5 10
|
||||||
|
101 6 12
|
||||||
|
110 7 14
|
||||||
|
111 8 16
|
||||||
|
|
||||||
|
------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
`timescale 1ps/1ps
|
||||||
|
|
||||||
|
/*
|
||||||
|
module ring_osc_adjust (
|
||||||
|
input reset_i, // async reset
|
||||||
|
input clk_ringosc_i, // the ring oscillator output divided by 2 (this is not clk_main)
|
||||||
|
input clk_32khz_i, // 32.768KHz reference clock
|
||||||
|
input enable_i, // enable, can be tied off externally or driven occasionally to force re-calibration
|
||||||
|
output [2:0] div_sel_o // divider selection control for the ring oscillator divider circuit (in ASSP)
|
||||||
|
);
|
||||||
|
|
||||||
|
reg clk32k_r1, clk32k_r2;
|
||||||
|
reg clk32k_cycle_start;
|
||||||
|
reg enable_32k_sync, enable_32k_sync_r1;
|
||||||
|
reg enable_main_sync, enable_main_sync_r1, enable_main;
|
||||||
|
reg [10:0] clk_ringosc_div2_cnt;
|
||||||
|
reg [2:0] ring_osc_div, ring_osc_div_reg;
|
||||||
|
|
||||||
|
// divider SEL values
|
||||||
|
localparam [2:0] DIV2_SEL = 3'b001;
|
||||||
|
localparam [2:0] DIV3_SEL = 3'b010;
|
||||||
|
localparam [2:0] DIV4_SEL = 3'b011;
|
||||||
|
localparam [2:0] DIV5_SEL = 3'b100;
|
||||||
|
localparam [2:0] DIV6_SEL = 3'b101;
|
||||||
|
localparam [2:0] DIV7_SEL = 3'b110;
|
||||||
|
localparam [2:0] DIV8_SEL = 3'b111;
|
||||||
|
|
||||||
|
// threshold values for each divider value.
|
||||||
|
// These are the count values where each divider value will be applied.
|
||||||
|
// Example: if there are 395 counts on clk_ringosc_div2 within a 32KHz clock period, the ring osc is divided by 5.
|
||||||
|
// A divider of 5 means that sysclk_x2 = ring_osc/5, and sysclk = ring_osc/10.
|
||||||
|
// Nomenclature:
|
||||||
|
// ring_osc = ring oscillator raw clock (not accessible outside of ASSP)
|
||||||
|
// ring_osc_div2 = ring oscillator divided by 2 (used for calibration)
|
||||||
|
// sysclk_x2 = ring oscillator divided by SEL
|
||||||
|
// sysclk = ring oscillator divided by SEL*2 (used as system clock A.K.A. FFE clock)
|
||||||
|
// Assumptions:
|
||||||
|
// Ring osc range: 25.2MHz - 53.2MHz (39.7ns to 18.8ns period)
|
||||||
|
// I2C master will divide clk_main by 9 to produce SCL.
|
||||||
|
// SCL freq cannot exceed 400KHz.
|
||||||
|
// Guardband of 10% is added to allow for temperature/voltage variation, in case calibration is only done once at startup.
|
||||||
|
// A smaller guardband can be used if calibration is performed periodically.
|
||||||
|
localparam [10:0] DIV4_THRESHOLD = 11'd32; // (the threshold of 32 is arbitrary... just needs to be somewhat larger than 0)
|
||||||
|
localparam [10:0] DIV5_THRESHOLD = 11'd395;
|
||||||
|
localparam [10:0] DIV6_THRESHOLD = 11'd494;
|
||||||
|
localparam [10:0] DIV7_THRESHOLD = 11'd595;
|
||||||
|
localparam [10:0] DIV8_THRESHOLD = 11'd693;
|
||||||
|
|
||||||
|
|
||||||
|
// synchronize the enable to clk32k (set this FF on the rising edge of enable_i,
|
||||||
|
// clear it after one full 32KHz period has elapsed)
|
||||||
|
always @(posedge enable_i or posedge clk_32khz_i)
|
||||||
|
if (enable_i)
|
||||||
|
enable_32k_sync <= 1'b1;
|
||||||
|
else
|
||||||
|
if (enable_32k_sync_r1)
|
||||||
|
enable_32k_sync <= 1'b0;
|
||||||
|
else
|
||||||
|
enable_32k_sync <= enable_32k_sync;
|
||||||
|
|
||||||
|
always @(posedge clk_32khz_i)
|
||||||
|
enable_32k_sync_r1 <= enable_32k_sync;
|
||||||
|
|
||||||
|
assign enable_32k = enable_32k_sync_r1;
|
||||||
|
|
||||||
|
|
||||||
|
// detect rising edge on clk32khz
|
||||||
|
always @(posedge clk_ringosc_i) begin
|
||||||
|
if (!enable_i) begin
|
||||||
|
clk32k_r1 <= 1'b0;
|
||||||
|
clk32k_r2 <= 1'b0;
|
||||||
|
clk32k_cycle_start <= 1'b0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
clk32k_r1 <= clk_32khz_i;
|
||||||
|
clk32k_r2 <= clk32k_r1;
|
||||||
|
clk32k_cycle_start <= clk32k_r1 && !clk32k_r2;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// synchronize the stretched enable to the main clk domain,
|
||||||
|
// turn this enable off when clk32k_cycle_start is active
|
||||||
|
always @(posedge clk_ringosc_i or posedge reset_i) begin
|
||||||
|
if (reset_i) begin
|
||||||
|
enable_main_sync <= 1'b0;
|
||||||
|
enable_main_sync_r1 <= 1'b0;
|
||||||
|
enable_main <= 1'b0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
enable_main_sync <= enable_32k;
|
||||||
|
enable_main_sync_r1 <= enable_main_sync;
|
||||||
|
case (enable_main)
|
||||||
|
1'b0: if (clk32k_cycle_start && enable_main_sync_r1)
|
||||||
|
enable_main <= 1'b1;
|
||||||
|
else
|
||||||
|
enable_main <= 1'b0;
|
||||||
|
1'b1: if (clk32k_cycle_start && !enable_32k)
|
||||||
|
enable_main <= 1'b0;
|
||||||
|
else
|
||||||
|
enable_main <= 1'b1;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// count # of clk_ringosc_div2 cycles per 32khz clock period
|
||||||
|
always @(posedge clk_ringosc_i or posedge reset_i)
|
||||||
|
if (reset_i)
|
||||||
|
clk_ringosc_div2_cnt <= 0;
|
||||||
|
else
|
||||||
|
if (enable_main)
|
||||||
|
if (clk32k_cycle_start)
|
||||||
|
clk_ringosc_div2_cnt <= 0;
|
||||||
|
else
|
||||||
|
clk_ringosc_div2_cnt <= clk_ringosc_div2_cnt + 1;
|
||||||
|
else
|
||||||
|
clk_ringosc_div2_cnt <= 0;
|
||||||
|
|
||||||
|
|
||||||
|
// set the ring_osc clock divider value
|
||||||
|
// _div holds the temporary divider SEL valud
|
||||||
|
// _div_reg gets assigned after a full 32KHz clock period
|
||||||
|
always @(posedge clk_ringosc_i or posedge reset_i)
|
||||||
|
if (reset_i) begin
|
||||||
|
ring_osc_div <= 3'b111; // use the largest divide value by default
|
||||||
|
ring_osc_div_reg <= 3'b111;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (enable_main)
|
||||||
|
case (clk_ringosc_div2_cnt)
|
||||||
|
DIV4_THRESHOLD: ring_osc_div <= DIV4_SEL;
|
||||||
|
DIV5_THRESHOLD: ring_osc_div <= DIV5_SEL;
|
||||||
|
DIV6_THRESHOLD: ring_osc_div <= DIV6_SEL;
|
||||||
|
DIV7_THRESHOLD: ring_osc_div <= DIV7_SEL;
|
||||||
|
DIV8_THRESHOLD: ring_osc_div <= DIV8_SEL;
|
||||||
|
default: ring_osc_div <= ring_osc_div; // hold for all other values
|
||||||
|
endcase
|
||||||
|
else
|
||||||
|
ring_osc_div <= ring_osc_div; // need to retain the old value when enable is off
|
||||||
|
|
||||||
|
if (clk32k_cycle_start)
|
||||||
|
ring_osc_div_reg <= ring_osc_div;
|
||||||
|
else
|
||||||
|
ring_osc_div_reg <= ring_osc_div_reg;
|
||||||
|
end
|
||||||
|
|
||||||
|
assign div_sel_o = ring_osc_div_reg;
|
||||||
|
|
||||||
|
|
||||||
|
//// New Logic to produce CNT to system
|
||||||
|
//// Detect transition of Calibration aneble from Low to Hi
|
||||||
|
always @(posedge clk_32khz_i or posedge reset_i)
|
||||||
|
begin
|
||||||
|
if (reset_i) begin
|
||||||
|
enable_r1 <= 1'b0;
|
||||||
|
enable_r2 <= 1'b0;
|
||||||
|
enable_r3 <= 1'b0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
enable_r1 <= enable_i;
|
||||||
|
enable_r2 <= enable_r1;
|
||||||
|
enable_r3 <= enable_r2;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// Generating enable for Clock Cnt circuit
|
||||||
|
// Default is is 2 32KHz CLK period
|
||||||
|
always @(posedge clk_32khz_i or posedge reset_i)
|
||||||
|
begin
|
||||||
|
if (reset_i)
|
||||||
|
downCnt <= 2'b0;
|
||||||
|
else
|
||||||
|
if (enable_r2 && !enable_r3)
|
||||||
|
downCnt <= 2'b11;
|
||||||
|
else if (downCnt[1] || downCnt[0])
|
||||||
|
downCnt <= downCnt - 1'b1;
|
||||||
|
else
|
||||||
|
downCnt <= downCnt;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Sync to ring osc clk
|
||||||
|
always @(posedge clk_ringosc_i or posedge reset_i)
|
||||||
|
if (reset_i)
|
||||||
|
downCnt1_r1 <= 1'b0;
|
||||||
|
downCnt1_r2 <= 1'b0;
|
||||||
|
else
|
||||||
|
downCnt1_r1 <= downCnt[1];
|
||||||
|
downCnt1_r2 <= downCnt1_r1;
|
||||||
|
|
||||||
|
assign ringosccnt_reset = reset_i && !enable_i;
|
||||||
|
// Counting # of ringosc cyces in two 32KHz clock
|
||||||
|
always @(posedge clk_ringosc_i or posedge ringosccnt_reset)
|
||||||
|
begin
|
||||||
|
if (ringosccnt_reset)
|
||||||
|
ringosc_2_cnt <= 16'b0;
|
||||||
|
else if (downCnt1_r2)
|
||||||
|
ringosc_2_cnt <= ringosc_2_cnt + 1'b0;
|
||||||
|
else
|
||||||
|
ringosc_2_cnt <= ringosc_2_cnt;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
*/
|
||||||
|
|
||||||
|
module ring_osc_adjust (
|
||||||
|
input reset_i, // async reset
|
||||||
|
input clk_ringosc_i, // the ring oscillator output divided by 2 (this is not clk_main)
|
||||||
|
input clk_32khz_i, // 32.768KHz reference clock
|
||||||
|
input enable_i, // enable, can be tied off externally or driven occasionally to force re-calibration
|
||||||
|
output [15:0] cal_val_o // divider selection control for the ring oscillator divider circuit (in ASSP)
|
||||||
|
);
|
||||||
|
|
||||||
|
reg enable_r1, enable_r2, enable_r3;
|
||||||
|
reg [2:0] downCnt;
|
||||||
|
reg downCnt1_r1, downCnt1_r2;
|
||||||
|
reg [15:0] ringosc_2_cnt;
|
||||||
|
wire ringosccnt_reset;
|
||||||
|
|
||||||
|
//// New Logic to produce CNT to system
|
||||||
|
//// Detect transition of Calibration aneble from Low to Hi
|
||||||
|
always @(posedge clk_32khz_i or posedge reset_i)
|
||||||
|
begin
|
||||||
|
if (reset_i) begin
|
||||||
|
enable_r1 <= 1'b0;
|
||||||
|
enable_r2 <= 1'b0;
|
||||||
|
enable_r3 <= 1'b0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
enable_r1 <= enable_i;
|
||||||
|
enable_r2 <= enable_r1;
|
||||||
|
enable_r3 <= enable_r2;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// Generating enable for Clock Cnt circuit
|
||||||
|
// Default is is 2 32KHz CLK period
|
||||||
|
always @(posedge clk_32khz_i or posedge reset_i)
|
||||||
|
begin
|
||||||
|
if (reset_i)
|
||||||
|
downCnt <= 3'b0;
|
||||||
|
else
|
||||||
|
if (enable_r2 && !enable_r3)
|
||||||
|
downCnt <= 3'b111;
|
||||||
|
else if (downCnt != 3'b000)
|
||||||
|
downCnt <= downCnt - 1'b1;
|
||||||
|
else
|
||||||
|
downCnt <= downCnt;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Sync to ring osc clk
|
||||||
|
always @(posedge clk_ringosc_i or posedge reset_i)
|
||||||
|
if (reset_i)
|
||||||
|
begin
|
||||||
|
downCnt1_r1 <= 1'b0;
|
||||||
|
downCnt1_r2 <= 1'b0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
downCnt1_r1 <= downCnt[2];
|
||||||
|
downCnt1_r2 <= downCnt1_r1;
|
||||||
|
end
|
||||||
|
|
||||||
|
assign ringosccnt_reset = reset_i || !enable_i;
|
||||||
|
// Counting # of ringosc cyces in two 32KHz clock
|
||||||
|
always @(posedge clk_ringosc_i or posedge ringosccnt_reset)
|
||||||
|
begin
|
||||||
|
if (ringosccnt_reset)
|
||||||
|
ringosc_2_cnt <= 16'b0;
|
||||||
|
else if (downCnt1_r2)
|
||||||
|
ringosc_2_cnt <= ringosc_2_cnt + 1'b1;
|
||||||
|
else
|
||||||
|
ringosc_2_cnt <= ringosc_2_cnt;
|
||||||
|
end
|
||||||
|
|
||||||
|
assign cal_val_o = ringosc_2_cnt;
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,26 @@
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// title : ulpsh_rtl_defines.v
|
||||||
|
// project : ULP Sensor Hub
|
||||||
|
// description : RTL defines
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// copyright (c) 2014, QuickLogic Corporation
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Clock Circuit control defines
|
||||||
|
`define OP_CLK_DIV 8'b01000000
|
||||||
|
`define FFE1CLK_FREQ_SLT 8'b01000000
|
||||||
|
`define SM1CLK_FREQ_SLT 8'b00100000
|
||||||
|
|
||||||
|
`ifdef SIMULATION
|
||||||
|
`define OSC_SELECTION 1'b0
|
||||||
|
`else
|
||||||
|
`define OSC_SELECTION 1'b1
|
||||||
|
`endif
|
||||||
|
|
||||||
|
`define ENABLE_FFE_F0_SINGLE_DM
|
||||||
|
|
||||||
|
`define ENABLE_FFE_F0_EXTENDED_DM
|
||||||
|
|
||||||
|
`define FFE_F0_SEG0_OFFSET 9'h095
|
||||||
|
|
||||||
|
`define ENABLE_FFE_F0_CM_SIZE_4K
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,162 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// cavlc_fsm ////
|
||||||
|
//// ////
|
||||||
|
//// Description ////
|
||||||
|
//// controls the cavlc parsing process ////
|
||||||
|
//// ////
|
||||||
|
//// Author(s): ////
|
||||||
|
//// - bin qiu, qiubin@opencores.org ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2011 Authors and OPENCORES.ORG ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer. ////
|
||||||
|
//// ////
|
||||||
|
//// This source file is free software; you can redistribute it ////
|
||||||
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||||
|
//// Public License as published by the Free Software Foundation; ////
|
||||||
|
//// either version 2.1 of the License, or (at your option) any ////
|
||||||
|
//// later version. ////
|
||||||
|
//// ////
|
||||||
|
//// This source is distributed in the hope that it will be ////
|
||||||
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||||
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||||
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||||
|
//// details. ////
|
||||||
|
//// ////
|
||||||
|
//// You should have received a copy of the GNU Lesser General ////
|
||||||
|
//// Public License along with this source; if not, download it ////
|
||||||
|
//// from http://www.opencores.org/lgpl.shtml ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//2011-8-7 18:57 initial revision
|
||||||
|
|
||||||
|
`include "defines.v"
|
||||||
|
|
||||||
|
module cavlc_fsm
|
||||||
|
(
|
||||||
|
clk,
|
||||||
|
rst_n,
|
||||||
|
ena,
|
||||||
|
start,
|
||||||
|
max_coeff_num,
|
||||||
|
TotalCoeff,
|
||||||
|
TotalCoeff_comb,
|
||||||
|
TrailingOnes,
|
||||||
|
TrailingOnes_comb,
|
||||||
|
ZeroLeft,
|
||||||
|
state,
|
||||||
|
i,
|
||||||
|
idle,
|
||||||
|
valid
|
||||||
|
);
|
||||||
|
//------------------------
|
||||||
|
//ports
|
||||||
|
//------------------------
|
||||||
|
input clk;
|
||||||
|
input rst_n;
|
||||||
|
input ena;
|
||||||
|
input start;
|
||||||
|
|
||||||
|
input [4:0] max_coeff_num;
|
||||||
|
input [4:0] TotalCoeff;
|
||||||
|
input [4:0] TotalCoeff_comb;
|
||||||
|
input [1:0] TrailingOnes;
|
||||||
|
input [1:0] TrailingOnes_comb;
|
||||||
|
input [3:0] ZeroLeft;
|
||||||
|
|
||||||
|
output [7:0] state;
|
||||||
|
output [3:0] i;
|
||||||
|
output idle;
|
||||||
|
output valid;
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
//FFs
|
||||||
|
//------------------------
|
||||||
|
reg [7:0] state;
|
||||||
|
reg [3:0] i;
|
||||||
|
reg valid;
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
//state & i & valid
|
||||||
|
//------------------------
|
||||||
|
always @(posedge clk or negedge rst_n)
|
||||||
|
if (!rst_n) begin
|
||||||
|
state <= `cavlc_idle_s;
|
||||||
|
i <= 0;
|
||||||
|
valid <= 0;
|
||||||
|
end
|
||||||
|
else if (ena)
|
||||||
|
case(state)
|
||||||
|
`cavlc_idle_s : begin
|
||||||
|
if (start) begin
|
||||||
|
state <= `cavlc_read_total_coeffs_s;
|
||||||
|
valid <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
state <= `cavlc_idle_s;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
`cavlc_read_total_coeffs_s : begin
|
||||||
|
i <= TotalCoeff_comb -1;
|
||||||
|
if (TrailingOnes_comb > 0 && TotalCoeff_comb > 0)
|
||||||
|
state <= `cavlc_read_t1s_flags_s;
|
||||||
|
else if (TotalCoeff_comb > 0)
|
||||||
|
state <= `cavlc_read_level_prefix_s;
|
||||||
|
else begin
|
||||||
|
state <= `cavlc_idle_s;
|
||||||
|
valid <= 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
`cavlc_read_t1s_flags_s : begin
|
||||||
|
if (TrailingOnes == TotalCoeff)
|
||||||
|
state <= `cavlc_read_total_zeros_s;
|
||||||
|
else begin
|
||||||
|
state <= `cavlc_read_level_prefix_s;
|
||||||
|
i <= i - TrailingOnes;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
`cavlc_read_level_prefix_s : begin
|
||||||
|
state <= `cavlc_read_level_suffix_s;
|
||||||
|
end
|
||||||
|
`cavlc_read_level_suffix_s : begin
|
||||||
|
state <= `cavlc_calc_level_s;
|
||||||
|
end
|
||||||
|
`cavlc_calc_level_s : begin
|
||||||
|
if ( i == 0 && TotalCoeff < max_coeff_num)
|
||||||
|
state <= `cavlc_read_total_zeros_s;
|
||||||
|
else if (i == 0) begin
|
||||||
|
state <= `cavlc_read_run_befores_s;
|
||||||
|
i <= TotalCoeff - 1;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
state <= `cavlc_read_level_prefix_s;
|
||||||
|
i <= i - 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
`cavlc_read_total_zeros_s : begin
|
||||||
|
state <= `cavlc_read_run_befores_s;
|
||||||
|
i <= TotalCoeff - 1;
|
||||||
|
end
|
||||||
|
`cavlc_read_run_befores_s : begin
|
||||||
|
if (i == 0 || ZeroLeft == 0) begin
|
||||||
|
state <= `cavlc_idle_s;
|
||||||
|
valid <= 1;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
state <= `cavlc_read_run_befores_s;
|
||||||
|
i <= i - 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
|
||||||
|
assign idle = state[`cavlc_idle_bit];
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// cavlc_len_gen ////
|
||||||
|
//// ////
|
||||||
|
//// Description ////
|
||||||
|
//// generate the number of bits to forward ////
|
||||||
|
//// ////
|
||||||
|
//// Author(s): ////
|
||||||
|
//// - bin qiu, qiubin@opencores.org ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2011 Authors and OPENCORES.ORG ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer. ////
|
||||||
|
//// ////
|
||||||
|
//// This source file is free software; you can redistribute it ////
|
||||||
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||||
|
//// Public License as published by the Free Software Foundation; ////
|
||||||
|
//// either version 2.1 of the License, or (at your option) any ////
|
||||||
|
//// later version. ////
|
||||||
|
//// ////
|
||||||
|
//// This source is distributed in the hope that it will be ////
|
||||||
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||||
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||||
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||||
|
//// details. ////
|
||||||
|
//// ////
|
||||||
|
//// You should have received a copy of the GNU Lesser General ////
|
||||||
|
//// Public License along with this source; if not, download it ////
|
||||||
|
//// from http://www.opencores.org/lgpl.shtml ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//2011-8-7 20:19 initial revision
|
||||||
|
|
||||||
|
`include "defines.v"
|
||||||
|
|
||||||
|
module cavlc_len_gen
|
||||||
|
(
|
||||||
|
cavlc_state,
|
||||||
|
len_read_total_coeffs_comb,
|
||||||
|
len_read_levels_comb,
|
||||||
|
len_read_total_zeros_comb,
|
||||||
|
len_read_run_befores_comb,
|
||||||
|
len_comb
|
||||||
|
);
|
||||||
|
//------------------------
|
||||||
|
// ports
|
||||||
|
//------------------------
|
||||||
|
input [7:0] cavlc_state;
|
||||||
|
input [4:0] len_read_total_coeffs_comb;
|
||||||
|
input [4:0] len_read_levels_comb;
|
||||||
|
input [3:0] len_read_total_zeros_comb;
|
||||||
|
input [3:0] len_read_run_befores_comb;
|
||||||
|
|
||||||
|
output [4:0] len_comb;
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// regs
|
||||||
|
//------------------------
|
||||||
|
reg [4:0] len_comb; //number of bits comsumed by cavlc in a cycle
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// len_comb
|
||||||
|
//------------------------
|
||||||
|
always @ (*)
|
||||||
|
case (1'b1) //synthesis parallel_case
|
||||||
|
cavlc_state[`cavlc_read_total_coeffs_bit] : len_comb <= len_read_total_coeffs_comb;
|
||||||
|
cavlc_state[`cavlc_read_t1s_flags_bit],
|
||||||
|
cavlc_state[`cavlc_read_level_prefix_bit],
|
||||||
|
cavlc_state[`cavlc_read_level_suffix_bit] : len_comb <= len_read_levels_comb;
|
||||||
|
cavlc_state[`cavlc_read_total_zeros_bit] : len_comb <= len_read_total_zeros_comb;
|
||||||
|
cavlc_state[`cavlc_read_run_befores_bit] : len_comb <= len_read_run_befores_comb;
|
||||||
|
cavlc_state[`cavlc_calc_level_bit],
|
||||||
|
cavlc_state[`cavlc_idle_bit] : len_comb <= 0;
|
||||||
|
default : len_comb <= 'bx;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,400 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// cavlc_read_levels ////
|
||||||
|
//// ////
|
||||||
|
//// Description ////
|
||||||
|
//// decode levels for coeffs ////
|
||||||
|
//// ////
|
||||||
|
//// Author(s): ////
|
||||||
|
//// - bin qiu, qiubin@opencores.org ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2011 Authors and OPENCORES.ORG ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer. ////
|
||||||
|
//// ////
|
||||||
|
//// This source file is free software; you can redistribute it ////
|
||||||
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||||
|
//// Public License as published by the Free Software Foundation; ////
|
||||||
|
//// either version 2.1 of the License, or (at your option) any ////
|
||||||
|
//// later version. ////
|
||||||
|
//// ////
|
||||||
|
//// This source is distributed in the hope that it will be ////
|
||||||
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||||
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||||
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||||
|
//// details. ////
|
||||||
|
//// ////
|
||||||
|
//// You should have received a copy of the GNU Lesser General ////
|
||||||
|
//// Public License along with this source; if not, download it ////
|
||||||
|
//// from http://www.opencores.org/lgpl.shtml ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
//2011-8-6 initiial revision
|
||||||
|
//2011-8-19 reverse the order of level
|
||||||
|
|
||||||
|
// include TrailingOnes
|
||||||
|
|
||||||
|
`include "defines.v"
|
||||||
|
|
||||||
|
module cavlc_read_levels (
|
||||||
|
clk,
|
||||||
|
rst_n,
|
||||||
|
ena,
|
||||||
|
t1s_sel,
|
||||||
|
prefix_sel,
|
||||||
|
suffix_sel,
|
||||||
|
calc_sel,
|
||||||
|
TrailingOnes,
|
||||||
|
TotalCoeff,
|
||||||
|
rbsp,
|
||||||
|
i,
|
||||||
|
level_0,
|
||||||
|
level_1,
|
||||||
|
level_2,
|
||||||
|
level_3,
|
||||||
|
level_4,
|
||||||
|
level_5,
|
||||||
|
level_6,
|
||||||
|
level_7,
|
||||||
|
level_8,
|
||||||
|
level_9,
|
||||||
|
level_10,
|
||||||
|
level_11,
|
||||||
|
level_12,
|
||||||
|
level_13,
|
||||||
|
level_14,
|
||||||
|
level_15,
|
||||||
|
len_comb
|
||||||
|
);
|
||||||
|
//------------------------
|
||||||
|
// ports
|
||||||
|
//------------------------
|
||||||
|
input clk;
|
||||||
|
input rst_n;
|
||||||
|
|
||||||
|
input ena;
|
||||||
|
input t1s_sel;
|
||||||
|
input prefix_sel;
|
||||||
|
input suffix_sel;
|
||||||
|
input calc_sel;
|
||||||
|
|
||||||
|
input [1:0] TrailingOnes;
|
||||||
|
input [4:0] TotalCoeff;
|
||||||
|
input [0:15] rbsp;
|
||||||
|
input [3:0] i;
|
||||||
|
|
||||||
|
output [8:0] level_0;
|
||||||
|
output [8:0] level_1;
|
||||||
|
output [8:0] level_2;
|
||||||
|
output [8:0] level_3;
|
||||||
|
output [8:0] level_4;
|
||||||
|
output [8:0] level_5;
|
||||||
|
output [8:0] level_6;
|
||||||
|
output [8:0] level_7;
|
||||||
|
output [8:0] level_8;
|
||||||
|
output [8:0] level_9;
|
||||||
|
output [8:0] level_10;
|
||||||
|
output [8:0] level_11;
|
||||||
|
output [8:0] level_12;
|
||||||
|
output [8:0] level_13;
|
||||||
|
output [8:0] level_14;
|
||||||
|
output [8:0] level_15;
|
||||||
|
|
||||||
|
output [4:0] len_comb;
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// regs
|
||||||
|
//------------------------
|
||||||
|
reg [0:15] rbsp_internal; // reduce toggle rate
|
||||||
|
reg [3:0] level_prefix_comb;
|
||||||
|
reg [8:0] level_suffix;
|
||||||
|
reg [4:0] len_comb;
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// FFs
|
||||||
|
//------------------------
|
||||||
|
reg [3:0] level_prefix;
|
||||||
|
reg [2:0] suffixLength; // range from 0 to 6
|
||||||
|
reg [8:0] level;
|
||||||
|
reg [8:0] level_abs;
|
||||||
|
reg [8:0] level_code_tmp;
|
||||||
|
reg [8:0] level_0, level_1, level_2, level_3, level_4, level_5, level_6, level_7;
|
||||||
|
reg [8:0] level_8, level_9, level_10, level_11, level_12, level_13, level_14, level_15;
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// level_prefix_comb
|
||||||
|
//------------------------
|
||||||
|
always @(*)
|
||||||
|
if ((t1s_sel || prefix_sel || suffix_sel)&& ena)
|
||||||
|
rbsp_internal <= rbsp;
|
||||||
|
else
|
||||||
|
rbsp_internal <= 'hffff;
|
||||||
|
|
||||||
|
always @(*)
|
||||||
|
if (rbsp_internal[0]) level_prefix_comb <= 0;
|
||||||
|
else if (rbsp_internal[1]) level_prefix_comb <= 1;
|
||||||
|
else if (rbsp_internal[2]) level_prefix_comb <= 2;
|
||||||
|
else if (rbsp_internal[3]) level_prefix_comb <= 3;
|
||||||
|
else if (rbsp_internal[4]) level_prefix_comb <= 4;
|
||||||
|
else if (rbsp_internal[5]) level_prefix_comb <= 5;
|
||||||
|
else if (rbsp_internal[6]) level_prefix_comb <= 6;
|
||||||
|
else if (rbsp_internal[7]) level_prefix_comb <= 7;
|
||||||
|
else if (rbsp_internal[8]) level_prefix_comb <= 8;
|
||||||
|
else if (rbsp_internal[9]) level_prefix_comb <= 9;
|
||||||
|
else if (rbsp_internal[10]) level_prefix_comb <= 10;
|
||||||
|
else if (rbsp_internal[11]) level_prefix_comb <= 11;
|
||||||
|
else if (rbsp_internal[12]) level_prefix_comb <= 12;
|
||||||
|
else if (rbsp_internal[13]) level_prefix_comb <= 13;
|
||||||
|
else if (rbsp_internal[14]) level_prefix_comb <= 14;
|
||||||
|
else if (rbsp_internal[15]) level_prefix_comb <= 15;
|
||||||
|
else level_prefix_comb <= 'bx;
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// level_prefix
|
||||||
|
//------------------------
|
||||||
|
always @(posedge clk or negedge rst_n)
|
||||||
|
if (!rst_n)
|
||||||
|
level_prefix <= 0;
|
||||||
|
else if (prefix_sel && ena)
|
||||||
|
level_prefix <= level_prefix_comb;
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// suffixLength
|
||||||
|
//------------------------
|
||||||
|
wire first_level;
|
||||||
|
assign first_level = (i == TotalCoeff - TrailingOnes - 1);
|
||||||
|
|
||||||
|
always @(posedge clk or negedge rst_n)
|
||||||
|
if (!rst_n)
|
||||||
|
suffixLength <= 0;
|
||||||
|
else if (prefix_sel && ena) begin
|
||||||
|
if (TotalCoeff > 10 && TrailingOnes < 3 && first_level ) //initialize suffixLength before proceeding first level_suffix
|
||||||
|
suffixLength <= 1;
|
||||||
|
else if (first_level)
|
||||||
|
suffixLength <= 0;
|
||||||
|
else if (suffixLength == 0 && level_abs > 2'd3)
|
||||||
|
suffixLength <= 2;
|
||||||
|
else if (suffixLength == 0)
|
||||||
|
suffixLength <= 1;
|
||||||
|
else if ( level_abs > (2'd3 << (suffixLength - 1'b1) ) && suffixLength < 6)
|
||||||
|
suffixLength <= suffixLength + 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// level_suffix
|
||||||
|
//------------------------
|
||||||
|
always @(*)
|
||||||
|
if (suffixLength > 0 && level_prefix <= 14)
|
||||||
|
level_suffix <= {3'b0, rbsp_internal[0:5] >> (3'd6 - suffixLength)};
|
||||||
|
else if (level_prefix == 14) //level_prefix == 14 && suffixLength == 0
|
||||||
|
level_suffix <= {3'b0, rbsp_internal[0:3] };
|
||||||
|
else if (level_prefix == 15)
|
||||||
|
level_suffix <= rbsp_internal[3:11];
|
||||||
|
else
|
||||||
|
level_suffix <= 0;
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// level_code_tmp
|
||||||
|
//------------------------
|
||||||
|
always @(posedge clk or negedge rst_n)
|
||||||
|
if (!rst_n) begin
|
||||||
|
level_code_tmp <= 0;
|
||||||
|
end
|
||||||
|
else if (suffix_sel && ena) begin
|
||||||
|
level_code_tmp <= (level_prefix << suffixLength) + level_suffix +
|
||||||
|
((suffixLength == 0 && level_prefix == 15) ? 4'd15 : 0);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// level
|
||||||
|
//------------------------
|
||||||
|
wire [2:0] tmp1;
|
||||||
|
|
||||||
|
assign tmp1 = (first_level && TrailingOnes < 3)? 2'd2 : 2'd0;
|
||||||
|
|
||||||
|
always @(*)
|
||||||
|
begin
|
||||||
|
if (level_code_tmp % 2 == 0) begin
|
||||||
|
level <= ( level_code_tmp + tmp1 + 2 ) >> 1;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
level <= (-level_code_tmp - tmp1 - 1 ) >> 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// level_abs
|
||||||
|
//------------------------
|
||||||
|
wire level_abs_refresh;
|
||||||
|
assign level_abs_refresh = calc_sel && ena;
|
||||||
|
|
||||||
|
always @(posedge clk or negedge rst_n)
|
||||||
|
if (!rst_n) begin
|
||||||
|
level_abs <= 0;
|
||||||
|
end
|
||||||
|
else if (level_abs_refresh) begin
|
||||||
|
level_abs <= level[8] ? -level : level;
|
||||||
|
end
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// level regfile
|
||||||
|
//------------------------
|
||||||
|
always @ (posedge clk or negedge rst_n)
|
||||||
|
if (!rst_n) begin
|
||||||
|
level_0 <= 0; level_1 <= 0; level_2 <= 0; level_3 <= 0;
|
||||||
|
level_4 <= 0; level_5 <= 0; level_6 <= 0; level_7 <= 0;
|
||||||
|
level_8 <= 0; level_9 <= 0; level_10<= 0; level_11<= 0;
|
||||||
|
level_12<= 0; level_13<= 0; level_14<= 0; level_15<= 0;
|
||||||
|
end
|
||||||
|
else if (t1s_sel && ena)
|
||||||
|
case (i)
|
||||||
|
0 : level_0 <= rbsp_internal[0]? -1 : 1;
|
||||||
|
1 : begin
|
||||||
|
level_1 <= rbsp_internal[0]? -1 : 1;
|
||||||
|
if (TrailingOnes[1])
|
||||||
|
level_0 <= rbsp_internal[1]? -1 : 1;
|
||||||
|
end
|
||||||
|
2 : begin
|
||||||
|
level_2 <= rbsp_internal[0]? -1 : 1;
|
||||||
|
if (TrailingOnes[1])
|
||||||
|
level_1 <= rbsp_internal[1]? -1 : 1;
|
||||||
|
if (TrailingOnes == 3)
|
||||||
|
level_0 <= rbsp_internal[2]? -1 : 1;
|
||||||
|
end
|
||||||
|
3 : begin
|
||||||
|
level_3 <= rbsp_internal[0]? -1 : 1;
|
||||||
|
if (TrailingOnes[1])
|
||||||
|
level_2 <= rbsp_internal[1]? -1 : 1;
|
||||||
|
if (TrailingOnes == 3)
|
||||||
|
level_1 <= rbsp_internal[2]? -1 : 1;
|
||||||
|
end
|
||||||
|
4 : begin
|
||||||
|
level_4 <= rbsp_internal[0]? -1 : 1;
|
||||||
|
if (TrailingOnes[1])
|
||||||
|
level_3 <= rbsp_internal[1]? -1 : 1;
|
||||||
|
if (TrailingOnes == 3)
|
||||||
|
level_2 <= rbsp_internal[2]? -1 : 1;
|
||||||
|
end
|
||||||
|
5 : begin
|
||||||
|
level_5 <= rbsp_internal[0]? -1 : 1;
|
||||||
|
if (TrailingOnes[1])
|
||||||
|
level_4 <= rbsp_internal[1]? -1 : 1;
|
||||||
|
if (TrailingOnes == 3)
|
||||||
|
level_3 <= rbsp_internal[2]? -1 : 1;
|
||||||
|
end
|
||||||
|
6 : begin
|
||||||
|
level_6 <= rbsp_internal[0]? -1 : 1;
|
||||||
|
if (TrailingOnes[1])
|
||||||
|
level_5 <= rbsp_internal[1]? -1 : 1;
|
||||||
|
if (TrailingOnes == 3)
|
||||||
|
level_4 <= rbsp_internal[2]? -1 : 1;
|
||||||
|
end
|
||||||
|
7 : begin
|
||||||
|
level_7 <= rbsp_internal[0]? -1 : 1;
|
||||||
|
if (TrailingOnes[1])
|
||||||
|
level_6 <= rbsp_internal[1]? -1 : 1;
|
||||||
|
if (TrailingOnes == 3)
|
||||||
|
level_5 <= rbsp_internal[2]? -1 : 1;
|
||||||
|
end
|
||||||
|
8 : begin
|
||||||
|
level_8 <= rbsp_internal[0]? -1 : 1;
|
||||||
|
if (TrailingOnes[1])
|
||||||
|
level_7 <= rbsp_internal[1]? -1 : 1;
|
||||||
|
if (TrailingOnes == 3)
|
||||||
|
level_6 <= rbsp_internal[2]? -1 : 1;
|
||||||
|
end
|
||||||
|
9 : begin
|
||||||
|
level_9 <= rbsp_internal[0]? -1 : 1;
|
||||||
|
if (TrailingOnes[1])
|
||||||
|
level_8 <= rbsp_internal[1]? -1 : 1;
|
||||||
|
if (TrailingOnes == 3)
|
||||||
|
level_7 <= rbsp_internal[2]? -1 : 1;
|
||||||
|
end
|
||||||
|
10: begin
|
||||||
|
level_10 <= rbsp_internal[0]? -1 : 1;
|
||||||
|
if (TrailingOnes[1])
|
||||||
|
level_9 <= rbsp_internal[1]? -1 : 1;
|
||||||
|
if (TrailingOnes == 3)
|
||||||
|
level_8 <= rbsp_internal[2]? -1 : 1;
|
||||||
|
end
|
||||||
|
11: begin
|
||||||
|
level_11 <= rbsp_internal[0]? -1 : 1;
|
||||||
|
if (TrailingOnes[1])
|
||||||
|
level_10 <= rbsp_internal[1]? -1 : 1;
|
||||||
|
if (TrailingOnes == 3)
|
||||||
|
level_9 <= rbsp_internal[2]? -1 : 1;
|
||||||
|
end
|
||||||
|
12: begin
|
||||||
|
level_12 <= rbsp_internal[0]? -1 : 1;
|
||||||
|
if (TrailingOnes[1])
|
||||||
|
level_11 <= rbsp_internal[1]? -1 : 1;
|
||||||
|
if (TrailingOnes == 3)
|
||||||
|
level_10 <= rbsp_internal[2]? -1 : 1;
|
||||||
|
end
|
||||||
|
13: begin
|
||||||
|
level_13 <= rbsp_internal[0]? -1 : 1;
|
||||||
|
if (TrailingOnes[1])
|
||||||
|
level_12 <= rbsp_internal[1]? -1 : 1;
|
||||||
|
if (TrailingOnes == 3)
|
||||||
|
level_11 <= rbsp_internal[2]? -1 : 1;
|
||||||
|
end
|
||||||
|
14: begin
|
||||||
|
level_14 <= rbsp_internal[0]? -1 : 1;
|
||||||
|
if (TrailingOnes[1])
|
||||||
|
level_13 <= rbsp_internal[1]? -1 : 1;
|
||||||
|
if (TrailingOnes == 3)
|
||||||
|
level_12 <= rbsp_internal[2]? -1 : 1;
|
||||||
|
end
|
||||||
|
15: begin
|
||||||
|
level_15 <= rbsp_internal[0]? -1 : 1;
|
||||||
|
if (TrailingOnes[1])
|
||||||
|
level_14 <= rbsp_internal[1]? -1 : 1;
|
||||||
|
if (TrailingOnes == 3)
|
||||||
|
level_13 <= rbsp_internal[2]? -1 : 1;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
else if (calc_sel && ena)
|
||||||
|
case (i)
|
||||||
|
0 :level_0 <= level;
|
||||||
|
1 :level_1 <= level;
|
||||||
|
2 :level_2 <= level;
|
||||||
|
3 :level_3 <= level;
|
||||||
|
4 :level_4 <= level;
|
||||||
|
5 :level_5 <= level;
|
||||||
|
6 :level_6 <= level;
|
||||||
|
7 :level_7 <= level;
|
||||||
|
8 :level_8 <= level;
|
||||||
|
9 :level_9 <= level;
|
||||||
|
10:level_10<= level;
|
||||||
|
11:level_11<= level;
|
||||||
|
12:level_12<= level;
|
||||||
|
13:level_13<= level;
|
||||||
|
14:level_14<= level;
|
||||||
|
15:level_15<= level;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
always @(*)
|
||||||
|
if(t1s_sel)
|
||||||
|
len_comb <= TrailingOnes;
|
||||||
|
else if(prefix_sel)
|
||||||
|
len_comb <= level_prefix_comb + 1;
|
||||||
|
else if(suffix_sel && suffixLength > 0 && level_prefix <= 14)
|
||||||
|
len_comb <= suffixLength;
|
||||||
|
else if(suffix_sel && level_prefix == 14)
|
||||||
|
len_comb <= 4;
|
||||||
|
else if(suffix_sel && level_prefix == 15)
|
||||||
|
len_comb <= 12;
|
||||||
|
else
|
||||||
|
len_comb <= 0;
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,368 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// cavlc_read_run_befores ////
|
||||||
|
//// ////
|
||||||
|
//// Description ////
|
||||||
|
//// decode runs and combine them with levels ////
|
||||||
|
//// ////
|
||||||
|
//// Author(s): ////
|
||||||
|
//// - bin qiu, qiubin@opencores.org ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2011 Authors and OPENCORES.ORG ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer. ////
|
||||||
|
//// ////
|
||||||
|
//// This source file is free software; you can redistribute it ////
|
||||||
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||||
|
//// Public License as published by the Free Software Foundation; ////
|
||||||
|
//// either version 2.1 of the License, or (at your option) any ////
|
||||||
|
//// later version. ////
|
||||||
|
//// ////
|
||||||
|
//// This source is distributed in the hope that it will be ////
|
||||||
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||||
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||||
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||||
|
//// details. ////
|
||||||
|
//// ////
|
||||||
|
//// You should have received a copy of the GNU Lesser General ////
|
||||||
|
//// Public License along with this source; if not, download it ////
|
||||||
|
//// from http://www.opencores.org/lgpl.shtml ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//2011-8-16 initiial revision
|
||||||
|
|
||||||
|
`include "defines.v"
|
||||||
|
|
||||||
|
module cavlc_read_run_befores
|
||||||
|
(
|
||||||
|
clk,
|
||||||
|
rst_n,
|
||||||
|
ena,
|
||||||
|
sel,
|
||||||
|
clr,
|
||||||
|
ZeroLeft_init,
|
||||||
|
|
||||||
|
rbsp,
|
||||||
|
i,
|
||||||
|
TotalZeros_comb,
|
||||||
|
|
||||||
|
level_0,
|
||||||
|
level_1,
|
||||||
|
level_2,
|
||||||
|
level_3,
|
||||||
|
level_4,
|
||||||
|
level_5,
|
||||||
|
level_6,
|
||||||
|
level_7,
|
||||||
|
level_8,
|
||||||
|
level_9,
|
||||||
|
level_10,
|
||||||
|
level_11,
|
||||||
|
level_12,
|
||||||
|
level_13,
|
||||||
|
level_14,
|
||||||
|
level_15,
|
||||||
|
|
||||||
|
coeff_0,
|
||||||
|
coeff_1,
|
||||||
|
coeff_2,
|
||||||
|
coeff_3,
|
||||||
|
coeff_4,
|
||||||
|
coeff_5,
|
||||||
|
coeff_6,
|
||||||
|
coeff_7,
|
||||||
|
coeff_8,
|
||||||
|
coeff_9,
|
||||||
|
coeff_10,
|
||||||
|
coeff_11,
|
||||||
|
coeff_12,
|
||||||
|
coeff_13,
|
||||||
|
coeff_14,
|
||||||
|
coeff_15,
|
||||||
|
ZeroLeft,
|
||||||
|
len_comb
|
||||||
|
);
|
||||||
|
//----------------------
|
||||||
|
//ports
|
||||||
|
//----------------------
|
||||||
|
input clk;
|
||||||
|
input rst_n;
|
||||||
|
input ena;
|
||||||
|
input sel;
|
||||||
|
input clr;
|
||||||
|
input ZeroLeft_init;
|
||||||
|
|
||||||
|
input [0:10] rbsp;
|
||||||
|
input [3:0] i; //range from TotalCoeff-1 to 0
|
||||||
|
input [3:0] TotalZeros_comb;
|
||||||
|
|
||||||
|
input [8:0] level_0;
|
||||||
|
input [8:0] level_1;
|
||||||
|
input [8:0] level_2;
|
||||||
|
input [8:0] level_3;
|
||||||
|
input [8:0] level_4;
|
||||||
|
input [8:0] level_5;
|
||||||
|
input [8:0] level_6;
|
||||||
|
input [8:0] level_7;
|
||||||
|
input [8:0] level_8;
|
||||||
|
input [8:0] level_9;
|
||||||
|
input [8:0] level_10;
|
||||||
|
input [8:0] level_11;
|
||||||
|
input [8:0] level_12;
|
||||||
|
input [8:0] level_13;
|
||||||
|
input [8:0] level_14;
|
||||||
|
input [8:0] level_15;
|
||||||
|
|
||||||
|
output [8:0] coeff_0;
|
||||||
|
output [8:0] coeff_1;
|
||||||
|
output [8:0] coeff_2;
|
||||||
|
output [8:0] coeff_3;
|
||||||
|
output [8:0] coeff_4;
|
||||||
|
output [8:0] coeff_5;
|
||||||
|
output [8:0] coeff_6;
|
||||||
|
output [8:0] coeff_7;
|
||||||
|
output [8:0] coeff_8;
|
||||||
|
output [8:0] coeff_9;
|
||||||
|
output [8:0] coeff_10;
|
||||||
|
output [8:0] coeff_11;
|
||||||
|
output [8:0] coeff_12;
|
||||||
|
output [8:0] coeff_13;
|
||||||
|
output [8:0] coeff_14;
|
||||||
|
output [8:0] coeff_15;
|
||||||
|
|
||||||
|
output [3:0] ZeroLeft;
|
||||||
|
|
||||||
|
output [3:0] len_comb;
|
||||||
|
|
||||||
|
//----------------------
|
||||||
|
//regs
|
||||||
|
//----------------------
|
||||||
|
reg [3:0] run;
|
||||||
|
reg [3:0] len;
|
||||||
|
reg [8:0] coeff;
|
||||||
|
|
||||||
|
|
||||||
|
reg [3:0] len_comb;
|
||||||
|
|
||||||
|
//----------------------
|
||||||
|
//FFs
|
||||||
|
//----------------------
|
||||||
|
reg [3:0] ZeroLeft;
|
||||||
|
|
||||||
|
reg [8:0] coeff_0;
|
||||||
|
reg [8:0] coeff_1;
|
||||||
|
reg [8:0] coeff_2;
|
||||||
|
reg [8:0] coeff_3;
|
||||||
|
reg [8:0] coeff_4;
|
||||||
|
reg [8:0] coeff_5;
|
||||||
|
reg [8:0] coeff_6;
|
||||||
|
reg [8:0] coeff_7;
|
||||||
|
reg [8:0] coeff_8;
|
||||||
|
reg [8:0] coeff_9;
|
||||||
|
reg [8:0] coeff_10;
|
||||||
|
reg [8:0] coeff_11;
|
||||||
|
reg [8:0] coeff_12;
|
||||||
|
reg [8:0] coeff_13;
|
||||||
|
reg [8:0] coeff_14;
|
||||||
|
reg [8:0] coeff_15;
|
||||||
|
|
||||||
|
//----------------------
|
||||||
|
//run & len
|
||||||
|
//----------------------
|
||||||
|
always @(rbsp or ZeroLeft or ena or sel)
|
||||||
|
if (ena && sel)
|
||||||
|
case(ZeroLeft)
|
||||||
|
0 : begin len <= 0; run <= 0; end
|
||||||
|
1 : begin len <= 1; run <= rbsp[0]? 0:1; end
|
||||||
|
2 : begin if (rbsp[0]) begin
|
||||||
|
run <= 0;
|
||||||
|
len <= 1;
|
||||||
|
end
|
||||||
|
else if (rbsp[1]) begin
|
||||||
|
run <= 1;
|
||||||
|
len <= 2;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
run <= 2;
|
||||||
|
len <= 2;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
3 : begin
|
||||||
|
run <= 3 - rbsp[0:1];
|
||||||
|
len <= 2;
|
||||||
|
end
|
||||||
|
4 : begin
|
||||||
|
if (rbsp[0:1] != 0) begin
|
||||||
|
run <= 3 - rbsp[0:1];
|
||||||
|
len <= 2;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
run <= rbsp[2]? 3:4;
|
||||||
|
len <= 3;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
5 : begin
|
||||||
|
if (rbsp[0]) begin
|
||||||
|
run <= rbsp[1]? 0:1;
|
||||||
|
len <= 2;
|
||||||
|
end
|
||||||
|
else if (rbsp[1]) begin
|
||||||
|
run <= rbsp[2]? 2:3;
|
||||||
|
len <= 3;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
run <= rbsp[2]? 4:5;
|
||||||
|
len <= 3;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
6 : begin
|
||||||
|
if (rbsp[0:1] == 2'b11) begin
|
||||||
|
run <= 0;
|
||||||
|
len <= 2;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
len <= 3;
|
||||||
|
case(rbsp[0:2])
|
||||||
|
3'b000 : run <= 1;
|
||||||
|
3'b001 : run <= 2;
|
||||||
|
3'b011 : run <= 3;
|
||||||
|
3'b010 : run <= 4;
|
||||||
|
3'b101 : run <= 5;
|
||||||
|
default: run <= 6;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
default : begin
|
||||||
|
if (rbsp[0:2] != 0) begin
|
||||||
|
run <= 7 - rbsp[0:2];
|
||||||
|
len <= 3;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
case (1'b1)
|
||||||
|
rbsp[3] : begin run <= 7; len <= 4; end
|
||||||
|
rbsp[4] : begin run <= 8; len <= 5; end
|
||||||
|
rbsp[5] : begin run <= 9; len <= 6; end
|
||||||
|
rbsp[6] : begin run <= 10; len <= 7; end
|
||||||
|
rbsp[7] : begin run <= 11; len <= 8; end
|
||||||
|
rbsp[8] : begin run <= 12; len <= 9; end
|
||||||
|
rbsp[9] : begin run <= 13; len <= 10;end
|
||||||
|
rbsp[10]: begin run <= 14; len <= 11;end
|
||||||
|
default : begin run <= 'bx; len <='bx;end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
else begin
|
||||||
|
len <= 0;
|
||||||
|
run <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
//----------------------
|
||||||
|
//len_comb
|
||||||
|
//----------------------
|
||||||
|
always @(*)
|
||||||
|
if (i > 0)
|
||||||
|
len_comb <= len;
|
||||||
|
else
|
||||||
|
len_comb <= 0;
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------
|
||||||
|
//ZeroLeft
|
||||||
|
//----------------------
|
||||||
|
always @(posedge clk or negedge rst_n)
|
||||||
|
if (!rst_n)
|
||||||
|
ZeroLeft <= 0;
|
||||||
|
else if (ena && clr) //in case TotalCoeff >= max_coeff_num
|
||||||
|
ZeroLeft <= 0;
|
||||||
|
else if (ena && ZeroLeft_init)
|
||||||
|
ZeroLeft <= TotalZeros_comb;
|
||||||
|
else if (ena && sel )//if ZeroLeft == 0, run will be 0
|
||||||
|
ZeroLeft <= ZeroLeft - run;
|
||||||
|
|
||||||
|
//----------------------
|
||||||
|
//coeff
|
||||||
|
//----------------------
|
||||||
|
always @(*)
|
||||||
|
if (ena && sel)
|
||||||
|
case (i)
|
||||||
|
0 :coeff <= level_0;
|
||||||
|
1 :coeff <= level_1;
|
||||||
|
2 :coeff <= level_2;
|
||||||
|
3 :coeff <= level_3;
|
||||||
|
4 :coeff <= level_4;
|
||||||
|
5 :coeff <= level_5;
|
||||||
|
6 :coeff <= level_6;
|
||||||
|
7 :coeff <= level_7;
|
||||||
|
8 :coeff <= level_8;
|
||||||
|
9 :coeff <= level_9;
|
||||||
|
10:coeff <= level_10;
|
||||||
|
11:coeff <= level_11;
|
||||||
|
12:coeff <= level_12;
|
||||||
|
13:coeff <= level_13;
|
||||||
|
14:coeff <= level_14;
|
||||||
|
15:coeff <= level_15;
|
||||||
|
endcase
|
||||||
|
else
|
||||||
|
coeff <= 0;
|
||||||
|
|
||||||
|
//----------------------
|
||||||
|
//coeff_0 to coeff_15
|
||||||
|
//----------------------
|
||||||
|
always @(posedge clk or negedge rst_n)
|
||||||
|
if (!rst_n) begin
|
||||||
|
coeff_0 <= 0; coeff_1 <= 0; coeff_2 <= 0; coeff_3 <= 0;
|
||||||
|
coeff_4 <= 0; coeff_5 <= 0; coeff_6 <= 0; coeff_7 <= 0;
|
||||||
|
coeff_8 <= 0; coeff_9 <= 0; coeff_10<= 0; coeff_11<= 0;
|
||||||
|
coeff_12<= 0; coeff_13<= 0; coeff_14<= 0; coeff_15<= 0;
|
||||||
|
end
|
||||||
|
else if (ena && clr) begin
|
||||||
|
coeff_0 <= 0; coeff_1 <= 0; coeff_2 <= 0; coeff_3 <= 0;
|
||||||
|
coeff_4 <= 0; coeff_5 <= 0; coeff_6 <= 0; coeff_7 <= 0;
|
||||||
|
coeff_8 <= 0; coeff_9 <= 0; coeff_10<= 0; coeff_11<= 0;
|
||||||
|
coeff_12<= 0; coeff_13<= 0; coeff_14<= 0; coeff_15<= 0;
|
||||||
|
end
|
||||||
|
else if (ena && sel && ZeroLeft > 0)
|
||||||
|
case (ZeroLeft+i)
|
||||||
|
1 :coeff_1 <= coeff;
|
||||||
|
2 :coeff_2 <= coeff;
|
||||||
|
3 :coeff_3 <= coeff;
|
||||||
|
4 :coeff_4 <= coeff;
|
||||||
|
5 :coeff_5 <= coeff;
|
||||||
|
6 :coeff_6 <= coeff;
|
||||||
|
7 :coeff_7 <= coeff;
|
||||||
|
8 :coeff_8 <= coeff;
|
||||||
|
9 :coeff_9 <= coeff;
|
||||||
|
10:coeff_10 <= coeff;
|
||||||
|
11:coeff_11 <= coeff;
|
||||||
|
12:coeff_12 <= coeff;
|
||||||
|
13:coeff_13 <= coeff;
|
||||||
|
14:coeff_14 <= coeff;
|
||||||
|
default:
|
||||||
|
coeff_15 <= coeff;
|
||||||
|
endcase
|
||||||
|
else if (ena && sel) begin
|
||||||
|
if (i >= 0) coeff_0 <= level_0;
|
||||||
|
if (i >= 1) coeff_1 <= level_1;
|
||||||
|
if (i >= 2) coeff_2 <= level_2;
|
||||||
|
if (i >= 3) coeff_3 <= level_3;
|
||||||
|
if (i >= 4) coeff_4 <= level_4;
|
||||||
|
if (i >= 5) coeff_5 <= level_5;
|
||||||
|
if (i >= 6) coeff_6 <= level_6;
|
||||||
|
if (i >= 7) coeff_7 <= level_7;
|
||||||
|
if (i >= 8) coeff_8 <= level_8;
|
||||||
|
if (i >= 9) coeff_9 <= level_9;
|
||||||
|
if (i >= 10)coeff_10 <= level_10;
|
||||||
|
if (i >= 11)coeff_11 <= level_11;
|
||||||
|
if (i >= 12)coeff_12 <= level_12;
|
||||||
|
if (i >= 13)coeff_13 <= level_13;
|
||||||
|
if (i >= 14)coeff_14 <= level_14;
|
||||||
|
if (i == 15)coeff_15 <= level_15;
|
||||||
|
end
|
||||||
|
endmodule
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,716 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// cavlc_read_total_zeros ////
|
||||||
|
//// ////
|
||||||
|
//// Description ////
|
||||||
|
//// decode total_zeros ////
|
||||||
|
//// ////
|
||||||
|
//// Author(s): ////
|
||||||
|
//// - bin qiu, qiubin@opencores.org ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2011 Authors and OPENCORES.ORG ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer. ////
|
||||||
|
//// ////
|
||||||
|
//// This source file is free software; you can redistribute it ////
|
||||||
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||||
|
//// Public License as published by the Free Software Foundation; ////
|
||||||
|
//// either version 2.1 of the License, or (at your option) any ////
|
||||||
|
//// later version. ////
|
||||||
|
//// ////
|
||||||
|
//// This source is distributed in the hope that it will be ////
|
||||||
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||||
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||||
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||||
|
//// details. ////
|
||||||
|
//// ////
|
||||||
|
//// You should have received a copy of the GNU Lesser General ////
|
||||||
|
//// Public License along with this source; if not, download it ////
|
||||||
|
//// from http://www.opencores.org/lgpl.shtml ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//2011-8-14 initial version
|
||||||
|
|
||||||
|
`include "defines.v"
|
||||||
|
|
||||||
|
module cavlc_read_total_zeros
|
||||||
|
(
|
||||||
|
ena,
|
||||||
|
sel,
|
||||||
|
chroma_DC_sel,
|
||||||
|
rbsp,
|
||||||
|
TotalCoeff,
|
||||||
|
TotalZeros_comb,
|
||||||
|
len_comb
|
||||||
|
);
|
||||||
|
//------------------------
|
||||||
|
//ports
|
||||||
|
//------------------------
|
||||||
|
input ena;
|
||||||
|
input sel;
|
||||||
|
input chroma_DC_sel;
|
||||||
|
input [0:8] rbsp;
|
||||||
|
input [3:0] TotalCoeff;
|
||||||
|
|
||||||
|
output [3:0] TotalZeros_comb;
|
||||||
|
output [3:0] len_comb;
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
//rregs
|
||||||
|
//-------------------------
|
||||||
|
reg [3:0] TotalZeros_comb; //TotalZeros will be saved as ZeroLeft in module cavlc_read_run_befores
|
||||||
|
reg [3:0] len_comb;
|
||||||
|
|
||||||
|
|
||||||
|
//for chroma_DC
|
||||||
|
reg [0:2] rbsp_chroma_DC;
|
||||||
|
reg [1:0] TotalZeros_chroma_DC;
|
||||||
|
reg [1:0] len_chroma_DC;
|
||||||
|
|
||||||
|
//for TotalCoeff <= 3
|
||||||
|
reg [0:8] rbsp_LE3;
|
||||||
|
reg [3:0] TotalZeros_LE3;
|
||||||
|
reg [3:0] len_LE3;
|
||||||
|
|
||||||
|
//for TotalCoeff > 3
|
||||||
|
reg [0:5] rbsp_G3;
|
||||||
|
reg [3:0] TotalZeros_G3;
|
||||||
|
reg [2:0] len_G3;
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------
|
||||||
|
//input mux
|
||||||
|
//----------------------------------------
|
||||||
|
always @(*)
|
||||||
|
if (ena && sel && chroma_DC_sel) begin
|
||||||
|
rbsp_chroma_DC <= rbsp[0:2];
|
||||||
|
rbsp_LE3 <= 'hffff;
|
||||||
|
rbsp_G3 <= 'hffff;
|
||||||
|
end
|
||||||
|
else if (ena && sel && TotalCoeff[3:2] == 2'b00) begin
|
||||||
|
rbsp_chroma_DC <= 'hffff;
|
||||||
|
rbsp_LE3 <= rbsp[0:8];
|
||||||
|
rbsp_G3 <= 'hffff;
|
||||||
|
end
|
||||||
|
else if (ena && sel)begin
|
||||||
|
rbsp_chroma_DC <= 'hffff;
|
||||||
|
rbsp_LE3 <= 'hffff;
|
||||||
|
rbsp_G3 <= rbsp[0:5];
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
rbsp_chroma_DC <= 'hffff;
|
||||||
|
rbsp_LE3 <= 'hffff;
|
||||||
|
rbsp_G3 <= 'hffff;
|
||||||
|
end
|
||||||
|
|
||||||
|
//----------------------------------------
|
||||||
|
//TotalZeros_chroma_DC & len_chroma_DC
|
||||||
|
//----------------------------------------
|
||||||
|
always @(*)
|
||||||
|
if ( TotalCoeff == 1 && rbsp_chroma_DC[0] ) begin
|
||||||
|
TotalZeros_chroma_DC <= 0;
|
||||||
|
len_chroma_DC <= 1;
|
||||||
|
end
|
||||||
|
else if ( TotalCoeff == 1 && rbsp_chroma_DC[1] ) begin
|
||||||
|
TotalZeros_chroma_DC <= 1;
|
||||||
|
len_chroma_DC <= 2;
|
||||||
|
end
|
||||||
|
else if ( TotalCoeff == 1 && rbsp_chroma_DC[2] ) begin
|
||||||
|
TotalZeros_chroma_DC <= 2;
|
||||||
|
len_chroma_DC <= 3;
|
||||||
|
end
|
||||||
|
else if ( TotalCoeff == 1 ) begin
|
||||||
|
TotalZeros_chroma_DC <= 3;
|
||||||
|
len_chroma_DC <= 3;
|
||||||
|
end
|
||||||
|
else if ( TotalCoeff == 2 && rbsp_chroma_DC[0] ) begin
|
||||||
|
TotalZeros_chroma_DC <= 0;
|
||||||
|
len_chroma_DC <= 1;
|
||||||
|
end
|
||||||
|
else if ( TotalCoeff == 2 && rbsp_chroma_DC[1] ) begin
|
||||||
|
TotalZeros_chroma_DC <= 1;
|
||||||
|
len_chroma_DC <= 2;
|
||||||
|
end
|
||||||
|
else if ( TotalCoeff == 2 ) begin
|
||||||
|
TotalZeros_chroma_DC <= 2;
|
||||||
|
len_chroma_DC <= 2;
|
||||||
|
end
|
||||||
|
else if ( rbsp_chroma_DC[0] ) begin
|
||||||
|
TotalZeros_chroma_DC <= 0;
|
||||||
|
len_chroma_DC <= 1;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
TotalZeros_chroma_DC <= 1;
|
||||||
|
len_chroma_DC <= 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------
|
||||||
|
//TotalZeros_LE3 & len_LE3
|
||||||
|
//---------------------------------
|
||||||
|
always @(rbsp_LE3 or TotalCoeff)
|
||||||
|
case (TotalCoeff[1:0])
|
||||||
|
1 :begin
|
||||||
|
case(1'b1)
|
||||||
|
rbsp_LE3[0] : begin
|
||||||
|
TotalZeros_LE3 <= 0;
|
||||||
|
len_LE3 <= 1;
|
||||||
|
end
|
||||||
|
rbsp_LE3[1] : begin
|
||||||
|
len_LE3 <= 3;
|
||||||
|
if (rbsp_LE3[2])
|
||||||
|
TotalZeros_LE3 <= 1;
|
||||||
|
else
|
||||||
|
TotalZeros_LE3 <= 2;
|
||||||
|
end
|
||||||
|
rbsp_LE3[2] : begin
|
||||||
|
len_LE3 <= 4;
|
||||||
|
if (rbsp_LE3[3])
|
||||||
|
TotalZeros_LE3 <= 3;
|
||||||
|
else
|
||||||
|
TotalZeros_LE3 <= 4;
|
||||||
|
end
|
||||||
|
rbsp_LE3[3] : begin
|
||||||
|
len_LE3 <= 5;
|
||||||
|
if (rbsp_LE3[4])
|
||||||
|
TotalZeros_LE3 <= 5;
|
||||||
|
else
|
||||||
|
TotalZeros_LE3 <= 6;
|
||||||
|
end
|
||||||
|
rbsp_LE3[4] : begin
|
||||||
|
len_LE3 <= 6;
|
||||||
|
if (rbsp_LE3[5])
|
||||||
|
TotalZeros_LE3 <= 7;
|
||||||
|
else
|
||||||
|
TotalZeros_LE3 <= 8;
|
||||||
|
end
|
||||||
|
rbsp_LE3[5] : begin
|
||||||
|
len_LE3 <= 7;
|
||||||
|
if (rbsp_LE3[6])
|
||||||
|
TotalZeros_LE3 <= 9;
|
||||||
|
else
|
||||||
|
TotalZeros_LE3 <= 10;
|
||||||
|
end
|
||||||
|
rbsp_LE3[6] : begin
|
||||||
|
len_LE3 <= 8;
|
||||||
|
if (rbsp_LE3[7])
|
||||||
|
TotalZeros_LE3 <= 11;
|
||||||
|
else
|
||||||
|
TotalZeros_LE3 <= 12;
|
||||||
|
end
|
||||||
|
rbsp_LE3[7] : begin
|
||||||
|
len_LE3 <= 9;
|
||||||
|
if (rbsp_LE3[8])
|
||||||
|
TotalZeros_LE3 <= 13;
|
||||||
|
else
|
||||||
|
TotalZeros_LE3 <= 14;
|
||||||
|
end
|
||||||
|
default : begin
|
||||||
|
len_LE3 <= 9;
|
||||||
|
TotalZeros_LE3 <= 15;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
2 : begin
|
||||||
|
case(1'b1)
|
||||||
|
rbsp_LE3[0] : begin
|
||||||
|
len_LE3 <= 3;
|
||||||
|
case(rbsp_LE3[1:2])
|
||||||
|
'b11 : TotalZeros_LE3 <= 0;
|
||||||
|
'b10 : TotalZeros_LE3 <= 1;
|
||||||
|
'b01 : TotalZeros_LE3 <= 2;
|
||||||
|
'b00 : TotalZeros_LE3 <= 3;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
rbsp_LE3[1] : begin
|
||||||
|
if (rbsp_LE3[2]) begin
|
||||||
|
TotalZeros_LE3 <= 4;
|
||||||
|
len_LE3 <= 3;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
len_LE3 <= 4;
|
||||||
|
if (rbsp_LE3[3])
|
||||||
|
TotalZeros_LE3 <= 5;
|
||||||
|
else
|
||||||
|
TotalZeros_LE3 <= 6;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rbsp_LE3[2] : begin
|
||||||
|
len_LE3 <= 4;
|
||||||
|
if (rbsp_LE3[3])
|
||||||
|
TotalZeros_LE3 <= 7;
|
||||||
|
else
|
||||||
|
TotalZeros_LE3 <= 8;
|
||||||
|
end
|
||||||
|
rbsp_LE3[3] : begin
|
||||||
|
len_LE3 <= 5;
|
||||||
|
if (rbsp_LE3[4])
|
||||||
|
TotalZeros_LE3 <= 9;
|
||||||
|
else
|
||||||
|
TotalZeros_LE3 <= 10;
|
||||||
|
end
|
||||||
|
default : begin
|
||||||
|
len_LE3 <= 6;
|
||||||
|
case(rbsp_LE3[4:5])
|
||||||
|
'b11 : TotalZeros_LE3 <= 11;
|
||||||
|
'b10 : TotalZeros_LE3 <= 12;
|
||||||
|
'b01 : TotalZeros_LE3 <= 13;
|
||||||
|
'b00 : TotalZeros_LE3 <= 14;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
3 : begin
|
||||||
|
case(1'b1)
|
||||||
|
rbsp_LE3[0] : begin
|
||||||
|
len_LE3 <= 3;
|
||||||
|
case(rbsp_LE3[1:2])
|
||||||
|
'b11 : TotalZeros_LE3 <= 1;
|
||||||
|
'b10 : TotalZeros_LE3 <= 2;
|
||||||
|
'b01 : TotalZeros_LE3 <= 3;
|
||||||
|
'b00 : TotalZeros_LE3 <= 6;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
rbsp_LE3[1] : begin
|
||||||
|
if (rbsp_LE3[2]) begin
|
||||||
|
TotalZeros_LE3 <= 7;
|
||||||
|
len_LE3 <= 3;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
len_LE3 <= 4;
|
||||||
|
if (rbsp_LE3[3])
|
||||||
|
TotalZeros_LE3 <= 0;
|
||||||
|
else
|
||||||
|
TotalZeros_LE3 <= 4;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rbsp_LE3[2] : begin
|
||||||
|
len_LE3 <= 4;
|
||||||
|
if (rbsp_LE3[3])
|
||||||
|
TotalZeros_LE3 <= 5;
|
||||||
|
else
|
||||||
|
TotalZeros_LE3 <= 8;
|
||||||
|
end
|
||||||
|
rbsp_LE3[3] : begin
|
||||||
|
len_LE3 <= 5;
|
||||||
|
if (rbsp_LE3[4])
|
||||||
|
TotalZeros_LE3 <= 9;
|
||||||
|
else
|
||||||
|
TotalZeros_LE3 <= 10;
|
||||||
|
end
|
||||||
|
rbsp_LE3[4] : begin
|
||||||
|
len_LE3 <= 5;
|
||||||
|
TotalZeros_LE3 <= 12;
|
||||||
|
end
|
||||||
|
default : begin
|
||||||
|
len_LE3 <= 6;
|
||||||
|
if(rbsp_LE3[5])
|
||||||
|
TotalZeros_LE3 <= 11;
|
||||||
|
else
|
||||||
|
TotalZeros_LE3 <= 13;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
default : begin
|
||||||
|
len_LE3 <= 'bx;
|
||||||
|
TotalZeros_LE3 <= 'bx;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
|
||||||
|
//---------------------------------
|
||||||
|
//TotalZeros_G3 & len_G3
|
||||||
|
//---------------------------------
|
||||||
|
always @(rbsp_G3 or TotalCoeff)
|
||||||
|
case (TotalCoeff)
|
||||||
|
4 : begin
|
||||||
|
case(1'b1)
|
||||||
|
rbsp_G3[0] : begin
|
||||||
|
len_G3 <= 3;
|
||||||
|
case(rbsp_G3[1:2])
|
||||||
|
'b11 : TotalZeros_G3 <= 1;
|
||||||
|
'b10 : TotalZeros_G3 <= 4;
|
||||||
|
'b01 : TotalZeros_G3 <= 5;
|
||||||
|
'b00 : TotalZeros_G3 <= 6;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
rbsp_G3[1] : begin
|
||||||
|
if (rbsp_G3[2]) begin
|
||||||
|
TotalZeros_G3 <= 8;
|
||||||
|
len_G3 <= 3;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
len_G3 <= 4;
|
||||||
|
if (rbsp_G3[3])
|
||||||
|
TotalZeros_G3 <= 2;
|
||||||
|
else
|
||||||
|
TotalZeros_G3 <= 3;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rbsp_G3[2] : begin
|
||||||
|
len_G3 <= 4;
|
||||||
|
if (rbsp_G3[3])
|
||||||
|
TotalZeros_G3 <= 7;
|
||||||
|
else
|
||||||
|
TotalZeros_G3 <= 9;
|
||||||
|
end
|
||||||
|
default : begin
|
||||||
|
len_G3 <= 5;
|
||||||
|
case(rbsp_G3[3:4])
|
||||||
|
'b11 : TotalZeros_G3 <= 0;
|
||||||
|
'b10 : TotalZeros_G3 <= 10;
|
||||||
|
'b01 : TotalZeros_G3 <= 11;
|
||||||
|
'b00 : TotalZeros_G3 <= 12;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
5 :begin
|
||||||
|
case(1'b1)
|
||||||
|
rbsp_G3[0] : begin
|
||||||
|
len_G3 <= 3;
|
||||||
|
case(rbsp_G3[1:2])
|
||||||
|
'b11 : TotalZeros_G3 <= 3;
|
||||||
|
'b10 : TotalZeros_G3 <= 4;
|
||||||
|
'b01 : TotalZeros_G3 <= 5;
|
||||||
|
'b00 : TotalZeros_G3 <= 6;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
rbsp_G3[1] : begin
|
||||||
|
if (rbsp_G3[2]) begin
|
||||||
|
TotalZeros_G3 <= 7;
|
||||||
|
len_G3 <= 3;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
len_G3 <= 4;
|
||||||
|
if (rbsp_G3[3])
|
||||||
|
TotalZeros_G3 <= 0;
|
||||||
|
else
|
||||||
|
TotalZeros_G3 <= 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rbsp_G3[2] : begin
|
||||||
|
len_G3 <= 4;
|
||||||
|
if (rbsp_G3[3])
|
||||||
|
TotalZeros_G3 <= 2;
|
||||||
|
else
|
||||||
|
TotalZeros_G3 <= 8;
|
||||||
|
end
|
||||||
|
rbsp_G3[3] : begin
|
||||||
|
len_G3 <= 4;
|
||||||
|
TotalZeros_G3 <= 10;
|
||||||
|
end
|
||||||
|
default : begin
|
||||||
|
len_G3 <= 5;
|
||||||
|
if (rbsp_G3[4])
|
||||||
|
TotalZeros_G3 <= 9;
|
||||||
|
else
|
||||||
|
TotalZeros_G3 <= 11;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
6 : begin
|
||||||
|
case(1'b1)
|
||||||
|
rbsp_G3[0] : begin
|
||||||
|
len_G3 <= 3;
|
||||||
|
case(rbsp_G3[1:2])
|
||||||
|
'b11 : TotalZeros_G3 <= 2;
|
||||||
|
'b10 : TotalZeros_G3 <= 3;
|
||||||
|
'b01 : TotalZeros_G3 <= 4;
|
||||||
|
'b00 : TotalZeros_G3 <= 5;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
rbsp_G3[1] : begin
|
||||||
|
len_G3 <= 3;
|
||||||
|
if (rbsp_G3[2])
|
||||||
|
TotalZeros_G3 <= 6;
|
||||||
|
else
|
||||||
|
TotalZeros_G3 <= 7;
|
||||||
|
end
|
||||||
|
rbsp_G3[2] : begin
|
||||||
|
len_G3 <= 3;
|
||||||
|
TotalZeros_G3 <= 9;
|
||||||
|
end
|
||||||
|
rbsp_G3[3] : begin
|
||||||
|
len_G3 <= 4;
|
||||||
|
TotalZeros_G3 <= 8;
|
||||||
|
end
|
||||||
|
rbsp_G3[4] : begin
|
||||||
|
len_G3 <= 5;
|
||||||
|
TotalZeros_G3 <= 1;
|
||||||
|
end
|
||||||
|
default : begin
|
||||||
|
len_G3 <= 6;
|
||||||
|
if (rbsp_G3[5])
|
||||||
|
TotalZeros_G3 <= 0;
|
||||||
|
else
|
||||||
|
TotalZeros_G3 <= 10;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
7 :begin
|
||||||
|
case(1'b1)
|
||||||
|
rbsp_G3[0] : begin
|
||||||
|
if (rbsp_G3[1]) begin
|
||||||
|
TotalZeros_G3 <= 5;
|
||||||
|
len_G3 <= 2;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
len_G3 <= 3;
|
||||||
|
if (rbsp_G3[2])
|
||||||
|
TotalZeros_G3 <= 2;
|
||||||
|
else
|
||||||
|
TotalZeros_G3 <= 3;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rbsp_G3[1] : begin
|
||||||
|
len_G3 <= 3;
|
||||||
|
if (rbsp_G3[2])
|
||||||
|
TotalZeros_G3 <= 4;
|
||||||
|
else
|
||||||
|
TotalZeros_G3 <= 6;
|
||||||
|
end
|
||||||
|
rbsp_G3[2] : begin
|
||||||
|
len_G3 <= 3;
|
||||||
|
TotalZeros_G3 <= 8;
|
||||||
|
end
|
||||||
|
rbsp_G3[3] : begin
|
||||||
|
len_G3 <= 4;
|
||||||
|
TotalZeros_G3 <= 7;
|
||||||
|
end
|
||||||
|
rbsp_G3[4] : begin
|
||||||
|
len_G3 <= 5;
|
||||||
|
TotalZeros_G3 <= 1;
|
||||||
|
end
|
||||||
|
default : begin
|
||||||
|
len_G3 <= 6;
|
||||||
|
if (rbsp_G3[5])
|
||||||
|
TotalZeros_G3 <= 0;
|
||||||
|
else
|
||||||
|
TotalZeros_G3 <= 9;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
8 :begin
|
||||||
|
case(1'b1)
|
||||||
|
rbsp_G3[0] : begin
|
||||||
|
len_G3 <= 2;
|
||||||
|
if (rbsp_G3[1])
|
||||||
|
TotalZeros_G3 <= 4;
|
||||||
|
else
|
||||||
|
TotalZeros_G3 <= 5;
|
||||||
|
end
|
||||||
|
rbsp_G3[1] : begin
|
||||||
|
len_G3 <= 3;
|
||||||
|
if (rbsp_G3[2])
|
||||||
|
TotalZeros_G3 <= 3;
|
||||||
|
else
|
||||||
|
TotalZeros_G3 <= 6;
|
||||||
|
end
|
||||||
|
rbsp_G3[2] : begin
|
||||||
|
len_G3 <= 3;
|
||||||
|
TotalZeros_G3 <= 7;
|
||||||
|
end
|
||||||
|
rbsp_G3[3] : begin
|
||||||
|
len_G3 <= 4;
|
||||||
|
TotalZeros_G3 <= 1;
|
||||||
|
end
|
||||||
|
rbsp_G3[4] : begin
|
||||||
|
len_G3 <= 5;
|
||||||
|
TotalZeros_G3 <= 2;
|
||||||
|
end
|
||||||
|
default : begin
|
||||||
|
len_G3 <= 6;
|
||||||
|
if (rbsp_G3[5])
|
||||||
|
TotalZeros_G3 <= 0;
|
||||||
|
else
|
||||||
|
TotalZeros_G3 <= 8;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
9 : begin
|
||||||
|
case(1'b1)
|
||||||
|
rbsp_G3[0] : begin
|
||||||
|
len_G3 <= 2;
|
||||||
|
if (rbsp_G3[1])
|
||||||
|
TotalZeros_G3 <= 3;
|
||||||
|
else
|
||||||
|
TotalZeros_G3 <= 4;
|
||||||
|
end
|
||||||
|
rbsp_G3[1] : begin
|
||||||
|
len_G3 <= 2;
|
||||||
|
TotalZeros_G3 <= 6;
|
||||||
|
end
|
||||||
|
rbsp_G3[2] : begin
|
||||||
|
len_G3 <= 3;
|
||||||
|
TotalZeros_G3 <= 5;
|
||||||
|
end
|
||||||
|
rbsp_G3[3] : begin
|
||||||
|
len_G3 <= 4;
|
||||||
|
TotalZeros_G3 <= 2;
|
||||||
|
end
|
||||||
|
rbsp_G3[4] : begin
|
||||||
|
len_G3 <= 5;
|
||||||
|
TotalZeros_G3 <= 7;
|
||||||
|
end
|
||||||
|
default : begin
|
||||||
|
len_G3 <= 6;
|
||||||
|
if (rbsp_G3[5])
|
||||||
|
TotalZeros_G3 <= 0;
|
||||||
|
else
|
||||||
|
TotalZeros_G3 <= 1;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
10 : begin
|
||||||
|
case(1'b1)
|
||||||
|
rbsp_G3[0] : begin
|
||||||
|
len_G3 <= 2;
|
||||||
|
if (rbsp_G3[1])
|
||||||
|
TotalZeros_G3 <= 3;
|
||||||
|
else
|
||||||
|
TotalZeros_G3 <= 4;
|
||||||
|
end
|
||||||
|
rbsp_G3[1] : begin
|
||||||
|
len_G3 <= 2;
|
||||||
|
TotalZeros_G3 <= 5;
|
||||||
|
end
|
||||||
|
rbsp_G3[2] : begin
|
||||||
|
len_G3 <= 3;
|
||||||
|
TotalZeros_G3 <= 2;
|
||||||
|
end
|
||||||
|
rbsp_G3[3] : begin
|
||||||
|
len_G3 <= 4;
|
||||||
|
TotalZeros_G3 <= 6;
|
||||||
|
end
|
||||||
|
default : begin
|
||||||
|
len_G3 <= 5;
|
||||||
|
if (rbsp_G3[4])
|
||||||
|
TotalZeros_G3 <= 0;
|
||||||
|
else
|
||||||
|
TotalZeros_G3 <= 1;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
11 : begin
|
||||||
|
case(1'b1)
|
||||||
|
rbsp_G3[0] : begin
|
||||||
|
len_G3 <= 1;
|
||||||
|
TotalZeros_G3 <= 4;
|
||||||
|
end
|
||||||
|
rbsp_G3[1] : begin
|
||||||
|
len_G3 <= 3;
|
||||||
|
if (rbsp_G3[2])
|
||||||
|
TotalZeros_G3 <= 5;
|
||||||
|
else
|
||||||
|
TotalZeros_G3 <= 3;
|
||||||
|
end
|
||||||
|
rbsp_G3[2] : begin
|
||||||
|
len_G3 <= 3;
|
||||||
|
TotalZeros_G3 <= 2;
|
||||||
|
end
|
||||||
|
default : begin
|
||||||
|
len_G3 <= 4;
|
||||||
|
if (rbsp_G3[3])
|
||||||
|
TotalZeros_G3 <= 1;
|
||||||
|
else
|
||||||
|
TotalZeros_G3 <= 0;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
12 : begin
|
||||||
|
case(1'b1)
|
||||||
|
rbsp_G3[0] : begin
|
||||||
|
len_G3 <= 1;
|
||||||
|
TotalZeros_G3 <= 3;
|
||||||
|
end
|
||||||
|
rbsp_G3[1] : begin
|
||||||
|
len_G3 <= 2;
|
||||||
|
TotalZeros_G3 <= 2;
|
||||||
|
end
|
||||||
|
rbsp_G3[2] : begin
|
||||||
|
len_G3 <= 3;
|
||||||
|
TotalZeros_G3 <= 4;
|
||||||
|
end
|
||||||
|
default : begin
|
||||||
|
len_G3 <= 4;
|
||||||
|
if (rbsp_G3[3])
|
||||||
|
TotalZeros_G3 <= 1;
|
||||||
|
else
|
||||||
|
TotalZeros_G3 <= 0;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
13 :begin
|
||||||
|
if (rbsp_G3[0]) begin
|
||||||
|
TotalZeros_G3 <= 2;
|
||||||
|
len_G3 <= 1;
|
||||||
|
end
|
||||||
|
else if (rbsp_G3[1]) begin
|
||||||
|
TotalZeros_G3 <= 3;
|
||||||
|
len_G3 <= 2;
|
||||||
|
end
|
||||||
|
else if (rbsp_G3[2]) begin
|
||||||
|
TotalZeros_G3 <= 1;
|
||||||
|
len_G3 <= 3;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
TotalZeros_G3 <= 0;
|
||||||
|
len_G3 <= 3;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
14 : begin
|
||||||
|
if (rbsp_G3[0]) begin
|
||||||
|
TotalZeros_G3 <= 2;
|
||||||
|
len_G3 <= 1;
|
||||||
|
end
|
||||||
|
else if (rbsp_G3[1]) begin
|
||||||
|
TotalZeros_G3 <= 1;
|
||||||
|
len_G3 <= 2;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
TotalZeros_G3 <= 0;
|
||||||
|
len_G3 <= 2;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
15 : begin
|
||||||
|
len_G3 <= 1;
|
||||||
|
if (rbsp_G3[0])
|
||||||
|
TotalZeros_G3 <= 1;
|
||||||
|
else
|
||||||
|
TotalZeros_G3 <= 0;
|
||||||
|
end
|
||||||
|
default : begin
|
||||||
|
len_G3 <= 'bx;
|
||||||
|
TotalZeros_G3 <= 'bx;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
|
||||||
|
//---------------------------------
|
||||||
|
//TotalZeros_comb & len_comb
|
||||||
|
//---------------------------------
|
||||||
|
always @(*)
|
||||||
|
if (ena && sel && chroma_DC_sel) begin
|
||||||
|
TotalZeros_comb <= TotalZeros_chroma_DC;
|
||||||
|
len_comb <= len_chroma_DC;
|
||||||
|
end
|
||||||
|
else if (ena && sel && TotalCoeff[3:2] == 2'b00) begin
|
||||||
|
TotalZeros_comb <= TotalZeros_LE3;
|
||||||
|
len_comb <= len_LE3;
|
||||||
|
end
|
||||||
|
else if (ena && sel)begin
|
||||||
|
TotalZeros_comb <= TotalZeros_G3;
|
||||||
|
len_comb <= len_G3;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
TotalZeros_comb <= 0;
|
||||||
|
len_comb <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,294 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// cavlc_top ////
|
||||||
|
//// ////
|
||||||
|
//// Description ////
|
||||||
|
//// top module of cavlc decoder ////
|
||||||
|
//// ////
|
||||||
|
//// Author(s): ////
|
||||||
|
//// - bin qiu, qiubin@opencores.org ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2011 Authors and OPENCORES.ORG ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer. ////
|
||||||
|
//// ////
|
||||||
|
//// This source file is free software; you can redistribute it ////
|
||||||
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||||
|
//// Public License as published by the Free Software Foundation; ////
|
||||||
|
//// either version 2.1 of the License, or (at your option) any ////
|
||||||
|
//// later version. ////
|
||||||
|
//// ////
|
||||||
|
//// This source is distributed in the hope that it will be ////
|
||||||
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||||
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||||
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||||
|
//// details. ////
|
||||||
|
//// ////
|
||||||
|
//// You should have received a copy of the GNU Lesser General ////
|
||||||
|
//// Public License along with this source; if not, download it ////
|
||||||
|
//// from http://www.opencores.org/lgpl.shtml ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//2011-8-7 initial version
|
||||||
|
|
||||||
|
`include "defines.v"
|
||||||
|
|
||||||
|
module cavlc_top
|
||||||
|
(
|
||||||
|
clk,
|
||||||
|
rst_n,
|
||||||
|
ena,
|
||||||
|
start,
|
||||||
|
rbsp,
|
||||||
|
nC,
|
||||||
|
max_coeff_num,
|
||||||
|
|
||||||
|
coeff_0,
|
||||||
|
coeff_1,
|
||||||
|
coeff_2,
|
||||||
|
coeff_3,
|
||||||
|
coeff_4,
|
||||||
|
coeff_5,
|
||||||
|
coeff_6,
|
||||||
|
coeff_7,
|
||||||
|
coeff_8,
|
||||||
|
coeff_9,
|
||||||
|
coeff_10,
|
||||||
|
coeff_11,
|
||||||
|
coeff_12,
|
||||||
|
coeff_13,
|
||||||
|
coeff_14,
|
||||||
|
coeff_15,
|
||||||
|
TotalCoeff,
|
||||||
|
len_comb,
|
||||||
|
idle,
|
||||||
|
valid
|
||||||
|
);
|
||||||
|
//------------------------
|
||||||
|
// ports
|
||||||
|
//------------------------
|
||||||
|
input clk, rst_n;
|
||||||
|
input ena;
|
||||||
|
input start;
|
||||||
|
input [0:15] rbsp;
|
||||||
|
input signed [5:0] nC;
|
||||||
|
input [4:0] max_coeff_num;
|
||||||
|
|
||||||
|
output signed [8:0] coeff_0;
|
||||||
|
output signed [8:0] coeff_1;
|
||||||
|
output signed [8:0] coeff_2;
|
||||||
|
output signed [8:0] coeff_3;
|
||||||
|
output signed [8:0] coeff_4;
|
||||||
|
output signed [8:0] coeff_5;
|
||||||
|
output signed [8:0] coeff_6;
|
||||||
|
output signed [8:0] coeff_7;
|
||||||
|
output signed [8:0] coeff_8;
|
||||||
|
output signed [8:0] coeff_9;
|
||||||
|
output signed [8:0] coeff_10;
|
||||||
|
output signed [8:0] coeff_11;
|
||||||
|
output signed [8:0] coeff_12;
|
||||||
|
output signed [8:0] coeff_13;
|
||||||
|
output signed [8:0] coeff_14;
|
||||||
|
output signed [8:0] coeff_15;
|
||||||
|
output [4:0] TotalCoeff;
|
||||||
|
output [4:0] len_comb;
|
||||||
|
output idle;
|
||||||
|
output valid;
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// cavlc_read_total_coeffs
|
||||||
|
//------------------------
|
||||||
|
wire [1:0] TrailingOnes;
|
||||||
|
wire [4:0] TotalCoeff;
|
||||||
|
wire [1:0] TrailingOnes_comb;
|
||||||
|
wire [4:0] TotalCoeff_comb;
|
||||||
|
wire [4:0] len_read_total_coeffs_comb;
|
||||||
|
wire [7:0] cavlc_state;
|
||||||
|
|
||||||
|
cavlc_read_total_coeffs cavlc_read_total_coeffs(
|
||||||
|
.clk(clk),
|
||||||
|
.rst_n(rst_n),
|
||||||
|
.ena(ena),
|
||||||
|
.start(start),
|
||||||
|
.sel(cavlc_state[`cavlc_read_total_coeffs_bit]),
|
||||||
|
|
||||||
|
.rbsp(rbsp),
|
||||||
|
.nC(nC),
|
||||||
|
|
||||||
|
.TrailingOnes(TrailingOnes),
|
||||||
|
.TotalCoeff(TotalCoeff),
|
||||||
|
|
||||||
|
.TrailingOnes_comb(TrailingOnes_comb),
|
||||||
|
.TotalCoeff_comb(TotalCoeff_comb),
|
||||||
|
|
||||||
|
.len_comb(len_read_total_coeffs_comb)
|
||||||
|
);
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// cavlc_read_levels
|
||||||
|
//------------------------
|
||||||
|
wire [4:0] len_read_levels_comb;
|
||||||
|
wire [3:0] i;
|
||||||
|
|
||||||
|
wire [8:0] level_0;
|
||||||
|
wire [8:0] level_1;
|
||||||
|
wire [8:0] level_2;
|
||||||
|
wire [8:0] level_3;
|
||||||
|
wire [8:0] level_4;
|
||||||
|
wire [8:0] level_5;
|
||||||
|
wire [8:0] level_6;
|
||||||
|
wire [8:0] level_7;
|
||||||
|
wire [8:0] level_8;
|
||||||
|
wire [8:0] level_9;
|
||||||
|
wire [8:0] level_10;
|
||||||
|
wire [8:0] level_11;
|
||||||
|
wire [8:0] level_12;
|
||||||
|
wire [8:0] level_13;
|
||||||
|
wire [8:0] level_14;
|
||||||
|
wire [8:0] level_15;
|
||||||
|
|
||||||
|
cavlc_read_levels cavlc_read_levels(
|
||||||
|
.clk(clk),
|
||||||
|
.rst_n(rst_n),
|
||||||
|
.ena(ena),
|
||||||
|
.t1s_sel(cavlc_state[`cavlc_read_t1s_flags_bit]),
|
||||||
|
.prefix_sel(cavlc_state[`cavlc_read_level_prefix_bit]),
|
||||||
|
.suffix_sel(cavlc_state[`cavlc_read_level_suffix_bit]),
|
||||||
|
.calc_sel(cavlc_state[`cavlc_calc_level_bit]),
|
||||||
|
.TrailingOnes(TrailingOnes),
|
||||||
|
.TotalCoeff(TotalCoeff),
|
||||||
|
.i(i),
|
||||||
|
.rbsp(rbsp),
|
||||||
|
|
||||||
|
.level_0(level_0),
|
||||||
|
.level_1(level_1),
|
||||||
|
.level_2(level_2),
|
||||||
|
.level_3(level_3),
|
||||||
|
.level_4(level_4),
|
||||||
|
.level_5(level_5),
|
||||||
|
.level_6(level_6),
|
||||||
|
.level_7(level_7),
|
||||||
|
.level_8(level_8),
|
||||||
|
.level_9(level_9),
|
||||||
|
.level_10(level_10),
|
||||||
|
.level_11(level_11),
|
||||||
|
.level_12(level_12),
|
||||||
|
.level_13(level_13),
|
||||||
|
.level_14(level_14),
|
||||||
|
.level_15(level_15),
|
||||||
|
.len_comb(len_read_levels_comb)
|
||||||
|
);
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// cavlc_read_total_zeros
|
||||||
|
//------------------------
|
||||||
|
wire [3:0] TotalZeros_comb;
|
||||||
|
wire [3:0] len_read_total_zeros_comb;
|
||||||
|
|
||||||
|
cavlc_read_total_zeros cavlc_read_total_zeros(
|
||||||
|
.ena(ena),
|
||||||
|
.sel(cavlc_state[`cavlc_read_total_zeros_bit]),
|
||||||
|
.chroma_DC_sel(nC[5]),
|
||||||
|
.rbsp(rbsp[0:8]),
|
||||||
|
.TotalCoeff(TotalCoeff[3:0]),
|
||||||
|
.TotalZeros_comb(TotalZeros_comb),
|
||||||
|
.len_comb(len_read_total_zeros_comb)
|
||||||
|
);
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// read_run_before
|
||||||
|
//------------------------
|
||||||
|
wire [3:0] ZeroLeft;
|
||||||
|
wire [3:0] len_read_run_befores_comb;
|
||||||
|
|
||||||
|
cavlc_read_run_befores cavlc_read_run_befores(
|
||||||
|
.clk(clk),
|
||||||
|
.rst_n(rst_n),
|
||||||
|
.ena(ena),
|
||||||
|
.clr(cavlc_state[`cavlc_read_total_coeffs_bit]),
|
||||||
|
.sel(cavlc_state[`cavlc_read_run_befores_bit]),
|
||||||
|
.ZeroLeft_init(cavlc_state[`cavlc_read_total_zeros_bit]),
|
||||||
|
|
||||||
|
.rbsp(rbsp[0:10]),
|
||||||
|
.i(i),
|
||||||
|
.TotalZeros_comb(TotalZeros_comb),
|
||||||
|
|
||||||
|
.level_0(level_0),
|
||||||
|
.level_1(level_1),
|
||||||
|
.level_2(level_2),
|
||||||
|
.level_3(level_3),
|
||||||
|
.level_4(level_4),
|
||||||
|
.level_5(level_5),
|
||||||
|
.level_6(level_6),
|
||||||
|
.level_7(level_7),
|
||||||
|
.level_8(level_8),
|
||||||
|
.level_9(level_9),
|
||||||
|
.level_10(level_10),
|
||||||
|
.level_11(level_11),
|
||||||
|
.level_12(level_12),
|
||||||
|
.level_13(level_13),
|
||||||
|
.level_14(level_14),
|
||||||
|
.level_15(level_15),
|
||||||
|
|
||||||
|
.coeff_0(coeff_0),
|
||||||
|
.coeff_1(coeff_1),
|
||||||
|
.coeff_2(coeff_2),
|
||||||
|
.coeff_3(coeff_3),
|
||||||
|
.coeff_4(coeff_4),
|
||||||
|
.coeff_5(coeff_5),
|
||||||
|
.coeff_6(coeff_6),
|
||||||
|
.coeff_7(coeff_7),
|
||||||
|
.coeff_8(coeff_8),
|
||||||
|
.coeff_9(coeff_9),
|
||||||
|
.coeff_10(coeff_10),
|
||||||
|
.coeff_11(coeff_11),
|
||||||
|
.coeff_12(coeff_12),
|
||||||
|
.coeff_13(coeff_13),
|
||||||
|
.coeff_14(coeff_14),
|
||||||
|
.coeff_15(coeff_15),
|
||||||
|
.ZeroLeft(ZeroLeft),
|
||||||
|
.len_comb(len_read_run_befores_comb)
|
||||||
|
);
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// cavlc_len_gen
|
||||||
|
//------------------------
|
||||||
|
wire [4:0] len_comb;
|
||||||
|
|
||||||
|
cavlc_len_gen cavlc_len_gen(
|
||||||
|
.cavlc_state(cavlc_state),
|
||||||
|
.len_read_total_coeffs_comb(len_read_total_coeffs_comb),
|
||||||
|
.len_read_levels_comb(len_read_levels_comb),
|
||||||
|
.len_read_total_zeros_comb(len_read_total_zeros_comb),
|
||||||
|
.len_read_run_befores_comb(len_read_run_befores_comb),
|
||||||
|
.len_comb(len_comb)
|
||||||
|
);
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// fsm
|
||||||
|
//------------------------
|
||||||
|
cavlc_fsm cavlc_fsm(
|
||||||
|
.clk(clk),
|
||||||
|
.rst_n(rst_n),
|
||||||
|
.ena(ena),
|
||||||
|
.start(start),
|
||||||
|
|
||||||
|
.max_coeff_num(max_coeff_num),
|
||||||
|
.TotalCoeff(TotalCoeff),
|
||||||
|
.TotalCoeff_comb(TotalCoeff_comb),
|
||||||
|
.TrailingOnes(TrailingOnes),
|
||||||
|
.TrailingOnes_comb(TrailingOnes_comb),
|
||||||
|
.ZeroLeft(ZeroLeft),
|
||||||
|
.state(cavlc_state),
|
||||||
|
.i(i),
|
||||||
|
.idle(idle),
|
||||||
|
.valid(valid)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,22 @@
|
||||||
|
`timescale 1ns / 1ns // timescale time_unit/time_presicion
|
||||||
|
|
||||||
|
`define cavlc_idle_bit 0
|
||||||
|
`define cavlc_read_total_coeffs_bit 1
|
||||||
|
`define cavlc_read_t1s_flags_bit 2
|
||||||
|
`define cavlc_read_level_prefix_bit 3
|
||||||
|
`define cavlc_read_level_suffix_bit 4
|
||||||
|
`define cavlc_calc_level_bit 5
|
||||||
|
`define cavlc_read_total_zeros_bit 6
|
||||||
|
`define cavlc_read_run_befores_bit 7
|
||||||
|
|
||||||
|
`define cavlc_idle_s 8'b00000001
|
||||||
|
`define cavlc_read_total_coeffs_s 8'b00000010
|
||||||
|
`define cavlc_read_t1s_flags_s 8'b00000100
|
||||||
|
`define cavlc_read_level_prefix_s 8'b00001000
|
||||||
|
`define cavlc_read_level_suffix_s 8'b00010000
|
||||||
|
`define cavlc_calc_level_s 8'b00100000
|
||||||
|
`define cavlc_read_total_zeros_s 8'b01000000
|
||||||
|
`define cavlc_read_run_befores_s 8'b10000000
|
||||||
|
|
||||||
|
|
||||||
|
|
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
|
@ -0,0 +1,102 @@
|
||||||
|
// 5 counter with 5 clock domain
|
||||||
|
// each counter has 130 bits
|
||||||
|
// each counter has 21 output
|
||||||
|
|
||||||
|
// test: placement , routing and performace for each clock domain
|
||||||
|
|
||||||
|
module counter120bitx5(clk1,clk2,clk3,clk4,clk5,out1x,out2x,out3x,out4x,out5x,reset);
|
||||||
|
|
||||||
|
input clk1,clk2,clk3,clk4,clk5,reset;
|
||||||
|
|
||||||
|
output [13:0] out1x;
|
||||||
|
output [13:0] out2x;
|
||||||
|
output [13:0] out3x;
|
||||||
|
output [13:0] out4x;
|
||||||
|
output [13:0] out5x;
|
||||||
|
|
||||||
|
reg [120:0] cnt1;
|
||||||
|
reg [120:0] cnt2;
|
||||||
|
reg [120:0] cnt3;
|
||||||
|
reg [120:0] cnt4;
|
||||||
|
reg [120:0] cnt5;
|
||||||
|
|
||||||
|
|
||||||
|
assign out1x = {cnt1[120:115],cnt1[7:0]};
|
||||||
|
assign out2x = {cnt2[120:115],cnt2[7:0]};
|
||||||
|
assign out3x = {cnt3[120:115],cnt3[7:0]};
|
||||||
|
assign out4x = {cnt4[120:115],cnt4[7:0]};
|
||||||
|
assign out5x = {cnt5[120:115],cnt5[7:0]};
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clk1)
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
if (reset)
|
||||||
|
|
||||||
|
cnt1 <=1'b0;
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
cnt1 <= cnt1+1;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clk2)
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
if (reset)
|
||||||
|
|
||||||
|
cnt2 <=1'b0;
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
cnt2 <= cnt2 +1;
|
||||||
|
|
||||||
|
end
|
||||||
|
always @(posedge clk3)
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
if (reset)
|
||||||
|
|
||||||
|
cnt3 <=1'b0;
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
cnt3 <= cnt3 +1;
|
||||||
|
|
||||||
|
end
|
||||||
|
always @(posedge clk4)
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
if (reset)
|
||||||
|
|
||||||
|
cnt4 <=1'b0;
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
cnt4 <= cnt4 +1;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk5)
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
if (reset)
|
||||||
|
|
||||||
|
cnt5 <=1'b0;
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
cnt5 <= cnt5 +1;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,246 @@
|
||||||
|
# Generated by Yosys 0.9+2406 (git sha1 470f9532, gcc 9.3.0 -fPIC -Os)
|
||||||
|
|
||||||
|
.model top
|
||||||
|
.inputs clk reset enable
|
||||||
|
.outputs count(0) count(1) count(2) count(3) count(4) count(5) count(6) count(7) count(8) count(9) count(10) count(11) count(12) count(13) count(14) count(15)
|
||||||
|
.names $false
|
||||||
|
.names $true
|
||||||
|
1
|
||||||
|
.names $undef
|
||||||
|
.subckt logic_0 a=$auto$hilomap.cc:47:hilomap_worker$708
|
||||||
|
.subckt in_buff A=clk Q=$iopadmap$clk
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:12.13-12.45"
|
||||||
|
.subckt out_buff A=$iopadmap$count(0) Q=count(0)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||||
|
.subckt out_buff A=$iopadmap$count(1) Q=count(1)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||||
|
.subckt out_buff A=$iopadmap$count(10) Q=count(10)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||||
|
.subckt out_buff A=$iopadmap$count(11) Q=count(11)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||||
|
.subckt out_buff A=$iopadmap$count(12) Q=count(12)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||||
|
.subckt out_buff A=$iopadmap$count(13) Q=count(13)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||||
|
.subckt out_buff A=$iopadmap$count(14) Q=count(14)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||||
|
.subckt out_buff A=$iopadmap$count(15) Q=count(15)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||||
|
.subckt out_buff A=$iopadmap$count(2) Q=count(2)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||||
|
.subckt out_buff A=$iopadmap$count(3) Q=count(3)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||||
|
.subckt out_buff A=$iopadmap$count(4) Q=count(4)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||||
|
.subckt out_buff A=$iopadmap$count(5) Q=count(5)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||||
|
.subckt out_buff A=$iopadmap$count(6) Q=count(6)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||||
|
.subckt out_buff A=$iopadmap$count(7) Q=count(7)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||||
|
.subckt out_buff A=$iopadmap$count(8) Q=count(8)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||||
|
.subckt out_buff A=$iopadmap$count(9) Q=count(9)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||||
|
.subckt in_buff A=enable Q=$iopadmap$enable
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:12.13-12.45"
|
||||||
|
.subckt in_buff A=reset Q=$iopadmap$reset
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:12.13-12.45"
|
||||||
|
.subckt ff CQZ=$iopadmap$count(15) D=count_ff_CQZ_D(15) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||||
|
.subckt ff CQZ=$iopadmap$count(14) D=count_ff_CQZ_D(14) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||||
|
.subckt ff CQZ=$iopadmap$count(5) D=count_ff_CQZ_D(5) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||||
|
.subckt ff CQZ=$iopadmap$count(4) D=count_ff_CQZ_D(4) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||||
|
.subckt ff CQZ=$iopadmap$count(3) D=count_ff_CQZ_D(3) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||||
|
.subckt ff CQZ=$iopadmap$count(2) D=count_ff_CQZ_D(2) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||||
|
.subckt ff CQZ=$iopadmap$count(1) D=count_ff_CQZ_D(1) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||||
|
.subckt ff CQZ=$iopadmap$count(0) D=count_ff_CQZ_D(0) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||||
|
.subckt ff CQZ=$iopadmap$count(13) D=count_ff_CQZ_D(13) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||||
|
.subckt ff CQZ=$iopadmap$count(12) D=count_ff_CQZ_D(12) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||||
|
.subckt ff CQZ=$iopadmap$count(11) D=count_ff_CQZ_D(11) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||||
|
.subckt ff CQZ=$iopadmap$count(10) D=count_ff_CQZ_D(10) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||||
|
.subckt ff CQZ=$iopadmap$count(9) D=count_ff_CQZ_D(9) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||||
|
.subckt ff CQZ=$iopadmap$count(8) D=count_ff_CQZ_D(8) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||||
|
.subckt ff CQZ=$iopadmap$count(7) D=count_ff_CQZ_D(7) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||||
|
.subckt ff CQZ=$iopadmap$count(6) D=count_ff_CQZ_D(6) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||||
|
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$auto$hilomap.cc:47:hilomap_worker$708 I2=$iopadmap$enable I3=$iopadmap$reset O=enable_LUT4_I2_O
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:16.41-16.110"
|
||||||
|
.param EQN "(I0*~I1*I2*I3)+(~I0*I1*I2*I3)+(I0*I1*I2*I3)"
|
||||||
|
.param INIT 1110
|
||||||
|
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$auto$hilomap.cc:47:hilomap_worker$708 I2=$iopadmap$reset I3=reset_LUT4_I2_I3 O=count_ff_CQZ_D(15)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:16.41-16.110"
|
||||||
|
.param EQN "(~I0*~I1*I2*I3)"
|
||||||
|
.param INIT 0001
|
||||||
|
.subckt LUT4 I0=reset_LUT4_I3_I2 I1=$iopadmap$count(13) I2=$iopadmap$reset I3=$iopadmap$count(14) O=count_ff_CQZ_D(14)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||||
|
.param EQN "(I0*I1*~I2*~I3)+(~I0*~I1*~I2*I3)+(I0*~I1*~I2*I3)+(~I0*I1*~I2*I3)"
|
||||||
|
.param INIT 0000011100001000
|
||||||
|
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$auto$hilomap.cc:47:hilomap_worker$708 I2=$iopadmap$reset I3=reset_LUT4_I2_2_I3 O=count_ff_CQZ_D(12)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:16.41-16.110"
|
||||||
|
.param EQN "(~I0*~I1*I2*I3)"
|
||||||
|
.param INIT 0001
|
||||||
|
.subckt LUT4 I0=reset_LUT4_I3_1_I2 I1=$iopadmap$count(10) I2=$iopadmap$count(11) I3=$iopadmap$count(12) O=reset_LUT4_I2_2_I3
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||||
|
.param EQN "(~I0*~I1*~I2*~I3)+(I0*~I1*~I2*~I3)+(~I0*I1*~I2*~I3)+(I0*I1*~I2*~I3)+(~I0*~I1*I2*~I3)+(I0*~I1*I2*~I3)+(~I0*I1*I2*~I3)+(I0*I1*I2*I3)"
|
||||||
|
.param INIT 1000000001111111
|
||||||
|
.subckt LUT4 I0=reset_LUT4_I3_1_I2 I1=$iopadmap$count(10) I2=$iopadmap$reset I3=$iopadmap$count(11) O=count_ff_CQZ_D(11)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||||
|
.param EQN "(I0*I1*~I2*~I3)+(~I0*~I1*~I2*I3)+(I0*~I1*~I2*I3)+(~I0*I1*~I2*I3)"
|
||||||
|
.param INIT 0000011100001000
|
||||||
|
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$auto$hilomap.cc:47:hilomap_worker$708 I2=$iopadmap$reset I3=reset_LUT4_I2_4_I3 O=count_ff_CQZ_D(9)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:16.41-16.110"
|
||||||
|
.param EQN "(~I0*~I1*I2*I3)"
|
||||||
|
.param INIT 0001
|
||||||
|
.subckt LUT4 I0=reset_LUT4_I3_2_I2 I1=$iopadmap$count(7) I2=$iopadmap$count(8) I3=$iopadmap$count(9) O=reset_LUT4_I2_4_I3
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||||
|
.param EQN "(~I0*~I1*~I2*~I3)+(I0*~I1*~I2*~I3)+(~I0*I1*~I2*~I3)+(I0*I1*~I2*~I3)+(~I0*~I1*I2*~I3)+(I0*~I1*I2*~I3)+(~I0*I1*I2*~I3)+(I0*I1*I2*I3)"
|
||||||
|
.param INIT 1000000001111111
|
||||||
|
.subckt LUT4 I0=reset_LUT4_I3_2_I2 I1=$iopadmap$count(7) I2=$iopadmap$reset I3=$iopadmap$count(8) O=count_ff_CQZ_D(8)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||||
|
.param EQN "(I0*I1*~I2*~I3)+(~I0*~I1*~I2*I3)+(I0*~I1*~I2*I3)+(~I0*I1*~I2*I3)"
|
||||||
|
.param INIT 0000011100001000
|
||||||
|
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$auto$hilomap.cc:47:hilomap_worker$708 I2=$iopadmap$reset I3=reset_LUT4_I2_6_I3 O=count_ff_CQZ_D(6)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:16.41-16.110"
|
||||||
|
.param EQN "(~I0*~I1*I2*I3)"
|
||||||
|
.param INIT 0001
|
||||||
|
.subckt LUT4 I0=reset_LUT4_I3_3_I2 I1=$iopadmap$count(4) I2=$iopadmap$count(5) I3=$iopadmap$count(6) O=reset_LUT4_I2_6_I3
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||||
|
.param EQN "(~I0*~I1*~I2*~I3)+(I0*~I1*~I2*~I3)+(~I0*I1*~I2*~I3)+(I0*I1*~I2*~I3)+(~I0*~I1*I2*~I3)+(I0*~I1*I2*~I3)+(~I0*I1*I2*~I3)+(I0*I1*I2*I3)"
|
||||||
|
.param INIT 1000000001111111
|
||||||
|
.subckt LUT4 I0=reset_LUT4_I3_3_I2 I1=$iopadmap$count(4) I2=$iopadmap$reset I3=$iopadmap$count(5) O=count_ff_CQZ_D(5)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||||
|
.param EQN "(I0*I1*~I2*~I3)+(~I0*~I1*~I2*I3)+(I0*~I1*~I2*I3)+(~I0*I1*~I2*I3)"
|
||||||
|
.param INIT 0000011100001000
|
||||||
|
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$auto$hilomap.cc:47:hilomap_worker$708 I2=$iopadmap$reset I3=reset_LUT4_I2_8_I3 O=count_ff_CQZ_D(3)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:16.41-16.110"
|
||||||
|
.param EQN "(~I0*~I1*I2*I3)"
|
||||||
|
.param INIT 0001
|
||||||
|
.subckt LUT4 I0=$iopadmap$count(0) I1=$iopadmap$count(1) I2=$iopadmap$count(2) I3=$iopadmap$count(3) O=reset_LUT4_I2_8_I3
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||||
|
.param EQN "(~I0*~I1*~I2*~I3)+(I0*~I1*~I2*~I3)+(~I0*I1*~I2*~I3)+(I0*I1*~I2*~I3)+(~I0*~I1*I2*~I3)+(I0*~I1*I2*~I3)+(~I0*I1*I2*~I3)+(I0*I1*I2*I3)"
|
||||||
|
.param INIT 1000000001111111
|
||||||
|
.subckt LUT4 I0=$iopadmap$count(0) I1=$iopadmap$count(1) I2=$iopadmap$reset I3=$iopadmap$count(2) O=count_ff_CQZ_D(2)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||||
|
.param EQN "(I0*I1*~I2*~I3)+(~I0*~I1*~I2*I3)+(I0*~I1*~I2*I3)+(~I0*I1*~I2*I3)"
|
||||||
|
.param INIT 0000011100001000
|
||||||
|
.subckt LUT4 I0=reset_LUT4_I3_I2 I1=$iopadmap$count(13) I2=$iopadmap$count(14) I3=$iopadmap$count(15) O=reset_LUT4_I2_I3
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||||
|
.param EQN "(~I0*~I1*~I2*~I3)+(I0*~I1*~I2*~I3)+(~I0*I1*~I2*~I3)+(I0*I1*~I2*~I3)+(~I0*~I1*I2*~I3)+(I0*~I1*I2*~I3)+(~I0*I1*I2*~I3)+(I0*I1*I2*I3)"
|
||||||
|
.param INIT 1000000001111111
|
||||||
|
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$iopadmap$count(13) I2=reset_LUT4_I3_I2 I3=$iopadmap$reset O=count_ff_CQZ_D(13)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:20.41-20.110"
|
||||||
|
.param EQN "(~I0*I1*~I2*I3)+(~I0*~I1*I2*I3)"
|
||||||
|
.param INIT 00010100
|
||||||
|
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$iopadmap$count(10) I2=reset_LUT4_I3_1_I2 I3=$iopadmap$reset O=count_ff_CQZ_D(10)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:20.41-20.110"
|
||||||
|
.param EQN "(~I0*I1*~I2*I3)+(~I0*~I1*I2*I3)"
|
||||||
|
.param INIT 00010100
|
||||||
|
.subckt LUT4 I0=reset_LUT4_I3_2_I2 I1=$iopadmap$count(7) I2=$iopadmap$count(8) I3=$iopadmap$count(9) O=reset_LUT4_I3_1_I2
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||||
|
.param EQN "(I0*I1*I2*I3)"
|
||||||
|
.param INIT 1000000000000000
|
||||||
|
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$iopadmap$count(7) I2=reset_LUT4_I3_2_I2 I3=$iopadmap$reset O=count_ff_CQZ_D(7)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:20.41-20.110"
|
||||||
|
.param EQN "(~I0*I1*~I2*I3)+(~I0*~I1*I2*I3)"
|
||||||
|
.param INIT 00010100
|
||||||
|
.subckt LUT4 I0=reset_LUT4_I3_3_I2 I1=$iopadmap$count(4) I2=$iopadmap$count(5) I3=$iopadmap$count(6) O=reset_LUT4_I3_2_I2
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||||
|
.param EQN "(I0*I1*I2*I3)"
|
||||||
|
.param INIT 1000000000000000
|
||||||
|
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$iopadmap$count(4) I2=reset_LUT4_I3_3_I2 I3=$iopadmap$reset O=count_ff_CQZ_D(4)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:20.41-20.110"
|
||||||
|
.param EQN "(~I0*I1*~I2*I3)+(~I0*~I1*I2*I3)"
|
||||||
|
.param INIT 00010100
|
||||||
|
.subckt LUT4 I0=$iopadmap$count(0) I1=$iopadmap$count(1) I2=$iopadmap$count(2) I3=$iopadmap$count(3) O=reset_LUT4_I3_3_I2
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||||
|
.param EQN "(I0*I1*I2*I3)"
|
||||||
|
.param INIT 1000000000000000
|
||||||
|
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$iopadmap$count(1) I2=$iopadmap$count(0) I3=$iopadmap$reset O=count_ff_CQZ_D(1)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:20.41-20.110"
|
||||||
|
.param EQN "(~I0*I1*~I2*I3)+(~I0*~I1*I2*I3)"
|
||||||
|
.param INIT 00010100
|
||||||
|
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$auto$hilomap.cc:47:hilomap_worker$708 I2=$iopadmap$count(0) I3=$iopadmap$reset O=count_ff_CQZ_D(0)
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:16.41-16.110"
|
||||||
|
.param EQN "(~I0*~I1*I2*I3)"
|
||||||
|
.param INIT 0001
|
||||||
|
.subckt LUT4 I0=reset_LUT4_I3_1_I2 I1=$iopadmap$count(10) I2=$iopadmap$count(11) I3=$iopadmap$count(12) O=reset_LUT4_I3_I2
|
||||||
|
.attr module_not_derived 00000000000000000000000000000001
|
||||||
|
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||||
|
.param EQN "(I0*I1*I2*I3)"
|
||||||
|
.param INIT 1000000000000000
|
||||||
|
.end
|
|
@ -0,0 +1,21 @@
|
||||||
|
//
|
||||||
|
// Copyright (c) 2020 QuickLogic Corporation. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Description :
|
||||||
|
// Example of asimple 16 bit up counter in Verilog HDL
|
||||||
|
//
|
||||||
|
// Version 1.0 : Initial Creation
|
||||||
|
//
|
||||||
|
module top (clk, reset, enable, count);
|
||||||
|
input clk, reset, enable;
|
||||||
|
output [15:0] count;
|
||||||
|
reg [15:0] count;
|
||||||
|
|
||||||
|
always @ (posedge clk)
|
||||||
|
if (reset == 1'b1) begin
|
||||||
|
count <= 0;
|
||||||
|
end else if ( enable == 1'b1) begin
|
||||||
|
count <= count + 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,311 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Discrete Cosine Transform, Parallel implementation ////
|
||||||
|
//// ////
|
||||||
|
//// Author: Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// www.asics.ws ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2002 Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer.////
|
||||||
|
//// ////
|
||||||
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||||
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||||
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||||
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||||
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||||
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||||
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||||
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||||
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||||
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||||
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||||
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||||
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// CVS Log
|
||||||
|
//
|
||||||
|
// $Id: dct.v,v 1.3 2002-10-31 12:50:03 rherveille Exp $
|
||||||
|
//
|
||||||
|
// $Date: 2002-10-31 12:50:03 $
|
||||||
|
// $Revision: 1.3 $
|
||||||
|
// $Author: rherveille $
|
||||||
|
// $Locker: $
|
||||||
|
// $State: Exp $
|
||||||
|
//
|
||||||
|
// Change History:
|
||||||
|
// $Log: not supported by cvs2svn $
|
||||||
|
// Revision 1.2 2002/10/23 09:06:59 rherveille
|
||||||
|
// Improved many files.
|
||||||
|
// Fixed some bugs in Run-Length-Encoder.
|
||||||
|
// Removed dependency on ud_cnt and ro_cnt.
|
||||||
|
// Started (Motion)JPEG hardware encoder project.
|
||||||
|
//
|
||||||
|
|
||||||
|
//synopsys translate_off
|
||||||
|
`include "timescale.v"
|
||||||
|
//synopsys translate_on
|
||||||
|
|
||||||
|
module dct(
|
||||||
|
clk,
|
||||||
|
ena,
|
||||||
|
rst,
|
||||||
|
dstrb,
|
||||||
|
din,
|
||||||
|
dout_00, dout_01, dout_02, dout_03, dout_04, dout_05, dout_06, dout_07,
|
||||||
|
dout_10, dout_11, dout_12, dout_13, dout_14, dout_15, dout_16, dout_17,
|
||||||
|
dout_20, dout_21, dout_22, dout_23, dout_24, dout_25, dout_26, dout_27,
|
||||||
|
dout_30, dout_31, dout_32, dout_33, dout_34, dout_35, dout_36, dout_37,
|
||||||
|
dout_40, dout_41, dout_42, dout_43, dout_44, dout_45, dout_46, dout_47,
|
||||||
|
dout_50, dout_51, dout_52, dout_53, dout_54, dout_55, dout_56, dout_57,
|
||||||
|
dout_60, dout_61, dout_62, dout_63, dout_64, dout_65, dout_66, dout_67,
|
||||||
|
dout_70, dout_71, dout_72, dout_73, dout_74, dout_75, dout_76, dout_77,
|
||||||
|
douten
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// parameters
|
||||||
|
//
|
||||||
|
// Worst case errors (Din = 64* -128) remain in decimal bit
|
||||||
|
// when using 13bit coefficients
|
||||||
|
//
|
||||||
|
// For ultra-high
|
||||||
|
parameter coef_width = 11;
|
||||||
|
parameter di_width = 8;
|
||||||
|
parameter do_width = 12;
|
||||||
|
|
||||||
|
//
|
||||||
|
// inputs & outputs
|
||||||
|
//
|
||||||
|
|
||||||
|
input clk;
|
||||||
|
input ena;
|
||||||
|
input rst; // active low asynchronous reset
|
||||||
|
|
||||||
|
input dstrb; // data-strobe. Present dstrb 1clk-cycle before data block
|
||||||
|
input [di_width:1] din;
|
||||||
|
output [do_width:1]
|
||||||
|
dout_00, dout_01, dout_02, dout_03, dout_04, dout_05, dout_06, dout_07,
|
||||||
|
dout_10, dout_11, dout_12, dout_13, dout_14, dout_15, dout_16, dout_17,
|
||||||
|
dout_20, dout_21, dout_22, dout_23, dout_24, dout_25, dout_26, dout_27,
|
||||||
|
dout_30, dout_31, dout_32, dout_33, dout_34, dout_35, dout_36, dout_37,
|
||||||
|
dout_40, dout_41, dout_42, dout_43, dout_44, dout_45, dout_46, dout_47,
|
||||||
|
dout_50, dout_51, dout_52, dout_53, dout_54, dout_55, dout_56, dout_57,
|
||||||
|
dout_60, dout_61, dout_62, dout_63, dout_64, dout_65, dout_66, dout_67,
|
||||||
|
dout_70, dout_71, dout_72, dout_73, dout_74, dout_75, dout_76, dout_77;
|
||||||
|
|
||||||
|
output douten; // data-out enable
|
||||||
|
reg douten;
|
||||||
|
|
||||||
|
//
|
||||||
|
// variables
|
||||||
|
//
|
||||||
|
reg go, dgo, ddgo, ddcnt, dddcnt;
|
||||||
|
reg [di_width:1] ddin;
|
||||||
|
|
||||||
|
//
|
||||||
|
// module body
|
||||||
|
//
|
||||||
|
|
||||||
|
// generate sample counter
|
||||||
|
reg [5:0] sample_cnt;
|
||||||
|
wire dcnt = &sample_cnt;
|
||||||
|
|
||||||
|
always @(posedge clk or negedge rst)
|
||||||
|
if (~rst)
|
||||||
|
sample_cnt <= #1 6'h0;
|
||||||
|
else if (ena)
|
||||||
|
if(dstrb)
|
||||||
|
sample_cnt <= #1 6'h0;
|
||||||
|
else if(~dcnt)
|
||||||
|
sample_cnt <= #1 sample_cnt + 6'h1;
|
||||||
|
|
||||||
|
// internal signals
|
||||||
|
always @(posedge clk or negedge rst)
|
||||||
|
if (~rst)
|
||||||
|
begin
|
||||||
|
go <= #1 1'b0;
|
||||||
|
dgo <= #1 1'b0;
|
||||||
|
ddgo <= #1 1'b0;
|
||||||
|
ddin <= #1 0;
|
||||||
|
|
||||||
|
douten <= #1 1'b0;
|
||||||
|
ddcnt <= #1 1'b1;
|
||||||
|
dddcnt <= #1 1'b1;
|
||||||
|
end
|
||||||
|
else if (ena)
|
||||||
|
begin
|
||||||
|
go <= #1 dstrb;
|
||||||
|
dgo <= #1 go;
|
||||||
|
ddgo <= #1 dgo;
|
||||||
|
ddin <= #1 din;
|
||||||
|
|
||||||
|
ddcnt <= #1 dcnt;
|
||||||
|
dddcnt <= #1 ddcnt;
|
||||||
|
|
||||||
|
douten <= #1 ddcnt & ~dddcnt;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Hookup DCT units
|
||||||
|
|
||||||
|
// V = 0
|
||||||
|
dctub #(coef_width, di_width, 3'h0)
|
||||||
|
dct_block_0 (
|
||||||
|
.clk(clk),
|
||||||
|
.ena(ena),
|
||||||
|
.ddgo(ddgo),
|
||||||
|
.x(sample_cnt[2:0]),
|
||||||
|
.y(sample_cnt[5:3]),
|
||||||
|
.ddin(ddin),
|
||||||
|
.dout0(dout_00), // (U,V) = (0,0)
|
||||||
|
.dout1(dout_01), // (U,V) = (0,1)
|
||||||
|
.dout2(dout_02), // (U,V) = (0,2)
|
||||||
|
.dout3(dout_03), // (U,V) = (0,3)
|
||||||
|
.dout4(dout_04), // (U,V) = (0,4)
|
||||||
|
.dout5(dout_05), // (U,V) = (0,5)
|
||||||
|
.dout6(dout_06), // (U,V) = (0,6)
|
||||||
|
.dout7(dout_07) // (U,V) = (0,7)
|
||||||
|
);
|
||||||
|
|
||||||
|
// V = 1
|
||||||
|
dctub #(coef_width, di_width, 3'h1)
|
||||||
|
dct_block_1 (
|
||||||
|
.clk(clk),
|
||||||
|
.ena(ena),
|
||||||
|
.ddgo(ddgo),
|
||||||
|
.x(sample_cnt[2:0]),
|
||||||
|
.y(sample_cnt[5:3]),
|
||||||
|
.ddin(ddin),
|
||||||
|
.dout0(dout_10), // (U,V) = (1,0)
|
||||||
|
.dout1(dout_11), // (U,V) = (1,1)
|
||||||
|
.dout2(dout_12), // (U,V) = (1,2)
|
||||||
|
.dout3(dout_13), // (U,V) = (1,3)
|
||||||
|
.dout4(dout_14), // (U,V) = (1,4)
|
||||||
|
.dout5(dout_15), // (U,V) = (1,5)
|
||||||
|
.dout6(dout_16), // (U,V) = (1,6)
|
||||||
|
.dout7(dout_17) // (U,V) = (1,7)
|
||||||
|
);
|
||||||
|
|
||||||
|
// V = 2
|
||||||
|
dctub #(coef_width, di_width, 3'h2)
|
||||||
|
dct_block_2 (
|
||||||
|
.clk(clk),
|
||||||
|
.ena(ena),
|
||||||
|
.ddgo(ddgo),
|
||||||
|
.x(sample_cnt[2:0]),
|
||||||
|
.y(sample_cnt[5:3]),
|
||||||
|
.ddin(ddin),
|
||||||
|
.dout0(dout_20), // (U,V) = (2,0)
|
||||||
|
.dout1(dout_21), // (U,V) = (2,1)
|
||||||
|
.dout2(dout_22), // (U,V) = (2,2)
|
||||||
|
.dout3(dout_23), // (U,V) = (2,3)
|
||||||
|
.dout4(dout_24), // (U,V) = (2,4)
|
||||||
|
.dout5(dout_25), // (U,V) = (2,5)
|
||||||
|
.dout6(dout_26), // (U,V) = (2,6)
|
||||||
|
.dout7(dout_27) // (U,V) = (2,7)
|
||||||
|
);
|
||||||
|
|
||||||
|
// V = 3
|
||||||
|
dctub #(coef_width, di_width, 3'h3)
|
||||||
|
dct_block_3 (
|
||||||
|
.clk(clk),
|
||||||
|
.ena(ena),
|
||||||
|
.ddgo(ddgo),
|
||||||
|
.x(sample_cnt[2:0]),
|
||||||
|
.y(sample_cnt[5:3]),
|
||||||
|
.ddin(ddin),
|
||||||
|
.dout0(dout_30), // (U,V) = (3,0)
|
||||||
|
.dout1(dout_31), // (U,V) = (3,1)
|
||||||
|
.dout2(dout_32), // (U,V) = (3,2)
|
||||||
|
.dout3(dout_33), // (U,V) = (3,3)
|
||||||
|
.dout4(dout_34), // (U,V) = (3,4)
|
||||||
|
.dout5(dout_35), // (U,V) = (3,5)
|
||||||
|
.dout6(dout_36), // (U,V) = (3,6)
|
||||||
|
.dout7(dout_37) // (U,V) = (3,7)
|
||||||
|
);
|
||||||
|
|
||||||
|
// V = 4
|
||||||
|
dctub #(coef_width, di_width, 3'h4)
|
||||||
|
dct_block_4 (
|
||||||
|
.clk(clk),
|
||||||
|
.ena(ena),
|
||||||
|
.ddgo(ddgo),
|
||||||
|
.x(sample_cnt[2:0]),
|
||||||
|
.y(sample_cnt[5:3]),
|
||||||
|
.ddin(ddin),
|
||||||
|
.dout0(dout_40), // (U,V) = (4,0)
|
||||||
|
.dout1(dout_41), // (U,V) = (4,1)
|
||||||
|
.dout2(dout_42), // (U,V) = (4,2)
|
||||||
|
.dout3(dout_43), // (U,V) = (4,3)
|
||||||
|
.dout4(dout_44), // (U,V) = (4,4)
|
||||||
|
.dout5(dout_45), // (U,V) = (4,5)
|
||||||
|
.dout6(dout_46), // (U,V) = (4,6)
|
||||||
|
.dout7(dout_47) // (U,V) = (4,7)
|
||||||
|
);
|
||||||
|
|
||||||
|
// V = 5
|
||||||
|
dctub #(coef_width, di_width, 3'h5)
|
||||||
|
dct_block_5 (
|
||||||
|
.clk(clk),
|
||||||
|
.ena(ena),
|
||||||
|
.ddgo(ddgo),
|
||||||
|
.x(sample_cnt[2:0]),
|
||||||
|
.y(sample_cnt[5:3]),
|
||||||
|
.ddin(ddin),
|
||||||
|
.dout0(dout_50), // (U,V) = (5,0)
|
||||||
|
.dout1(dout_51), // (U,V) = (5,1)
|
||||||
|
.dout2(dout_52), // (U,V) = (5,2)
|
||||||
|
.dout3(dout_53), // (U,V) = (5,3)
|
||||||
|
.dout4(dout_54), // (U,V) = (5,4)
|
||||||
|
.dout5(dout_55), // (U,V) = (5,5)
|
||||||
|
.dout6(dout_56), // (U,V) = (5,6)
|
||||||
|
.dout7(dout_57) // (U,V) = (5,7)
|
||||||
|
);
|
||||||
|
|
||||||
|
// V = 6
|
||||||
|
dctub #(coef_width, di_width, 3'h6)
|
||||||
|
dct_block_6 (
|
||||||
|
.clk(clk),
|
||||||
|
.ena(ena),
|
||||||
|
.ddgo(ddgo),
|
||||||
|
.x(sample_cnt[2:0]),
|
||||||
|
.y(sample_cnt[5:3]),
|
||||||
|
.ddin(ddin),
|
||||||
|
.dout0(dout_60), // (U,V) = (6,0)
|
||||||
|
.dout1(dout_61), // (U,V) = (6,1)
|
||||||
|
.dout2(dout_62), // (U,V) = (6,2)
|
||||||
|
.dout3(dout_63), // (U,V) = (6,3)
|
||||||
|
.dout4(dout_64), // (U,V) = (6,4)
|
||||||
|
.dout5(dout_65), // (U,V) = (6,5)
|
||||||
|
.dout6(dout_66), // (U,V) = (6,6)
|
||||||
|
.dout7(dout_67) // (U,V) = (6,7)
|
||||||
|
);
|
||||||
|
|
||||||
|
// V = 7
|
||||||
|
dctub #(coef_width, di_width, 3'h7)
|
||||||
|
dct_block_7 (
|
||||||
|
.clk(clk),
|
||||||
|
.ena(ena),
|
||||||
|
.ddgo(ddgo),
|
||||||
|
.x(sample_cnt[2:0]),
|
||||||
|
.y(sample_cnt[5:3]),
|
||||||
|
.ddin(ddin),
|
||||||
|
.dout0(dout_70), // (U,V) = (7,0)
|
||||||
|
.dout1(dout_71), // (U,V) = (7,1)
|
||||||
|
.dout2(dout_72), // (U,V) = (7,2)
|
||||||
|
.dout3(dout_73), // (U,V) = (7,3)
|
||||||
|
.dout4(dout_74), // (U,V) = (7,4)
|
||||||
|
.dout5(dout_75), // (U,V) = (7,5)
|
||||||
|
.dout6(dout_76), // (U,V) = (7,6)
|
||||||
|
.dout7(dout_77) // (U,V) = (7,7)
|
||||||
|
);
|
||||||
|
endmodule
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,123 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Discrete Cosine Transform, MAC unit ////
|
||||||
|
//// ////
|
||||||
|
//// Virtex-II: Block-Multiplier is used ////
|
||||||
|
//// ////
|
||||||
|
//// Author: Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// www.asics.ws ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2001 Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer.////
|
||||||
|
//// ////
|
||||||
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||||
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||||
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||||
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||||
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||||
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||||
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||||
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||||
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||||
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||||
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||||
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||||
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// CVS Log
|
||||||
|
//
|
||||||
|
// $Id: dct_mac.v,v 1.3 2002-10-31 12:50:03 rherveille Exp $
|
||||||
|
//
|
||||||
|
// $Date: 2002-10-31 12:50:03 $
|
||||||
|
// $Revision: 1.3 $
|
||||||
|
// $Author: rherveille $
|
||||||
|
// $Locker: $
|
||||||
|
// $State: Exp $
|
||||||
|
//
|
||||||
|
// Change History:
|
||||||
|
// $Log: not supported by cvs2svn $
|
||||||
|
// Revision 1.2 2002/10/23 09:06:59 rherveille
|
||||||
|
// Improved many files.
|
||||||
|
// Fixed some bugs in Run-Length-Encoder.
|
||||||
|
// Removed dependency on ud_cnt and ro_cnt.
|
||||||
|
// Started (Motion)JPEG hardware encoder project.
|
||||||
|
//
|
||||||
|
|
||||||
|
//synopsys translate_off
|
||||||
|
`include "timescale.v"
|
||||||
|
//synopsys translate_on
|
||||||
|
|
||||||
|
module dct_mac(clk, ena, dclr, din, coef, result);
|
||||||
|
|
||||||
|
//
|
||||||
|
// parameters
|
||||||
|
//
|
||||||
|
parameter dwidth = 8;
|
||||||
|
parameter cwidth = 16;
|
||||||
|
parameter mwidth = dwidth + cwidth; // multiplier result
|
||||||
|
parameter rwidth = mwidth +3; // add 3 bits for growth
|
||||||
|
|
||||||
|
//
|
||||||
|
// inputs & outputs
|
||||||
|
//
|
||||||
|
input clk; // clock input
|
||||||
|
input ena; // clock enable
|
||||||
|
input dclr; // start new mac (delayed 1 cycle)
|
||||||
|
input [dwidth-1:0] din; // data input
|
||||||
|
input [cwidth-1:0] coef; // coefficient input
|
||||||
|
output [rwidth-1:0] result; // mac-result
|
||||||
|
reg [rwidth -1:0] result;
|
||||||
|
|
||||||
|
//
|
||||||
|
// variables
|
||||||
|
//
|
||||||
|
wire [mwidth-1:0] idin;
|
||||||
|
wire [mwidth-1:0] icoef;
|
||||||
|
|
||||||
|
reg [mwidth -1:0] mult_res /* synthesis syn_multstyle="block_mult" syn_pipeline=1*/ ;
|
||||||
|
wire [rwidth -1:0] ext_mult_res;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// module body
|
||||||
|
//
|
||||||
|
assign icoef = { {(mwidth-cwidth){coef[cwidth-1]}}, coef};
|
||||||
|
assign idin = { {(mwidth-dwidth){din[dwidth-1]}}, din};
|
||||||
|
|
||||||
|
// generate multiplier structure
|
||||||
|
always @(posedge clk)
|
||||||
|
if(ena)
|
||||||
|
mult_res <= #1 icoef * idin;
|
||||||
|
|
||||||
|
assign ext_mult_res = { {3{mult_res[mwidth-1]}}, mult_res};
|
||||||
|
|
||||||
|
// generate adder structure
|
||||||
|
always @(posedge clk)
|
||||||
|
if(ena)
|
||||||
|
if(dclr)
|
||||||
|
result <= #1 ext_mult_res;
|
||||||
|
else
|
||||||
|
result <= #1 ext_mult_res + result;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Discrete Cosine Transform Synthesis Test ////
|
||||||
|
//// ////
|
||||||
|
//// Author: Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// www.asics.ws ////
|
||||||
|
//// ////
|
||||||
|
//// Synthesis results: ////
|
||||||
|
//// ////
|
||||||
|
//// ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2002 Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer.////
|
||||||
|
//// ////
|
||||||
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||||
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||||
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||||
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||||
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||||
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||||
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||||
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||||
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||||
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||||
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||||
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||||
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// CVS Log
|
||||||
|
//
|
||||||
|
// $Id: dct_syn.v,v 1.3 2002-10-31 12:50:03 rherveille Exp $
|
||||||
|
//
|
||||||
|
// $Date: 2002-10-31 12:50:03 $
|
||||||
|
// $Revision: 1.3 $
|
||||||
|
// $Author: rherveille $
|
||||||
|
// $Locker: $
|
||||||
|
// $State: Exp $
|
||||||
|
//
|
||||||
|
// Change History:
|
||||||
|
// $Log: not supported by cvs2svn $
|
||||||
|
// Revision 1.2 2002/10/23 09:06:59 rherveille
|
||||||
|
// Improved many files.
|
||||||
|
// Fixed some bugs in Run-Length-Encoder.
|
||||||
|
// Removed dependency on ud_cnt and ro_cnt.
|
||||||
|
// Started (Motion)JPEG hardware encoder project.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
// synopsys translate_off
|
||||||
|
`include "timescale.v"
|
||||||
|
// synopsys translate_on
|
||||||
|
|
||||||
|
module dct_syn(clk, ena, rst, dstrb, din, dout, den);
|
||||||
|
|
||||||
|
input clk;
|
||||||
|
input ena;
|
||||||
|
input rst;
|
||||||
|
|
||||||
|
input dstrb;
|
||||||
|
input [7:0] din;
|
||||||
|
|
||||||
|
output [11:0] dout;
|
||||||
|
output den;
|
||||||
|
|
||||||
|
//
|
||||||
|
// DCT unit
|
||||||
|
//
|
||||||
|
|
||||||
|
// As little as 11bits coefficients can be used while
|
||||||
|
// all errors remain in the decimal bit range (dout[0])
|
||||||
|
// total errors = 5(14bit resolution)
|
||||||
|
// = 12(13bit resolution)
|
||||||
|
// = 26(12bit resolution)
|
||||||
|
// = 54(11bit resolution)
|
||||||
|
fdct #(13) dut (
|
||||||
|
.clk(clk),
|
||||||
|
.ena(1'b1),
|
||||||
|
.rst(rst),
|
||||||
|
.dstrb(dstrb),
|
||||||
|
.din(din),
|
||||||
|
.dout(dout),
|
||||||
|
.douten(den)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,106 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Discrete Cosine Transform Unit ////
|
||||||
|
//// ////
|
||||||
|
//// Author: Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// www.asics.ws ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2001 Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer.////
|
||||||
|
//// ////
|
||||||
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||||
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||||
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||||
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||||
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||||
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||||
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||||
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||||
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||||
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||||
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||||
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||||
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// CVS Log
|
||||||
|
//
|
||||||
|
// $Id: dctu.v,v 1.3 2002-10-31 12:50:03 rherveille Exp $
|
||||||
|
//
|
||||||
|
// $Date: 2002-10-31 12:50:03 $
|
||||||
|
// $Revision: 1.3 $
|
||||||
|
// $Author: rherveille $
|
||||||
|
// $Locker: $
|
||||||
|
// $State: Exp $
|
||||||
|
//
|
||||||
|
// Change History:
|
||||||
|
// $Log: not supported by cvs2svn $
|
||||||
|
// Revision 1.2 2002/10/23 09:06:59 rherveille
|
||||||
|
// Improved many files.
|
||||||
|
// Fixed some bugs in Run-Length-Encoder.
|
||||||
|
// Removed dependency on ud_cnt and ro_cnt.
|
||||||
|
// Started (Motion)JPEG hardware encoder project.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
//synopsys translate_off
|
||||||
|
`include "timescale.v"
|
||||||
|
//synopsys translate_on
|
||||||
|
|
||||||
|
module dctu(clk, ena, ddgo, x, y, ddin, dout);
|
||||||
|
|
||||||
|
parameter coef_width = 16;
|
||||||
|
parameter di_width = 8;
|
||||||
|
parameter [2:0] v = 0;
|
||||||
|
parameter [2:0] u = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// inputs & outputs
|
||||||
|
//
|
||||||
|
|
||||||
|
input clk;
|
||||||
|
input ena;
|
||||||
|
input ddgo; // double delayed go signal
|
||||||
|
input [2:0] x, y;
|
||||||
|
|
||||||
|
input [di_width:1] ddin; // delayed data input
|
||||||
|
output [11:0] dout;
|
||||||
|
|
||||||
|
//
|
||||||
|
// variables
|
||||||
|
//
|
||||||
|
reg [ 31:0] coef;
|
||||||
|
|
||||||
|
wire [coef_width +10:0] result;
|
||||||
|
`include "dct_cos_table.v"
|
||||||
|
//
|
||||||
|
// module body
|
||||||
|
//
|
||||||
|
|
||||||
|
// hookup cosine-table
|
||||||
|
always @(posedge clk)
|
||||||
|
if(ena)
|
||||||
|
coef <= #1 dct_cos_table(x, y, u, v);
|
||||||
|
|
||||||
|
// hookup dct-mac unit
|
||||||
|
dct_mac #(8, coef_width)
|
||||||
|
macu (
|
||||||
|
.clk(clk),
|
||||||
|
.ena(ena),
|
||||||
|
.dclr(ddgo),
|
||||||
|
.din(ddin),
|
||||||
|
.coef( coef[31:31 -coef_width +1] ),
|
||||||
|
.result(result)
|
||||||
|
);
|
||||||
|
|
||||||
|
assign dout = result[coef_width +10: coef_width -1];
|
||||||
|
endmodule
|
|
@ -0,0 +1,169 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Discrete Cosine Transform, DCT unit block ////
|
||||||
|
//// ////
|
||||||
|
//// Author: Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// www.asics.ws ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2001 Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer.////
|
||||||
|
//// ////
|
||||||
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||||
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||||
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||||
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||||
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||||
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||||
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||||
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||||
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||||
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||||
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||||
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||||
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// CVS Log
|
||||||
|
//
|
||||||
|
// $Id: dctub.v,v 1.3 2002-10-31 12:50:03 rherveille Exp $
|
||||||
|
//
|
||||||
|
// $Date: 2002-10-31 12:50:03 $
|
||||||
|
// $Revision: 1.3 $
|
||||||
|
// $Author: rherveille $
|
||||||
|
// $Locker: $
|
||||||
|
// $State: Exp $
|
||||||
|
//
|
||||||
|
// Change History:
|
||||||
|
// $Log: not supported by cvs2svn $
|
||||||
|
// Revision 1.2 2002/10/23 09:06:59 rherveille
|
||||||
|
// Improved many files.
|
||||||
|
// Fixed some bugs in Run-Length-Encoder.
|
||||||
|
// Removed dependency on ud_cnt and ro_cnt.
|
||||||
|
// Started (Motion)JPEG hardware encoder project.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
//synopsys translate_off
|
||||||
|
`include "timescale.v"
|
||||||
|
//synopsys translate_on
|
||||||
|
|
||||||
|
module dctub(clk, ena, ddgo, x, y, ddin,
|
||||||
|
dout0, dout1, dout2, dout3, dout4, dout5, dout6, dout7);
|
||||||
|
|
||||||
|
parameter coef_width = 16;
|
||||||
|
parameter di_width = 8;
|
||||||
|
parameter [2:0] v = 3'h0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// inputs & outputs
|
||||||
|
//
|
||||||
|
input clk;
|
||||||
|
input ena;
|
||||||
|
input ddgo; // double delayed go strobe
|
||||||
|
input [2:0] x, y;
|
||||||
|
|
||||||
|
input [di_width:1] ddin; // delayed data input
|
||||||
|
output [11:0] dout0, dout1, dout2, dout3, dout4, dout5, dout6, dout7;
|
||||||
|
|
||||||
|
//
|
||||||
|
// module body
|
||||||
|
//
|
||||||
|
|
||||||
|
// Hookup DCT units
|
||||||
|
dctu #(coef_width, di_width, v, 3'h0)
|
||||||
|
dct_unit_0 (
|
||||||
|
.clk(clk),
|
||||||
|
.ena(ena),
|
||||||
|
.ddgo(ddgo),
|
||||||
|
.x(x),
|
||||||
|
.y(y),
|
||||||
|
.ddin(ddin),
|
||||||
|
.dout(dout0)
|
||||||
|
);
|
||||||
|
|
||||||
|
dctu #(coef_width, di_width, v, 3'h1)
|
||||||
|
dct_unit_1 (
|
||||||
|
.clk(clk),
|
||||||
|
.ena(ena),
|
||||||
|
.ddgo(ddgo),
|
||||||
|
.x(x),
|
||||||
|
.y(y),
|
||||||
|
.ddin(ddin),
|
||||||
|
.dout(dout1)
|
||||||
|
);
|
||||||
|
|
||||||
|
dctu #(coef_width, di_width, v, 3'h2)
|
||||||
|
dct_unit_2 (
|
||||||
|
.clk(clk),
|
||||||
|
.ena(ena),
|
||||||
|
.ddgo(ddgo),
|
||||||
|
.x(x),
|
||||||
|
.y(y),
|
||||||
|
.ddin(ddin),
|
||||||
|
.dout(dout2)
|
||||||
|
);
|
||||||
|
|
||||||
|
dctu #(coef_width, di_width, v, 3'h3)
|
||||||
|
dct_unit_3 (
|
||||||
|
.clk(clk),
|
||||||
|
.ena(ena),
|
||||||
|
.ddgo(ddgo),
|
||||||
|
.x(x),
|
||||||
|
.y(y),
|
||||||
|
.ddin(ddin),
|
||||||
|
.dout(dout3)
|
||||||
|
);
|
||||||
|
|
||||||
|
dctu #(coef_width, di_width, v, 3'h4)
|
||||||
|
dct_unit_4 (
|
||||||
|
.clk(clk),
|
||||||
|
.ena(ena),
|
||||||
|
.ddgo(ddgo),
|
||||||
|
.x(x),
|
||||||
|
.y(y),
|
||||||
|
.ddin(ddin),
|
||||||
|
.dout(dout4)
|
||||||
|
);
|
||||||
|
|
||||||
|
dctu #(coef_width, di_width, v, 3'h5)
|
||||||
|
dct_unit_5 (
|
||||||
|
.clk(clk),
|
||||||
|
.ena(ena),
|
||||||
|
.ddgo(ddgo),
|
||||||
|
.x(x),
|
||||||
|
.y(y),
|
||||||
|
.ddin(ddin),
|
||||||
|
.dout(dout5)
|
||||||
|
);
|
||||||
|
|
||||||
|
dctu #(coef_width, di_width, v, 3'h6)
|
||||||
|
dct_unit_6 (
|
||||||
|
.clk(clk),
|
||||||
|
.ena(ena),
|
||||||
|
.ddgo(ddgo),
|
||||||
|
.x(x),
|
||||||
|
.y(y),
|
||||||
|
.ddin(ddin),
|
||||||
|
.dout(dout6)
|
||||||
|
);
|
||||||
|
|
||||||
|
dctu #(coef_width, di_width, v, 3'h7)
|
||||||
|
dct_unit_7 (
|
||||||
|
.clk(clk),
|
||||||
|
.ena(ena),
|
||||||
|
.ddgo(ddgo),
|
||||||
|
.x(x),
|
||||||
|
.y(y),
|
||||||
|
.ddin(ddin),
|
||||||
|
.dout(dout7)
|
||||||
|
);
|
||||||
|
endmodule
|
|
@ -0,0 +1,292 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Forward Discrete Cosine Transform and ZigZag unit ////
|
||||||
|
//// ////
|
||||||
|
//// Author: Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// www.asics.ws ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2002 Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer.////
|
||||||
|
//// ////
|
||||||
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||||
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||||
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||||
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||||
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||||
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||||
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||||
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||||
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||||
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||||
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||||
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||||
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// CVS Log
|
||||||
|
//
|
||||||
|
// $Id: fdct.v,v 1.3 2002-10-31 12:50:03 rherveille Exp $
|
||||||
|
//
|
||||||
|
// $Date: 2002-10-31 12:50:03 $
|
||||||
|
// $Revision: 1.3 $
|
||||||
|
// $Author: rherveille $
|
||||||
|
// $Locker: $
|
||||||
|
// $State: Exp $
|
||||||
|
//
|
||||||
|
// Change History:
|
||||||
|
// $Log: not supported by cvs2svn $
|
||||||
|
// Revision 1.2 2002/10/23 09:06:59 rherveille
|
||||||
|
// Improved many files.
|
||||||
|
// Fixed some bugs in Run-Length-Encoder.
|
||||||
|
// Removed dependency on ud_cnt and ro_cnt.
|
||||||
|
// Started (Motion)JPEG hardware encoder project.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
//synopsys translate_off
|
||||||
|
`include "timescale.v"
|
||||||
|
//synopsys translate_on
|
||||||
|
|
||||||
|
module fdct(clk, ena, rst, dstrb, din, dout, douten);
|
||||||
|
|
||||||
|
//
|
||||||
|
// parameters
|
||||||
|
//
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// //
|
||||||
|
// ITU-T.81, ITU-T.83 & Coefficient resolution notes //
|
||||||
|
// //
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// //
|
||||||
|
// Worst case error (all input values -128) is //
|
||||||
|
// zero (i.e. no errors) when using 15bit coefficients //
|
||||||
|
// //
|
||||||
|
// Using less bits for the coefficients produces a biterror //
|
||||||
|
// approx. equal to (15 - used_coefficient-bits). //
|
||||||
|
// i.e. 14bit coefficients, errors in dout-bit[0] only //
|
||||||
|
// 13bit coefficients, errors in dout-bits[1:0] //
|
||||||
|
// 12bit coefficients, errors in dout-bits[2:0] etc. //
|
||||||
|
// Tests with real non-continous tone image data have shown that //
|
||||||
|
// even when using 13bit coefficients errors remain in the lsb //
|
||||||
|
// only (i.e. dout-bit[0] //
|
||||||
|
// //
|
||||||
|
// The amount of coefficient-bits needed is dependent on the //
|
||||||
|
// desired quality. //
|
||||||
|
// The JPEG-standard compliance specs.(ITU-T.83) prescribe //
|
||||||
|
// that the output of the combined DCT AND Quantization unit //
|
||||||
|
// shall not exceed 1 for the desired quality. //
|
||||||
|
// //
|
||||||
|
// This means for high quantization levels, lesser bits //
|
||||||
|
// for the DCT unit can be used. //
|
||||||
|
// //
|
||||||
|
// Looking at the recommended "quantization tables for generic //
|
||||||
|
// compliance testing of DCT-based processes" (ITU-T.83 annex B) //
|
||||||
|
// it can be noticed that relatively large quantization values //
|
||||||
|
// are being used. Errors in the lower-order bits should //
|
||||||
|
// therefore not be visible. //
|
||||||
|
// For certain applications some of the lower-order bits could //
|
||||||
|
// actually be discarded. When looking at the luminance and //
|
||||||
|
// chrominance example quantization tables (ITU-T.81 annex K) //
|
||||||
|
// it can be seen that the smallest quantization value is ten //
|
||||||
|
// (qnt_val_min = 10). This means that the lowest 2bits can be //
|
||||||
|
// discarded (set to zero '0') without having any effect on the //
|
||||||
|
// final result. In this example 11 bit or 12 bit coefficients //
|
||||||
|
// would be sufficient. //
|
||||||
|
// //
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
parameter coef_width = 11;
|
||||||
|
parameter di_width = 8;
|
||||||
|
parameter do_width = 12;
|
||||||
|
|
||||||
|
//
|
||||||
|
// inputs & outputs
|
||||||
|
//
|
||||||
|
input clk; // system clock
|
||||||
|
input ena; // clock enable
|
||||||
|
input rst; // active low asynchronous reset
|
||||||
|
|
||||||
|
input dstrb; // data-strobe. Present dstrb 1clk-cycle before data block
|
||||||
|
input [di_width-1:0] din;
|
||||||
|
output [do_width-1:0] dout;
|
||||||
|
output douten; // data-out enable
|
||||||
|
|
||||||
|
//
|
||||||
|
// variables
|
||||||
|
//
|
||||||
|
|
||||||
|
wire doe;
|
||||||
|
|
||||||
|
wire [do_width -1:0] // results from DCT module
|
||||||
|
res00, res01, res02, res03, res04, res05, res06, res07,
|
||||||
|
res10, res11, res12, res13, res14, res15, res16, res17,
|
||||||
|
res20, res21, res22, res23, res24, res25, res26, res27,
|
||||||
|
res30, res31, res32, res33, res34, res35, res36, res37,
|
||||||
|
res40, res41, res42, res43, res44, res45, res46, res47,
|
||||||
|
res50, res51, res52, res53, res54, res55, res56, res57,
|
||||||
|
res60, res61, res62, res63, res64, res65, res66, res67,
|
||||||
|
res70, res71, res72, res73, res74, res75, res76, res77;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// module body
|
||||||
|
//
|
||||||
|
|
||||||
|
// Hookup DCT module
|
||||||
|
dct #(coef_width, di_width, do_width)
|
||||||
|
dct_mod(
|
||||||
|
.clk(clk),
|
||||||
|
.ena(ena),
|
||||||
|
.rst(rst),
|
||||||
|
.dstrb(dstrb),
|
||||||
|
.din(din),
|
||||||
|
.dout_00(res00),
|
||||||
|
.dout_01(res01),
|
||||||
|
.dout_02(res02),
|
||||||
|
.dout_03(res03),
|
||||||
|
.dout_04(res04),
|
||||||
|
.dout_05(res05),
|
||||||
|
.dout_06(res06),
|
||||||
|
.dout_07(res07),
|
||||||
|
.dout_10(res10),
|
||||||
|
.dout_11(res11),
|
||||||
|
.dout_12(res12),
|
||||||
|
.dout_13(res13),
|
||||||
|
.dout_14(res14),
|
||||||
|
.dout_15(res15),
|
||||||
|
.dout_16(res16),
|
||||||
|
.dout_17(res17),
|
||||||
|
.dout_20(res20),
|
||||||
|
.dout_21(res21),
|
||||||
|
.dout_22(res22),
|
||||||
|
.dout_23(res23),
|
||||||
|
.dout_24(res24),
|
||||||
|
.dout_25(res25),
|
||||||
|
.dout_26(res26),
|
||||||
|
.dout_27(res27),
|
||||||
|
.dout_30(res30),
|
||||||
|
.dout_31(res31),
|
||||||
|
.dout_32(res32),
|
||||||
|
.dout_33(res33),
|
||||||
|
.dout_34(res34),
|
||||||
|
.dout_35(res35),
|
||||||
|
.dout_36(res36),
|
||||||
|
.dout_37(res37),
|
||||||
|
.dout_40(res40),
|
||||||
|
.dout_41(res41),
|
||||||
|
.dout_42(res42),
|
||||||
|
.dout_43(res43),
|
||||||
|
.dout_44(res44),
|
||||||
|
.dout_45(res45),
|
||||||
|
.dout_46(res46),
|
||||||
|
.dout_47(res47),
|
||||||
|
.dout_50(res50),
|
||||||
|
.dout_51(res51),
|
||||||
|
.dout_52(res52),
|
||||||
|
.dout_53(res53),
|
||||||
|
.dout_54(res54),
|
||||||
|
.dout_55(res55),
|
||||||
|
.dout_56(res56),
|
||||||
|
.dout_57(res57),
|
||||||
|
.dout_60(res60),
|
||||||
|
.dout_61(res61),
|
||||||
|
.dout_62(res62),
|
||||||
|
.dout_63(res63),
|
||||||
|
.dout_64(res64),
|
||||||
|
.dout_65(res65),
|
||||||
|
.dout_66(res66),
|
||||||
|
.dout_67(res67),
|
||||||
|
.dout_70(res70),
|
||||||
|
.dout_71(res71),
|
||||||
|
.dout_72(res72),
|
||||||
|
.dout_73(res73),
|
||||||
|
.dout_74(res74),
|
||||||
|
.dout_75(res75),
|
||||||
|
.dout_76(res76),
|
||||||
|
.dout_77(res77),
|
||||||
|
.douten(doe)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Hookup ZigZag unit
|
||||||
|
zigzag zigzag_mod(
|
||||||
|
.clk(clk),
|
||||||
|
.ena(ena),
|
||||||
|
.dstrb(doe),
|
||||||
|
.din_00(res00),
|
||||||
|
.din_01(res01),
|
||||||
|
.din_02(res02),
|
||||||
|
.din_03(res03),
|
||||||
|
.din_04(res04),
|
||||||
|
.din_05(res05),
|
||||||
|
.din_06(res06),
|
||||||
|
.din_07(res07),
|
||||||
|
.din_10(res10),
|
||||||
|
.din_11(res11),
|
||||||
|
.din_12(res12),
|
||||||
|
.din_13(res13),
|
||||||
|
.din_14(res14),
|
||||||
|
.din_15(res15),
|
||||||
|
.din_16(res16),
|
||||||
|
.din_17(res17),
|
||||||
|
.din_20(res20),
|
||||||
|
.din_21(res21),
|
||||||
|
.din_22(res22),
|
||||||
|
.din_23(res23),
|
||||||
|
.din_24(res24),
|
||||||
|
.din_25(res25),
|
||||||
|
.din_26(res26),
|
||||||
|
.din_27(res27),
|
||||||
|
.din_30(res30),
|
||||||
|
.din_31(res31),
|
||||||
|
.din_32(res32),
|
||||||
|
.din_33(res33),
|
||||||
|
.din_34(res34),
|
||||||
|
.din_35(res35),
|
||||||
|
.din_36(res36),
|
||||||
|
.din_37(res37),
|
||||||
|
.din_40(res40),
|
||||||
|
.din_41(res41),
|
||||||
|
.din_42(res42),
|
||||||
|
.din_43(res43),
|
||||||
|
.din_44(res44),
|
||||||
|
.din_45(res45),
|
||||||
|
.din_46(res46),
|
||||||
|
.din_47(res47),
|
||||||
|
.din_50(res50),
|
||||||
|
.din_51(res51),
|
||||||
|
.din_52(res52),
|
||||||
|
.din_53(res53),
|
||||||
|
.din_54(res54),
|
||||||
|
.din_55(res55),
|
||||||
|
.din_56(res56),
|
||||||
|
.din_57(res57),
|
||||||
|
.din_60(res60),
|
||||||
|
.din_61(res61),
|
||||||
|
.din_62(res62),
|
||||||
|
.din_63(res63),
|
||||||
|
.din_64(res64),
|
||||||
|
.din_65(res65),
|
||||||
|
.din_66(res66),
|
||||||
|
.din_67(res67),
|
||||||
|
.din_70(res70),
|
||||||
|
.din_71(res71),
|
||||||
|
.din_72(res72),
|
||||||
|
.din_73(res73),
|
||||||
|
.din_74(res74),
|
||||||
|
.din_75(res75),
|
||||||
|
.din_76(res76),
|
||||||
|
.din_77(res77),
|
||||||
|
.dout(dout),
|
||||||
|
.douten(douten)
|
||||||
|
);
|
||||||
|
endmodule
|
|
@ -0,0 +1,201 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Zig-Zag Unit ////
|
||||||
|
//// Performs zigzag-ing, as used by many DCT based encoders ////
|
||||||
|
//// ////
|
||||||
|
//// Author: Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// www.asics.ws ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2002 Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer.////
|
||||||
|
//// ////
|
||||||
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||||
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||||
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||||
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||||
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||||
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||||
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||||
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||||
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||||
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||||
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||||
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||||
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// CVS Log
|
||||||
|
//
|
||||||
|
// $Id: zigzag.v,v 1.2 2002-10-23 09:06:59 rherveille Exp $
|
||||||
|
//
|
||||||
|
// $Date: 2002-10-23 09:06:59 $
|
||||||
|
// $Revision: 1.2 $
|
||||||
|
// $Author: rherveille $
|
||||||
|
// $Locker: $
|
||||||
|
// $State: Exp $
|
||||||
|
//
|
||||||
|
// Change History:
|
||||||
|
// $Log: not supported by cvs2svn $
|
||||||
|
|
||||||
|
|
||||||
|
// synopsys translate_off
|
||||||
|
`include "timescale.v"
|
||||||
|
// synopsys translate_on
|
||||||
|
|
||||||
|
module zigzag(
|
||||||
|
clk,
|
||||||
|
ena,
|
||||||
|
dstrb,
|
||||||
|
din_00, din_01, din_02, din_03, din_04, din_05, din_06, din_07,
|
||||||
|
din_10, din_11, din_12, din_13, din_14, din_15, din_16, din_17,
|
||||||
|
din_20, din_21, din_22, din_23, din_24, din_25, din_26, din_27,
|
||||||
|
din_30, din_31, din_32, din_33, din_34, din_35, din_36, din_37,
|
||||||
|
din_40, din_41, din_42, din_43, din_44, din_45, din_46, din_47,
|
||||||
|
din_50, din_51, din_52, din_53, din_54, din_55, din_56, din_57,
|
||||||
|
din_60, din_61, din_62, din_63, din_64, din_65, din_66, din_67,
|
||||||
|
din_70, din_71, din_72, din_73, din_74, din_75, din_76, din_77,
|
||||||
|
dout,
|
||||||
|
douten
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// inputs & outputs
|
||||||
|
//
|
||||||
|
|
||||||
|
input clk; // system clock
|
||||||
|
input ena; // clock enable
|
||||||
|
|
||||||
|
input dstrb; // data-strobe. Present dstrb 1clk-cycle before data block
|
||||||
|
input [11:0]
|
||||||
|
din_00, din_01, din_02, din_03, din_04, din_05, din_06, din_07,
|
||||||
|
din_10, din_11, din_12, din_13, din_14, din_15, din_16, din_17,
|
||||||
|
din_20, din_21, din_22, din_23, din_24, din_25, din_26, din_27,
|
||||||
|
din_30, din_31, din_32, din_33, din_34, din_35, din_36, din_37,
|
||||||
|
din_40, din_41, din_42, din_43, din_44, din_45, din_46, din_47,
|
||||||
|
din_50, din_51, din_52, din_53, din_54, din_55, din_56, din_57,
|
||||||
|
din_60, din_61, din_62, din_63, din_64, din_65, din_66, din_67,
|
||||||
|
din_70, din_71, din_72, din_73, din_74, din_75, din_76, din_77;
|
||||||
|
output [11:0] dout;
|
||||||
|
output douten; // data-out enable
|
||||||
|
|
||||||
|
//
|
||||||
|
// variables
|
||||||
|
//
|
||||||
|
|
||||||
|
reg ld_zigzag;
|
||||||
|
reg [11:0] sresult [63:0]; // store results for zig-zagging
|
||||||
|
|
||||||
|
//
|
||||||
|
// module body
|
||||||
|
//
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
if(ena)
|
||||||
|
ld_zigzag <= #1 dstrb;
|
||||||
|
|
||||||
|
assign douten = ld_zigzag;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Generate zig-zag structure
|
||||||
|
//
|
||||||
|
// This implicates that the quantization step be performed after
|
||||||
|
// the zig-zagging.
|
||||||
|
//
|
||||||
|
// 0: 1: 2: 3: 4: 5: 6: 7: 0: 1: 2: 3: 4: 5: 6: 7:
|
||||||
|
// 0: 63 62 58 57 49 48 36 35 3f 3e 3a 39 31 30 24 23
|
||||||
|
// 1: 61 59 56 50 47 37 34 21 3d 3b 38 32 2f 25 22 15
|
||||||
|
// 2: 60 55 51 46 38 33 22 20 3c 37 33 2e 26 21 16 14
|
||||||
|
// 3: 54 52 45 39 32 23 19 10 36 34 2d 27 20 17 13 0a
|
||||||
|
// 4: 53 44 40 31 24 18 11 09 35 2c 28 1f 18 12 0b 09
|
||||||
|
// 5: 43 41 30 25 17 12 08 03 2b 29 1e 19 11 0c 08 03
|
||||||
|
// 6: 42 29 26 16 13 07 04 02 2a 1d 1a 10 0d 07 04 02
|
||||||
|
// 7: 28 27 15 14 06 05 01 00 1c 1b 0f 0e 06 05 01 00
|
||||||
|
//
|
||||||
|
// zig-zag the DCT results
|
||||||
|
integer n;
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
if(ena)
|
||||||
|
if(ld_zigzag) // reload results-register file
|
||||||
|
begin
|
||||||
|
sresult[63] <= #1 din_00;
|
||||||
|
sresult[62] <= #1 din_01;
|
||||||
|
sresult[61] <= #1 din_10;
|
||||||
|
sresult[60] <= #1 din_20;
|
||||||
|
sresult[59] <= #1 din_11;
|
||||||
|
sresult[58] <= #1 din_02;
|
||||||
|
sresult[57] <= #1 din_03;
|
||||||
|
sresult[56] <= #1 din_12;
|
||||||
|
sresult[55] <= #1 din_21;
|
||||||
|
sresult[54] <= #1 din_30;
|
||||||
|
sresult[53] <= #1 din_40;
|
||||||
|
sresult[52] <= #1 din_31;
|
||||||
|
sresult[51] <= #1 din_22;
|
||||||
|
sresult[50] <= #1 din_13;
|
||||||
|
sresult[49] <= #1 din_04;
|
||||||
|
sresult[48] <= #1 din_05;
|
||||||
|
sresult[47] <= #1 din_14;
|
||||||
|
sresult[46] <= #1 din_23;
|
||||||
|
sresult[45] <= #1 din_32;
|
||||||
|
sresult[44] <= #1 din_41;
|
||||||
|
sresult[43] <= #1 din_50;
|
||||||
|
sresult[42] <= #1 din_60;
|
||||||
|
sresult[41] <= #1 din_51;
|
||||||
|
sresult[40] <= #1 din_42;
|
||||||
|
sresult[39] <= #1 din_33;
|
||||||
|
sresult[38] <= #1 din_24;
|
||||||
|
sresult[37] <= #1 din_15;
|
||||||
|
sresult[36] <= #1 din_06;
|
||||||
|
sresult[35] <= #1 din_07;
|
||||||
|
sresult[34] <= #1 din_16;
|
||||||
|
sresult[33] <= #1 din_25;
|
||||||
|
sresult[32] <= #1 din_34;
|
||||||
|
sresult[31] <= #1 din_43;
|
||||||
|
sresult[30] <= #1 din_52;
|
||||||
|
sresult[29] <= #1 din_61;
|
||||||
|
sresult[28] <= #1 din_70;
|
||||||
|
sresult[27] <= #1 din_71;
|
||||||
|
sresult[26] <= #1 din_62;
|
||||||
|
sresult[25] <= #1 din_53;
|
||||||
|
sresult[24] <= #1 din_44;
|
||||||
|
sresult[23] <= #1 din_35;
|
||||||
|
sresult[22] <= #1 din_26;
|
||||||
|
sresult[21] <= #1 din_17;
|
||||||
|
sresult[20] <= #1 din_27;
|
||||||
|
sresult[19] <= #1 din_36;
|
||||||
|
sresult[18] <= #1 din_45;
|
||||||
|
sresult[17] <= #1 din_54;
|
||||||
|
sresult[16] <= #1 din_63;
|
||||||
|
sresult[15] <= #1 din_72;
|
||||||
|
sresult[14] <= #1 din_73;
|
||||||
|
sresult[13] <= #1 din_64;
|
||||||
|
sresult[12] <= #1 din_55;
|
||||||
|
sresult[11] <= #1 din_46;
|
||||||
|
sresult[10] <= #1 din_37;
|
||||||
|
sresult[09] <= #1 din_47;
|
||||||
|
sresult[08] <= #1 din_56;
|
||||||
|
sresult[07] <= #1 din_65;
|
||||||
|
sresult[06] <= #1 din_74;
|
||||||
|
sresult[05] <= #1 din_75;
|
||||||
|
sresult[04] <= #1 din_66;
|
||||||
|
sresult[03] <= #1 din_57;
|
||||||
|
sresult[02] <= #1 din_67;
|
||||||
|
sresult[01] <= #1 din_76;
|
||||||
|
sresult[00] <= #1 din_77;
|
||||||
|
end
|
||||||
|
else // shift results out
|
||||||
|
for (n=1; n<=63; n=n+1) // do not change sresult[0]
|
||||||
|
sresult[n] <= #1 sresult[n -1];
|
||||||
|
|
||||||
|
assign dout = sresult[63];
|
||||||
|
endmodule
|
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
|
@ -0,0 +1,63 @@
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- File Name : diffeq.v
|
||||||
|
-- Author(s) : P. Sridhar
|
||||||
|
-- Affiliation : Laboratory for Digital Design Environments
|
||||||
|
-- Department of Electrical & Computer Engineering
|
||||||
|
-- University of Cincinnati
|
||||||
|
-- Date Created : June 1991.
|
||||||
|
-- Introduction : Behavioral description of a differential equation
|
||||||
|
-- solver written in a synthesizable subset of VHDL.
|
||||||
|
-- Source : Written in HardwareC by Rajesh Gupta, Stanford Univ.
|
||||||
|
-- Obtained from the Highlevel Synthesis Workshop
|
||||||
|
-- Repository.
|
||||||
|
--
|
||||||
|
-- Modified For Synthesis by Jay(anta) Roy, University of Cincinnati.
|
||||||
|
-- Date Modified : Sept, 91.
|
||||||
|
--
|
||||||
|
-- Disclaimer : This comes with absolutely no guarantees of any
|
||||||
|
-- kind (just stating the obvious ...)
|
||||||
|
--
|
||||||
|
-- Acknowledgement : The Distributed Synthesis Systems research at
|
||||||
|
-- the Laboratory for Digital Design Environments,
|
||||||
|
-- University of Cincinnati, is sponsored in part
|
||||||
|
-- by the Defense Advanced Research Projects Agency
|
||||||
|
-- under order number 7056 monitored by the Federal
|
||||||
|
-- Bureau of Investigation under contract number
|
||||||
|
-- J-FBI-89-094.
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
module diffeq_f_systemC(aport, dxport, xport, yport, uport, clk, reset);
|
||||||
|
|
||||||
|
input clk;
|
||||||
|
input reset;
|
||||||
|
input [31:0]aport;
|
||||||
|
input [31:0]dxport;
|
||||||
|
output [31:0]xport;
|
||||||
|
output [31:0]yport;
|
||||||
|
output [31:0]uport;
|
||||||
|
reg [31:0]xport;
|
||||||
|
reg [31:0]yport;
|
||||||
|
reg [31:0]uport;
|
||||||
|
wire [31:0]temp;
|
||||||
|
|
||||||
|
assign temp = uport * dxport;
|
||||||
|
always @(posedge clk )
|
||||||
|
begin
|
||||||
|
if (reset == 1'b1)
|
||||||
|
begin
|
||||||
|
xport <= 0;
|
||||||
|
yport <= 0;
|
||||||
|
uport <= 0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if (xport < aport)
|
||||||
|
begin
|
||||||
|
xport <= xport + dxport;
|
||||||
|
yport <= yport + temp;//(uport * dxport);
|
||||||
|
uport <= (uport - (temp/*(uport * dxport)*/ * (5 * xport))) - (dxport * (3 * yport));
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,589 @@
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// title : Sensor Manager Statemachine
|
||||||
|
// project : ULP Sensor Hub
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// file : StateMachine.v
|
||||||
|
// author : Glen Gomes
|
||||||
|
// company : QuickLogic Corp
|
||||||
|
// created : 2013/12/06
|
||||||
|
// last update : 2013/12/06
|
||||||
|
// platform : PolarPro III
|
||||||
|
// standard : Verilog 2001
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// description: The Sensor Manger Statemachine is responsible for controlling the
|
||||||
|
// operations of the Sensor Manager. These include performing
|
||||||
|
// transfers between Sensor Memory and various registers.
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// copyright (c) 2013
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// revisions :
|
||||||
|
// date version author description
|
||||||
|
// 2013/12/06 1.0 Glen Gomes created
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Comments: This solution is specifically for use with the QuickLogic
|
||||||
|
// PolarPro III device.
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1ns/10ps
|
||||||
|
|
||||||
|
module StateMachine (
|
||||||
|
|
||||||
|
CLK_IN,
|
||||||
|
RESET_IN,
|
||||||
|
|
||||||
|
RUNTIME_ADDRESS,
|
||||||
|
CONTROL_JUMP_REG_DCD,
|
||||||
|
SAVE_REG_2_MEM,
|
||||||
|
|
||||||
|
WB_ACK_I,
|
||||||
|
WB_BUSY_I,
|
||||||
|
WB_BUSY_POLL_I,
|
||||||
|
|
||||||
|
WB_WE_O,
|
||||||
|
WB_STB_O,
|
||||||
|
WB_CYC_O,
|
||||||
|
|
||||||
|
SM_CNTL_REG_RUN,
|
||||||
|
SM_CNTL_INIT_SEQ,
|
||||||
|
SM_READ_DATA,
|
||||||
|
|
||||||
|
SM_INSTR_PTR,
|
||||||
|
SM_READ_SELECT,
|
||||||
|
|
||||||
|
SM_WRITE_SELECT,
|
||||||
|
|
||||||
|
SM_BUSY
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//-----Port Signals--------------------
|
||||||
|
//
|
||||||
|
|
||||||
|
input CLK_IN;
|
||||||
|
input RESET_IN;
|
||||||
|
|
||||||
|
input [7:0] RUNTIME_ADDRESS;
|
||||||
|
input CONTROL_JUMP_REG_DCD;
|
||||||
|
input SAVE_REG_2_MEM;
|
||||||
|
|
||||||
|
input WB_ACK_I;
|
||||||
|
input WB_BUSY_I;
|
||||||
|
input WB_BUSY_POLL_I;
|
||||||
|
|
||||||
|
output WB_WE_O;
|
||||||
|
output WB_STB_O;
|
||||||
|
output WB_CYC_O;
|
||||||
|
|
||||||
|
input SM_CNTL_REG_RUN;
|
||||||
|
input SM_CNTL_INIT_SEQ;
|
||||||
|
input [7:0] SM_READ_DATA;
|
||||||
|
|
||||||
|
output [7:0] SM_INSTR_PTR;
|
||||||
|
output SM_READ_SELECT;
|
||||||
|
|
||||||
|
output SM_WRITE_SELECT;
|
||||||
|
|
||||||
|
output SM_BUSY;
|
||||||
|
|
||||||
|
|
||||||
|
wire CLK_IN;
|
||||||
|
wire RESET_IN;
|
||||||
|
|
||||||
|
wire [7:0] RUNTIME_ADDRESS;
|
||||||
|
wire CONTROL_JUMP_REG_DCD;
|
||||||
|
wire SAVE_REG_2_MEM;
|
||||||
|
|
||||||
|
wire WB_ACK_I;
|
||||||
|
wire WB_BUSY_I;
|
||||||
|
wire WB_BUSY_POLL_I;
|
||||||
|
|
||||||
|
reg WB_WE_O;
|
||||||
|
reg wb_we_o_nxt;
|
||||||
|
|
||||||
|
reg WB_STB_O;
|
||||||
|
reg wb_stb_o_nxt;
|
||||||
|
|
||||||
|
reg WB_CYC_O;
|
||||||
|
reg wb_cyc_o_nxt;
|
||||||
|
|
||||||
|
wire SM_CNTL_REG_RUN;
|
||||||
|
wire SM_CNTL_INIT_SEQ;
|
||||||
|
wire [7:0] SM_READ_DATA;
|
||||||
|
|
||||||
|
reg [7:0] SM_INSTR_PTR;
|
||||||
|
reg [7:0] sm_instr_ptr_nxt;
|
||||||
|
|
||||||
|
reg SM_READ_SELECT;
|
||||||
|
reg sm_read_select_nxt;
|
||||||
|
|
||||||
|
reg SM_WRITE_SELECT;
|
||||||
|
reg sm_write_select_nxt;
|
||||||
|
|
||||||
|
reg SM_BUSY;
|
||||||
|
reg sm_busy_nxt;
|
||||||
|
|
||||||
|
//-----Internal Signals--------------------
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define the Statemachine registers
|
||||||
|
//
|
||||||
|
reg [3:0] sensor_manager_sm;
|
||||||
|
reg [3:0] sensor_manager_sm_nxt;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define the Instruction Pointer variables
|
||||||
|
//
|
||||||
|
|
||||||
|
reg sm_instr_ptr_ce;
|
||||||
|
reg sm_instr_ptr_ce_nxt;
|
||||||
|
|
||||||
|
reg sm_instr_ptr_ld;
|
||||||
|
reg sm_instr_ptr_ld_nxt;
|
||||||
|
|
||||||
|
reg sm_instr_ptr_sel;
|
||||||
|
reg sm_instr_ptr_sel_nxt;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//------Define Parameters---------
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define the Sensor Manager Statemachine States
|
||||||
|
//
|
||||||
|
// Note: These states are chosen to allow for overlap of various signals
|
||||||
|
// during operation. This overlap should help reduce timing
|
||||||
|
// dependancies.
|
||||||
|
//
|
||||||
|
parameter SM_IDLE = 4'h0;
|
||||||
|
parameter SM_INC_PTR = 4'h1;
|
||||||
|
parameter SM_INST_RD = 4'h2;
|
||||||
|
//parameter SM_INST_DCD = 4'h3; // Note: Will be used for TimeStamp Support in a future design
|
||||||
|
parameter SM_REG_WR = 4'h4;
|
||||||
|
parameter SM_REG_RD = 4'h5;
|
||||||
|
parameter SM_WAIT_BUSY_ON = 4'h6;
|
||||||
|
parameter SM_WAIT_BUSY_OFF = 4'h7;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Sensor Manager Initialization Start Address
|
||||||
|
//
|
||||||
|
// Note: The previous IP used the reset of the "RuntimeAddress" register to
|
||||||
|
// select the sensor initialization code. This value explicity selects
|
||||||
|
// the value for the start (or re-start) of initialization.
|
||||||
|
//
|
||||||
|
parameter SM_INIT_INSTR_ADR = 8'h0; // Address for the start in initialization instructions
|
||||||
|
|
||||||
|
|
||||||
|
//------Logic Operations----------
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define the Instruction Pointer
|
||||||
|
//
|
||||||
|
// Note: This pointer can start at either the sensor initialization code start
|
||||||
|
// address or the run-time code start address.
|
||||||
|
//
|
||||||
|
always @( SM_INSTR_PTR or
|
||||||
|
sm_instr_ptr_ld or
|
||||||
|
sm_instr_ptr_ce or
|
||||||
|
sm_instr_ptr_sel or
|
||||||
|
SM_READ_DATA or
|
||||||
|
CONTROL_JUMP_REG_DCD or
|
||||||
|
RUNTIME_ADDRESS
|
||||||
|
)
|
||||||
|
begin
|
||||||
|
case({sm_instr_ptr_ld, sm_instr_ptr_ce})
|
||||||
|
2'b00: sm_instr_ptr_nxt <= SM_INSTR_PTR; // Hold Current Value
|
||||||
|
2'b01: sm_instr_ptr_nxt <= SM_INSTR_PTR + 1'b1; // Increment to the next address
|
||||||
|
2'b10:
|
||||||
|
begin
|
||||||
|
case({CONTROL_JUMP_REG_DCD, sm_instr_ptr_sel})
|
||||||
|
2'b00: sm_instr_ptr_nxt <= SM_INIT_INSTR_ADR; // Initialization Code Address
|
||||||
|
2'b01: sm_instr_ptr_nxt <= RUNTIME_ADDRESS; // Run-time Code Address
|
||||||
|
2'b10: sm_instr_ptr_nxt <= SM_READ_DATA[7:0]; // Jump Address
|
||||||
|
2'b11: sm_instr_ptr_nxt <= SM_READ_DATA[7:0]; // Jump Address
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
2'b11: sm_instr_ptr_nxt <= SM_INSTR_PTR; // Hold Current Value
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// Define the registers associated with the Sensor Manager Statemachine
|
||||||
|
//
|
||||||
|
always @(posedge CLK_IN or posedge RESET_IN)
|
||||||
|
begin
|
||||||
|
if (RESET_IN)
|
||||||
|
begin
|
||||||
|
sensor_manager_sm <= SM_IDLE;
|
||||||
|
|
||||||
|
SM_INSTR_PTR <= 8'h0;
|
||||||
|
sm_instr_ptr_ce <= 1'b0;
|
||||||
|
sm_instr_ptr_ld <= 1'b0;
|
||||||
|
sm_instr_ptr_sel <= 1'b0;
|
||||||
|
|
||||||
|
WB_WE_O <= 1'b0;
|
||||||
|
WB_STB_O <= 1'b0;
|
||||||
|
WB_CYC_O <= 1'b0;
|
||||||
|
|
||||||
|
SM_READ_SELECT <= 1'b0;
|
||||||
|
SM_WRITE_SELECT <= 1'b0;
|
||||||
|
|
||||||
|
SM_BUSY <= 1'b0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
sensor_manager_sm <= sensor_manager_sm_nxt;
|
||||||
|
|
||||||
|
SM_INSTR_PTR <= sm_instr_ptr_nxt;
|
||||||
|
sm_instr_ptr_ce <= sm_instr_ptr_ce_nxt;
|
||||||
|
sm_instr_ptr_ld <= sm_instr_ptr_ld_nxt;
|
||||||
|
sm_instr_ptr_sel <= sm_instr_ptr_sel_nxt;
|
||||||
|
|
||||||
|
WB_WE_O <= wb_we_o_nxt;
|
||||||
|
WB_STB_O <= wb_stb_o_nxt;
|
||||||
|
WB_CYC_O <= wb_cyc_o_nxt;
|
||||||
|
|
||||||
|
SM_READ_SELECT <= sm_read_select_nxt;
|
||||||
|
SM_WRITE_SELECT <= sm_write_select_nxt;
|
||||||
|
|
||||||
|
SM_BUSY <= sm_busy_nxt;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// Define the Sensor Manager Statemachine
|
||||||
|
//
|
||||||
|
always @( sensor_manager_sm or
|
||||||
|
SM_CNTL_INIT_SEQ or
|
||||||
|
SM_CNTL_REG_RUN or
|
||||||
|
CONTROL_JUMP_REG_DCD or
|
||||||
|
SAVE_REG_2_MEM or
|
||||||
|
WB_BUSY_I or
|
||||||
|
WB_BUSY_POLL_I or
|
||||||
|
WB_ACK_I
|
||||||
|
)
|
||||||
|
begin
|
||||||
|
case(sensor_manager_sm)
|
||||||
|
SM_IDLE:
|
||||||
|
begin
|
||||||
|
case({SM_CNTL_INIT_SEQ, SM_CNTL_REG_RUN})
|
||||||
|
2'b00: // No Activity
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_IDLE;
|
||||||
|
|
||||||
|
sm_busy_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_sel_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
2'b01: // Start at the Sensor Run-Time Code
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_INC_PTR;
|
||||||
|
|
||||||
|
sm_busy_nxt <= 1'b1;
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b1;
|
||||||
|
sm_instr_ptr_sel_nxt <= 1'b1;
|
||||||
|
end
|
||||||
|
2'b10: // No Activity
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_IDLE;
|
||||||
|
|
||||||
|
sm_busy_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_sel_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
2'b11: // Start at the Sensor Initialization Code
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_INC_PTR;
|
||||||
|
|
||||||
|
sm_busy_nxt <= 1'b1;
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b1;
|
||||||
|
sm_instr_ptr_sel_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_read_select_nxt <= 1'b0;
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b0;
|
||||||
|
wb_stb_o_nxt <= 1'b0;
|
||||||
|
wb_cyc_o_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
SM_INC_PTR:
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_INST_RD;
|
||||||
|
|
||||||
|
sm_busy_nxt <= 1'b1;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_sel_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_read_select_nxt <= 1'b1;
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b0;
|
||||||
|
wb_stb_o_nxt <= 1'b0;
|
||||||
|
wb_cyc_o_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
SM_INST_RD:
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_REG_WR;
|
||||||
|
|
||||||
|
sm_busy_nxt <= 1'b1;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_sel_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_read_select_nxt <= 1'b0;
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b1;
|
||||||
|
wb_stb_o_nxt <= 1'b1;
|
||||||
|
wb_cyc_o_nxt <= 1'b1;
|
||||||
|
end
|
||||||
|
SM_REG_WR:
|
||||||
|
begin
|
||||||
|
sm_instr_ptr_sel_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_read_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
case(SM_CNTL_REG_RUN)
|
||||||
|
1'b0: // A write of "0" to bit "0" of the Command register at address "0" turns off
|
||||||
|
// the Sensor Manager's Statemachine
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_IDLE;
|
||||||
|
|
||||||
|
sm_busy_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b0;
|
||||||
|
wb_stb_o_nxt <= 1'b0;
|
||||||
|
wb_cyc_o_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
1'b1: // Sensor Manager Statemachine is not stopped; continue processing
|
||||||
|
begin
|
||||||
|
sm_busy_nxt <= 1'b1;
|
||||||
|
|
||||||
|
case({WB_BUSY_POLL_I, WB_ACK_I})
|
||||||
|
2'b00: // Wait for Wish Bone Acknowledge and no need to wait for transfer complete
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_REG_WR;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b1;
|
||||||
|
wb_stb_o_nxt <= 1'b1;
|
||||||
|
wb_cyc_o_nxt <= 1'b1;
|
||||||
|
end
|
||||||
|
2'b01: // Wish Bone Acknowledge Received and no need to wait for transfer complete
|
||||||
|
begin
|
||||||
|
case(SAVE_REG_2_MEM)
|
||||||
|
1'b0:
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_INC_PTR;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= CONTROL_JUMP_REG_DCD;
|
||||||
|
sm_instr_ptr_ce_nxt <= ~CONTROL_JUMP_REG_DCD;
|
||||||
|
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b0;
|
||||||
|
wb_stb_o_nxt <= 1'b0;
|
||||||
|
wb_cyc_o_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
1'b1:
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_REG_RD;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_write_select_nxt <= 1'b1;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b0;
|
||||||
|
wb_stb_o_nxt <= 1'b1;
|
||||||
|
wb_cyc_o_nxt <= 1'b1;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
2'b10: // Wait for Wish Bone Acknowledge and will need to wait for transfer complete
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_REG_WR;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b1;
|
||||||
|
wb_stb_o_nxt <= 1'b1;
|
||||||
|
wb_cyc_o_nxt <= 1'b1;
|
||||||
|
end
|
||||||
|
2'b11: // Acknowledge received but need to wait for transfer complete
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_WAIT_BUSY_ON;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b0;
|
||||||
|
wb_stb_o_nxt <= 1'b0;
|
||||||
|
wb_cyc_o_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
SM_REG_RD:
|
||||||
|
begin
|
||||||
|
sm_busy_nxt <= 1'b1;
|
||||||
|
|
||||||
|
sm_instr_ptr_sel_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_read_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b0;
|
||||||
|
|
||||||
|
case(WB_ACK_I)
|
||||||
|
1'b0: // Waiting for Wish Bone Acknowledge
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_REG_RD;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_write_select_nxt <= 1'b1;
|
||||||
|
|
||||||
|
wb_stb_o_nxt <= 1'b1;
|
||||||
|
wb_cyc_o_nxt <= 1'b1;
|
||||||
|
end
|
||||||
|
1'b1: // Got Wish Bone Acknowledge
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_INC_PTR;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= CONTROL_JUMP_REG_DCD;
|
||||||
|
sm_instr_ptr_ce_nxt <= ~CONTROL_JUMP_REG_DCD;
|
||||||
|
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_stb_o_nxt <= 1'b0;
|
||||||
|
wb_cyc_o_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
SM_WAIT_BUSY_ON:
|
||||||
|
begin
|
||||||
|
sm_busy_nxt <= 1'b1;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_sel_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_read_select_nxt <= 1'b0;
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b0;
|
||||||
|
wb_stb_o_nxt <= 1'b0;
|
||||||
|
wb_cyc_o_nxt <= 1'b0;
|
||||||
|
|
||||||
|
case(WB_BUSY_I)
|
||||||
|
1'b0: sensor_manager_sm_nxt <= SM_WAIT_BUSY_ON; // Wait for Busy from I/F
|
||||||
|
1'b1: sensor_manager_sm_nxt <= SM_WAIT_BUSY_OFF; // Got Busy from I/F
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
SM_WAIT_BUSY_OFF:
|
||||||
|
begin
|
||||||
|
sm_busy_nxt <= 1'b1;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_sel_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_read_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b0;
|
||||||
|
|
||||||
|
case({SAVE_REG_2_MEM, WB_BUSY_I})
|
||||||
|
2'b00: // Wishbone transfer complete; no need to write anything to Sensor Manager Memory
|
||||||
|
//
|
||||||
|
// Note: Writes to the command register do not enter this state.
|
||||||
|
// Therefore, there is no need to check for the end of processing.
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_INC_PTR;
|
||||||
|
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b1;
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_stb_o_nxt <= 1'b0;
|
||||||
|
wb_cyc_o_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
2'b01: // Wait for Wishbone transfer to complete
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_WAIT_BUSY_OFF;
|
||||||
|
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_stb_o_nxt <= 1'b0;
|
||||||
|
wb_cyc_o_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
2'b10: // Wishbone transfer complete; Write resulting register value to Sensor Manager Memory
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_REG_RD;
|
||||||
|
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
sm_write_select_nxt <= 1'b1;
|
||||||
|
|
||||||
|
wb_stb_o_nxt <= 1'b1;
|
||||||
|
wb_cyc_o_nxt <= 1'b1;
|
||||||
|
end
|
||||||
|
2'b11: // Wait for Wishbone transfer to complete
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_WAIT_BUSY_OFF;
|
||||||
|
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_stb_o_nxt <= 1'b0;
|
||||||
|
wb_cyc_o_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
default:
|
||||||
|
begin
|
||||||
|
sensor_manager_sm_nxt <= SM_IDLE;
|
||||||
|
|
||||||
|
sm_busy_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||||
|
sm_instr_ptr_sel_nxt <= 1'b0;
|
||||||
|
|
||||||
|
sm_read_select_nxt <= 1'b0;
|
||||||
|
sm_write_select_nxt <= 1'b0;
|
||||||
|
|
||||||
|
wb_we_o_nxt <= 1'b0;
|
||||||
|
wb_stb_o_nxt <= 1'b0;
|
||||||
|
wb_cyc_o_nxt <= 1'b0;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,598 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// WISHBONE rev.B2 compliant I2C Master bit-controller ////
|
||||||
|
//// ////
|
||||||
|
//// ////
|
||||||
|
//// Author: Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// www.asics.ws ////
|
||||||
|
//// ////
|
||||||
|
//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2001 Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer.////
|
||||||
|
//// ////
|
||||||
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||||
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||||
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||||
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||||
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||||
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||||
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||||
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||||
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||||
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||||
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||||
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||||
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// CVS Log
|
||||||
|
//
|
||||||
|
// $Id: i2c_master_bit_ctrl.v,v 1.14 2009-01-20 10:25:29 rherveille Exp $
|
||||||
|
//
|
||||||
|
// $Date: 2009-01-20 10:25:29 $
|
||||||
|
// $Revision: 1.14 $
|
||||||
|
// $Author: rherveille $
|
||||||
|
// $Locker: $
|
||||||
|
// $State: Exp $
|
||||||
|
//
|
||||||
|
// Change History:
|
||||||
|
// $Log: $
|
||||||
|
// Revision 1.14 2009/01/20 10:25:29 rherveille
|
||||||
|
// Added clock synchronization logic
|
||||||
|
// Fixed slave_wait signal
|
||||||
|
//
|
||||||
|
// Revision 1.13 2009/01/19 20:29:26 rherveille
|
||||||
|
// Fixed synopsys miss spell (synopsis)
|
||||||
|
// Fixed cr[0] register width
|
||||||
|
// Fixed ! usage instead of ~
|
||||||
|
// Fixed bit controller parameter width to 18bits
|
||||||
|
//
|
||||||
|
// Revision 1.12 2006/09/04 09:08:13 rherveille
|
||||||
|
// fixed short scl high pulse after clock stretch
|
||||||
|
// fixed slave model not returning correct '(n)ack' signal
|
||||||
|
//
|
||||||
|
// Revision 1.11 2004/05/07 11:02:26 rherveille
|
||||||
|
// Fixed a bug where the core would signal an arbitration lost (AL bit set), when another master controls the bus and the other master generates a STOP bit.
|
||||||
|
//
|
||||||
|
// Revision 1.10 2003/08/09 07:01:33 rherveille
|
||||||
|
// Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
|
||||||
|
// Fixed a potential bug in the byte controller's host-acknowledge generation.
|
||||||
|
//
|
||||||
|
// Revision 1.9 2003/03/10 14:26:37 rherveille
|
||||||
|
// Fixed cmd_ack generation item (no bug).
|
||||||
|
//
|
||||||
|
// Revision 1.8 2003/02/05 00:06:10 rherveille
|
||||||
|
// Fixed a bug where the core would trigger an erroneous 'arbitration lost' interrupt after being reset, when the reset pulse width < 3 clk cycles.
|
||||||
|
//
|
||||||
|
// Revision 1.7 2002/12/26 16:05:12 rherveille
|
||||||
|
// Small code simplifications
|
||||||
|
//
|
||||||
|
// Revision 1.6 2002/12/26 15:02:32 rherveille
|
||||||
|
// Core is now a Multimaster I2C controller
|
||||||
|
//
|
||||||
|
// Revision 1.5 2002/11/30 22:24:40 rherveille
|
||||||
|
// Cleaned up code
|
||||||
|
//
|
||||||
|
// Revision 1.4 2002/10/30 18:10:07 rherveille
|
||||||
|
// Fixed some reported minor start/stop generation timing issuess.
|
||||||
|
//
|
||||||
|
// Revision 1.3 2002/06/15 07:37:03 rherveille
|
||||||
|
// Fixed a small timing bug in the bit controller.\nAdded verilog simulation environment.
|
||||||
|
//
|
||||||
|
// Revision 1.2 2001/11/05 11:59:25 rherveille
|
||||||
|
// Fixed wb_ack_o generation bug.
|
||||||
|
// Fixed bug in the byte_controller statemachine.
|
||||||
|
// Added headers.
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
/////////////////////////////////////
|
||||||
|
// Bit controller section
|
||||||
|
/////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Translate simple commands into SCL/SDA transitions
|
||||||
|
// Each command has 5 states, A/B/C/D/idle
|
||||||
|
//
|
||||||
|
// start: SCL ~~~~~~~~~~\____
|
||||||
|
// SDA ~~~~~~~~\______
|
||||||
|
// x | A | B | C | D | i
|
||||||
|
//
|
||||||
|
// repstart SCL ____/~~~~\___
|
||||||
|
// SDA __/~~~\______
|
||||||
|
// x | A | B | C | D | i
|
||||||
|
//
|
||||||
|
// stop SCL ____/~~~~~~~~
|
||||||
|
// SDA ==\____/~~~~~
|
||||||
|
// x | A | B | C | D | i
|
||||||
|
//
|
||||||
|
//- write SCL ____/~~~~\____
|
||||||
|
// SDA ==X=========X=
|
||||||
|
// x | A | B | C | D | i
|
||||||
|
//
|
||||||
|
//- read SCL ____/~~~~\____
|
||||||
|
// SDA XXXX=====XXXX
|
||||||
|
// x | A | B | C | D | i
|
||||||
|
//
|
||||||
|
|
||||||
|
// Timing: Normal mode Fast mode
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
// Fscl 100KHz 400KHz
|
||||||
|
// Th_scl 4.0us 0.6us High period of SCL
|
||||||
|
// Tl_scl 4.7us 1.3us Low period of SCL
|
||||||
|
// Tsu:sta 4.7us 0.6us setup time for a repeated start condition
|
||||||
|
// Tsu:sto 4.0us 0.6us setup time for a stop conditon
|
||||||
|
// Tbuf 4.7us 1.3us Bus free time between a stop and start condition
|
||||||
|
//
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
// QuickLogic Change History:
|
||||||
|
//
|
||||||
|
// Date: February 11, 2014
|
||||||
|
// Engineer: Anthony Le
|
||||||
|
// Issue: i2c master generates back to back stop conditions that violate i2c protocol
|
||||||
|
// Change:
|
||||||
|
// 1. Move the generation of cmd_ack to one clock earlier in stop_c state
|
||||||
|
// 2. Change the condition to unset (set to 0) for cmd_ack in stop_d state
|
||||||
|
//
|
||||||
|
// synopsys translate_off
|
||||||
|
// synopsys translate_on
|
||||||
|
`timescale 1ns / 10ps
|
||||||
|
|
||||||
|
`include "i2c_master_defines.v"
|
||||||
|
|
||||||
|
module i2c_master_bit_ctrl (
|
||||||
|
input clk, // system clock
|
||||||
|
input rst, // synchronous active high reset
|
||||||
|
input Reset, // asynchronous active low reset
|
||||||
|
input ena, // core enable signal
|
||||||
|
|
||||||
|
input [15:0] clk_cnt, // clock prescale value
|
||||||
|
|
||||||
|
input [ 3:0] cmd, // command (from byte controller)
|
||||||
|
output reg cmd_ack, // command complete acknowledge
|
||||||
|
output reg busy, // i2c bus busy
|
||||||
|
output reg al, // i2c bus arbitration lost
|
||||||
|
|
||||||
|
input din,
|
||||||
|
output reg dout,
|
||||||
|
|
||||||
|
input scl_i, // i2c clock line input
|
||||||
|
output scl_o, // i2c clock line output
|
||||||
|
output reg scl_oen, // i2c clock line output enable (active low)
|
||||||
|
input sda_i, // i2c data line input
|
||||||
|
output sda_o, // i2c data line output
|
||||||
|
output reg sda_oen, // i2c data line output enable (active low)
|
||||||
|
output TP1,
|
||||||
|
output TP2
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// variable declarations
|
||||||
|
//
|
||||||
|
|
||||||
|
reg [ 1:0] cSCL, cSDA; // capture SCL and SDA
|
||||||
|
reg [ 2:0] fSCL, fSDA; // SCL and SDA filter inputs
|
||||||
|
reg sSCL, sSDA; // filtered and synchronized SCL and SDA inputs
|
||||||
|
reg dSCL, dSDA; // delayed versions of sSCL and sSDA
|
||||||
|
reg dscl_oen; // delayed scl_oen
|
||||||
|
reg sda_chk; // check SDA output (Multi-master arbitration)
|
||||||
|
reg clk_en; // clock generation signals
|
||||||
|
reg slave_wait; // slave inserts wait states
|
||||||
|
reg [15:0] cnt; // clock divider counter (synthesis)
|
||||||
|
reg [13:0] filter_cnt; // clock divider for filter
|
||||||
|
|
||||||
|
assign TP1 = cnt[0];
|
||||||
|
assign TP2 = cnt[1];
|
||||||
|
|
||||||
|
// state machine variable
|
||||||
|
reg [17:0] c_state; // synopsys enum_state
|
||||||
|
|
||||||
|
//
|
||||||
|
// module body
|
||||||
|
//
|
||||||
|
|
||||||
|
// whenever the slave is not ready it can delay the cycle by pulling SCL low
|
||||||
|
// delay scl_oen
|
||||||
|
always @(posedge clk)
|
||||||
|
dscl_oen <= #1 scl_oen;
|
||||||
|
|
||||||
|
// slave_wait is asserted when master wants to drive SCL high, but the slave pulls it low
|
||||||
|
// slave_wait remains asserted until the slave releases SCL
|
||||||
|
always @(posedge clk or posedge Reset)
|
||||||
|
if (Reset) slave_wait <= 1'b0;
|
||||||
|
else slave_wait <= (scl_oen & ~dscl_oen & ~sSCL) | (slave_wait & ~sSCL);
|
||||||
|
|
||||||
|
// master drives SCL high, but another master pulls it low
|
||||||
|
// master start counting down its low cycle now (clock synchronization)
|
||||||
|
wire scl_sync = dSCL & ~sSCL & scl_oen;
|
||||||
|
|
||||||
|
|
||||||
|
// generate clk enable signal
|
||||||
|
always @(posedge clk or posedge Reset)
|
||||||
|
if (Reset)
|
||||||
|
begin
|
||||||
|
cnt <= #1 16'h0;
|
||||||
|
clk_en <= #1 1'b1;
|
||||||
|
end
|
||||||
|
else if (rst || ~|cnt || !ena || scl_sync)
|
||||||
|
begin
|
||||||
|
cnt <= #1 clk_cnt;
|
||||||
|
clk_en <= #1 1'b1;
|
||||||
|
end
|
||||||
|
else if (slave_wait)
|
||||||
|
begin
|
||||||
|
cnt <= #1 cnt;
|
||||||
|
clk_en <= #1 1'b0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
cnt <= #1 cnt - 16'h1;
|
||||||
|
clk_en <= #1 1'b0;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// generate bus status controller
|
||||||
|
|
||||||
|
// capture SDA and SCL
|
||||||
|
// reduce metastability risk
|
||||||
|
always @(posedge clk or posedge Reset)
|
||||||
|
if (Reset)
|
||||||
|
begin
|
||||||
|
cSCL <= #1 2'b00;
|
||||||
|
cSDA <= #1 2'b00;
|
||||||
|
end
|
||||||
|
else if (rst)
|
||||||
|
begin
|
||||||
|
cSCL <= #1 2'b00;
|
||||||
|
cSDA <= #1 2'b00;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
cSCL <= {cSCL[0],scl_i};
|
||||||
|
cSDA <= {cSDA[0],sda_i};
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// filter SCL and SDA signals; (attempt to) remove glitches
|
||||||
|
always @(posedge clk or posedge Reset)
|
||||||
|
if (Reset ) filter_cnt <= 14'h0;
|
||||||
|
else if (rst || !ena ) filter_cnt <= 14'h0;
|
||||||
|
else if (~|filter_cnt) filter_cnt <= clk_cnt >> 2; //16x I2C bus frequency
|
||||||
|
else filter_cnt <= filter_cnt -1;
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clk or posedge Reset)
|
||||||
|
if (Reset)
|
||||||
|
begin
|
||||||
|
fSCL <= 3'b111;
|
||||||
|
fSDA <= 3'b111;
|
||||||
|
end
|
||||||
|
else if (rst)
|
||||||
|
begin
|
||||||
|
fSCL <= 3'b111;
|
||||||
|
fSDA <= 3'b111;
|
||||||
|
end
|
||||||
|
else if (~|filter_cnt)
|
||||||
|
begin
|
||||||
|
fSCL <= {fSCL[1:0],cSCL[1]};
|
||||||
|
fSDA <= {fSDA[1:0],cSDA[1]};
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// generate filtered SCL and SDA signals
|
||||||
|
always @(posedge clk or posedge Reset)
|
||||||
|
if (Reset)
|
||||||
|
begin
|
||||||
|
sSCL <= #1 1'b1;
|
||||||
|
sSDA <= #1 1'b1;
|
||||||
|
|
||||||
|
dSCL <= #1 1'b1;
|
||||||
|
dSDA <= #1 1'b1;
|
||||||
|
end
|
||||||
|
else if (rst)
|
||||||
|
begin
|
||||||
|
sSCL <= #1 1'b1;
|
||||||
|
sSDA <= #1 1'b1;
|
||||||
|
|
||||||
|
dSCL <= #1 1'b1;
|
||||||
|
dSDA <= #1 1'b1;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
sSCL <= #1 &fSCL[2:1] | &fSCL[1:0] | (fSCL[2] & fSCL[0]);
|
||||||
|
sSDA <= #1 &fSDA[2:1] | &fSDA[1:0] | (fSDA[2] & fSDA[0]);
|
||||||
|
|
||||||
|
dSCL <= #1 sSCL;
|
||||||
|
dSDA <= #1 sSDA;
|
||||||
|
end
|
||||||
|
|
||||||
|
// detect start condition => detect falling edge on SDA while SCL is high
|
||||||
|
// detect stop condition => detect rising edge on SDA while SCL is high
|
||||||
|
reg sta_condition;
|
||||||
|
reg sto_condition;
|
||||||
|
always @(posedge clk or posedge Reset)
|
||||||
|
if (Reset)
|
||||||
|
begin
|
||||||
|
sta_condition <= #1 1'b0;
|
||||||
|
sto_condition <= #1 1'b0;
|
||||||
|
end
|
||||||
|
else if (rst)
|
||||||
|
begin
|
||||||
|
sta_condition <= #1 1'b0;
|
||||||
|
sto_condition <= #1 1'b0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
sta_condition <= #1 ~sSDA & dSDA & sSCL;
|
||||||
|
sto_condition <= #1 sSDA & ~dSDA & sSCL;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// generate i2c bus busy signal
|
||||||
|
always @(posedge clk or posedge Reset)
|
||||||
|
if (Reset) busy <= #1 1'b0;
|
||||||
|
else if (rst ) busy <= #1 1'b0;
|
||||||
|
else busy <= #1 (sta_condition | busy) & ~sto_condition;
|
||||||
|
|
||||||
|
|
||||||
|
// generate arbitration lost signal
|
||||||
|
// aribitration lost when:
|
||||||
|
// 1) master drives SDA high, but the i2c bus is low
|
||||||
|
// 2) stop detected while not requested
|
||||||
|
reg cmd_stop;
|
||||||
|
always @(posedge clk or posedge Reset)
|
||||||
|
if (Reset)
|
||||||
|
cmd_stop <= #1 1'b0;
|
||||||
|
else if (rst)
|
||||||
|
cmd_stop <= #1 1'b0;
|
||||||
|
else if (clk_en)
|
||||||
|
cmd_stop <= #1 cmd == `I2C_CMD_STOP;
|
||||||
|
|
||||||
|
always @(posedge clk or posedge Reset)
|
||||||
|
if (Reset)
|
||||||
|
al <= #1 1'b0;
|
||||||
|
else if (rst)
|
||||||
|
al <= #1 1'b0;
|
||||||
|
else
|
||||||
|
al <= 0;
|
||||||
|
// al <= #1 (sda_chk & ~sSDA & sda_oen) | (|c_state & sto_condition & ~cmd_stop);
|
||||||
|
|
||||||
|
|
||||||
|
// generate dout signal (store SDA on rising edge of SCL)
|
||||||
|
always @(posedge clk)
|
||||||
|
if (sSCL & ~dSCL) dout <= #1 sSDA;
|
||||||
|
|
||||||
|
|
||||||
|
// generate statemachine
|
||||||
|
|
||||||
|
// nxt_state decoder
|
||||||
|
parameter [17:0] idle = 18'b0_0000_0000_0000_0000;
|
||||||
|
parameter [17:0] start_a = 18'b0_0000_0000_0000_0001;
|
||||||
|
parameter [17:0] start_b = 18'b0_0000_0000_0000_0010;
|
||||||
|
parameter [17:0] start_c = 18'b0_0000_0000_0000_0100;
|
||||||
|
parameter [17:0] start_d = 18'b0_0000_0000_0000_1000;
|
||||||
|
parameter [17:0] start_e = 18'b0_0000_0000_0001_0000;
|
||||||
|
parameter [17:0] stop_a = 18'b0_0000_0000_0010_0000;
|
||||||
|
parameter [17:0] stop_b = 18'b0_0000_0000_0100_0000;
|
||||||
|
parameter [17:0] stop_c = 18'b0_0000_0000_1000_0000;
|
||||||
|
parameter [17:0] stop_d = 18'b0_0000_0001_0000_0000;
|
||||||
|
parameter [17:0] rd_a = 18'b0_0000_0010_0000_0000;
|
||||||
|
parameter [17:0] rd_b = 18'b0_0000_0100_0000_0000;
|
||||||
|
parameter [17:0] rd_c = 18'b0_0000_1000_0000_0000;
|
||||||
|
parameter [17:0] rd_d = 18'b0_0001_0000_0000_0000;
|
||||||
|
parameter [17:0] wr_a = 18'b0_0010_0000_0000_0000;
|
||||||
|
parameter [17:0] wr_b = 18'b0_0100_0000_0000_0000;
|
||||||
|
parameter [17:0] wr_c = 18'b0_1000_0000_0000_0000;
|
||||||
|
parameter [17:0] wr_d = 18'b1_0000_0000_0000_0000;
|
||||||
|
|
||||||
|
always @(posedge clk or posedge Reset)
|
||||||
|
if (Reset)
|
||||||
|
begin
|
||||||
|
c_state <= #1 idle;
|
||||||
|
cmd_ack <= #1 1'b0;
|
||||||
|
scl_oen <= #1 1'b1;
|
||||||
|
sda_oen <= #1 1'b1;
|
||||||
|
sda_chk <= #1 1'b0;
|
||||||
|
end
|
||||||
|
else if (rst | al)
|
||||||
|
begin
|
||||||
|
c_state <= #1 idle;
|
||||||
|
cmd_ack <= #1 1'b0;
|
||||||
|
scl_oen <= #1 1'b1;
|
||||||
|
sda_oen <= #1 1'b1;
|
||||||
|
sda_chk <= #1 1'b0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
cmd_ack <= #1 1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle
|
||||||
|
|
||||||
|
if (clk_en)
|
||||||
|
case (c_state) // synopsys full_case parallel_case
|
||||||
|
// idle state
|
||||||
|
idle:
|
||||||
|
begin
|
||||||
|
case (cmd) // synopsys full_case parallel_case
|
||||||
|
`I2C_CMD_START: c_state <= #1 start_a;
|
||||||
|
`I2C_CMD_STOP: c_state <= #1 stop_a;
|
||||||
|
`I2C_CMD_WRITE: c_state <= #1 wr_a;
|
||||||
|
`I2C_CMD_READ: c_state <= #1 rd_a;
|
||||||
|
default: c_state <= #1 idle;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
scl_oen <= #1 scl_oen; // keep SCL in same state
|
||||||
|
sda_oen <= #1 sda_oen; // keep SDA in same state
|
||||||
|
sda_chk <= #1 1'b0; // don't check SDA output
|
||||||
|
end
|
||||||
|
|
||||||
|
// start
|
||||||
|
start_a:
|
||||||
|
begin
|
||||||
|
c_state <= #1 start_b;
|
||||||
|
scl_oen <= #1 scl_oen; // keep SCL in same state
|
||||||
|
sda_oen <= #1 1'b1; // set SDA high
|
||||||
|
sda_chk <= #1 1'b0; // don't check SDA output
|
||||||
|
end
|
||||||
|
|
||||||
|
start_b:
|
||||||
|
begin
|
||||||
|
c_state <= #1 start_c;
|
||||||
|
scl_oen <= #1 1'b1; // set SCL high
|
||||||
|
sda_oen <= #1 1'b1; // keep SDA high
|
||||||
|
sda_chk <= #1 1'b0; // don't check SDA output
|
||||||
|
end
|
||||||
|
|
||||||
|
start_c:
|
||||||
|
begin
|
||||||
|
c_state <= #1 start_d;
|
||||||
|
scl_oen <= #1 1'b1; // keep SCL high
|
||||||
|
sda_oen <= #1 1'b0; // set SDA low
|
||||||
|
sda_chk <= #1 1'b0; // don't check SDA output
|
||||||
|
end
|
||||||
|
|
||||||
|
start_d:
|
||||||
|
begin
|
||||||
|
c_state <= #1 start_e;
|
||||||
|
scl_oen <= #1 1'b1; // keep SCL high
|
||||||
|
sda_oen <= #1 1'b0; // keep SDA low
|
||||||
|
sda_chk <= #1 1'b0; // don't check SDA output
|
||||||
|
if(clk_cnt == 0) cmd_ack <= #1 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
start_e:
|
||||||
|
begin
|
||||||
|
c_state <= #1 idle;
|
||||||
|
if(clk_cnt == 0) cmd_ack <= #1 1'b0;
|
||||||
|
else cmd_ack <= #1 1'b1;
|
||||||
|
scl_oen <= #1 1'b0; // set SCL low
|
||||||
|
sda_oen <= #1 1'b0; // keep SDA low
|
||||||
|
sda_chk <= #1 1'b0; // don't check SDA output
|
||||||
|
end
|
||||||
|
|
||||||
|
// stop
|
||||||
|
stop_a:
|
||||||
|
begin
|
||||||
|
c_state <= #1 stop_b;
|
||||||
|
scl_oen <= #1 1'b0; // keep SCL low
|
||||||
|
sda_oen <= #1 1'b0; // set SDA low
|
||||||
|
sda_chk <= #1 1'b0; // don't check SDA output
|
||||||
|
end
|
||||||
|
|
||||||
|
stop_b:
|
||||||
|
begin
|
||||||
|
c_state <= #1 stop_c;
|
||||||
|
scl_oen <= #1 1'b1; // set SCL high
|
||||||
|
sda_oen <= #1 1'b0; // keep SDA low
|
||||||
|
sda_chk <= #1 1'b0; // don't check SDA output
|
||||||
|
end
|
||||||
|
|
||||||
|
stop_c:
|
||||||
|
begin
|
||||||
|
c_state <= #1 stop_d;
|
||||||
|
cmd_ack <= #1 1'b1;
|
||||||
|
scl_oen <= #1 1'b1; // keep SCL high
|
||||||
|
sda_oen <= #1 1'b0; // keep SDA low
|
||||||
|
sda_chk <= #1 1'b0; // don't check SDA output
|
||||||
|
end
|
||||||
|
|
||||||
|
stop_d:
|
||||||
|
begin
|
||||||
|
c_state <= #1 idle;
|
||||||
|
cmd_ack <= #1 1'b0;
|
||||||
|
scl_oen <= #1 1'b1; // keep SCL high
|
||||||
|
sda_oen <= #1 1'b1; // set SDA high
|
||||||
|
sda_chk <= #1 1'b0; // don't check SDA output
|
||||||
|
end
|
||||||
|
|
||||||
|
// read
|
||||||
|
rd_a:
|
||||||
|
begin
|
||||||
|
c_state <= #1 rd_b;
|
||||||
|
scl_oen <= #1 1'b0; // keep SCL low
|
||||||
|
sda_oen <= #1 1'b1; // tri-state SDA
|
||||||
|
sda_chk <= #1 1'b0; // don't check SDA output
|
||||||
|
end
|
||||||
|
|
||||||
|
rd_b:
|
||||||
|
begin
|
||||||
|
c_state <= #1 rd_c;
|
||||||
|
scl_oen <= #1 1'b1; // set SCL high
|
||||||
|
sda_oen <= #1 1'b1; // keep SDA tri-stated
|
||||||
|
sda_chk <= #1 1'b0; // don't check SDA output
|
||||||
|
end
|
||||||
|
|
||||||
|
rd_c:
|
||||||
|
begin
|
||||||
|
c_state <= #1 rd_d;
|
||||||
|
scl_oen <= #1 1'b1; // keep SCL high
|
||||||
|
sda_oen <= #1 1'b1; // keep SDA tri-stated
|
||||||
|
sda_chk <= #1 1'b0; // don't check SDA output
|
||||||
|
if (clk_cnt == 0) cmd_ack <= #1 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
rd_d:
|
||||||
|
begin
|
||||||
|
c_state <= #1 idle;
|
||||||
|
if (clk_cnt == 0) cmd_ack <= #1 0;
|
||||||
|
else cmd_ack <= #1 1;
|
||||||
|
scl_oen <= #1 1'b0; // set SCL low
|
||||||
|
sda_oen <= #1 1'b1; // keep SDA tri-stated
|
||||||
|
sda_chk <= #1 1'b0; // don't check SDA output
|
||||||
|
end
|
||||||
|
|
||||||
|
// write
|
||||||
|
wr_a:
|
||||||
|
begin
|
||||||
|
c_state <= #1 wr_b;
|
||||||
|
scl_oen <= #1 1'b0; // keep SCL low
|
||||||
|
sda_oen <= #1 din; // set SDA
|
||||||
|
sda_chk <= #1 1'b0; // don't check SDA output (SCL low)
|
||||||
|
end
|
||||||
|
|
||||||
|
wr_b:
|
||||||
|
begin
|
||||||
|
c_state <= #1 wr_c;
|
||||||
|
scl_oen <= #1 1'b1; // set SCL high
|
||||||
|
sda_oen <= #1 din; // keep SDA
|
||||||
|
sda_chk <= #1 1'b0; // don't check SDA output yet
|
||||||
|
// allow some time for SDA and SCL to settle
|
||||||
|
end
|
||||||
|
|
||||||
|
wr_c:
|
||||||
|
begin
|
||||||
|
c_state <= #1 wr_d;
|
||||||
|
scl_oen <= #1 1'b1; // keep SCL high
|
||||||
|
sda_oen <= #1 din;
|
||||||
|
sda_chk <= #1 1'b1; // check SDA output
|
||||||
|
if (clk_cnt == 0) cmd_ack <= #1 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
wr_d:
|
||||||
|
begin
|
||||||
|
c_state <= #1 idle;
|
||||||
|
if (clk_cnt == 0) cmd_ack <= #1 0;
|
||||||
|
else cmd_ack <= #1 1;
|
||||||
|
scl_oen <= #1 1'b0; // set SCL low
|
||||||
|
sda_oen <= #1 din;
|
||||||
|
sda_chk <= #1 1'b0; // don't check SDA output (SCL low)
|
||||||
|
end
|
||||||
|
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// assign scl and sda output (always gnd)
|
||||||
|
assign scl_o = 1'b0;
|
||||||
|
assign sda_o = 1'b0;
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,386 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// WISHBONE rev.B2 compliant I2C Master byte-controller ////
|
||||||
|
//// ////
|
||||||
|
//// ////
|
||||||
|
//// Author: Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// www.asics.ws ////
|
||||||
|
//// ////
|
||||||
|
//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2001 Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer.////
|
||||||
|
//// ////
|
||||||
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||||
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||||
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||||
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||||
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||||
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||||
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||||
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||||
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||||
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||||
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||||
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||||
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// CVS Log
|
||||||
|
//
|
||||||
|
// $Id: i2c_master_byte_ctrl.v,v 1.8 2009-01-19 20:29:26 rherveille Exp $
|
||||||
|
//
|
||||||
|
// $Date: 2009-01-19 20:29:26 $
|
||||||
|
// $Revision: 1.8 $
|
||||||
|
// $Author: rherveille $
|
||||||
|
// $Locker: $
|
||||||
|
// $State: Exp $
|
||||||
|
//
|
||||||
|
// Change History:
|
||||||
|
// $Log: not supported by cvs2svn $
|
||||||
|
// Revision 1.7 2004/02/18 11:40:46 rherveille
|
||||||
|
// Fixed a potential bug in the statemachine. During a 'stop' 2 cmd_ack signals were generated. Possibly canceling a new start command.
|
||||||
|
//
|
||||||
|
// Revision 1.6 2003/08/09 07:01:33 rherveille
|
||||||
|
// Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
|
||||||
|
// Fixed a potential bug in the byte controller's host-acknowledge generation.
|
||||||
|
//
|
||||||
|
// Revision 1.5 2002/12/26 15:02:32 rherveille
|
||||||
|
// Core is now a Multimaster I2C controller
|
||||||
|
//
|
||||||
|
// Revision 1.4 2002/11/30 22:24:40 rherveille
|
||||||
|
// Cleaned up code
|
||||||
|
//
|
||||||
|
// Revision 1.3 2001/11/05 11:59:25 rherveille
|
||||||
|
// Fixed wb_ack_o generation bug.
|
||||||
|
// Fixed bug in the byte_controller statemachine.
|
||||||
|
// Added headers.
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
// QuickLogic Change History:
|
||||||
|
//
|
||||||
|
// Date: February 12, 2014
|
||||||
|
// Engineer: Anthony Le
|
||||||
|
// Issue: i2c SDA to SCL timing violation
|
||||||
|
// Change:
|
||||||
|
// 1. Generate LD during IDLE to speed up the input data to SR
|
||||||
|
//
|
||||||
|
|
||||||
|
// synopsys translate_off
|
||||||
|
// synopsys translate_on
|
||||||
|
`timescale 1ns / 10ps
|
||||||
|
|
||||||
|
`include "i2c_master_defines.v"
|
||||||
|
|
||||||
|
module i2c_master_byte_ctrl (
|
||||||
|
clk, rst, Reset, ena, clk_cnt, start, stop, read, write, ack_in, din,
|
||||||
|
cmd_ack, ack_out, dout, i2c_busy, i2c_al, scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen, DrivingI2cBusOut,
|
||||||
|
TP1,
|
||||||
|
TP2 );
|
||||||
|
|
||||||
|
//
|
||||||
|
// inputs & outputs
|
||||||
|
//
|
||||||
|
input clk; // master clock
|
||||||
|
input rst; // synchronous active high reset
|
||||||
|
input Reset; // asynchronous active high reset
|
||||||
|
input ena; // core enable signal
|
||||||
|
|
||||||
|
input [15:0] clk_cnt; // 4x SCL
|
||||||
|
|
||||||
|
// control inputs
|
||||||
|
input start;
|
||||||
|
input stop;
|
||||||
|
input read;
|
||||||
|
input write;
|
||||||
|
input ack_in;
|
||||||
|
input [7:0] din;
|
||||||
|
|
||||||
|
// status outputs
|
||||||
|
output cmd_ack;
|
||||||
|
reg cmd_ack;
|
||||||
|
output ack_out;
|
||||||
|
reg ack_out;
|
||||||
|
output i2c_busy;
|
||||||
|
output i2c_al;
|
||||||
|
output [7:0] dout;
|
||||||
|
|
||||||
|
// I2C signals
|
||||||
|
input scl_i;
|
||||||
|
output scl_o;
|
||||||
|
output scl_oen;
|
||||||
|
input sda_i;
|
||||||
|
output sda_o;
|
||||||
|
output sda_oen;
|
||||||
|
|
||||||
|
// control signals
|
||||||
|
output DrivingI2cBusOut;
|
||||||
|
|
||||||
|
// test signals
|
||||||
|
output TP1;
|
||||||
|
output TP2;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Variable declarations
|
||||||
|
//
|
||||||
|
|
||||||
|
// statemachine
|
||||||
|
parameter [5:0] ST_IDLE = 6'b00_0000;
|
||||||
|
parameter [5:0] ST_START = 6'b00_0001;
|
||||||
|
parameter [5:0] ST_READ = 6'b00_0010;
|
||||||
|
parameter [5:0] ST_WRITE = 6'b00_0100;
|
||||||
|
parameter [5:0] ST_ACK = 6'b00_1000;
|
||||||
|
parameter [5:0] ST_STOP = 6'b01_0000;
|
||||||
|
parameter [5:0] ST_DLWR = 6'b10_0000;
|
||||||
|
|
||||||
|
// signals for bit_controller
|
||||||
|
reg [3:0] core_cmd;
|
||||||
|
reg core_txd;
|
||||||
|
wire core_ack, core_rxd;
|
||||||
|
|
||||||
|
// signals for shift register
|
||||||
|
reg [7:0] sr; //8bit shift register
|
||||||
|
reg shift, ld;
|
||||||
|
|
||||||
|
// signals for state machine
|
||||||
|
wire go;
|
||||||
|
reg [2:0] dcnt;
|
||||||
|
wire cnt_done;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Module body
|
||||||
|
//
|
||||||
|
assign DrivingI2cBusOut = (core_cmd != `I2C_CMD_READ);
|
||||||
|
|
||||||
|
// hookup bit_controller
|
||||||
|
i2c_master_bit_ctrl bit_controller (
|
||||||
|
.clk ( clk ),
|
||||||
|
.rst ( rst ),
|
||||||
|
.Reset ( Reset ),
|
||||||
|
.ena ( ena ),
|
||||||
|
.clk_cnt ( clk_cnt ),
|
||||||
|
.cmd ( core_cmd ),
|
||||||
|
.cmd_ack ( core_ack ),
|
||||||
|
.busy ( i2c_busy ),
|
||||||
|
.al ( i2c_al ),
|
||||||
|
.din ( core_txd ),
|
||||||
|
.dout ( core_rxd ),
|
||||||
|
.scl_i ( scl_i ),
|
||||||
|
.scl_o ( scl_o ),
|
||||||
|
.scl_oen ( scl_oen ),
|
||||||
|
.sda_i ( sda_i ),
|
||||||
|
.sda_o ( sda_o ),
|
||||||
|
.sda_oen ( sda_oen ),
|
||||||
|
.TP1 ( TP1 ),
|
||||||
|
.TP2 ( TP2 )
|
||||||
|
);
|
||||||
|
|
||||||
|
// generate go-signal
|
||||||
|
assign go = (read | write | stop) & ~cmd_ack;
|
||||||
|
|
||||||
|
// assign dout output to shift-register
|
||||||
|
assign dout = sr;
|
||||||
|
|
||||||
|
//
|
||||||
|
// state machine
|
||||||
|
//
|
||||||
|
reg [5:0] c_state; // synopsys enum_state
|
||||||
|
|
||||||
|
// generate shift register
|
||||||
|
// always @(posedge clk or posedge Reset)
|
||||||
|
// if (Reset)
|
||||||
|
// sr <= #1 8'h0;
|
||||||
|
// else if (rst)
|
||||||
|
// sr <= #1 8'h0;
|
||||||
|
// else if (ld)
|
||||||
|
// sr <= #1 din;
|
||||||
|
// else if (shift && clk_cnt !=0)
|
||||||
|
// sr <= #1 {sr[6:0], core_rxd};
|
||||||
|
// else if (shift && c_state != ST_WRITE)
|
||||||
|
// sr <= #1 {sr[6:0], core_rxd};
|
||||||
|
|
||||||
|
// generate counter
|
||||||
|
always @(posedge clk or posedge Reset)
|
||||||
|
if (Reset)
|
||||||
|
dcnt <= #1 3'h0;
|
||||||
|
else if (rst)
|
||||||
|
dcnt <= #1 3'h0;
|
||||||
|
else if (ld)
|
||||||
|
dcnt <= #1 3'h7;
|
||||||
|
else if (shift)
|
||||||
|
dcnt <= #1 dcnt - 3'h1;
|
||||||
|
|
||||||
|
assign cnt_done = ~(|dcnt);
|
||||||
|
|
||||||
|
always @(posedge clk or posedge Reset)
|
||||||
|
if (Reset)
|
||||||
|
begin
|
||||||
|
sr <= #1 8'h0;
|
||||||
|
core_cmd <= #1 `I2C_CMD_NOP;
|
||||||
|
core_txd <= #1 1'b0;
|
||||||
|
shift <= #1 1'b0;
|
||||||
|
ld <= #1 1'b0;
|
||||||
|
cmd_ack <= #1 1'b0;
|
||||||
|
c_state <= #1 ST_IDLE;
|
||||||
|
ack_out <= #1 1'b0;
|
||||||
|
end
|
||||||
|
else if (rst | i2c_al)
|
||||||
|
begin
|
||||||
|
sr <= #1 8'h0;
|
||||||
|
core_cmd <= #1 `I2C_CMD_NOP;
|
||||||
|
core_txd <= #1 1'b0;
|
||||||
|
shift <= #1 1'b0;
|
||||||
|
ld <= #1 1'b0;
|
||||||
|
cmd_ack <= #1 1'b0;
|
||||||
|
c_state <= #1 ST_IDLE;
|
||||||
|
ack_out <= #1 1'b0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if (ld)
|
||||||
|
sr <= #1 din;
|
||||||
|
else if (shift && clk_cnt !=0)
|
||||||
|
sr <= #1 {sr[6:0], core_rxd};
|
||||||
|
else if (shift && c_state != ST_WRITE)
|
||||||
|
sr <= #1 {sr[6:0], core_rxd};
|
||||||
|
// initially reset all signals
|
||||||
|
core_txd <= #1 sr[7];
|
||||||
|
shift <= #1 1'b0;
|
||||||
|
ld <= #1 1'b0;
|
||||||
|
cmd_ack <= #1 1'b0;
|
||||||
|
|
||||||
|
case (c_state) // synopsys full_case parallel_case
|
||||||
|
ST_IDLE:
|
||||||
|
if (go)
|
||||||
|
begin
|
||||||
|
if (start)
|
||||||
|
begin
|
||||||
|
c_state <= #1 ST_START;
|
||||||
|
core_cmd <= #1 `I2C_CMD_START;
|
||||||
|
end
|
||||||
|
else if (read)
|
||||||
|
begin
|
||||||
|
c_state <= #1 ST_READ;
|
||||||
|
core_cmd <= #1 `I2C_CMD_READ;
|
||||||
|
end
|
||||||
|
else if (write)
|
||||||
|
begin
|
||||||
|
c_state <= #1 ST_DLWR;
|
||||||
|
core_cmd <= #1 `I2C_CMD_NOP;
|
||||||
|
end
|
||||||
|
else // stop
|
||||||
|
begin
|
||||||
|
c_state <= #1 ST_STOP;
|
||||||
|
core_cmd <= #1 `I2C_CMD_STOP;
|
||||||
|
end
|
||||||
|
|
||||||
|
ld <= #1 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
ST_START:
|
||||||
|
if (core_ack)
|
||||||
|
begin
|
||||||
|
if (read)
|
||||||
|
begin
|
||||||
|
c_state <= #1 ST_READ;
|
||||||
|
core_cmd <= #1 `I2C_CMD_READ;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
c_state <= #1 ST_WRITE;
|
||||||
|
core_cmd <= #1 `I2C_CMD_WRITE;
|
||||||
|
end
|
||||||
|
|
||||||
|
ld <= #1 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
ST_DLWR:
|
||||||
|
begin
|
||||||
|
c_state <= #1 ST_WRITE;
|
||||||
|
core_cmd <= #1 `I2C_CMD_WRITE;
|
||||||
|
end
|
||||||
|
|
||||||
|
ST_WRITE:
|
||||||
|
if (core_ack)
|
||||||
|
if (cnt_done)
|
||||||
|
begin
|
||||||
|
c_state <= #1 ST_ACK;
|
||||||
|
core_cmd <= #1 `I2C_CMD_READ;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
c_state <= #1 ST_WRITE; // stay in same state
|
||||||
|
core_cmd <= #1 `I2C_CMD_WRITE; // write next bit
|
||||||
|
shift <= #1 1'b1;
|
||||||
|
if (clk_cnt == 0) sr <= #1 {sr[6:0], core_rxd};
|
||||||
|
end
|
||||||
|
|
||||||
|
ST_READ:
|
||||||
|
if (core_ack)
|
||||||
|
begin
|
||||||
|
if (cnt_done)
|
||||||
|
begin
|
||||||
|
c_state <= #1 ST_ACK;
|
||||||
|
core_cmd <= #1 `I2C_CMD_WRITE;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
c_state <= #1 ST_READ; // stay in same state
|
||||||
|
core_cmd <= #1 `I2C_CMD_READ; // read next bit
|
||||||
|
end
|
||||||
|
|
||||||
|
shift <= #1 1'b1;
|
||||||
|
//sr <= #1 {sr[6:0], core_rxd};
|
||||||
|
core_txd <= #1 ack_in;
|
||||||
|
end
|
||||||
|
|
||||||
|
ST_ACK:
|
||||||
|
if (core_ack)
|
||||||
|
begin
|
||||||
|
if (stop)
|
||||||
|
begin
|
||||||
|
c_state <= #1 ST_STOP;
|
||||||
|
core_cmd <= #1 `I2C_CMD_STOP;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
c_state <= #1 ST_IDLE;
|
||||||
|
core_cmd <= #1 `I2C_CMD_NOP;
|
||||||
|
|
||||||
|
// generate command acknowledge signal
|
||||||
|
cmd_ack <= #1 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
// assign ack_out output to bit_controller_rxd (contains last received bit)
|
||||||
|
ack_out <= #1 core_rxd;
|
||||||
|
|
||||||
|
core_txd <= #1 1'b1;
|
||||||
|
|
||||||
|
if (clk_cnt == 0) shift <= #1 1;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
core_txd <= #1 ack_in;
|
||||||
|
|
||||||
|
ST_STOP:
|
||||||
|
if (core_ack)
|
||||||
|
begin
|
||||||
|
c_state <= #1 ST_IDLE;
|
||||||
|
core_cmd <= #1 `I2C_CMD_NOP;
|
||||||
|
|
||||||
|
// generate command acknowledge signal
|
||||||
|
cmd_ack <= #1 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
endmodule
|
|
@ -0,0 +1,59 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// WISHBONE rev.B2 compliant I2C Master controller defines ////
|
||||||
|
//// ////
|
||||||
|
//// ////
|
||||||
|
//// Author: Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// www.asics.ws ////
|
||||||
|
//// ////
|
||||||
|
//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2001 Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer.////
|
||||||
|
//// ////
|
||||||
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||||
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||||
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||||
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||||
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||||
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||||
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||||
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||||
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||||
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||||
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||||
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||||
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// CVS Log
|
||||||
|
//
|
||||||
|
// $Id: i2c_master_defines.v,v 1.3 2001-11-05 11:59:25 rherveille Exp $
|
||||||
|
//
|
||||||
|
// $Date: 2001-11-05 11:59:25 $
|
||||||
|
// $Revision: 1.3 $
|
||||||
|
// $Author: rherveille $
|
||||||
|
// $Locker: $
|
||||||
|
// $State: Exp $
|
||||||
|
//
|
||||||
|
// Change History:
|
||||||
|
// $Log: not supported by cvs2svn $
|
||||||
|
|
||||||
|
|
||||||
|
// I2C registers wishbone addresses
|
||||||
|
|
||||||
|
// bitcontroller states
|
||||||
|
`define I2C_CMD_NOP 4'b0000
|
||||||
|
`define I2C_CMD_START 4'b0001
|
||||||
|
`define I2C_CMD_STOP 4'b0010
|
||||||
|
`define I2C_CMD_WRITE 4'b0100
|
||||||
|
`define I2C_CMD_READ 4'b1000
|
|
@ -0,0 +1,323 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// WISHBONE revB.2 compliant I2C Master controller Top-level ////
|
||||||
|
//// ////
|
||||||
|
//// ////
|
||||||
|
//// Author: Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// www.asics.ws ////
|
||||||
|
//// ////
|
||||||
|
//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2001 Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer.////
|
||||||
|
//// ////
|
||||||
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||||
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||||
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||||
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||||
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||||
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||||
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||||
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||||
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||||
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||||
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||||
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||||
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// 1.12 2012-12-17 Tim Saxe
|
||||||
|
// Changed wb_ack_o to be derived from in internal version
|
||||||
|
// wb_ack_i
|
||||||
|
|
||||||
|
// CVS Log
|
||||||
|
//
|
||||||
|
// $Id: i2c_master_top.v,v 1.12 2009-01-19 20:29:26 rherveille Exp $
|
||||||
|
//
|
||||||
|
// $Date: 2009-01-19 20:29:26 $
|
||||||
|
// $Revision: 1.12 $
|
||||||
|
// $Author: rherveille $
|
||||||
|
// $Locker: $
|
||||||
|
// $State: Exp $
|
||||||
|
//
|
||||||
|
// Change History:
|
||||||
|
// Revision 1.11 2005/02/27 09:26:24 rherveille
|
||||||
|
// Fixed register overwrite issue.
|
||||||
|
// Removed full_case pragma, replaced it by a default statement.
|
||||||
|
//
|
||||||
|
// Revision 1.10 2003/09/01 10:34:38 rherveille
|
||||||
|
// Fix a blocking vs. non-blocking error in the wb_dat output mux.
|
||||||
|
//
|
||||||
|
// Revision 1.9 2003/01/09 16:44:45 rherveille
|
||||||
|
// Fixed a bug in the Command Register declaration.
|
||||||
|
//
|
||||||
|
// Revision 1.8 2002/12/26 16:05:12 rherveille
|
||||||
|
// Small code simplifications
|
||||||
|
//
|
||||||
|
// Revision 1.7 2002/12/26 15:02:32 rherveille
|
||||||
|
// Core is now a Multimaster I2C controller
|
||||||
|
//
|
||||||
|
// Revision 1.6 2002/11/30 22:24:40 rherveille
|
||||||
|
// Cleaned up code
|
||||||
|
//
|
||||||
|
// Revision 1.5 2001/11/10 10:52:55 rherveille
|
||||||
|
// Changed PRER reset value from 0x0000 to 0xffff, conform specs.
|
||||||
|
//
|
||||||
|
|
||||||
|
// synopsys translate_off
|
||||||
|
// synopsys translate_on
|
||||||
|
`timescale 1ns / 10ps
|
||||||
|
|
||||||
|
`include "i2c_master_defines.v"
|
||||||
|
|
||||||
|
module i2c_master_top(
|
||||||
|
wb_clk_i, wb_rst_i, arst_i, wb_adr_i, wb_dat_i, wb_dat_o,
|
||||||
|
wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_inta_o,
|
||||||
|
scl_pad_i, scl_pad_o, scl_padoen_o, sda_pad_i, sda_pad_o, sda_padoen_o, tip_o, DrivingI2cBusOut,
|
||||||
|
TP1,
|
||||||
|
TP2);
|
||||||
|
|
||||||
|
// parameters
|
||||||
|
|
||||||
|
//
|
||||||
|
// inputs & outputs
|
||||||
|
//
|
||||||
|
|
||||||
|
// wishbone signals
|
||||||
|
input wb_clk_i; // master clock input
|
||||||
|
input wb_rst_i; // synchronous active high reset
|
||||||
|
input arst_i; // asynchronous reset
|
||||||
|
input [2:0] wb_adr_i; // lower address bits
|
||||||
|
input [7:0] wb_dat_i; // databus input
|
||||||
|
output [7:0] wb_dat_o; // databus output
|
||||||
|
input wb_we_i; // write enable input
|
||||||
|
input wb_stb_i; // stobe/core select signal
|
||||||
|
input wb_cyc_i; // valid bus cycle input
|
||||||
|
inout wb_ack_o; // bus cycle acknowledge output
|
||||||
|
output wb_inta_o; // interrupt request signal output
|
||||||
|
|
||||||
|
// control signals
|
||||||
|
output tip_o; // transfer in progress
|
||||||
|
output DrivingI2cBusOut; // master is driving i2c bus
|
||||||
|
|
||||||
|
reg [7:0] wb_dat_o;
|
||||||
|
reg wb_ack_i;
|
||||||
|
wire wb_ack_o = wb_ack_i;
|
||||||
|
reg wb_inta_o;
|
||||||
|
|
||||||
|
// I2C signals
|
||||||
|
// i2c clock line
|
||||||
|
input scl_pad_i; // SCL-line input
|
||||||
|
output scl_pad_o; // SCL-line output (always 1'b0)
|
||||||
|
output scl_padoen_o; // SCL-line output enable (active low)
|
||||||
|
|
||||||
|
// i2c data line
|
||||||
|
input sda_pad_i; // SDA-line input
|
||||||
|
output sda_pad_o; // SDA-line output (always 1'b0)
|
||||||
|
output sda_padoen_o; // SDA-line output enable (active low)
|
||||||
|
|
||||||
|
// test signal
|
||||||
|
output TP1;
|
||||||
|
output TP2;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// variable declarations
|
||||||
|
//
|
||||||
|
|
||||||
|
// registers
|
||||||
|
reg [15:0] prer; // clock prescale register
|
||||||
|
reg [ 7:0] ctr; // control register
|
||||||
|
reg [ 7:0] txr; // transmit register
|
||||||
|
wire [ 7:0] rxr; // receive register
|
||||||
|
reg [ 7:0] cr; // command register
|
||||||
|
wire [ 7:0] sr; // status register
|
||||||
|
|
||||||
|
// done signal: command completed, clear command register
|
||||||
|
wire done;
|
||||||
|
|
||||||
|
// core enable signal
|
||||||
|
wire core_en;
|
||||||
|
wire ien;
|
||||||
|
|
||||||
|
// status register signals
|
||||||
|
wire irxack;
|
||||||
|
reg rxack; // received aknowledge from slave
|
||||||
|
reg tip; // transfer in progress
|
||||||
|
reg irq_flag; // interrupt pending flag
|
||||||
|
wire i2c_busy; // bus busy (start signal detected)
|
||||||
|
wire i2c_al; // i2c bus arbitration lost
|
||||||
|
reg al; // status register arbitration lost bit
|
||||||
|
|
||||||
|
//
|
||||||
|
// module body
|
||||||
|
//
|
||||||
|
|
||||||
|
assign tip_o = tip;
|
||||||
|
|
||||||
|
// generate internal reset
|
||||||
|
wire rst_i = arst_i;
|
||||||
|
|
||||||
|
// generate wishbone signals
|
||||||
|
wire wb_wacc = wb_we_i & wb_ack_i;
|
||||||
|
|
||||||
|
// generate acknowledge output signal
|
||||||
|
always @(posedge wb_clk_i)
|
||||||
|
wb_ack_i <= #1 wb_cyc_i & wb_stb_i & ~wb_ack_i; // because timing is always honored
|
||||||
|
|
||||||
|
// assign DAT_O
|
||||||
|
always @(posedge wb_clk_i)
|
||||||
|
begin
|
||||||
|
case (wb_adr_i) // synopsys parallel_case
|
||||||
|
3'b000: wb_dat_o <= #1 prer[ 7:0];
|
||||||
|
3'b001: wb_dat_o <= #1 prer[15:8];
|
||||||
|
3'b010: wb_dat_o <= #1 ctr;
|
||||||
|
3'b011: wb_dat_o <= #1 rxr; // write is transmit register (txr)
|
||||||
|
3'b100: wb_dat_o <= #1 sr; // write is command register (cr)
|
||||||
|
3'b101: wb_dat_o <= #1 txr;
|
||||||
|
3'b110: wb_dat_o <= #1 cr;
|
||||||
|
3'b111: wb_dat_o <= #1 0; // reserved
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
// generate registers
|
||||||
|
always @(posedge wb_clk_i or posedge rst_i)
|
||||||
|
if (rst_i)
|
||||||
|
begin
|
||||||
|
// prer <= #1 16'hffff;
|
||||||
|
// ctr <= #1 8'h0;
|
||||||
|
prer <= #1 16'h0000;
|
||||||
|
ctr <= #1 8'h80;
|
||||||
|
txr <= #1 8'h0;
|
||||||
|
end
|
||||||
|
else if (wb_rst_i)
|
||||||
|
begin
|
||||||
|
// prer <= #1 16'hffff;
|
||||||
|
// ctr <= #1 8'h0;
|
||||||
|
prer <= #1 16'h0000;
|
||||||
|
ctr <= #1 8'h80;
|
||||||
|
txr <= #1 8'h0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if (wb_wacc)
|
||||||
|
case (wb_adr_i) // synopsys parallel_case
|
||||||
|
// 3'b000 : prer [ 7:0] <= #1 wb_dat_i;
|
||||||
|
// 3'b001 : prer [15:8] <= #1 wb_dat_i;
|
||||||
|
// 3'b010 : ctr <= #1 wb_dat_i;
|
||||||
|
3'b011 : txr <= #1 wb_dat_i;
|
||||||
|
default: ;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
// generate command register (special case)
|
||||||
|
always @(posedge wb_clk_i or posedge rst_i)
|
||||||
|
if (rst_i)
|
||||||
|
cr <= #1 8'h0;
|
||||||
|
else if (wb_rst_i)
|
||||||
|
cr <= #1 8'h0;
|
||||||
|
else if (wb_wacc)
|
||||||
|
begin
|
||||||
|
if (core_en & (wb_adr_i == 3'b100) )
|
||||||
|
cr <= #1 wb_dat_i;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if (done | i2c_al)
|
||||||
|
cr[7:4] <= #1 4'h0; // clear command bits when done
|
||||||
|
// or when aribitration lost
|
||||||
|
cr[2:1] <= #1 2'b0; // reserved bits
|
||||||
|
cr[0] <= #1 1'b0; // clear IRQ_ACK bit
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// decode command register
|
||||||
|
wire sta = cr[7];
|
||||||
|
wire sto = cr[6];
|
||||||
|
wire rd = cr[5];
|
||||||
|
wire wr = cr[4];
|
||||||
|
wire ack = cr[3];
|
||||||
|
wire iack = cr[0];
|
||||||
|
|
||||||
|
// decode control register
|
||||||
|
assign core_en = ctr[7];
|
||||||
|
assign ien = ctr[6];
|
||||||
|
|
||||||
|
// hookup byte controller block
|
||||||
|
i2c_master_byte_ctrl byte_controller (
|
||||||
|
.clk ( wb_clk_i ),
|
||||||
|
.rst ( wb_rst_i ),
|
||||||
|
.Reset ( rst_i ),
|
||||||
|
.ena ( core_en ),
|
||||||
|
.clk_cnt ( prer ),
|
||||||
|
.start ( sta ),
|
||||||
|
.stop ( sto ),
|
||||||
|
.read ( rd ),
|
||||||
|
.write ( wr ),
|
||||||
|
.ack_in ( ack ),
|
||||||
|
.din ( txr ),
|
||||||
|
.cmd_ack ( done ),
|
||||||
|
.ack_out ( irxack ),
|
||||||
|
.dout ( rxr ),
|
||||||
|
.i2c_busy ( i2c_busy ),
|
||||||
|
.i2c_al ( i2c_al ),
|
||||||
|
.scl_i ( scl_pad_i ),
|
||||||
|
.scl_o ( scl_pad_o ),
|
||||||
|
.scl_oen ( scl_padoen_o ),
|
||||||
|
.sda_i ( sda_pad_i ),
|
||||||
|
.sda_o ( sda_pad_o ),
|
||||||
|
.sda_oen ( sda_padoen_o ),
|
||||||
|
.DrivingI2cBusOut (DrivingI2cBusOut),
|
||||||
|
.TP1 ( TP1 ),
|
||||||
|
.TP2 ( TP2 )
|
||||||
|
);
|
||||||
|
|
||||||
|
// status register block + interrupt request signal
|
||||||
|
always @(posedge wb_clk_i or posedge rst_i)
|
||||||
|
if (rst_i)
|
||||||
|
begin
|
||||||
|
al <= #1 1'b0;
|
||||||
|
rxack <= #1 1'b0;
|
||||||
|
tip <= #1 1'b0;
|
||||||
|
irq_flag <= #1 1'b0;
|
||||||
|
end
|
||||||
|
else if (wb_rst_i)
|
||||||
|
begin
|
||||||
|
al <= #1 1'b0;
|
||||||
|
rxack <= #1 1'b0;
|
||||||
|
tip <= #1 1'b0;
|
||||||
|
irq_flag <= #1 1'b0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
al <= #1 i2c_al | (al & ~sta);
|
||||||
|
rxack <= #1 irxack;
|
||||||
|
tip <= #1 (rd | wr);
|
||||||
|
irq_flag <= #1 (done | i2c_al | irq_flag) & ~iack; // interrupt request flag is always generated
|
||||||
|
end
|
||||||
|
|
||||||
|
// generate interrupt request signals
|
||||||
|
always @(posedge wb_clk_i or posedge rst_i)
|
||||||
|
if (rst_i)
|
||||||
|
wb_inta_o <= #1 1'b0;
|
||||||
|
else if (wb_rst_i)
|
||||||
|
wb_inta_o <= #1 1'b0;
|
||||||
|
else
|
||||||
|
wb_inta_o <= #1 irq_flag && ien; // interrupt signal is only generated when IEN (interrupt enable bit is set)
|
||||||
|
|
||||||
|
// assign status register bits
|
||||||
|
assign sr[7] = rxack;
|
||||||
|
assign sr[6] = i2c_busy;
|
||||||
|
assign sr[5] = al;
|
||||||
|
assign sr[4:2] = 3'h0; // reserved
|
||||||
|
assign sr[1] = tip;
|
||||||
|
assign sr[0] = irq_flag;
|
||||||
|
|
||||||
|
endmodule
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,238 @@
|
||||||
|
module iir (clk, reset, start, din, params, dout, ready,iir_start,iir_done);
|
||||||
|
input clk, reset, start;
|
||||||
|
input [7:0] din;
|
||||||
|
input [15:0] params;
|
||||||
|
output [7:0] dout;
|
||||||
|
reg [7:0] dout;
|
||||||
|
output ready;
|
||||||
|
reg ready;
|
||||||
|
reg temp_ready;
|
||||||
|
reg [6:0] finite_counter;
|
||||||
|
wire count0;
|
||||||
|
input iir_start;
|
||||||
|
output iir_done;
|
||||||
|
wire iir_done;
|
||||||
|
reg del_count0;
|
||||||
|
|
||||||
|
reg [15:0] a1, a2, b0, b1, b2, yk1, yk2;
|
||||||
|
reg [7:0] uk, uk1, uk2 ;
|
||||||
|
reg [28:0] ysum ;
|
||||||
|
reg [26:0] yk ;
|
||||||
|
reg [22:0] utmp;
|
||||||
|
reg [3:0] wait_counter ;
|
||||||
|
// temporary variable
|
||||||
|
wire [31:0] yo1, yo2;
|
||||||
|
//wire [23:0] b0t, b1t, b2t;
|
||||||
|
wire [22:0] b0t, b1t, b2t;
|
||||||
|
wire [22:0] b0tpaj, b1tpaj, b2tpaj;
|
||||||
|
|
||||||
|
reg [3:0] obf_state, obf_next_state ;
|
||||||
|
|
||||||
|
reg [7:0] temp_uk, temp_uk1, temp_uk2 ;
|
||||||
|
reg [15:0] temp_a1, temp_a2, temp_b0, temp_b1, temp_b2, temp_yk1, temp_yk2;
|
||||||
|
reg [28:0] temp_ysum ;
|
||||||
|
reg [26:0] temp_yk ;
|
||||||
|
reg [22:0] temp_utmp;
|
||||||
|
reg [7:0] temp_dout;
|
||||||
|
reg [3:0] temp_wait_counter ;
|
||||||
|
|
||||||
|
parameter
|
||||||
|
idle = 4'b0001 ,
|
||||||
|
load_a2 = 4'b0010 ,
|
||||||
|
load_b0 = 4'b0011 ,
|
||||||
|
load_b1 = 4'b0100 ,
|
||||||
|
load_b2 = 4'b0101 ,
|
||||||
|
wait4_start = 4'b0110 ,
|
||||||
|
latch_din = 4'b0111 ,
|
||||||
|
compute_a = 4'b1000 ,
|
||||||
|
compute_b = 4'b1001 ,
|
||||||
|
compute_yk = 4'b1010 ,
|
||||||
|
wait4_count = 4'b1011 ,
|
||||||
|
latch_dout = 4'b1100 ;
|
||||||
|
|
||||||
|
always @(obf_state or start or din or wait_counter or iir_start or count0)
|
||||||
|
begin
|
||||||
|
case (obf_state )
|
||||||
|
idle :
|
||||||
|
begin
|
||||||
|
if (iir_start)
|
||||||
|
obf_next_state = load_a2 ;
|
||||||
|
else
|
||||||
|
obf_next_state = idle;
|
||||||
|
temp_a1 = params ;
|
||||||
|
end
|
||||||
|
load_a2 :
|
||||||
|
begin
|
||||||
|
obf_next_state = load_b0 ;
|
||||||
|
temp_a2 = params ;
|
||||||
|
end
|
||||||
|
load_b0 :
|
||||||
|
begin
|
||||||
|
obf_next_state = load_b1 ;
|
||||||
|
temp_b0 = params ;
|
||||||
|
end
|
||||||
|
load_b1 :
|
||||||
|
begin
|
||||||
|
obf_next_state = load_b2 ;
|
||||||
|
temp_b1 = params ;
|
||||||
|
end
|
||||||
|
load_b2 :
|
||||||
|
begin
|
||||||
|
obf_next_state = wait4_start ;
|
||||||
|
temp_b2 = params ;
|
||||||
|
end
|
||||||
|
wait4_start :
|
||||||
|
begin
|
||||||
|
if (start)
|
||||||
|
begin
|
||||||
|
obf_next_state = latch_din ;
|
||||||
|
temp_uk = din ;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
obf_next_state = wait4_start ;
|
||||||
|
temp_uk = uk;
|
||||||
|
end
|
||||||
|
temp_ready = wait4_start;
|
||||||
|
end
|
||||||
|
latch_din :
|
||||||
|
begin
|
||||||
|
obf_next_state = compute_a ;
|
||||||
|
end
|
||||||
|
compute_a :
|
||||||
|
begin
|
||||||
|
obf_next_state = compute_b ;
|
||||||
|
|
||||||
|
temp_ysum = yo1[31:3] + yo2[31:3];
|
||||||
|
end
|
||||||
|
compute_b :
|
||||||
|
begin
|
||||||
|
obf_next_state = compute_yk ;
|
||||||
|
|
||||||
|
// temp_utmp = b0t[23:0] + b1t[23:0] + b2t[23:0];
|
||||||
|
temp_utmp = b0t + b1t + b2t;
|
||||||
|
end
|
||||||
|
compute_yk :
|
||||||
|
begin
|
||||||
|
obf_next_state = wait4_count ;
|
||||||
|
temp_uk1 = uk ;
|
||||||
|
temp_uk2 = uk1 ;
|
||||||
|
temp_yk = ysum[26:0] + {utmp[22], utmp[22], utmp[22], utmp[22], utmp};
|
||||||
|
temp_wait_counter = 4 ;
|
||||||
|
end
|
||||||
|
|
||||||
|
wait4_count :
|
||||||
|
begin
|
||||||
|
if (wait_counter==0 )
|
||||||
|
begin
|
||||||
|
obf_next_state = latch_dout ;
|
||||||
|
|
||||||
|
temp_dout = yk[26:19];
|
||||||
|
temp_yk1 = yk[26:11] ;
|
||||||
|
temp_yk2 = yk1 ;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
obf_next_state = wait4_count ;
|
||||||
|
temp_dout = dout;
|
||||||
|
temp_yk1 = yk1;
|
||||||
|
//temp_yk2 = yk2;
|
||||||
|
end
|
||||||
|
|
||||||
|
temp_wait_counter = wait_counter - 1;
|
||||||
|
end
|
||||||
|
latch_dout :
|
||||||
|
if (count0)
|
||||||
|
obf_next_state = idle;
|
||||||
|
else
|
||||||
|
obf_next_state = wait4_start ;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//assign yo1 = mul_tc_16_16(yk1, a1, clk);
|
||||||
|
assign yo1 = yk1 * a1;
|
||||||
|
//assign yo2 = mul_tc_16_16(yk2, a2, clk);
|
||||||
|
assign yo2 = yk2*a2;
|
||||||
|
//assign b0t = mul_tc_8_16(uk, b0, clk);
|
||||||
|
//assign b1t = mul_tc_8_16(uk1, b1, clk);
|
||||||
|
//assign b2t = mul_tc_8_16(uk2, b2, clk);
|
||||||
|
assign b0t = uk*b0;
|
||||||
|
assign b1t = uk1*b1;
|
||||||
|
assign b2t = uk2*b2;
|
||||||
|
// paj added to solve unused high order bit
|
||||||
|
assign b0tpaj = b0t;
|
||||||
|
assign b1tpaj = b1t;
|
||||||
|
assign b2tpaj = b2t;
|
||||||
|
|
||||||
|
// A COEFFICENTS
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset ) begin
|
||||||
|
uk <= 0 ;
|
||||||
|
uk1 <= 0 ;
|
||||||
|
uk2 <= 0 ;
|
||||||
|
yk1 <= 0 ;
|
||||||
|
yk2 <= 0 ;
|
||||||
|
yk <= 0 ;
|
||||||
|
ysum <= 0 ;
|
||||||
|
utmp <= 0 ;
|
||||||
|
a1 <= 0 ;
|
||||||
|
a2 <= 0 ;
|
||||||
|
b0 <= 0 ;
|
||||||
|
b1 <= 0 ;
|
||||||
|
b2 <= 0 ;
|
||||||
|
dout <= 0 ;
|
||||||
|
obf_state <= idle ;
|
||||||
|
ready <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
obf_state <= obf_next_state ;
|
||||||
|
uk1 <= temp_uk1;
|
||||||
|
uk2 <= temp_uk2;
|
||||||
|
yk <= temp_yk;
|
||||||
|
uk <= temp_uk ;
|
||||||
|
a1 <= temp_a1 ;
|
||||||
|
a2 <= temp_a2 ;
|
||||||
|
b0 <= temp_b0 ;
|
||||||
|
b1 <= temp_b1 ;
|
||||||
|
b2 <= temp_b2 ;
|
||||||
|
ysum <= temp_ysum;
|
||||||
|
utmp <= temp_utmp;
|
||||||
|
dout <= temp_dout;
|
||||||
|
yk1 <= temp_yk1;
|
||||||
|
yk2 <= temp_yk2;
|
||||||
|
ready <= temp_ready;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// wait counter, count 4 clock after sum is calculated, to
|
||||||
|
// time outputs are ready, and filter is ready to accept next
|
||||||
|
// input
|
||||||
|
always @(posedge clk or posedge reset ) begin
|
||||||
|
if (reset )
|
||||||
|
wait_counter <= 0 ;
|
||||||
|
else begin
|
||||||
|
wait_counter <= temp_wait_counter ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (reset)
|
||||||
|
finite_counter<=100;
|
||||||
|
else
|
||||||
|
if (iir_start)
|
||||||
|
finite_counter<=finite_counter -1;
|
||||||
|
else
|
||||||
|
finite_counter<=finite_counter;
|
||||||
|
end
|
||||||
|
|
||||||
|
assign count0=finite_counter==7'b0;
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
del_count0 <= count0;
|
||||||
|
end
|
||||||
|
|
||||||
|
assign iir_done = (count0 && ~del_count0);
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,22 @@
|
||||||
|
module io_reg(clk, in, out);
|
||||||
|
|
||||||
|
input clk;
|
||||||
|
input in;
|
||||||
|
output out;
|
||||||
|
reg out;
|
||||||
|
|
||||||
|
//reg temp;
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
out <= in;
|
||||||
|
end
|
||||||
|
|
||||||
|
/*always @(posedge clk)
|
||||||
|
begin
|
||||||
|
out <= temp ;
|
||||||
|
end*/
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
module io_reg_tb;
|
||||||
|
|
||||||
|
reg clk_gen, in_gen;
|
||||||
|
wire out;
|
||||||
|
|
||||||
|
io_reg inst(.clk(clk_gen), .in(in_gen), .out(out));
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
#0 in_gen = 1'b1; clk_gen = 1'b0;
|
||||||
|
#100 in_gen = 1'b0;
|
||||||
|
end
|
||||||
|
|
||||||
|
always begin
|
||||||
|
#10 clk_gen = ~clk_gen;
|
||||||
|
end
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
#5000 $stop;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,106 @@
|
||||||
|
module demux_1x512 (in,sel,out);
|
||||||
|
input in;
|
||||||
|
input [8:0] sel;
|
||||||
|
output [511:0] out;
|
||||||
|
wire [1:0] out_w;
|
||||||
|
|
||||||
|
demux_1x2 d512_0(.in(in),.sel(sel[8]),.out(out_w[1:0]));
|
||||||
|
demux_1x256 d512_1(.in(out_w[0]),.sel(sel[7:0]),.out(out[255:0]));
|
||||||
|
demux_1x256 d512_2(.in(out_w[1]),.sel(sel[7:0]),.out(out[511:256]));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module demux_1x256 (in,sel,out);
|
||||||
|
input in;
|
||||||
|
input [7:0] sel;
|
||||||
|
output [255:0] out;
|
||||||
|
wire [1:0] out_w;
|
||||||
|
|
||||||
|
demux_1x2 d256_0(.in(in),.sel(sel[7]),.out(out_w[1:0]));
|
||||||
|
demux_1x128 d256_1(.in(out_w[0]),.sel(sel[6:0]),.out(out[127:0]));
|
||||||
|
demux_1x128 d256_2(.in(out_w[1]),.sel(sel[6:0]),.out(out[255:128]));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module demux_1x128 (in,sel,out);
|
||||||
|
input in;
|
||||||
|
input [6:0] sel;
|
||||||
|
output [127:0] out;
|
||||||
|
wire [1:0] out_w;
|
||||||
|
|
||||||
|
demux_1x2 d128_0(.in(in),.sel(sel[6]),.out(out_w[1:0]));
|
||||||
|
demux_1x64 d128_1(.in(out_w[0]),.sel(sel[5:0]),.out(out[63:0]));
|
||||||
|
demux_1x64 d128_2(.in(out_w[1]),.sel(sel[5:0]),.out(out[127:64]));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module demux_1x64 (in,sel,out);
|
||||||
|
input in;
|
||||||
|
input [5:0] sel;
|
||||||
|
output [63:0] out;
|
||||||
|
wire [1:0] out_w;
|
||||||
|
|
||||||
|
demux_1x2 d64_0(.in(in),.sel(sel[5]),.out(out_w[1:0]));
|
||||||
|
demux_1x32 d64_1(.in(out_w[0]),.sel(sel[4:0]),.out(out[31:0]));
|
||||||
|
demux_1x32 d64_2(.in(out_w[1]),.sel(sel[4:0]),.out(out[63:32]));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module demux_1x32 (in,sel,out);
|
||||||
|
input in;
|
||||||
|
input [4:0] sel;
|
||||||
|
output [31:0] out;
|
||||||
|
wire [1:0] out_w;
|
||||||
|
|
||||||
|
demux_1x2 d32_0(.in(in),.sel(sel[4]),.out(out_w[1:0]));
|
||||||
|
demux_1x16 d32_1(.in(out_w[0]),.sel(sel[3:0]),.out(out[15:0]));
|
||||||
|
demux_1x16 d32_2(.in(out_w[1]),.sel(sel[3:0]),.out(out[31:16]));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
module demux_1x16 (in,sel,out);
|
||||||
|
input in;
|
||||||
|
input [3:0] sel;
|
||||||
|
output [15:0] out;
|
||||||
|
wire [1:0] out_w;
|
||||||
|
|
||||||
|
demux_1x2 d16_0(.in(in),.sel(sel[3]),.out(out_w[1:0]));
|
||||||
|
demux_1x8 d16_1(.in(out_w[0]),.sel(sel[2:0]),.out(out[7:0]));
|
||||||
|
demux_1x8 d16_2(.in(out_w[1]),.sel(sel[2:0]),.out(out[15:8]));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module demux_1x8 (in,sel,out);
|
||||||
|
input in;
|
||||||
|
input [2:0] sel;
|
||||||
|
output [7:0] out;
|
||||||
|
wire [1:0] out_w;
|
||||||
|
|
||||||
|
demux_1x2 d8_0(.in(in),.sel(sel[2]),.out(out_w[1:0]));
|
||||||
|
demux_1x4 d8_1(.in(out_w[0]),.sel(sel[1:0]),.out(out[3:0]));
|
||||||
|
demux_1x4 d8_2(.in(out_w[1]),.sel(sel[1:0]),.out(out[7:4]));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module demux_1x4 (in,sel,out);
|
||||||
|
input in;
|
||||||
|
input [1:0] sel;
|
||||||
|
output [3:0] out;
|
||||||
|
wire [1:0]out_w;
|
||||||
|
|
||||||
|
demux_1x2 d4_0(.in(in),.sel(sel[1]),.out(out_w));
|
||||||
|
demux_1x2 d4_1(.in(out_w[0]),.sel(sel[0]),.out(out[1:0]));
|
||||||
|
demux_1x2 d4_2(.in(out_w[1]),.sel(sel[0]),.out(out[3:2]));
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module demux_1x2 (in,sel,out);
|
||||||
|
input in,sel;
|
||||||
|
output [1:0] out;
|
||||||
|
|
||||||
|
assign out[0] = (sel==0) ? in :0;
|
||||||
|
assign out[1] = (sel==1) ? in :0;
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,11 @@
|
||||||
|
module io_tc1 (mux_in, demux_out,mux_sel, demux_sel);
|
||||||
|
input [0:511] mux_in;
|
||||||
|
input [8:0]mux_sel;
|
||||||
|
input [8:0]demux_sel;
|
||||||
|
output [511:0]demux_out;
|
||||||
|
|
||||||
|
mux_512x1 mux0 (.in(mux_in),.sel(mux_sel),.out(mux_out));
|
||||||
|
demux_1x512 demux0 (.in(mux_out),.sel(demux_sel),.out(demux_out));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
module mux_512x1 (in,sel,out);
|
||||||
|
input [511:0] in;
|
||||||
|
input [8:0]sel;
|
||||||
|
output out;
|
||||||
|
wire out0_w, out1_w;
|
||||||
|
|
||||||
|
mux_256x1 m512_0(.in(in[255:0]),.sel(sel[7:0]),.out(out0_w));
|
||||||
|
mux_256x1 m512_1(.in(in[511:256]),.sel(sel[7:0]),.out(out1_w));
|
||||||
|
mux_2x1 m512_2(.a(out0_w),.b(out1_w),.sel(sel[8]),.out(out));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module mux_256x1 (in,sel,out);
|
||||||
|
input [255:0] in;
|
||||||
|
input [7:0]sel;
|
||||||
|
output out;
|
||||||
|
wire out0_w, out1_w;
|
||||||
|
|
||||||
|
mux_128x1 m256_0(.in(in[127:0]),.sel(sel[6:0]),.out(out0_w));
|
||||||
|
mux_128x1 m256_1(.in(in[255:128]),.sel(sel[6:0]),.out(out1_w));
|
||||||
|
mux_2x1 m256_2(.a(out0_w),.b(out1_w),.sel(sel[7]),.out(out));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module mux_128x1 (in,sel,out);
|
||||||
|
input [127:0] in;
|
||||||
|
input [6:0]sel;
|
||||||
|
output out;
|
||||||
|
wire out0_w, out1_w;
|
||||||
|
|
||||||
|
mux_64x1 m128_0(.in(in[63:0]),.sel(sel[5:0]),.out(out0_w));
|
||||||
|
mux_64x1 m128_1(.in(in[127:64]),.sel(sel[5:0]),.out(out1_w));
|
||||||
|
mux_2x1 m128_2(.a(out0_w),.b(out1_w),.sel(sel[6]),.out(out));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module mux_64x1 (in,sel,out);
|
||||||
|
input [63:0] in;
|
||||||
|
input [5:0]sel;
|
||||||
|
output out;
|
||||||
|
wire out0_w, out1_w;
|
||||||
|
|
||||||
|
mux_32x1 m64_0(.in(in[31:0]),.sel(sel[4:0]),.out(out0_w));
|
||||||
|
mux_32x1 m64_1(.in(in[63:32]),.sel(sel[4:0]),.out(out1_w));
|
||||||
|
mux_2x1 m64_2(.a(out0_w),.b(out1_w),.sel(sel[5]),.out(out));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module mux_32x1 (in,sel,out);
|
||||||
|
input [31:0] in;
|
||||||
|
input [4:0]sel;
|
||||||
|
output out;
|
||||||
|
wire out0_w, out1_w;
|
||||||
|
|
||||||
|
mux_16x1 m32_0(.in(in[15:0]),.sel(sel[3:0]),.out(out0_w));
|
||||||
|
mux_16x1 m32_1(.in(in[31:16]),.sel(sel[3:0]),.out(out1_w));
|
||||||
|
mux_2x1 m32_2(.a(out0_w),.b(out1_w),.sel(sel[4]),.out(out));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module mux_16x1 (in,sel,out);
|
||||||
|
input [15:0] in;
|
||||||
|
input [3:0]sel;
|
||||||
|
output out;
|
||||||
|
wire out0_w, out1_w;
|
||||||
|
|
||||||
|
mux_8x1 m16_0(.in(in[7:0]),.sel(sel[2:0]),.out(out0_w));
|
||||||
|
mux_8x1 m16_1(.in(in[15:8]),.sel(sel[2:0]),.out(out1_w));
|
||||||
|
mux_2x1 m16_2(.a(out0_w),.b(out1_w),.sel(sel[3]),.out(out));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module mux_8x1 (in,sel,out);
|
||||||
|
input [7:0] in;
|
||||||
|
input [2:0]sel;
|
||||||
|
output out;
|
||||||
|
wire out0_w, out1_w;
|
||||||
|
|
||||||
|
mux_4x1 m8_0(.in(in[3:0]),.sel(sel[1:0]),.out(out0_w));
|
||||||
|
mux_4x1 m8_1(.in(in[7:4]),.sel(sel[1:0]),.out(out1_w));
|
||||||
|
mux_2x1 m8_2(.a(out0_w),.b(out1_w),.sel(sel[2]),.out(out));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module mux_4x1 (in,sel,out);
|
||||||
|
input [3:0] in;
|
||||||
|
input [1:0]sel;
|
||||||
|
output out;
|
||||||
|
wire out0_w, out1_w;
|
||||||
|
|
||||||
|
mux_2x1 m4_0(.a(in[0]),.b(in[1]),.sel(sel[0]),.out(out0_w));
|
||||||
|
mux_2x1 m4_1(.a(in[2]),.b(in[3]),.sel(sel[0]),.out(out1_w));
|
||||||
|
mux_2x1 m4_2(.a(out0_w),.b(out1_w),.sel(sel[1]),.out(out));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module mux_2x1 (a,b,sel,out);
|
||||||
|
input a,b;
|
||||||
|
input sel;
|
||||||
|
output out;
|
||||||
|
|
||||||
|
assign out = sel ? b : a;
|
||||||
|
|
||||||
|
endmodule
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,157 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Non-restoring signed by unsigned divider ////
|
||||||
|
//// Uses the non-restoring unsigned by unsigned divider ////
|
||||||
|
//// ////
|
||||||
|
//// Author: Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// www.asics.ws ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2002 Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer.////
|
||||||
|
//// ////
|
||||||
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||||
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||||
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||||
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||||
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||||
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||||
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||||
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||||
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||||
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||||
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||||
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||||
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// CVS Log
|
||||||
|
//
|
||||||
|
// $Id: div_su.v,v 1.3 2002-10-31 12:52:54 rherveille Exp $
|
||||||
|
//
|
||||||
|
// $Date: 2002-10-31 12:52:54 $
|
||||||
|
// $Revision: 1.3 $
|
||||||
|
// $Author: rherveille $
|
||||||
|
// $Locker: $
|
||||||
|
// $State: Exp $
|
||||||
|
//
|
||||||
|
// Change History:
|
||||||
|
// $Log: not supported by cvs2svn $
|
||||||
|
// Revision 1.2 2002/10/23 09:07:03 rherveille
|
||||||
|
// Improved many files.
|
||||||
|
// Fixed some bugs in Run-Length-Encoder.
|
||||||
|
// Removed dependency on ud_cnt and ro_cnt.
|
||||||
|
// Started (Motion)JPEG hardware encoder project.
|
||||||
|
//
|
||||||
|
|
||||||
|
//synopsys translate_off
|
||||||
|
`include "timescale.v"
|
||||||
|
//synopsys translate_on
|
||||||
|
|
||||||
|
module div_su(clk, ena, z, d, q, s, div0, ovf);
|
||||||
|
|
||||||
|
//
|
||||||
|
// parameters
|
||||||
|
//
|
||||||
|
parameter z_width = 16;
|
||||||
|
parameter d_width = z_width /2;
|
||||||
|
|
||||||
|
//
|
||||||
|
// inputs & outputs
|
||||||
|
//
|
||||||
|
input clk; // system clock
|
||||||
|
input ena; // clock enable
|
||||||
|
|
||||||
|
input [z_width-1:0] z; // divident
|
||||||
|
input [d_width-1:0] d; // divisor
|
||||||
|
output [d_width :0] q; // quotient
|
||||||
|
output [d_width-1:0] s; // remainder
|
||||||
|
output div0;
|
||||||
|
output ovf;
|
||||||
|
|
||||||
|
reg [d_width :0] q;
|
||||||
|
reg [d_width-1:0] s;
|
||||||
|
reg div0;
|
||||||
|
reg ovf;
|
||||||
|
|
||||||
|
//
|
||||||
|
// variables
|
||||||
|
//
|
||||||
|
reg [z_width -1:0] iz;
|
||||||
|
reg [d_width -1:0] id;
|
||||||
|
reg [d_width +1:0] spipe;
|
||||||
|
|
||||||
|
wire [d_width -1:0] iq, is;
|
||||||
|
wire idiv0, iovf;
|
||||||
|
|
||||||
|
//
|
||||||
|
// module body
|
||||||
|
//
|
||||||
|
|
||||||
|
// delay d
|
||||||
|
always @(posedge clk)
|
||||||
|
if (ena)
|
||||||
|
id <= #1 d;
|
||||||
|
|
||||||
|
// check z, take abs value
|
||||||
|
always @(posedge clk)
|
||||||
|
if (ena)
|
||||||
|
if (z[z_width-1])
|
||||||
|
iz <= #1 ~z +1'h1;
|
||||||
|
else
|
||||||
|
iz <= #1 z;
|
||||||
|
|
||||||
|
// generate spipe (sign bit pipe)
|
||||||
|
integer n;
|
||||||
|
always @(posedge clk)
|
||||||
|
if(ena)
|
||||||
|
begin
|
||||||
|
spipe[0] <= #1 z[z_width-1];
|
||||||
|
|
||||||
|
for(n=1; n <= d_width+1; n=n+1)
|
||||||
|
spipe[n] <= #1 spipe[n-1];
|
||||||
|
end
|
||||||
|
|
||||||
|
// hookup non-restoring divider
|
||||||
|
div_uu #(z_width, d_width)
|
||||||
|
divider (
|
||||||
|
.clk(clk),
|
||||||
|
.ena(ena),
|
||||||
|
.z(iz),
|
||||||
|
.d(id),
|
||||||
|
.q(iq),
|
||||||
|
.s(is),
|
||||||
|
.div0(idiv0),
|
||||||
|
.ovf(iovf)
|
||||||
|
);
|
||||||
|
|
||||||
|
// correct divider results if 'd' was negative
|
||||||
|
always @(posedge clk)
|
||||||
|
if(ena)
|
||||||
|
if(spipe[d_width+1])
|
||||||
|
begin
|
||||||
|
q <= #1 (~iq) + 1'h1;
|
||||||
|
s <= #1 (~is) + 1'h1;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
q <= #1 {1'b0, iq};
|
||||||
|
s <= #1 {1'b0, is};
|
||||||
|
end
|
||||||
|
|
||||||
|
// delay flags same as results
|
||||||
|
always @(posedge clk)
|
||||||
|
if(ena)
|
||||||
|
begin
|
||||||
|
div0 <= #1 idiv0;
|
||||||
|
ovf <= #1 iovf;
|
||||||
|
end
|
||||||
|
endmodule
|
|
@ -0,0 +1,202 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Non-restoring unsinged divider ////
|
||||||
|
//// ////
|
||||||
|
//// Author: Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// www.asics.ws ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2002 Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer.////
|
||||||
|
//// ////
|
||||||
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||||
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||||
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||||
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||||
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||||
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||||
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||||
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||||
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||||
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||||
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||||
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||||
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// CVS Log
|
||||||
|
//
|
||||||
|
// $Id: div_uu.v,v 1.3 2002-10-31 12:52:55 rherveille Exp $
|
||||||
|
//
|
||||||
|
// $Date: 2002-10-31 12:52:55 $
|
||||||
|
// $Revision: 1.3 $
|
||||||
|
// $Author: rherveille $
|
||||||
|
// $Locker: $
|
||||||
|
// $State: Exp $
|
||||||
|
//
|
||||||
|
// Change History:
|
||||||
|
// $Log: not supported by cvs2svn $
|
||||||
|
// Revision 1.2 2002/10/23 09:07:03 rherveille
|
||||||
|
// Improved many files.
|
||||||
|
// Fixed some bugs in Run-Length-Encoder.
|
||||||
|
// Removed dependency on ud_cnt and ro_cnt.
|
||||||
|
// Started (Motion)JPEG hardware encoder project.
|
||||||
|
//
|
||||||
|
|
||||||
|
//synopsys translate_off
|
||||||
|
`include "timescale.v"
|
||||||
|
//synopsys translate_on
|
||||||
|
|
||||||
|
module div_uu(clk, ena, z, d, q, s, div0, ovf);
|
||||||
|
|
||||||
|
//
|
||||||
|
// parameters
|
||||||
|
//
|
||||||
|
parameter z_width = 16;
|
||||||
|
parameter d_width = z_width /2;
|
||||||
|
|
||||||
|
//
|
||||||
|
// inputs & outputs
|
||||||
|
//
|
||||||
|
input clk; // system clock
|
||||||
|
input ena; // clock enable
|
||||||
|
|
||||||
|
input [z_width -1:0] z; // divident
|
||||||
|
input [d_width -1:0] d; // divisor
|
||||||
|
output [d_width -1:0] q; // quotient
|
||||||
|
reg [d_width-1:0] q;
|
||||||
|
output [d_width -1:0] s; // remainder
|
||||||
|
reg [d_width-1:0] s;
|
||||||
|
output div0;
|
||||||
|
reg div0;
|
||||||
|
output ovf;
|
||||||
|
reg ovf;
|
||||||
|
|
||||||
|
//
|
||||||
|
// functions
|
||||||
|
//
|
||||||
|
function [z_width:0] gen_s;
|
||||||
|
input [z_width:0] si;
|
||||||
|
input [z_width:0] di;
|
||||||
|
begin
|
||||||
|
if(si[z_width])
|
||||||
|
gen_s = {si[z_width-1:0], 1'b0} + di;
|
||||||
|
else
|
||||||
|
gen_s = {si[z_width-1:0], 1'b0} - di;
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function [d_width-1:0] gen_q;
|
||||||
|
input [d_width-1:0] qi;
|
||||||
|
input [z_width:0] si;
|
||||||
|
begin
|
||||||
|
gen_q = {qi[d_width-2:0], ~si[z_width]};
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function [d_width-1:0] assign_s;
|
||||||
|
input [z_width:0] si;
|
||||||
|
input [z_width:0] di;
|
||||||
|
reg [z_width:0] tmp;
|
||||||
|
begin
|
||||||
|
if(si[z_width])
|
||||||
|
tmp = si + di;
|
||||||
|
else
|
||||||
|
tmp = si;
|
||||||
|
|
||||||
|
assign_s = tmp[z_width-1:z_width-4];
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
//
|
||||||
|
// variables
|
||||||
|
//
|
||||||
|
reg [d_width-1:0] q_pipe [d_width-1:0];
|
||||||
|
reg [z_width:0] s_pipe [d_width:0];
|
||||||
|
reg [z_width:0] d_pipe [d_width:0];
|
||||||
|
|
||||||
|
reg [d_width:0] div0_pipe, ovf_pipe;
|
||||||
|
//
|
||||||
|
// perform parameter checks
|
||||||
|
//
|
||||||
|
// synopsys translate_off
|
||||||
|
initial
|
||||||
|
begin
|
||||||
|
if(d_width !== z_width / 2)
|
||||||
|
$display("div.v parameter error (d_width != z_width/2).");
|
||||||
|
end
|
||||||
|
// synopsys translate_on
|
||||||
|
|
||||||
|
integer n0, n1, n2, n3;
|
||||||
|
|
||||||
|
// generate divisor (d) pipe
|
||||||
|
always @(d)
|
||||||
|
d_pipe[0] <= {1'b0, d, {(z_width-d_width){1'b0}} };
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
if(ena)
|
||||||
|
for(n0=1; n0 <= d_width; n0=n0+1)
|
||||||
|
d_pipe[n0] <= #1 d_pipe[n0-1];
|
||||||
|
|
||||||
|
// generate internal remainder pipe
|
||||||
|
always @(z)
|
||||||
|
s_pipe[0] <= z;
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
if(ena)
|
||||||
|
for(n1=1; n1 <= d_width; n1=n1+1)
|
||||||
|
s_pipe[n1] <= #1 gen_s(s_pipe[n1-1], d_pipe[n1-1]);
|
||||||
|
|
||||||
|
// generate quotient pipe
|
||||||
|
always @(posedge clk)
|
||||||
|
q_pipe[0] <= #1 0;
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
if(ena)
|
||||||
|
for(n2=1; n2 < d_width; n2=n2+1)
|
||||||
|
q_pipe[n2] <= #1 gen_q(q_pipe[n2-1], s_pipe[n2]);
|
||||||
|
|
||||||
|
|
||||||
|
// flags (divide_by_zero, overflow)
|
||||||
|
always @(z or d)
|
||||||
|
begin
|
||||||
|
ovf_pipe[0] <= !(z[z_width-1:d_width] < d);
|
||||||
|
div0_pipe[0] <= ~|d;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
if(ena)
|
||||||
|
for(n3=1; n3 <= d_width; n3=n3+1)
|
||||||
|
begin
|
||||||
|
ovf_pipe[n3] <= #1 ovf_pipe[n3-1];
|
||||||
|
div0_pipe[n3] <= #1 div0_pipe[n3-1];
|
||||||
|
end
|
||||||
|
|
||||||
|
// assign outputs
|
||||||
|
always @(posedge clk)
|
||||||
|
if(ena)
|
||||||
|
ovf <= #1 ovf_pipe[d_width];
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
if(ena)
|
||||||
|
div0 <= #1 div0_pipe[d_width];
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
if(ena)
|
||||||
|
q <= #1 gen_q(q_pipe[d_width-1], s_pipe[d_width]);
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
if(ena)
|
||||||
|
s <= #1 assign_s(s_pipe[d_width], d_pipe[d_width]);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,149 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// JPEG Quantization & Rounding Core ////
|
||||||
|
//// ////
|
||||||
|
//// Author: Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// www.asics.ws ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2002 Richard Herveille ////
|
||||||
|
//// richard@asics.ws ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer.////
|
||||||
|
//// ////
|
||||||
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||||
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||||
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||||
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||||
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||||
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||||
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||||
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||||
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||||
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||||
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||||
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||||
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// CVS Log
|
||||||
|
//
|
||||||
|
// $Id: jpeg_qnr.v,v 1.3 2002-10-31 12:52:55 rherveille Exp $
|
||||||
|
//
|
||||||
|
// $Date: 2002-10-31 12:52:55 $
|
||||||
|
// $Revision: 1.3 $
|
||||||
|
// $Author: rherveille $
|
||||||
|
// $Locker: $
|
||||||
|
// $State: Exp $
|
||||||
|
//
|
||||||
|
// Change History:
|
||||||
|
// $Log: not supported by cvs2svn $
|
||||||
|
// Revision 1.2 2002/10/23 09:07:03 rherveille
|
||||||
|
// Improved many files.
|
||||||
|
// Fixed some bugs in Run-Length-Encoder.
|
||||||
|
// Removed dependency on ud_cnt and ro_cnt.
|
||||||
|
// Started (Motion)JPEG hardware encoder project.
|
||||||
|
//
|
||||||
|
|
||||||
|
//synopsys translate_off
|
||||||
|
`include "timescale.v"
|
||||||
|
//synopsys translate_on
|
||||||
|
|
||||||
|
module jpeg_qnr(clk, ena, rst, dstrb, din, qnt_val, qnt_cnt, dout, douten);
|
||||||
|
|
||||||
|
//
|
||||||
|
// parameters
|
||||||
|
//
|
||||||
|
parameter d_width = 12;
|
||||||
|
parameter z_width = 2 * d_width;
|
||||||
|
|
||||||
|
//
|
||||||
|
// inputs & outputs
|
||||||
|
//
|
||||||
|
input clk; // system clock
|
||||||
|
input ena; // clock enable
|
||||||
|
input rst; // asynchronous active low reset
|
||||||
|
|
||||||
|
input dstrb; // present dstrb 1clk cycle before din
|
||||||
|
input [d_width-1:0] din; // data input
|
||||||
|
input [ 7:0] qnt_val; // quantization value
|
||||||
|
|
||||||
|
output [ 5:0] qnt_cnt; // sample number (get quantization value qnt_cnt)
|
||||||
|
output [10:0] dout; // data output
|
||||||
|
output douten;
|
||||||
|
|
||||||
|
//
|
||||||
|
// variables
|
||||||
|
//
|
||||||
|
wire [z_width-1:0] iz; // intermediate divident value
|
||||||
|
wire [d_width-1:0] id; // intermediate dividor value
|
||||||
|
wire [d_width :0] iq; // intermediate result divider
|
||||||
|
reg [d_width :0] rq; // rounded q-value
|
||||||
|
reg [d_width+3:0] dep;// data enable pipeline
|
||||||
|
|
||||||
|
// generate sample counter
|
||||||
|
reg [5:0] qnt_cnt;
|
||||||
|
wire dcnt = &qnt_cnt;
|
||||||
|
|
||||||
|
always @(posedge clk or negedge rst)
|
||||||
|
if (~rst)
|
||||||
|
qnt_cnt <= #1 6'h0;
|
||||||
|
else if (dstrb)
|
||||||
|
qnt_cnt <= #1 6'h0;
|
||||||
|
else if (ena)
|
||||||
|
qnt_cnt <= #1 qnt_cnt + 6'h1;
|
||||||
|
|
||||||
|
// generate intermediate dividor/divident values
|
||||||
|
assign id = { {(d_width - 8){1'b0}}, qnt_val};
|
||||||
|
assign iz = { {(z_width - d_width){din[d_width-1]}}, din};
|
||||||
|
|
||||||
|
// hookup division unit
|
||||||
|
div_su #(z_width)
|
||||||
|
divider (
|
||||||
|
.clk(clk),
|
||||||
|
.ena(ena),
|
||||||
|
.z(iz),
|
||||||
|
.d(id),
|
||||||
|
.q(iq),
|
||||||
|
.s(),
|
||||||
|
.div0(),
|
||||||
|
.ovf()
|
||||||
|
);
|
||||||
|
|
||||||
|
// round result to the nearest integer
|
||||||
|
always @(posedge clk)
|
||||||
|
if (ena)
|
||||||
|
if (iq[0])
|
||||||
|
if (iq[d_width])
|
||||||
|
rq <= #1 iq - 1'h1;
|
||||||
|
else
|
||||||
|
rq <= #1 iq + 1'h1;
|
||||||
|
else
|
||||||
|
rq <= #1 iq;
|
||||||
|
|
||||||
|
// assign dout signal
|
||||||
|
assign dout = rq[d_width -1: d_width-11];
|
||||||
|
|
||||||
|
|
||||||
|
// generate data-out enable signal
|
||||||
|
// This is a pipeline, data is not dependant on sample-count
|
||||||
|
integer n;
|
||||||
|
always @(posedge clk or negedge rst)
|
||||||
|
if (!rst)
|
||||||
|
dep <= #1 0;
|
||||||
|
else if(ena)
|
||||||
|
begin
|
||||||
|
dep[0] <= #1 dstrb;
|
||||||
|
|
||||||
|
for (n=1; n <= d_width +3; n = n +1)
|
||||||
|
dep[n] <= #1 dep[n-1];
|
||||||
|
end
|
||||||
|
|
||||||
|
assign douten = dep[d_width +3];
|
||||||
|
endmodule
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,110 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Created by SmartDesign Tue Jan 16 17:22:21 2018
|
||||||
|
// Version: v11.8 11.8.0.26
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
`timescale 1ns / 100ps
|
||||||
|
|
||||||
|
// TOP_multi_enc_decx2x4
|
||||||
|
module multi_enc_decx2x4(
|
||||||
|
// Inputs
|
||||||
|
clock,
|
||||||
|
datain,
|
||||||
|
datain1,
|
||||||
|
datain1_0,
|
||||||
|
datain_0,
|
||||||
|
reset,
|
||||||
|
// Outputs
|
||||||
|
dataout,
|
||||||
|
dataout1,
|
||||||
|
dataout1_0,
|
||||||
|
dataout_0
|
||||||
|
);
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// Input
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
input clock;
|
||||||
|
input [127:0] datain;
|
||||||
|
input [127:0] datain1;
|
||||||
|
input [127:0] datain1_0;
|
||||||
|
input [127:0] datain_0;
|
||||||
|
input reset;
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// Output
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
output [127:0] dataout;
|
||||||
|
output [127:0] dataout1;
|
||||||
|
output [127:0] dataout1_0;
|
||||||
|
output [127:0] dataout_0;
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// Nets
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
wire clock;
|
||||||
|
wire [127:0] datain;
|
||||||
|
wire [127:0] datain1;
|
||||||
|
wire [127:0] datain1_0;
|
||||||
|
wire [127:0] datain_0;
|
||||||
|
wire [127:0] dataout_net_0;
|
||||||
|
wire [127:0] dataout1_net_0;
|
||||||
|
wire [127:0] dataout1_0_net_0;
|
||||||
|
wire [127:0] dataout_0_net_0;
|
||||||
|
wire reset;
|
||||||
|
wire [127:0] top_0_dataout;
|
||||||
|
wire [127:0] top_1_dataout1;
|
||||||
|
wire [127:0] dataout_net_1;
|
||||||
|
wire [127:0] dataout1_net_1;
|
||||||
|
wire [127:0] dataout1_0_net_1;
|
||||||
|
wire [127:0] dataout_0_net_1;
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// Top level output port assignments
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
assign dataout_net_1 = dataout_net_0;
|
||||||
|
assign dataout[127:0] = dataout_net_1;
|
||||||
|
assign dataout1_net_1 = dataout1_net_0;
|
||||||
|
assign dataout1[127:0] = dataout1_net_1;
|
||||||
|
assign dataout1_0_net_1 = dataout1_0_net_0;
|
||||||
|
assign dataout1_0[127:0] = dataout1_0_net_1;
|
||||||
|
assign dataout_0_net_1 = dataout_0_net_0;
|
||||||
|
assign dataout_0[127:0] = dataout_0_net_1;
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// Component instances
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
//--------top
|
||||||
|
top top_0(
|
||||||
|
// Inputs
|
||||||
|
.clock ( clock ),
|
||||||
|
.reset ( reset ),
|
||||||
|
.datain ( datain ),
|
||||||
|
.datain1 ( datain1 ),
|
||||||
|
// Outputs
|
||||||
|
.dataout ( top_0_dataout ),
|
||||||
|
.dataout1 ( dataout1_0_net_0 )
|
||||||
|
);
|
||||||
|
|
||||||
|
//--------top
|
||||||
|
top top_1(
|
||||||
|
// Inputs
|
||||||
|
.clock ( clock ),
|
||||||
|
.reset ( reset ),
|
||||||
|
.datain ( datain_0 ),
|
||||||
|
.datain1 ( datain1_0 ),
|
||||||
|
// Outputs
|
||||||
|
.dataout ( dataout_0_net_0 ),
|
||||||
|
.dataout1 ( top_1_dataout1 )
|
||||||
|
);
|
||||||
|
|
||||||
|
//--------top
|
||||||
|
top top_2(
|
||||||
|
// Inputs
|
||||||
|
.clock ( clock ),
|
||||||
|
.reset ( reset ),
|
||||||
|
.datain ( top_0_dataout ),
|
||||||
|
.datain1 ( top_1_dataout1 ),
|
||||||
|
// Outputs
|
||||||
|
.dataout ( dataout_net_0 ),
|
||||||
|
.dataout1 ( dataout1_net_0 )
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,147 @@
|
||||||
|
module decoder128(datain,dataout);
|
||||||
|
|
||||||
|
input [6:0] datain;
|
||||||
|
output [127:0] dataout;
|
||||||
|
reg [127:0] dataout;
|
||||||
|
|
||||||
|
always @(datain)
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
case (datain)
|
||||||
|
|
||||||
|
7'b0000000: dataout <= 128'h00000000000000000000000000000001;
|
||||||
|
7'b0000001: dataout <= 128'h00000000000000000000000000000002;
|
||||||
|
7'b0000010: dataout <= 128'h00000000000000000000000000000004;
|
||||||
|
7'b0000011: dataout <= 128'h00000000000000000000000000000008;
|
||||||
|
7'b0000100: dataout <= 128'h00000000000000000000000000000010;
|
||||||
|
7'b0000101: dataout <= 128'h00000000000000000000000000000020;
|
||||||
|
7'b0000110: dataout <= 128'h00000000000000000000000000000040;
|
||||||
|
7'b0000111: dataout <= 128'h00000000000000000000000000000080;
|
||||||
|
7'b0001000: dataout <= 128'h00000000000000000000000000000100;
|
||||||
|
7'b0001001: dataout <= 128'h00000000000000000000000000000200;
|
||||||
|
7'b0001010: dataout <= 128'h00000000000000000000000000000400;
|
||||||
|
7'b0001011: dataout <= 128'h00000000000000000000000000000800;
|
||||||
|
7'b0001100: dataout <= 128'h00000000000000000000000000001000;
|
||||||
|
7'b0001101: dataout <= 128'h00000000000000000000000000002000;
|
||||||
|
7'b0001110: dataout <= 128'h00000000000000000000000000004000;
|
||||||
|
7'b0001111: dataout <= 128'h00000000000000000000000000008000;
|
||||||
|
7'b0010000: dataout <= 128'h00000000000000000000000000010000;
|
||||||
|
7'b0010001: dataout <= 128'h00000000000000000000000000020000;
|
||||||
|
7'b0010010: dataout <= 128'h00000000000000000000000000040000;
|
||||||
|
7'b0010011: dataout <= 128'h00000000000000000000000000080000;
|
||||||
|
7'b0010100: dataout <= 128'h00000000000000000000000000100000;
|
||||||
|
7'b0010101: dataout <= 128'h00000000000000000000000000200000;
|
||||||
|
7'b0010110: dataout <= 128'h00000000000000000000000000400000;
|
||||||
|
7'b0010111: dataout <= 128'h00000000000000000000000000800000;
|
||||||
|
7'b0011000: dataout <= 128'h00000000000000000000000001000000;
|
||||||
|
7'b0011001: dataout <= 128'h00000000000000000000000002000000;
|
||||||
|
7'b0011010: dataout <= 128'h00000000000000000000000004000000;
|
||||||
|
7'b0011011: dataout <= 128'h00000000000000000000000008000000;
|
||||||
|
7'b0011100: dataout <= 128'h00000000000000000000000010000000;
|
||||||
|
7'b0011101: dataout <= 128'h00000000000000000000000020000000;
|
||||||
|
7'b0011110: dataout <= 128'h00000000000000000000000040000000;
|
||||||
|
7'b0011111: dataout <= 128'h00000000000000000000000080000000;
|
||||||
|
7'b0100000: dataout <= 128'h00000000000000000000000100000000;
|
||||||
|
7'b0100001: dataout <= 128'h00000000000000000000000200000000;
|
||||||
|
7'b0100010: dataout <= 128'h00000000000000000000000400000000;
|
||||||
|
7'b0100011: dataout <= 128'h00000000000000000000000800000000;
|
||||||
|
7'b0100100: dataout <= 128'h00000000000000000000001000000000;
|
||||||
|
7'b0100101: dataout <= 128'h00000000000000000000002000000000;
|
||||||
|
7'b0100110: dataout <= 128'h00000000000000000000004000000000;
|
||||||
|
7'b0100111: dataout <= 128'h00000000000000000000008000000000;
|
||||||
|
7'b0101000: dataout <= 128'h00000000000000000000010000000000;
|
||||||
|
7'b0101001: dataout <= 128'h00000000000000000000020000000000;
|
||||||
|
7'b0101010: dataout <= 128'h00000000000000000000040000000000;
|
||||||
|
7'b0101011: dataout <= 128'h00000000000000000000080000000000;
|
||||||
|
7'b0101100: dataout <= 128'h00000000000000000000100000000000;
|
||||||
|
7'b0101101: dataout <= 128'h00000000000000000000200000000000;
|
||||||
|
7'b0101110: dataout <= 128'h00000000000000000000400000000000;
|
||||||
|
7'b0101111: dataout <= 128'h00000000000000000000800000000000;
|
||||||
|
7'b0110000: dataout <= 128'h00000000000000000001000000000000;
|
||||||
|
7'b0110001: dataout <= 128'h00000000000000000002000000000000;
|
||||||
|
7'b0110010: dataout <= 128'h00000000000000000004000000000000;
|
||||||
|
7'b0110011: dataout <= 128'h00000000000000000008000000000000;
|
||||||
|
7'b0110100: dataout <= 128'h00000000000000000010000000000000;
|
||||||
|
7'b0110101: dataout <= 128'h00000000000000000020000000000000;
|
||||||
|
7'b0110110: dataout <= 128'h00000000000000000040000000000000;
|
||||||
|
7'b0110111: dataout <= 128'h00000000000000000080000000000000;
|
||||||
|
7'b0111000: dataout <= 128'h00000000000000000100000000000000;
|
||||||
|
7'b0111001: dataout <= 128'h00000000000000000200000000000000;
|
||||||
|
7'b0111010: dataout <= 128'h00000000000000000400000000000000;
|
||||||
|
7'b0111011: dataout <= 128'h00000000000000000800000000000000;
|
||||||
|
7'b0111100: dataout <= 128'h00000000000000001000000000000000;
|
||||||
|
7'b0111101: dataout <= 128'h00000000000000002000000000000000;
|
||||||
|
7'b0111110: dataout <= 128'h00000000000000004000000000000000;
|
||||||
|
7'b0111111: dataout <= 128'h00000000000000008000000000000000;
|
||||||
|
7'b1000000: dataout <= 128'h00000000000000010000000000000000;
|
||||||
|
7'b1000001: dataout <= 128'h00000000000000020000000000000000;
|
||||||
|
7'b1000010: dataout <= 128'h00000000000000040000000000000000;
|
||||||
|
7'b1000011: dataout <= 128'h00000000000000080000000000000000;
|
||||||
|
7'b1000100: dataout <= 128'h00000000000000100000000000000000;
|
||||||
|
7'b1000101: dataout <= 128'h00000000000000200000000000000000;
|
||||||
|
7'b1000110: dataout <= 128'h00000000000000400000000000000000;
|
||||||
|
7'b1000111: dataout <= 128'h00000000000000800000000000000000;
|
||||||
|
7'b1001000: dataout <= 128'h00000000000001000000000000000000;
|
||||||
|
7'b1001001: dataout <= 128'h00000000000002000000000000000000;
|
||||||
|
7'b1001010: dataout <= 128'h00000000000004000000000000000000;
|
||||||
|
7'b1001011: dataout <= 128'h00000000000008000000000000000000;
|
||||||
|
7'b1001100: dataout <= 128'h00000000000010000000000000000000;
|
||||||
|
7'b1001101: dataout <= 128'h00000000000020000000000000000000;
|
||||||
|
7'b1001110: dataout <= 128'h00000000000040000000000000000000;
|
||||||
|
7'b1001111: dataout <= 128'h00000000000080000000000000000000;
|
||||||
|
7'b1010000: dataout <= 128'h00000000000100000000000000000000;
|
||||||
|
7'b1010001: dataout <= 128'h00000000000200000000000000000000;
|
||||||
|
7'b1010010: dataout <= 128'h00000000000400000000000000000000;
|
||||||
|
7'b1010011: dataout <= 128'h00000000000800000000000000000000;
|
||||||
|
7'b1010100: dataout <= 128'h00000000001000000000000000000000;
|
||||||
|
7'b1010101: dataout <= 128'h00000000002000000000000000000000;
|
||||||
|
7'b1010110: dataout <= 128'h00000000004000000000000000000000;
|
||||||
|
7'b1010111: dataout <= 128'h00000000008000000000000000000000;
|
||||||
|
7'b1011000: dataout <= 128'h00000000010000000000000000000000;
|
||||||
|
7'b1011001: dataout <= 128'h00000000020000000000000000000000;
|
||||||
|
7'b1011010: dataout <= 128'h00000000040000000000000000000000;
|
||||||
|
7'b1011011: dataout <= 128'h00000000080000000000000000000000;
|
||||||
|
7'b1011100: dataout <= 128'h00000000100000000000000000000000;
|
||||||
|
7'b1011101: dataout <= 128'h00000000200000000000000000000000;
|
||||||
|
7'b1011110: dataout <= 128'h00000000400000000000000000000000;
|
||||||
|
7'b1011111: dataout <= 128'h00000000800000000000000000000000;
|
||||||
|
7'b1100000: dataout <= 128'h00000001000000000000000000000000;
|
||||||
|
7'b1100001: dataout <= 128'h00000002000000000000000000000000;
|
||||||
|
7'b1100010: dataout <= 128'h00000004000000000000000000000000;
|
||||||
|
7'b1100011: dataout <= 128'h00000008000000000000000000000000;
|
||||||
|
7'b1100100: dataout <= 128'h00000010000000000000000000000000;
|
||||||
|
7'b1100101: dataout <= 128'h00000020000000000000000000000000;
|
||||||
|
7'b1100110: dataout <= 128'h00000040000000000000000000000000;
|
||||||
|
7'b1100111: dataout <= 128'h00000080000000000000000000000000;
|
||||||
|
7'b1101000: dataout <= 128'h00000100000000000000000000000000;
|
||||||
|
7'b1101001: dataout <= 128'h00000200000000000000000000000000;
|
||||||
|
7'b1101010: dataout <= 128'h00000400000000000000000000000000;
|
||||||
|
7'b1101011: dataout <= 128'h00000800000000000000000000000000;
|
||||||
|
7'b1101100: dataout <= 128'h00001000000000000000000000000000;
|
||||||
|
7'b1101101: dataout <= 128'h00002000000000000000000000000000;
|
||||||
|
7'b1101110: dataout <= 128'h00004000000000000000000000000000;
|
||||||
|
7'b1101111: dataout <= 128'h00008000000000000000000000000000;
|
||||||
|
7'b1110000: dataout <= 128'h00010000000000000000000000000000;
|
||||||
|
7'b1110001: dataout <= 128'h00020000000000000000000000000000;
|
||||||
|
7'b1110010: dataout <= 128'h00040000000000000000000000000000;
|
||||||
|
7'b1110011: dataout <= 128'h00080000000000000000000000000000;
|
||||||
|
7'b1110100: dataout <= 128'h00100000000000000000000000000000;
|
||||||
|
7'b1110101: dataout <= 128'h00200000000000000000000000000000;
|
||||||
|
7'b1110110: dataout <= 128'h00400000000000000000000000000000;
|
||||||
|
7'b1110111: dataout <= 128'h00800000000000000000000000000000;
|
||||||
|
7'b1111000: dataout <= 128'h01000000000000000000000000000000;
|
||||||
|
7'b1111001: dataout <= 128'h02000000000000000000000000000000;
|
||||||
|
7'b1111010: dataout <= 128'h04000000000000000000000000000000;
|
||||||
|
7'b1111011: dataout <= 128'h08000000000000000000000000000000;
|
||||||
|
7'b1111100: dataout <= 128'h10000000000000000000000000000000;
|
||||||
|
7'b1111101: dataout <= 128'h20000000000000000000000000000000;
|
||||||
|
7'b1111110: dataout <= 128'h40000000000000000000000000000000;
|
||||||
|
7'b1111111: dataout <= 128'h80000000000000000000000000000000;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
default: dataout<=128'h0;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
endmodule
|
|
@ -0,0 +1,149 @@
|
||||||
|
module encoder128(datain,dataout);
|
||||||
|
|
||||||
|
input [127:0] datain;
|
||||||
|
output [6:0] dataout;
|
||||||
|
reg [6:0] dataout;
|
||||||
|
|
||||||
|
always @(datain)
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
case (datain)
|
||||||
|
|
||||||
|
128'h00000000000000000000000000000001 : dataout<=7'b0000000;
|
||||||
|
128'h00000000000000000000000000000002 : dataout<=7'b0000001;
|
||||||
|
128'h00000000000000000000000000000004 : dataout<=7'b0000010;
|
||||||
|
128'h00000000000000000000000000000008 : dataout<=7'b0000011;
|
||||||
|
128'h00000000000000000000000000000010 : dataout<=7'b0000100;
|
||||||
|
128'h00000000000000000000000000000020 : dataout<=7'b0000101;
|
||||||
|
128'h00000000000000000000000000000040 : dataout<=7'b0000110;
|
||||||
|
128'h00000000000000000000000000000080 : dataout<=7'b0000111;
|
||||||
|
128'h00000000000000000000000000000100 : dataout<=7'b0001000;
|
||||||
|
128'h00000000000000000000000000000200 : dataout<=7'b0001001;
|
||||||
|
128'h00000000000000000000000000000400 : dataout<=7'b0001010;
|
||||||
|
128'h00000000000000000000000000000800 : dataout<=7'b0001011;
|
||||||
|
128'h00000000000000000000000000001000 : dataout<=7'b0001000;
|
||||||
|
128'h00000000000000000000000000002000 : dataout<=7'b0001101;
|
||||||
|
128'h00000000000000000000000000004000 : dataout<=7'b0001110;
|
||||||
|
128'h00000000000000000000000000008000 : dataout<=7'b0001111;
|
||||||
|
128'h00000000000000000000000000010000 : dataout<=7'b0010000;
|
||||||
|
128'h00000000000000000000000000020000 : dataout<=7'b0010001;
|
||||||
|
128'h00000000000000000000000000040000 : dataout<=7'b0010010;
|
||||||
|
128'h00000000000000000000000000080000 : dataout<=7'b0010011;
|
||||||
|
128'h00000000000000000000000000100000 : dataout<=7'b0010100;
|
||||||
|
128'h00000000000000000000000000200000 : dataout<=7'b0010101;
|
||||||
|
128'h00000000000000000000000000400000 : dataout<=7'b0010110;
|
||||||
|
128'h00000000000000000000000000800000 : dataout<=7'b0010111;
|
||||||
|
128'h00000000000000000000000001000000 : dataout<=7'b0011000;
|
||||||
|
128'h00000000000000000000000002000000 : dataout<=7'b0011001;
|
||||||
|
128'h00000000000000000000000004000000 : dataout<=7'b0011010;
|
||||||
|
128'h00000000000000000000000008000000 : dataout<=7'b0011011;
|
||||||
|
128'h00000000000000000000000010000000 : dataout<=7'b0011000;
|
||||||
|
128'h00000000000000000000000020000000 : dataout<=7'b0011101;
|
||||||
|
128'h00000000000000000000000040000000 : dataout<=7'b0011110;
|
||||||
|
128'h00000000000000000000000080000000 : dataout<=7'b0011111;
|
||||||
|
|
||||||
|
128'h00000000000000000000000100000000 : dataout<=7'b0100000;
|
||||||
|
128'h00000000000000000000000200000000 : dataout<=7'b0100001;
|
||||||
|
128'h00000000000000000000000400000000 : dataout<=7'b0100010;
|
||||||
|
128'h00000000000000000000000800000000 : dataout<=7'b0100011;
|
||||||
|
128'h00000000000000000000001000000000 : dataout<=7'b0100100;
|
||||||
|
128'h00000000000000000000002000000000 : dataout<=7'b0100101;
|
||||||
|
128'h00000000000000000000004000000000 : dataout<=7'b0100110;
|
||||||
|
128'h00000000000000000000008000000000 : dataout<=7'b0100111;
|
||||||
|
128'h00000000000000000000010000000000 : dataout<=7'b0101000;
|
||||||
|
128'h00000000000000000000020000000000 : dataout<=7'b0101001;
|
||||||
|
128'h00000000000000000000040000000000 : dataout<=7'b0101010;
|
||||||
|
128'h00000000000000000000080000000000 : dataout<=7'b0101011;
|
||||||
|
128'h00000000000000000000100000000000 : dataout<=7'b0101000;
|
||||||
|
128'h00000000000000000000200000000000 : dataout<=7'b0101101;
|
||||||
|
128'h00000000000000000000400000000000 : dataout<=7'b0101110;
|
||||||
|
128'h00000000000000000000800000000000 : dataout<=7'b0101111;
|
||||||
|
128'h00000000000000000001000000000000 : dataout<=7'b0110000;
|
||||||
|
128'h00000000000000000002000000000000 : dataout<=7'b0110001;
|
||||||
|
128'h00000000000000000004000000000000 : dataout<=7'b0110010;
|
||||||
|
128'h00000000000000000008000000000000 : dataout<=7'b0110011;
|
||||||
|
128'h00000000000000000010000000000000 : dataout<=7'b0110100;
|
||||||
|
128'h00000000000000000020000000000000 : dataout<=7'b0110101;
|
||||||
|
128'h00000000000000000040000000000000 : dataout<=7'b0110110;
|
||||||
|
128'h00000000000000000080000000000000 : dataout<=7'b0110111;
|
||||||
|
128'h00000000000000000100000000000000 : dataout<=7'b0111000;
|
||||||
|
128'h00000000000000000200000000000000 : dataout<=7'b0111001;
|
||||||
|
128'h00000000000000000400000000000000 : dataout<=7'b0111010;
|
||||||
|
128'h00000000000000000800000000000000 : dataout<=7'b0111011;
|
||||||
|
128'h00000000000000001000000000000000 : dataout<=7'b0111000;
|
||||||
|
128'h00000000000000002000000000000000 : dataout<=7'b0111101;
|
||||||
|
128'h00000000000000004000000000000000 : dataout<=7'b0111110;
|
||||||
|
128'h00000000000000008000000000000000 : dataout<=7'b0111111;
|
||||||
|
|
||||||
|
128'h00000000000000010000000000000000 : dataout<=7'b1000000;
|
||||||
|
128'h00000000000000020000000000000000 : dataout<=7'b1000001;
|
||||||
|
128'h00000000000000040000000000000000 : dataout<=7'b1000010;
|
||||||
|
128'h00000000000000080000000000000000 : dataout<=7'b1000011;
|
||||||
|
128'h00000000000000100000000000000000 : dataout<=7'b1000100;
|
||||||
|
128'h00000000000000200000000000000000 : dataout<=7'b1000101;
|
||||||
|
128'h00000000000000400000000000000000 : dataout<=7'b1000110;
|
||||||
|
128'h00000000000000800000000000000000 : dataout<=7'b1000111;
|
||||||
|
128'h00000000000001000000000000000000 : dataout<=7'b1001000;
|
||||||
|
128'h00000000000002000000000000000000 : dataout<=7'b1001001;
|
||||||
|
128'h00000000000004000000000000000000 : dataout<=7'b1001010;
|
||||||
|
128'h00000000000008000000000000000000 : dataout<=7'b1001011;
|
||||||
|
128'h00000000000010000000000000000000 : dataout<=7'b1001000;
|
||||||
|
128'h00000000000020000000000000000000 : dataout<=7'b1001101;
|
||||||
|
128'h00000000000040000000000000000000 : dataout<=7'b1001110;
|
||||||
|
128'h00000000000080000000000000000000 : dataout<=7'b1001111;
|
||||||
|
128'h00000000000100000000000000000000 : dataout<=7'b1010000;
|
||||||
|
128'h00000000000200000000000000000000 : dataout<=7'b1010001;
|
||||||
|
128'h00000000000400000000000000000000 : dataout<=7'b1010010;
|
||||||
|
128'h00000000000800000000000000000000 : dataout<=7'b1010011;
|
||||||
|
128'h00000000001000000000000000000000 : dataout<=7'b1010100;
|
||||||
|
128'h00000000002000000000000000000000 : dataout<=7'b1010101;
|
||||||
|
128'h00000000004000000000000000000000 : dataout<=7'b1010110;
|
||||||
|
128'h00000000008000000000000000000000 : dataout<=7'b1010111;
|
||||||
|
128'h00000000010000000000000000000000 : dataout<=7'b1011000;
|
||||||
|
128'h00000000020000000000000000000000 : dataout<=7'b1011001;
|
||||||
|
128'h00000000040000000000000000000000 : dataout<=7'b1011010;
|
||||||
|
128'h00000000080000000000000000000000 : dataout<=7'b1011011;
|
||||||
|
128'h00000000100000000000000000000000 : dataout<=7'b1011000;
|
||||||
|
128'h00000000200000000000000000000000 : dataout<=7'b1011101;
|
||||||
|
128'h00000000400000000000000000000000 : dataout<=7'b1011110;
|
||||||
|
128'h00000000800000000000000000000000 : dataout<=7'b1011111;
|
||||||
|
|
||||||
|
128'h00000001000000000000000000000000 : dataout<=7'b1100000;
|
||||||
|
128'h00000002000000000000000000000000 : dataout<=7'b1100001;
|
||||||
|
128'h00000004000000000000000000000000 : dataout<=7'b1100010;
|
||||||
|
128'h00000008000000000000000000000000 : dataout<=7'b1100011;
|
||||||
|
128'h00000010000000000000000000000000 : dataout<=7'b1100100;
|
||||||
|
128'h00000020000000000000000000000000 : dataout<=7'b1100101;
|
||||||
|
128'h00000040000000000000000000000000 : dataout<=7'b1100110;
|
||||||
|
128'h00000080000000000000000000000000 : dataout<=7'b1100111;
|
||||||
|
128'h00000100000000000000000000000000 : dataout<=7'b1101000;
|
||||||
|
128'h00000200000000000000000000000000 : dataout<=7'b1101001;
|
||||||
|
128'h00000400000000000000000000000000 : dataout<=7'b1101010;
|
||||||
|
128'h00000800000000000000000000000000 : dataout<=7'b1101011;
|
||||||
|
128'h00001000000000000000000000000000 : dataout<=7'b1101000;
|
||||||
|
128'h00002000000000000000000000000000 : dataout<=7'b1101101;
|
||||||
|
128'h00004000000000000000000000000000 : dataout<=7'b1101110;
|
||||||
|
128'h00008000000000000000000000000000 : dataout<=7'b1101111;
|
||||||
|
128'h00010000000000000000000000000000 : dataout<=7'b1110000;
|
||||||
|
128'h00020000000000000000000000000000 : dataout<=7'b1110001;
|
||||||
|
128'h00040000000000000000000000000000 : dataout<=7'b1110010;
|
||||||
|
128'h00080000000000000000000000000000 : dataout<=7'b1110011;
|
||||||
|
128'h00100000000000000000000000000000 : dataout<=7'b1110100;
|
||||||
|
128'h00200000000000000000000000000000 : dataout<=7'b1110101;
|
||||||
|
128'h00400000000000000000000000000000 : dataout<=7'b1110110;
|
||||||
|
128'h00800000000000000000000000000000 : dataout<=7'b1110111;
|
||||||
|
128'h01000000000000000000000000000000 : dataout<=7'b1111000;
|
||||||
|
128'h02000000000000000000000000000000 : dataout<=7'b1111001;
|
||||||
|
128'h04000000000000000000000000000000 : dataout<=7'b1111010;
|
||||||
|
128'h08000000000000000000000000000000 : dataout<=7'b1111011;
|
||||||
|
128'h10000000000000000000000000000000 : dataout<=7'b1111000;
|
||||||
|
128'h20000000000000000000000000000000 : dataout<=7'b1111101;
|
||||||
|
128'h40000000000000000000000000000000 : dataout<=7'b1111110;
|
||||||
|
128'h80000000000000000000000000000000 : dataout<=7'b1111111;
|
||||||
|
|
||||||
|
|
||||||
|
default: dataout<=7'b0000000;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
endmodule
|
|
@ -0,0 +1,104 @@
|
||||||
|
|
||||||
|
module top(clock,reset,datain,dataout,datain1,dataout1);
|
||||||
|
|
||||||
|
|
||||||
|
input clock,reset;
|
||||||
|
|
||||||
|
input [127:0] datain;
|
||||||
|
output [127:0] dataout;
|
||||||
|
|
||||||
|
input [127:0] datain1;
|
||||||
|
output [127:0] dataout1;
|
||||||
|
|
||||||
|
wire [6:0] enc_out;
|
||||||
|
reg [127:0] data_encin;
|
||||||
|
reg [6:0] data_encout;
|
||||||
|
|
||||||
|
wire [6:0] enc_out1;
|
||||||
|
reg [127:0] data_encin1;
|
||||||
|
reg [6:0] data_encout1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
encoder128 U01(.datain(data_encin),.dataout(enc_out));
|
||||||
|
decoder128 U02(.datain(data_encout),.dataout(dataout));
|
||||||
|
|
||||||
|
encoder128 U011(.datain(data_encin1),.dataout(enc_out1));
|
||||||
|
decoder128 U021(.datain(data_encout1),.dataout(dataout1));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clock)
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
if (reset)
|
||||||
|
|
||||||
|
data_encin <= 127'h00000;
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
data_encin <= datain;
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clock)
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
if (reset)
|
||||||
|
|
||||||
|
data_encout <= 7'h0;
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
data_encout<= enc_out;
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clock)
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
if (reset)
|
||||||
|
|
||||||
|
data_encin1 <= 127'h00000;
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
data_encin1 <= datain1;
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clock)
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
if (reset)
|
||||||
|
|
||||||
|
data_encout1 <= 7'h0;
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
data_encout1<= enc_out1;
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,75 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// WISHBONE SD Card Controller IP Core ////
|
||||||
|
//// ////
|
||||||
|
//// bistable_domain_cross.v ////
|
||||||
|
//// ////
|
||||||
|
//// This file is part of the WISHBONE SD Card ////
|
||||||
|
//// Controller IP Core project ////
|
||||||
|
//// http://opencores.org/project,sd_card_controller ////
|
||||||
|
//// ////
|
||||||
|
//// Description ////
|
||||||
|
//// Clock synchronisation beetween two clock domains. ////
|
||||||
|
//// Assumption is that input signal duration has to be at least ////
|
||||||
|
//// one clk_b clock period. ////
|
||||||
|
//// ////
|
||||||
|
//// Author(s): ////
|
||||||
|
//// - Marek Czerski, ma.czerski@gmail.com ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2013 Authors ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer. ////
|
||||||
|
//// ////
|
||||||
|
//// This source file is free software; you can redistribute it ////
|
||||||
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||||
|
//// Public License as published by the Free Software Foundation; ////
|
||||||
|
//// either version 2.1 of the License, or (at your option) any ////
|
||||||
|
//// later version. ////
|
||||||
|
//// ////
|
||||||
|
//// This source is distributed in the hope that it will be ////
|
||||||
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||||
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||||
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||||
|
//// details. ////
|
||||||
|
//// ////
|
||||||
|
//// You should have received a copy of the GNU Lesser General ////
|
||||||
|
//// Public License along with this source; if not, download it ////
|
||||||
|
//// from http://www.opencores.org/lgpl.shtml ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
module bistable_domain_cross(
|
||||||
|
rst,
|
||||||
|
clk_a,
|
||||||
|
in,
|
||||||
|
clk_b,
|
||||||
|
out
|
||||||
|
);
|
||||||
|
parameter width = 1;
|
||||||
|
input rst;
|
||||||
|
input clk_a;
|
||||||
|
input [width-1:0] in;
|
||||||
|
input clk_b;
|
||||||
|
output [width-1:0] out;
|
||||||
|
|
||||||
|
// We use a two-stages shift-register to synchronize in to the clk_b clock domain
|
||||||
|
reg [width-1:0] sync_clk_b [1:0];
|
||||||
|
always @(posedge clk_b or posedge rst)
|
||||||
|
begin
|
||||||
|
if (rst == 1) begin
|
||||||
|
sync_clk_b[0] <= 0;
|
||||||
|
sync_clk_b[1] <= 0;
|
||||||
|
end else begin
|
||||||
|
sync_clk_b[0] <= in;
|
||||||
|
sync_clk_b[1] <= sync_clk_b[0];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign out = sync_clk_b[1]; // new signal synchronized to (=ready to be used in) clk_b domain
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,64 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// WISHBONE SD Card Controller IP Core ////
|
||||||
|
//// ////
|
||||||
|
//// edge_detect.v ////
|
||||||
|
//// ////
|
||||||
|
//// This file is part of the WISHBONE SD Card ////
|
||||||
|
//// Controller IP Core project ////
|
||||||
|
//// http://opencores.org/project,sd_card_controller ////
|
||||||
|
//// ////
|
||||||
|
//// Description ////
|
||||||
|
//// Signal edge detection. If input signal transitions between ////
|
||||||
|
//// two states, output signal is generated for one clock cycle. ////
|
||||||
|
//// ////
|
||||||
|
//// Author(s): ////
|
||||||
|
//// - Marek Czerski, ma.czerski@gmail.com ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2013 Authors ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer. ////
|
||||||
|
//// ////
|
||||||
|
//// This source file is free software; you can redistribute it ////
|
||||||
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||||
|
//// Public License as published by the Free Software Foundation; ////
|
||||||
|
//// either version 2.1 of the License, or (at your option) any ////
|
||||||
|
//// later version. ////
|
||||||
|
//// ////
|
||||||
|
//// This source is distributed in the hope that it will be ////
|
||||||
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||||
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||||
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||||
|
//// details. ////
|
||||||
|
//// ////
|
||||||
|
//// You should have received a copy of the GNU Lesser General ////
|
||||||
|
//// Public License along with this source; if not, download it ////
|
||||||
|
//// from http://www.opencores.org/lgpl.shtml ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
module edge_detect (
|
||||||
|
input rst,
|
||||||
|
input clk,
|
||||||
|
input sig,
|
||||||
|
output rise,
|
||||||
|
output fall
|
||||||
|
);
|
||||||
|
|
||||||
|
reg [1:0] sig_reg;
|
||||||
|
|
||||||
|
always @(posedge clk or posedge rst)
|
||||||
|
if (rst == 1'b1)
|
||||||
|
sig_reg <= 2'b00;
|
||||||
|
else
|
||||||
|
sig_reg <= {sig_reg[0], sig};
|
||||||
|
|
||||||
|
assign rise = sig_reg[0] == 1'b1 && sig_reg[1] == 1'b0 ? 1'b1 : 1'b0;
|
||||||
|
assign fall = sig_reg[0] == 1'b0 && sig_reg[1] == 1'b1 ? 1'b1 : 1'b0;
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,501 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Generic Dual-Port Synchronous RAM ////
|
||||||
|
//// ////
|
||||||
|
//// This file is part of memory library available from ////
|
||||||
|
//// http://www.opencores.org/cvsweb.shtml/generic_memories/ ////
|
||||||
|
//// ////
|
||||||
|
//// Description ////
|
||||||
|
//// This block is a wrapper with common dual-port ////
|
||||||
|
//// synchronous memory interface for different ////
|
||||||
|
//// types of ASIC and FPGA RAMs. Beside universal memory ////
|
||||||
|
//// interface it also provides behavioral model of generic ////
|
||||||
|
//// dual-port synchronous RAM. ////
|
||||||
|
//// It also contains a fully synthesizeable model for FPGAs. ////
|
||||||
|
//// It should be used in all OPENCORES designs that want to be ////
|
||||||
|
//// portable accross different target technologies and ////
|
||||||
|
//// independent of target memory. ////
|
||||||
|
//// ////
|
||||||
|
//// Supported ASIC RAMs are: ////
|
||||||
|
//// - Artisan Dual-Port Sync RAM ////
|
||||||
|
//// - Avant! Two-Port Sync RAM (*) ////
|
||||||
|
//// - Virage 2-port Sync RAM ////
|
||||||
|
//// ////
|
||||||
|
//// Supported FPGA RAMs are: ////
|
||||||
|
//// - Generic FPGA (VENDOR_FPGA) ////
|
||||||
|
//// Tested RAMs: Altera, Xilinx ////
|
||||||
|
//// Synthesis tools: LeonardoSpectrum, Synplicity ////
|
||||||
|
//// - Xilinx (VENDOR_XILINX) ////
|
||||||
|
//// - Altera (VENDOR_ALTERA) ////
|
||||||
|
//// ////
|
||||||
|
//// To Do: ////
|
||||||
|
//// - fix Avant! ////
|
||||||
|
//// - add additional RAMs (VS etc) ////
|
||||||
|
//// ////
|
||||||
|
//// Author(s): ////
|
||||||
|
//// - Richard Herveille, richard@asics.ws ////
|
||||||
|
//// - Damjan Lampret, lampret@opencores.org ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer. ////
|
||||||
|
//// ////
|
||||||
|
//// This source file is free software; you can redistribute it ////
|
||||||
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||||
|
//// Public License as published by the Free Software Foundation; ////
|
||||||
|
//// either version 2.1 of the License, or (at your option) any ////
|
||||||
|
//// later version. ////
|
||||||
|
//// ////
|
||||||
|
//// This source is distributed in the hope that it will be ////
|
||||||
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||||
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||||
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||||
|
//// details. ////
|
||||||
|
//// ////
|
||||||
|
//// You should have received a copy of the GNU Lesser General ////
|
||||||
|
//// Public License along with this source; if not, download it ////
|
||||||
|
//// from http://www.opencores.org/lgpl.shtml ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// CVS Revision History
|
||||||
|
//
|
||||||
|
// $Log: not supported by cvs2svn $
|
||||||
|
// Revision 1.3 2001/11/09 00:34:18 samg
|
||||||
|
// minor changes: unified with all common rams
|
||||||
|
//
|
||||||
|
// Revision 1.2 2001/11/08 19:11:31 samg
|
||||||
|
// added valid checks to behvioral model
|
||||||
|
//
|
||||||
|
// Revision 1.1.1.1 2001/09/14 09:57:10 rherveille
|
||||||
|
// Major cleanup.
|
||||||
|
// Files are now compliant to Altera & Xilinx memories.
|
||||||
|
// Memories are now compatible, i.e. drop-in replacements.
|
||||||
|
// Added synthesizeable generic FPGA description.
|
||||||
|
// Created "generic_memories" cvs entry.
|
||||||
|
//
|
||||||
|
// Revision 1.1.1.2 2001/08/21 13:09:27 damjan
|
||||||
|
// *** empty log message ***
|
||||||
|
//
|
||||||
|
// Revision 1.1 2001/08/20 18:23:20 damjan
|
||||||
|
// Initial revision
|
||||||
|
//
|
||||||
|
// Revision 1.1 2001/08/09 13:39:33 lampret
|
||||||
|
// Major clean-up.
|
||||||
|
//
|
||||||
|
// Revision 1.2 2001/07/30 05:38:02 lampret
|
||||||
|
// Adding empty directories required by HDL coding guidelines
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
//`include "timescale.v"
|
||||||
|
|
||||||
|
`define VENDOR_FPGA
|
||||||
|
//`define VENDOR_XILINX
|
||||||
|
//`define VENDOR_ALTERA
|
||||||
|
|
||||||
|
module generic_dpram(
|
||||||
|
// Generic synchronous dual-port RAM interface
|
||||||
|
rclk, rrst, rce, oe, raddr, do,
|
||||||
|
wclk, wrst, wce, we, waddr, di
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Default address and data buses width
|
||||||
|
//
|
||||||
|
parameter aw = 5; // number of bits in address-bus
|
||||||
|
parameter dw = 16; // number of bits in data-bus
|
||||||
|
|
||||||
|
//
|
||||||
|
// Generic synchronous double-port RAM interface
|
||||||
|
//
|
||||||
|
// read port
|
||||||
|
input rclk; // read clock, rising edge trigger
|
||||||
|
input rrst; // read port reset, active high
|
||||||
|
input rce; // read port chip enable, active high
|
||||||
|
input oe; // output enable, active high
|
||||||
|
input [aw-1:0] raddr; // read address
|
||||||
|
output [dw-1:0] do; // data output
|
||||||
|
|
||||||
|
// write port
|
||||||
|
input wclk; // write clock, rising edge trigger
|
||||||
|
input wrst; // write port reset, active high
|
||||||
|
input wce; // write port chip enable, active high
|
||||||
|
input we; // write enable, active high
|
||||||
|
input [aw-1:0] waddr; // write address
|
||||||
|
input [dw-1:0] di; // data input
|
||||||
|
|
||||||
|
//
|
||||||
|
// Module body
|
||||||
|
//
|
||||||
|
|
||||||
|
`ifdef VENDOR_FPGA
|
||||||
|
//
|
||||||
|
// Instantiation synthesizeable FPGA memory
|
||||||
|
//
|
||||||
|
// This code has been tested using LeonardoSpectrum and Synplicity.
|
||||||
|
// The code correctly instantiates Altera EABs and Xilinx BlockRAMs.
|
||||||
|
//
|
||||||
|
reg [dw-1:0] mem [(1<<aw) -1:0]; //pragma attribute mem block_ram false
|
||||||
|
reg [aw-1:0] ra; // register read address
|
||||||
|
|
||||||
|
// read operation
|
||||||
|
always @(posedge rclk)
|
||||||
|
if (rce)
|
||||||
|
ra <= raddr;
|
||||||
|
|
||||||
|
assign do = mem[ra];
|
||||||
|
|
||||||
|
// write operation
|
||||||
|
always@(posedge wclk)
|
||||||
|
if (we && wce)
|
||||||
|
mem[waddr] <= di;
|
||||||
|
|
||||||
|
`else
|
||||||
|
|
||||||
|
`ifdef VENDOR_XILINX
|
||||||
|
//
|
||||||
|
// Instantiation of FPGA memory:
|
||||||
|
//
|
||||||
|
// Virtex/Spartan2 BlockRAMs
|
||||||
|
//
|
||||||
|
xilinx_ram_dp xilinx_ram(
|
||||||
|
// read port
|
||||||
|
.CLKA(rclk),
|
||||||
|
.RSTA(rrst),
|
||||||
|
.ENA(rce),
|
||||||
|
.ADDRA(raddr),
|
||||||
|
.DIA( {dw{1'b0}} ),
|
||||||
|
.WEA(1'b0),
|
||||||
|
.DOA(do),
|
||||||
|
|
||||||
|
// write port
|
||||||
|
.CLKB(wclk),
|
||||||
|
.RSTB(wrst),
|
||||||
|
.ENB(wce),
|
||||||
|
.ADDRB(waddr),
|
||||||
|
.DIB(di),
|
||||||
|
.WEB(we),
|
||||||
|
.DOB()
|
||||||
|
);
|
||||||
|
|
||||||
|
defparam
|
||||||
|
xilinx_ram.dwidth = dw,
|
||||||
|
xilinx_ram.awidth = aw;
|
||||||
|
|
||||||
|
`else
|
||||||
|
|
||||||
|
`ifdef VENDOR_ALTERA
|
||||||
|
//
|
||||||
|
// Instantiation of FPGA memory:
|
||||||
|
//
|
||||||
|
// Altera FLEX/APEX EABs
|
||||||
|
//
|
||||||
|
altera_ram_dp altera_ram(
|
||||||
|
// read port
|
||||||
|
.rdclock(rclk),
|
||||||
|
.rdclocken(rce),
|
||||||
|
.rdaddress(raddr),
|
||||||
|
.q(do),
|
||||||
|
|
||||||
|
// write port
|
||||||
|
.wrclock(wclk),
|
||||||
|
.wrclocken(wce),
|
||||||
|
.wren(we),
|
||||||
|
.wraddress(waddr),
|
||||||
|
.data(di)
|
||||||
|
);
|
||||||
|
|
||||||
|
defparam
|
||||||
|
altera_ram.dwidth = dw,
|
||||||
|
altera_ram.awidth = aw;
|
||||||
|
|
||||||
|
`else
|
||||||
|
|
||||||
|
`ifdef VENDOR_ARTISAN
|
||||||
|
|
||||||
|
//
|
||||||
|
// Instantiation of ASIC memory:
|
||||||
|
//
|
||||||
|
// Artisan Synchronous Double-Port RAM (ra2sh)
|
||||||
|
//
|
||||||
|
art_hsdp #(dw, 1<<aw, aw) artisan_sdp(
|
||||||
|
// read port
|
||||||
|
.qa(do),
|
||||||
|
.clka(rclk),
|
||||||
|
.cena(~rce),
|
||||||
|
.wena(1'b1),
|
||||||
|
.aa(raddr),
|
||||||
|
.da( {dw{1'b0}} ),
|
||||||
|
.oena(~oe),
|
||||||
|
|
||||||
|
// write port
|
||||||
|
.qb(),
|
||||||
|
.clkb(wclk),
|
||||||
|
.cenb(~wce),
|
||||||
|
.wenb(~we),
|
||||||
|
.ab(waddr),
|
||||||
|
.db(di),
|
||||||
|
.oenb(1'b1)
|
||||||
|
);
|
||||||
|
|
||||||
|
`else
|
||||||
|
|
||||||
|
`ifdef VENDOR_AVANT
|
||||||
|
|
||||||
|
//
|
||||||
|
// Instantiation of ASIC memory:
|
||||||
|
//
|
||||||
|
// Avant! Asynchronous Two-Port RAM
|
||||||
|
//
|
||||||
|
avant_atp avant_atp(
|
||||||
|
.web(~we),
|
||||||
|
.reb(),
|
||||||
|
.oeb(~oe),
|
||||||
|
.rcsb(),
|
||||||
|
.wcsb(),
|
||||||
|
.ra(raddr),
|
||||||
|
.wa(waddr),
|
||||||
|
.di(di),
|
||||||
|
.do(do)
|
||||||
|
);
|
||||||
|
|
||||||
|
`else
|
||||||
|
|
||||||
|
`ifdef VENDOR_VIRAGE
|
||||||
|
|
||||||
|
//
|
||||||
|
// Instantiation of ASIC memory:
|
||||||
|
//
|
||||||
|
// Virage Synchronous 2-port R/W RAM
|
||||||
|
//
|
||||||
|
virage_stp virage_stp(
|
||||||
|
// read port
|
||||||
|
.CLKA(rclk),
|
||||||
|
.MEA(rce_a),
|
||||||
|
.ADRA(raddr),
|
||||||
|
.DA( {dw{1'b0}} ),
|
||||||
|
.WEA(1'b0),
|
||||||
|
.OEA(oe),
|
||||||
|
.QA(do),
|
||||||
|
|
||||||
|
// write port
|
||||||
|
.CLKB(wclk),
|
||||||
|
.MEB(wce),
|
||||||
|
.ADRB(waddr),
|
||||||
|
.DB(di),
|
||||||
|
.WEB(we),
|
||||||
|
.OEB(1'b1),
|
||||||
|
.QB()
|
||||||
|
);
|
||||||
|
|
||||||
|
`else
|
||||||
|
|
||||||
|
//
|
||||||
|
// Generic dual-port synchronous RAM model
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Generic RAM's registers and wires
|
||||||
|
//
|
||||||
|
reg [dw-1:0] mem [(1<<aw)-1:0]; // RAM content
|
||||||
|
reg [dw-1:0] do_reg; // RAM data output register
|
||||||
|
|
||||||
|
//
|
||||||
|
// Data output drivers
|
||||||
|
//
|
||||||
|
assign do = (oe & rce) ? do_reg : {dw{1'bz}};
|
||||||
|
|
||||||
|
// read operation
|
||||||
|
always @(posedge rclk)
|
||||||
|
if (rce)
|
||||||
|
do_reg <= (we && (waddr==raddr)) ? {dw{1'b x}} : mem[raddr];
|
||||||
|
|
||||||
|
// write operation
|
||||||
|
always @(posedge wclk)
|
||||||
|
if (wce && we)
|
||||||
|
mem[waddr] <= di;
|
||||||
|
|
||||||
|
|
||||||
|
// Task prints range of memory
|
||||||
|
// *** Remember that tasks are non reentrant, don't call this task in parallel for multiple instantiations.
|
||||||
|
task print_ram;
|
||||||
|
input [aw-1:0] start;
|
||||||
|
input [aw-1:0] finish;
|
||||||
|
integer rnum;
|
||||||
|
begin
|
||||||
|
for (rnum=start;rnum<=finish;rnum=rnum+1)
|
||||||
|
$display("Addr %h = %h",rnum,mem[rnum]);
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
`endif // !VENDOR_VIRAGE
|
||||||
|
`endif // !VENDOR_AVANT
|
||||||
|
`endif // !VENDOR_ARTISAN
|
||||||
|
`endif // !VENDOR_ALTERA
|
||||||
|
`endif // !VENDOR_XILINX
|
||||||
|
`endif // !VENDOR_FPGA
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
//
|
||||||
|
// Black-box modules
|
||||||
|
//
|
||||||
|
|
||||||
|
`ifdef VENDOR_ALTERA
|
||||||
|
module altera_ram_dp(
|
||||||
|
data,
|
||||||
|
wraddress,
|
||||||
|
rdaddress,
|
||||||
|
wren,
|
||||||
|
wrclock,
|
||||||
|
wrclocken,
|
||||||
|
rdclock,
|
||||||
|
rdclocken,
|
||||||
|
q) /* synthesis black_box */;
|
||||||
|
|
||||||
|
parameter awidth = 7;
|
||||||
|
parameter dwidth = 8;
|
||||||
|
|
||||||
|
input [dwidth -1:0] data;
|
||||||
|
input [awidth -1:0] wraddress;
|
||||||
|
input [awidth -1:0] rdaddress;
|
||||||
|
input wren;
|
||||||
|
input wrclock;
|
||||||
|
input wrclocken;
|
||||||
|
input rdclock;
|
||||||
|
input rdclocken;
|
||||||
|
output [dwidth -1:0] q;
|
||||||
|
|
||||||
|
// synopsis translate_off
|
||||||
|
// exemplar translate_off
|
||||||
|
|
||||||
|
syn_dpram_rowr #(
|
||||||
|
"UNUSED",
|
||||||
|
dwidth,
|
||||||
|
awidth,
|
||||||
|
1 << awidth
|
||||||
|
)
|
||||||
|
altera_dpram_model (
|
||||||
|
// read port
|
||||||
|
.RdClock(rdclock),
|
||||||
|
.RdClken(rdclocken),
|
||||||
|
.RdAddress(rdaddress),
|
||||||
|
.RdEn(1'b1),
|
||||||
|
.Q(q),
|
||||||
|
|
||||||
|
// write port
|
||||||
|
.WrClock(wrclock),
|
||||||
|
.WrClken(wrclocken),
|
||||||
|
.WrAddress(wraddress),
|
||||||
|
.WrEn(wren),
|
||||||
|
.Data(data)
|
||||||
|
);
|
||||||
|
|
||||||
|
// exemplar translate_on
|
||||||
|
// synopsis translate_on
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
`endif // VENDOR_ALTERA
|
||||||
|
|
||||||
|
`ifdef VENDOR_XILINX
|
||||||
|
module xilinx_ram_dp (
|
||||||
|
ADDRA,
|
||||||
|
CLKA,
|
||||||
|
ADDRB,
|
||||||
|
CLKB,
|
||||||
|
DIA,
|
||||||
|
WEA,
|
||||||
|
DIB,
|
||||||
|
WEB,
|
||||||
|
ENA,
|
||||||
|
ENB,
|
||||||
|
RSTA,
|
||||||
|
RSTB,
|
||||||
|
DOA,
|
||||||
|
DOB) /* synthesis black_box */ ;
|
||||||
|
|
||||||
|
parameter awidth = 7;
|
||||||
|
parameter dwidth = 8;
|
||||||
|
|
||||||
|
// port_a
|
||||||
|
input CLKA;
|
||||||
|
input RSTA;
|
||||||
|
input ENA;
|
||||||
|
input [awidth-1:0] ADDRA;
|
||||||
|
input [dwidth-1:0] DIA;
|
||||||
|
input WEA;
|
||||||
|
output [dwidth-1:0] DOA;
|
||||||
|
|
||||||
|
// port_b
|
||||||
|
input CLKB;
|
||||||
|
input RSTB;
|
||||||
|
input ENB;
|
||||||
|
input [awidth-1:0] ADDRB;
|
||||||
|
input [dwidth-1:0] DIB;
|
||||||
|
input WEB;
|
||||||
|
output [dwidth-1:0] DOB;
|
||||||
|
|
||||||
|
// insert simulation model
|
||||||
|
|
||||||
|
|
||||||
|
// synopsys translate_off
|
||||||
|
// exemplar translate_off
|
||||||
|
|
||||||
|
C_MEM_DP_BLOCK_V1_0 #(
|
||||||
|
awidth,
|
||||||
|
awidth,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
"0",
|
||||||
|
1 << awidth,
|
||||||
|
1 << awidth,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
"",
|
||||||
|
16,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
dwidth,
|
||||||
|
dwidth)
|
||||||
|
xilinx_dpram_model (
|
||||||
|
.ADDRA(ADDRA),
|
||||||
|
.CLKA(CLKA),
|
||||||
|
.ADDRB(ADDRB),
|
||||||
|
.CLKB(CLKB),
|
||||||
|
.DIA(DIA),
|
||||||
|
.WEA(WEA),
|
||||||
|
.DIB(DIB),
|
||||||
|
.WEB(WEB),
|
||||||
|
.ENA(ENA),
|
||||||
|
.ENB(ENB),
|
||||||
|
.RSTA(RSTA),
|
||||||
|
.RSTB(RSTB),
|
||||||
|
.DOA(DOA),
|
||||||
|
.DOB(DOB));
|
||||||
|
|
||||||
|
// exemplar translate_on
|
||||||
|
// synopsys translate_on
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
`endif // VENDOR_XILINX
|
|
@ -0,0 +1,324 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Universal FIFO Dual Clock, gray encoded ////
|
||||||
|
//// ////
|
||||||
|
//// ////
|
||||||
|
//// Author: Rudolf Usselmann ////
|
||||||
|
//// rudi@asics.ws ////
|
||||||
|
//// ////
|
||||||
|
//// ////
|
||||||
|
//// D/L from: http://www.opencores.org/cores/generic_fifos/ ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
|
||||||
|
//// www.asics.ws ////
|
||||||
|
//// rudi@asics.ws ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer.////
|
||||||
|
//// ////
|
||||||
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||||
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||||
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||||
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||||
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||||
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||||
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||||
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||||
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||||
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||||
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||||
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||||
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||||
|
//// ////
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// CVS Log
|
||||||
|
//
|
||||||
|
// $Id: generic_fifo_dc_gray.v,v 1.2 2004-01-13 09:11:55 rudi Exp $
|
||||||
|
//
|
||||||
|
// $Date: 2004-01-13 09:11:55 $
|
||||||
|
// $Revision: 1.2 $
|
||||||
|
// $Author: rudi $
|
||||||
|
// $Locker: $
|
||||||
|
// $State: Exp $
|
||||||
|
//
|
||||||
|
// Change History:
|
||||||
|
// $Log: not supported by cvs2svn $
|
||||||
|
// Revision 1.1 2003/10/14 09:34:41 rudi
|
||||||
|
// Dual clock FIFO Gray Code encoded version.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
//`include "timescale.v"
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Description
|
||||||
|
===========
|
||||||
|
|
||||||
|
I/Os
|
||||||
|
----
|
||||||
|
rd_clk Read Port Clock
|
||||||
|
wr_clk Write Port Clock
|
||||||
|
rst low active, either sync. or async. master reset (see below how to select)
|
||||||
|
clr synchronous clear (just like reset but always synchronous), high active
|
||||||
|
re read enable, synchronous, high active
|
||||||
|
we read enable, synchronous, high active
|
||||||
|
din Data Input
|
||||||
|
dout Data Output
|
||||||
|
|
||||||
|
full Indicates the FIFO is full (driven at the rising edge of wr_clk)
|
||||||
|
empty Indicates the FIFO is empty (driven at the rising edge of rd_clk)
|
||||||
|
|
||||||
|
wr_level indicates the FIFO level:
|
||||||
|
2'b00 0-25% full
|
||||||
|
2'b01 25-50% full
|
||||||
|
2'b10 50-75% full
|
||||||
|
2'b11 %75-100% full
|
||||||
|
|
||||||
|
rd_level indicates the FIFO level:
|
||||||
|
2'b00 0-25% empty
|
||||||
|
2'b01 25-50% empty
|
||||||
|
2'b10 50-75% empty
|
||||||
|
2'b11 %75-100% empty
|
||||||
|
|
||||||
|
Status Timing
|
||||||
|
-------------
|
||||||
|
All status outputs are registered. They are asserted immediately
|
||||||
|
as the full/empty condition occurs, however, there is a 2 cycle
|
||||||
|
delay before they are de-asserted once the condition is not true
|
||||||
|
anymore.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
The FIFO takes 2 parameters:
|
||||||
|
dw Data bus width
|
||||||
|
aw Address bus width (Determines the FIFO size by evaluating 2^aw)
|
||||||
|
|
||||||
|
Synthesis Results
|
||||||
|
-----------------
|
||||||
|
In a Spartan 2e a 8 bit wide, 8 entries deep FIFO, takes 97 LUTs and runs
|
||||||
|
at about 113 MHz (IO insertion disabled).
|
||||||
|
|
||||||
|
Misc
|
||||||
|
----
|
||||||
|
This design assumes you will do appropriate status checking externally.
|
||||||
|
|
||||||
|
IMPORTANT ! writing while the FIFO is full or reading while the FIFO is
|
||||||
|
empty will place the FIFO in an undefined state.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
module generic_fifo_dc_gray( rd_clk, wr_clk, rst, clr, din, we,
|
||||||
|
dout, re, full, empty, wr_level, rd_level );
|
||||||
|
|
||||||
|
parameter dw=16;
|
||||||
|
parameter aw=8;
|
||||||
|
|
||||||
|
input rd_clk, wr_clk, rst, clr;
|
||||||
|
input [dw-1:0] din;
|
||||||
|
input we;
|
||||||
|
output [dw-1:0] dout;
|
||||||
|
input re;
|
||||||
|
output full;
|
||||||
|
output empty;
|
||||||
|
output [1:0] wr_level;
|
||||||
|
output [1:0] rd_level;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Local Wires
|
||||||
|
//
|
||||||
|
|
||||||
|
reg [aw:0] wp_bin, wp_gray;
|
||||||
|
reg [aw:0] rp_bin, rp_gray;
|
||||||
|
reg [aw:0] wp_s, rp_s;
|
||||||
|
reg full, empty;
|
||||||
|
|
||||||
|
wire [aw:0] wp_bin_next, wp_gray_next;
|
||||||
|
wire [aw:0] rp_bin_next, rp_gray_next;
|
||||||
|
|
||||||
|
wire [aw:0] wp_bin_x, rp_bin_x;
|
||||||
|
reg [aw-1:0] d1, d2;
|
||||||
|
|
||||||
|
reg rd_rst, wr_rst;
|
||||||
|
reg rd_rst_r, wr_rst_r;
|
||||||
|
reg rd_clr, wr_clr;
|
||||||
|
reg rd_clr_r, wr_clr_r;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Reset Logic
|
||||||
|
//
|
||||||
|
|
||||||
|
always @(posedge rd_clk or negedge rst)
|
||||||
|
if(!rst) rd_rst <= 1'b0;
|
||||||
|
else
|
||||||
|
if(rd_rst_r) rd_rst <= 1'b1; // Release Reset
|
||||||
|
|
||||||
|
always @(posedge rd_clk or negedge rst)
|
||||||
|
if(!rst) rd_rst_r <= 1'b0;
|
||||||
|
else rd_rst_r <= 1'b1;
|
||||||
|
|
||||||
|
always @(posedge wr_clk or negedge rst)
|
||||||
|
if(!rst) wr_rst <= 1'b0;
|
||||||
|
else
|
||||||
|
if(wr_rst_r) wr_rst <= 1'b1; // Release Reset
|
||||||
|
|
||||||
|
always @(posedge wr_clk or negedge rst)
|
||||||
|
if(!rst) wr_rst_r <= 1'b0;
|
||||||
|
else wr_rst_r <= 1'b1;
|
||||||
|
|
||||||
|
always @(posedge rd_clk or posedge clr)
|
||||||
|
if(clr) rd_clr <= 1'b1;
|
||||||
|
else
|
||||||
|
if(!rd_clr_r) rd_clr <= 1'b0; // Release Clear
|
||||||
|
|
||||||
|
always @(posedge rd_clk or posedge clr)
|
||||||
|
if(clr) rd_clr_r <= 1'b1;
|
||||||
|
else rd_clr_r <= 1'b0;
|
||||||
|
|
||||||
|
always @(posedge wr_clk or posedge clr)
|
||||||
|
if(clr) wr_clr <= 1'b1;
|
||||||
|
else
|
||||||
|
if(!wr_clr_r) wr_clr <= 1'b0; // Release Clear
|
||||||
|
|
||||||
|
always @(posedge wr_clk or posedge clr)
|
||||||
|
if(clr) wr_clr_r <= 1'b1;
|
||||||
|
else wr_clr_r <= 1'b0;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Memory Block
|
||||||
|
//
|
||||||
|
|
||||||
|
generic_dpram #(aw,dw) u0(
|
||||||
|
.rclk( rd_clk ),
|
||||||
|
.rrst( !rd_rst ),
|
||||||
|
.rce( 1'b1 ),
|
||||||
|
.oe( 1'b1 ),
|
||||||
|
.raddr( rp_bin[aw-1:0] ),
|
||||||
|
.do( dout ),
|
||||||
|
.wclk( wr_clk ),
|
||||||
|
.wrst( !wr_rst ),
|
||||||
|
.wce( 1'b1 ),
|
||||||
|
.we( we ),
|
||||||
|
.waddr( wp_bin[aw-1:0] ),
|
||||||
|
.di( din )
|
||||||
|
);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Read/Write Pointers Logic
|
||||||
|
//
|
||||||
|
|
||||||
|
always @(posedge wr_clk)
|
||||||
|
if(!wr_rst) wp_bin <= {aw+1{1'b0}};
|
||||||
|
else
|
||||||
|
if(wr_clr) wp_bin <= {aw+1{1'b0}};
|
||||||
|
else
|
||||||
|
if(we) wp_bin <= wp_bin_next;
|
||||||
|
|
||||||
|
always @(posedge wr_clk)
|
||||||
|
if(!wr_rst) wp_gray <= {aw+1{1'b0}};
|
||||||
|
else
|
||||||
|
if(wr_clr) wp_gray <= {aw+1{1'b0}};
|
||||||
|
else
|
||||||
|
if(we) wp_gray <= wp_gray_next;
|
||||||
|
|
||||||
|
assign wp_bin_next = wp_bin + {{aw{1'b0}},1'b1};
|
||||||
|
assign wp_gray_next = wp_bin_next ^ {1'b0, wp_bin_next[aw:1]};
|
||||||
|
|
||||||
|
always @(posedge rd_clk)
|
||||||
|
if(!rd_rst) rp_bin <= {aw+1{1'b0}};
|
||||||
|
else
|
||||||
|
if(rd_clr) rp_bin <= {aw+1{1'b0}};
|
||||||
|
else
|
||||||
|
if(re) rp_bin <= rp_bin_next;
|
||||||
|
|
||||||
|
always @(posedge rd_clk)
|
||||||
|
if(!rd_rst) rp_gray <= {aw+1{1'b0}};
|
||||||
|
else
|
||||||
|
if(rd_clr) rp_gray <= {aw+1{1'b0}};
|
||||||
|
else
|
||||||
|
if(re) rp_gray <= rp_gray_next;
|
||||||
|
|
||||||
|
assign rp_bin_next = rp_bin + {{aw{1'b0}},1'b1};
|
||||||
|
assign rp_gray_next = rp_bin_next ^ {1'b0, rp_bin_next[aw:1]};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Synchronization Logic
|
||||||
|
//
|
||||||
|
|
||||||
|
// write pointer
|
||||||
|
always @(posedge rd_clk) wp_s <= wp_gray;
|
||||||
|
|
||||||
|
// read pointer
|
||||||
|
always @(posedge wr_clk) rp_s <= rp_gray;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Registered Full & Empty Flags
|
||||||
|
//
|
||||||
|
|
||||||
|
assign wp_bin_x = wp_s ^ {1'b0, wp_bin_x[aw:1]}; // convert gray to binary
|
||||||
|
assign rp_bin_x = rp_s ^ {1'b0, rp_bin_x[aw:1]}; // convert gray to binary
|
||||||
|
|
||||||
|
always @(posedge rd_clk)
|
||||||
|
empty <= (wp_s == rp_gray) | (re & (wp_s == rp_gray_next));
|
||||||
|
|
||||||
|
always @(posedge wr_clk)
|
||||||
|
full <= ((wp_bin[aw-1:0] == rp_bin_x[aw-1:0]) & (wp_bin[aw] != rp_bin_x[aw])) |
|
||||||
|
(we & (wp_bin_next[aw-1:0] == rp_bin_x[aw-1:0]) & (wp_bin_next[aw] != rp_bin_x[aw]));
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Registered Level Indicators
|
||||||
|
//
|
||||||
|
reg [1:0] wr_level;
|
||||||
|
reg [1:0] rd_level;
|
||||||
|
reg [aw-1:0] wp_bin_xr, rp_bin_xr;
|
||||||
|
reg full_rc;
|
||||||
|
reg full_wc;
|
||||||
|
|
||||||
|
always @(posedge wr_clk) full_wc <= full;
|
||||||
|
always @(posedge wr_clk) rp_bin_xr <= ~rp_bin_x[aw-1:0] + {{aw-1{1'b0}}, 1'b1};
|
||||||
|
always @(posedge wr_clk) d1 <= wp_bin[aw-1:0] + rp_bin_xr[aw-1:0];
|
||||||
|
|
||||||
|
always @(posedge wr_clk) wr_level <= {d1[aw-1] | full | full_wc, d1[aw-2] | full | full_wc};
|
||||||
|
|
||||||
|
always @(posedge rd_clk) wp_bin_xr <= ~wp_bin_x[aw-1:0];
|
||||||
|
always @(posedge rd_clk) d2 <= rp_bin[aw-1:0] + wp_bin_xr[aw-1:0];
|
||||||
|
|
||||||
|
always @(posedge rd_clk) full_rc <= full;
|
||||||
|
always @(posedge rd_clk) rd_level <= full_rc ? 2'h0 : {d2[aw-1] | empty, d2[aw-2] | empty};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Sanity Check
|
||||||
|
//
|
||||||
|
|
||||||
|
// synopsys translate_off
|
||||||
|
//always @(posedge wr_clk)
|
||||||
|
// if(we && full)
|
||||||
|
// $display("%m WARNING: Writing while fifo is FULL (%t)",$time);
|
||||||
|
|
||||||
|
//always @(posedge rd_clk)
|
||||||
|
// if(re && empty)
|
||||||
|
// $display("%m WARNING: Reading while fifo is EMPTY (%t)",$time);
|
||||||
|
// synopsys translate_on
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// WISHBONE SD Card Controller IP Core ////
|
||||||
|
//// ////
|
||||||
|
//// monostable_domain_cross.v ////
|
||||||
|
//// ////
|
||||||
|
//// This file is part of the WISHBONE SD Card ////
|
||||||
|
//// Controller IP Core project ////
|
||||||
|
//// http://opencores.org/project,sd_card_controller ////
|
||||||
|
//// ////
|
||||||
|
//// Description ////
|
||||||
|
//// Clock synchronisation beetween two clock domains. ////
|
||||||
|
//// Assumption is that input signal duration is always ////
|
||||||
|
//// one clk_a clock period. If that is true output signal ////
|
||||||
|
//// duration is always one clk_b clock period. ////
|
||||||
|
//// ////
|
||||||
|
//// Author(s): ////
|
||||||
|
//// - Marek Czerski, ma.czerski@gmail.com ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2013 Authors ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer. ////
|
||||||
|
//// ////
|
||||||
|
//// This source file is free software; you can redistribute it ////
|
||||||
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||||
|
//// Public License as published by the Free Software Foundation; ////
|
||||||
|
//// either version 2.1 of the License, or (at your option) any ////
|
||||||
|
//// later version. ////
|
||||||
|
//// ////
|
||||||
|
//// This source is distributed in the hope that it will be ////
|
||||||
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||||
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||||
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||||
|
//// details. ////
|
||||||
|
//// ////
|
||||||
|
//// You should have received a copy of the GNU Lesser General ////
|
||||||
|
//// Public License along with this source; if not, download it ////
|
||||||
|
//// from http://www.opencores.org/lgpl.shtml ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
module monostable_domain_cross(
|
||||||
|
input rst,
|
||||||
|
input clk_a,
|
||||||
|
input in,
|
||||||
|
input clk_b,
|
||||||
|
output out
|
||||||
|
);
|
||||||
|
|
||||||
|
// this changes level when the in is seen in clk_a
|
||||||
|
reg toggle_clk_a;
|
||||||
|
always @(posedge clk_a or posedge rst)
|
||||||
|
begin
|
||||||
|
if (rst)
|
||||||
|
toggle_clk_a <= 0;
|
||||||
|
else
|
||||||
|
toggle_clk_a <= toggle_clk_a ^ in;
|
||||||
|
end
|
||||||
|
|
||||||
|
// which can then be sync-ed to clk_b
|
||||||
|
reg [2:0] sync_clk_b;
|
||||||
|
always @(posedge clk_b or posedge rst)
|
||||||
|
begin
|
||||||
|
if (rst)
|
||||||
|
sync_clk_b <= 0;
|
||||||
|
else
|
||||||
|
sync_clk_b <= {sync_clk_b[1:0], toggle_clk_a};
|
||||||
|
end
|
||||||
|
|
||||||
|
// and recreate the flag in clk_b
|
||||||
|
assign out = (sync_clk_b[2] ^ sync_clk_b[1]);
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,79 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// WISHBONE SD Card Controller IP Core ////
|
||||||
|
//// ////
|
||||||
|
//// sd_clock_divider.v ////
|
||||||
|
//// ////
|
||||||
|
//// This file is part of the WISHBONE SD Card ////
|
||||||
|
//// Controller IP Core project ////
|
||||||
|
//// http://opencores.org/project,sd_card_controller ////
|
||||||
|
//// ////
|
||||||
|
//// Description ////
|
||||||
|
//// Control of sd card clock rate ////
|
||||||
|
//// ////
|
||||||
|
//// Author(s): ////
|
||||||
|
//// - Marek Czerski, ma.czerski@gmail.com ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2013 Authors ////
|
||||||
|
//// ////
|
||||||
|
//// Based on original work by ////
|
||||||
|
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2009 Authors ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer. ////
|
||||||
|
//// ////
|
||||||
|
//// This source file is free software; you can redistribute it ////
|
||||||
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||||
|
//// Public License as published by the Free Software Foundation; ////
|
||||||
|
//// either version 2.1 of the License, or (at your option) any ////
|
||||||
|
//// later version. ////
|
||||||
|
//// ////
|
||||||
|
//// This source is distributed in the hope that it will be ////
|
||||||
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||||
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||||
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||||
|
//// details. ////
|
||||||
|
//// ////
|
||||||
|
//// You should have received a copy of the GNU Lesser General ////
|
||||||
|
//// Public License along with this source; if not, download it ////
|
||||||
|
//// from http://www.opencores.org/lgpl.shtml ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
module sd_clock_divider (
|
||||||
|
input CLK,
|
||||||
|
input [7:0] DIVIDER,
|
||||||
|
input RST,
|
||||||
|
output SD_CLK
|
||||||
|
);
|
||||||
|
|
||||||
|
reg [7:0] ClockDiv;
|
||||||
|
reg SD_CLK_O;
|
||||||
|
|
||||||
|
//assign SD_CLK = DIVIDER[7] ? CLK : SD_CLK_O;
|
||||||
|
assign SD_CLK = SD_CLK_O;
|
||||||
|
|
||||||
|
always @(posedge CLK or posedge RST)
|
||||||
|
begin
|
||||||
|
if (RST) begin
|
||||||
|
ClockDiv <= 8'b0000_0000;
|
||||||
|
SD_CLK_O <= 0;
|
||||||
|
end
|
||||||
|
else if (ClockDiv == DIVIDER) begin
|
||||||
|
ClockDiv <= 0;
|
||||||
|
SD_CLK_O <= ~SD_CLK_O;
|
||||||
|
end else begin
|
||||||
|
ClockDiv <= ClockDiv + 8'h1;
|
||||||
|
SD_CLK_O <= SD_CLK_O;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,245 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// WISHBONE SD Card Controller IP Core ////
|
||||||
|
//// ////
|
||||||
|
//// sd_cmd_master.v ////
|
||||||
|
//// ////
|
||||||
|
//// This file is part of the WISHBONE SD Card ////
|
||||||
|
//// Controller IP Core project ////
|
||||||
|
//// http://opencores.org/project,sd_card_controller ////
|
||||||
|
//// ////
|
||||||
|
//// Description ////
|
||||||
|
//// State machine resposible for controlling command transfers ////
|
||||||
|
//// on 1-bit sd card command interface ////
|
||||||
|
//// ////
|
||||||
|
//// Author(s): ////
|
||||||
|
//// - Marek Czerski, ma.czerski@gmail.com ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2013 Authors ////
|
||||||
|
//// ////
|
||||||
|
//// Based on original work by ////
|
||||||
|
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2009 Authors ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer. ////
|
||||||
|
//// ////
|
||||||
|
//// This source file is free software; you can redistribute it ////
|
||||||
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||||
|
//// Public License as published by the Free Software Foundation; ////
|
||||||
|
//// either version 2.1 of the License, or (at your option) any ////
|
||||||
|
//// later version. ////
|
||||||
|
//// ////
|
||||||
|
//// This source is distributed in the hope that it will be ////
|
||||||
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||||
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||||
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||||
|
//// details. ////
|
||||||
|
//// ////
|
||||||
|
//// You should have received a copy of the GNU Lesser General ////
|
||||||
|
//// Public License along with this source; if not, download it ////
|
||||||
|
//// from http://www.opencores.org/lgpl.shtml ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
`include "sd_defines.v"
|
||||||
|
|
||||||
|
module sd_cmd_master(
|
||||||
|
input sd_clk,
|
||||||
|
input rst,
|
||||||
|
input start_i,
|
||||||
|
input int_status_rst_i,
|
||||||
|
output [1:0] setting_o,
|
||||||
|
output reg start_xfr_o,
|
||||||
|
output reg go_idle_o,
|
||||||
|
output reg [39:0] cmd_o,
|
||||||
|
input [119:0] response_i,
|
||||||
|
input crc_ok_i,
|
||||||
|
input index_ok_i,
|
||||||
|
input finish_i,
|
||||||
|
input busy_i, //direct signal from data sd data input (data[0])
|
||||||
|
//input card_detect,
|
||||||
|
input [31:0] argument_i,
|
||||||
|
input [`CMD_REG_SIZE-1:0] command_i,
|
||||||
|
input [15:0] timeout_i,
|
||||||
|
output [`INT_CMD_SIZE-1:0] int_status_o,
|
||||||
|
output reg [31:0] response_0_o,
|
||||||
|
output reg [31:0] response_1_o,
|
||||||
|
output reg [31:0] response_2_o,
|
||||||
|
output reg [31:0] response_3_o
|
||||||
|
);
|
||||||
|
|
||||||
|
//-----------Types--------------------------------------------------------
|
||||||
|
reg [15:0] timeout_reg;
|
||||||
|
reg crc_check;
|
||||||
|
reg index_check;
|
||||||
|
reg busy_check;
|
||||||
|
reg expect_response;
|
||||||
|
reg long_response;
|
||||||
|
reg [`INT_CMD_SIZE-1:0] int_status_reg;
|
||||||
|
//reg card_present;
|
||||||
|
//reg [3:0]debounce;
|
||||||
|
reg [15:0] watchdog;
|
||||||
|
parameter SIZE = 2;
|
||||||
|
reg [SIZE-1:0] state;
|
||||||
|
reg [SIZE-1:0] next_state;
|
||||||
|
parameter IDLE = 2'b00;
|
||||||
|
parameter EXECUTE = 2'b01;
|
||||||
|
parameter BUSY_CHECK = 2'b10;
|
||||||
|
|
||||||
|
assign setting_o[1:0] = {long_response, expect_response};
|
||||||
|
assign int_status_o = state == IDLE ? int_status_reg : 5'h0;
|
||||||
|
|
||||||
|
//---------------Input ports---------------
|
||||||
|
|
||||||
|
// always @ (posedge sd_clk or posedge rst )
|
||||||
|
// begin
|
||||||
|
// if (rst) begin
|
||||||
|
// debounce<=0;
|
||||||
|
// card_present<=0;
|
||||||
|
// end
|
||||||
|
// else begin
|
||||||
|
// if (!card_detect) begin//Card present
|
||||||
|
// if (debounce!=4'b1111)
|
||||||
|
// debounce<=debounce+1'b1;
|
||||||
|
// end
|
||||||
|
// else
|
||||||
|
// debounce<=0;
|
||||||
|
//
|
||||||
|
// if (debounce==4'b1111)
|
||||||
|
// card_present<=1'b1;
|
||||||
|
// else
|
||||||
|
// card_present<=1'b0;
|
||||||
|
// end
|
||||||
|
// end
|
||||||
|
|
||||||
|
always @(state or start_i or finish_i or go_idle_o or busy_check or busy_i)
|
||||||
|
begin: FSM_COMBO
|
||||||
|
case(state)
|
||||||
|
IDLE: begin
|
||||||
|
if (start_i)
|
||||||
|
next_state <= EXECUTE;
|
||||||
|
else
|
||||||
|
next_state <= IDLE;
|
||||||
|
end
|
||||||
|
EXECUTE: begin
|
||||||
|
if ((finish_i && !busy_check) || go_idle_o)
|
||||||
|
next_state <= IDLE;
|
||||||
|
else if (finish_i && busy_check)
|
||||||
|
next_state <= BUSY_CHECK;
|
||||||
|
else
|
||||||
|
next_state <= EXECUTE;
|
||||||
|
end
|
||||||
|
BUSY_CHECK: begin
|
||||||
|
if (!busy_i)
|
||||||
|
next_state <= IDLE;
|
||||||
|
else
|
||||||
|
next_state <= BUSY_CHECK;
|
||||||
|
end
|
||||||
|
default: next_state <= IDLE;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge sd_clk or posedge rst)
|
||||||
|
begin: FSM_SEQ
|
||||||
|
if (rst) begin
|
||||||
|
state <= IDLE;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
state <= next_state;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge sd_clk or posedge rst)
|
||||||
|
begin
|
||||||
|
if (rst) begin
|
||||||
|
crc_check <= 0;
|
||||||
|
response_0_o <= 0;
|
||||||
|
response_1_o <= 0;
|
||||||
|
response_2_o <= 0;
|
||||||
|
response_3_o <= 0;
|
||||||
|
int_status_reg <= 0;
|
||||||
|
expect_response <= 0;
|
||||||
|
long_response <= 0;
|
||||||
|
cmd_o <= 0;
|
||||||
|
start_xfr_o <= 0;
|
||||||
|
index_check <= 0;
|
||||||
|
busy_check <= 0;
|
||||||
|
watchdog <= 0;
|
||||||
|
timeout_reg <= 0;
|
||||||
|
go_idle_o <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
case(state)
|
||||||
|
IDLE: begin
|
||||||
|
go_idle_o <= 0;
|
||||||
|
index_check <= command_i[`CMD_IDX_CHECK];
|
||||||
|
crc_check <= command_i[`CMD_CRC_CHECK];
|
||||||
|
busy_check <= command_i[`CMD_BUSY_CHECK];
|
||||||
|
if (command_i[`CMD_RESPONSE_CHECK] == 2'b10 || command_i[`CMD_RESPONSE_CHECK] == 2'b11) begin
|
||||||
|
expect_response <= 1;
|
||||||
|
long_response <= 1;
|
||||||
|
end
|
||||||
|
else if (command_i[`CMD_RESPONSE_CHECK] == 2'b01) begin
|
||||||
|
expect_response <= 1;
|
||||||
|
long_response <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
expect_response <= 0;
|
||||||
|
long_response <= 0;
|
||||||
|
end
|
||||||
|
cmd_o[39:38] <= 2'b01;
|
||||||
|
cmd_o[37:32] <= command_i[`CMD_INDEX]; //CMD_INDEX
|
||||||
|
cmd_o[31:0] <= argument_i; //CMD_Argument
|
||||||
|
timeout_reg <= timeout_i;
|
||||||
|
watchdog <= 0;
|
||||||
|
if (start_i) begin
|
||||||
|
start_xfr_o <= 1;
|
||||||
|
int_status_reg <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
EXECUTE: begin
|
||||||
|
start_xfr_o <= 0;
|
||||||
|
watchdog <= watchdog + 16'd1;
|
||||||
|
if (watchdog > timeout_reg) begin
|
||||||
|
int_status_reg[`INT_CMD_CTE] <= 1;
|
||||||
|
int_status_reg[`INT_CMD_EI] <= 1;
|
||||||
|
go_idle_o <= 1;
|
||||||
|
end
|
||||||
|
//Incoming New Status
|
||||||
|
else begin //if ( req_in_int == 1) begin
|
||||||
|
if (finish_i) begin //Data avaible
|
||||||
|
if (crc_check & !crc_ok_i) begin
|
||||||
|
int_status_reg[`INT_CMD_CCRCE] <= 1;
|
||||||
|
int_status_reg[`INT_CMD_EI] <= 1;
|
||||||
|
end
|
||||||
|
if (index_check & !index_ok_i) begin
|
||||||
|
int_status_reg[`INT_CMD_CIE] <= 1;
|
||||||
|
int_status_reg[`INT_CMD_EI] <= 1;
|
||||||
|
end
|
||||||
|
int_status_reg[`INT_CMD_CC] <= 1;
|
||||||
|
if (expect_response != 0) begin
|
||||||
|
response_0_o <= response_i[119:88];
|
||||||
|
response_1_o <= response_i[87:56];
|
||||||
|
response_2_o <= response_i[55:24];
|
||||||
|
response_3_o <= {response_i[23:0], 8'h00};
|
||||||
|
end
|
||||||
|
// end
|
||||||
|
end ////Data avaible
|
||||||
|
end //Status change
|
||||||
|
end //EXECUTE state
|
||||||
|
BUSY_CHECK: begin
|
||||||
|
start_xfr_o <= 0;
|
||||||
|
go_idle_o <= 0;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
if (int_status_rst_i)
|
||||||
|
int_status_reg <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,336 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// WISHBONE SD Card Controller IP Core ////
|
||||||
|
//// ////
|
||||||
|
//// sd_cmd_serial_host.v ////
|
||||||
|
//// ////
|
||||||
|
//// This file is part of the WISHBONE SD Card ////
|
||||||
|
//// Controller IP Core project ////
|
||||||
|
//// http://opencores.org/project,sd_card_controller ////
|
||||||
|
//// ////
|
||||||
|
//// Description ////
|
||||||
|
//// Module resposible for sending and receiving commands ////
|
||||||
|
//// through 1-bit sd card command interface ////
|
||||||
|
//// ////
|
||||||
|
//// Author(s): ////
|
||||||
|
//// - Marek Czerski, ma.czerski@gmail.com ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2013 Authors ////
|
||||||
|
//// ////
|
||||||
|
//// Based on original work by ////
|
||||||
|
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2009 Authors ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer. ////
|
||||||
|
//// ////
|
||||||
|
//// This source file is free software; you can redistribute it ////
|
||||||
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||||
|
//// Public License as published by the Free Software Foundation; ////
|
||||||
|
//// either version 2.1 of the License, or (at your option) any ////
|
||||||
|
//// later version. ////
|
||||||
|
//// ////
|
||||||
|
//// This source is distributed in the hope that it will be ////
|
||||||
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||||
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||||
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||||
|
//// details. ////
|
||||||
|
//// ////
|
||||||
|
//// You should have received a copy of the GNU Lesser General ////
|
||||||
|
//// Public License along with this source; if not, download it ////
|
||||||
|
//// from http://www.opencores.org/lgpl.shtml ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
module sd_cmd_serial_host (
|
||||||
|
sd_clk,
|
||||||
|
rst,
|
||||||
|
setting_i,
|
||||||
|
cmd_i,
|
||||||
|
start_i,
|
||||||
|
response_o,
|
||||||
|
crc_ok_o,
|
||||||
|
index_ok_o,
|
||||||
|
finish_o,
|
||||||
|
cmd_dat_i,
|
||||||
|
cmd_out_o,
|
||||||
|
cmd_oe_o
|
||||||
|
);
|
||||||
|
|
||||||
|
//---------------Input ports---------------
|
||||||
|
input sd_clk;
|
||||||
|
input rst;
|
||||||
|
input [1:0] setting_i;
|
||||||
|
input [39:0] cmd_i;
|
||||||
|
input start_i;
|
||||||
|
input cmd_dat_i;
|
||||||
|
//---------------Output ports---------------
|
||||||
|
output reg [119:0] response_o;
|
||||||
|
output reg finish_o;
|
||||||
|
output reg crc_ok_o;
|
||||||
|
output reg index_ok_o;
|
||||||
|
output reg cmd_oe_o;
|
||||||
|
output reg cmd_out_o;
|
||||||
|
|
||||||
|
//-------------Internal Constant-------------
|
||||||
|
parameter INIT_DELAY = 4;
|
||||||
|
parameter BITS_TO_SEND = 48;
|
||||||
|
parameter CMD_SIZE = 40;
|
||||||
|
parameter RESP_SIZE = 128;
|
||||||
|
|
||||||
|
//---------------Internal variable-----------
|
||||||
|
reg cmd_dat_reg;
|
||||||
|
integer resp_len;
|
||||||
|
reg with_response;
|
||||||
|
reg [CMD_SIZE-1:0] cmd_buff;
|
||||||
|
reg [RESP_SIZE-1:0] resp_buff;
|
||||||
|
integer resp_idx;
|
||||||
|
//CRC
|
||||||
|
reg crc_rst;
|
||||||
|
reg [6:0]crc_in;
|
||||||
|
wire [6:0] crc_val;
|
||||||
|
reg crc_enable;
|
||||||
|
reg crc_bit;
|
||||||
|
reg crc_ok;
|
||||||
|
//-Internal Counterns
|
||||||
|
integer counter;
|
||||||
|
//-State Machine
|
||||||
|
parameter STATE_SIZE = 10;
|
||||||
|
parameter
|
||||||
|
INIT = 7'h00,
|
||||||
|
IDLE = 7'h01,
|
||||||
|
SETUP_CRC = 7'h02,
|
||||||
|
WRITE = 7'h04,
|
||||||
|
READ_WAIT = 7'h08,
|
||||||
|
READ = 7'h10,
|
||||||
|
FINISH_WR = 7'h20,
|
||||||
|
FINISH_WO = 7'h40;
|
||||||
|
reg [STATE_SIZE-1:0] state;
|
||||||
|
reg [STATE_SIZE-1:0] next_state;
|
||||||
|
//Misc
|
||||||
|
`define cmd_idx (CMD_SIZE-1-counter)
|
||||||
|
|
||||||
|
//sd cmd input pad register
|
||||||
|
always @(posedge sd_clk)
|
||||||
|
cmd_dat_reg <= cmd_dat_i;
|
||||||
|
|
||||||
|
//------------------------------------------
|
||||||
|
sd_crc_7 CRC_7(
|
||||||
|
crc_bit,
|
||||||
|
crc_enable,
|
||||||
|
sd_clk,
|
||||||
|
crc_rst,
|
||||||
|
crc_val);
|
||||||
|
|
||||||
|
//------------------------------------------
|
||||||
|
always @(state or counter or start_i or with_response or cmd_dat_reg or resp_len)
|
||||||
|
begin: FSM_COMBO
|
||||||
|
case(state)
|
||||||
|
INIT: begin
|
||||||
|
if (counter >= INIT_DELAY) begin
|
||||||
|
next_state <= IDLE;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
next_state <= INIT;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
IDLE: begin
|
||||||
|
if (start_i) begin
|
||||||
|
next_state <= SETUP_CRC;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
next_state <= IDLE;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
SETUP_CRC:
|
||||||
|
next_state <= WRITE;
|
||||||
|
WRITE:
|
||||||
|
if (counter >= BITS_TO_SEND && with_response) begin
|
||||||
|
next_state <= READ_WAIT;
|
||||||
|
end
|
||||||
|
else if (counter >= BITS_TO_SEND) begin
|
||||||
|
next_state <= FINISH_WO;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
next_state <= WRITE;
|
||||||
|
end
|
||||||
|
READ_WAIT:
|
||||||
|
if (!cmd_dat_reg) begin
|
||||||
|
next_state <= READ;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
next_state <= READ_WAIT;
|
||||||
|
end
|
||||||
|
FINISH_WO:
|
||||||
|
next_state <= IDLE;
|
||||||
|
READ:
|
||||||
|
if (counter >= resp_len+8) begin
|
||||||
|
next_state <= FINISH_WR;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
next_state <= READ;
|
||||||
|
end
|
||||||
|
FINISH_WR:
|
||||||
|
next_state <= IDLE;
|
||||||
|
default:
|
||||||
|
next_state <= INIT;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge sd_clk or posedge rst)
|
||||||
|
begin: COMMAND_DECODER
|
||||||
|
if (rst) begin
|
||||||
|
resp_len <= 0;
|
||||||
|
with_response <= 0;
|
||||||
|
cmd_buff <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (start_i == 1) begin
|
||||||
|
resp_len <= setting_i[1] ? 127 : 39;
|
||||||
|
with_response <= setting_i[0];
|
||||||
|
cmd_buff <= cmd_i;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
//----------------Seq logic------------
|
||||||
|
always @(posedge sd_clk or posedge rst)
|
||||||
|
begin: FSM_SEQ
|
||||||
|
if (rst) begin
|
||||||
|
state <= INIT;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
state <= next_state;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
//-------------OUTPUT_LOGIC-------
|
||||||
|
always @(posedge sd_clk or posedge rst)
|
||||||
|
begin: FSM_OUT
|
||||||
|
if (rst) begin
|
||||||
|
crc_enable <= 0;
|
||||||
|
resp_idx <= 0;
|
||||||
|
cmd_oe_o <= 1;
|
||||||
|
cmd_out_o <= 1;
|
||||||
|
resp_buff <= 0;
|
||||||
|
finish_o <= 0;
|
||||||
|
crc_rst <= 1;
|
||||||
|
crc_bit <= 0;
|
||||||
|
crc_in <= 0;
|
||||||
|
response_o <= 0;
|
||||||
|
index_ok_o <= 0;
|
||||||
|
crc_ok_o <= 0;
|
||||||
|
crc_ok <= 0;
|
||||||
|
counter <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
case(state)
|
||||||
|
INIT: begin
|
||||||
|
counter <= counter+1;
|
||||||
|
cmd_oe_o <= 1;
|
||||||
|
cmd_out_o <= 1;
|
||||||
|
end
|
||||||
|
IDLE: begin
|
||||||
|
cmd_oe_o <= 0; //Put CMD to Z
|
||||||
|
counter <= 0;
|
||||||
|
crc_rst <= 1;
|
||||||
|
crc_enable <= 0;
|
||||||
|
response_o <= 0;
|
||||||
|
resp_idx <= 0;
|
||||||
|
crc_ok_o <= 0;
|
||||||
|
index_ok_o <= 0;
|
||||||
|
finish_o <= 0;
|
||||||
|
end
|
||||||
|
SETUP_CRC: begin
|
||||||
|
crc_rst <= 0;
|
||||||
|
crc_enable <= 1;
|
||||||
|
crc_bit <= cmd_buff[`cmd_idx];
|
||||||
|
end
|
||||||
|
WRITE: begin
|
||||||
|
if (counter < BITS_TO_SEND-8) begin // 1->40 CMD, (41 >= CNT && CNT <=47) CRC, 48 stop_bit
|
||||||
|
cmd_oe_o <= 1;
|
||||||
|
cmd_out_o <= cmd_buff[`cmd_idx];
|
||||||
|
if (counter < BITS_TO_SEND-9) begin //1 step ahead
|
||||||
|
crc_bit <= cmd_buff[`cmd_idx-1];
|
||||||
|
end else begin
|
||||||
|
crc_enable <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else if (counter < BITS_TO_SEND-1) begin
|
||||||
|
cmd_oe_o <= 1;
|
||||||
|
crc_enable <= 0;
|
||||||
|
cmd_out_o <= crc_val[BITS_TO_SEND-counter-2];
|
||||||
|
end
|
||||||
|
else if (counter == BITS_TO_SEND-1) begin
|
||||||
|
cmd_oe_o <= 1;
|
||||||
|
cmd_out_o <= 1'b1;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
cmd_oe_o <= 0;
|
||||||
|
cmd_out_o <= 1'b1;
|
||||||
|
end
|
||||||
|
counter <= counter+1;
|
||||||
|
end
|
||||||
|
READ_WAIT: begin
|
||||||
|
crc_enable <= 0;
|
||||||
|
crc_rst <= 1;
|
||||||
|
counter <= 1;
|
||||||
|
cmd_oe_o <= 0;
|
||||||
|
resp_buff[RESP_SIZE-1] <= cmd_dat_reg;
|
||||||
|
end
|
||||||
|
FINISH_WO: begin
|
||||||
|
finish_o <= 1;
|
||||||
|
crc_enable <= 0;
|
||||||
|
crc_rst <= 1;
|
||||||
|
counter <= 0;
|
||||||
|
cmd_oe_o <= 0;
|
||||||
|
end
|
||||||
|
READ: begin
|
||||||
|
crc_rst <= 0;
|
||||||
|
crc_enable <= (resp_len != RESP_SIZE-1 || counter > 7);
|
||||||
|
cmd_oe_o <= 0;
|
||||||
|
if (counter <= resp_len) begin
|
||||||
|
if (counter < 8) //1+1+6 (S,T,Index)
|
||||||
|
resp_buff[RESP_SIZE-1-counter] <= cmd_dat_reg;
|
||||||
|
else begin
|
||||||
|
resp_idx <= resp_idx + 1;
|
||||||
|
resp_buff[RESP_SIZE-9-resp_idx] <= cmd_dat_reg;
|
||||||
|
end
|
||||||
|
crc_bit <= cmd_dat_reg;
|
||||||
|
end
|
||||||
|
else if (counter-resp_len <= 7) begin
|
||||||
|
crc_in[(resp_len+7)-(counter)] <= cmd_dat_reg;
|
||||||
|
crc_enable <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
crc_enable <= 0;
|
||||||
|
if (crc_in == crc_val) crc_ok <= 1;
|
||||||
|
else crc_ok <= 0;
|
||||||
|
end
|
||||||
|
counter <= counter + 1;
|
||||||
|
end
|
||||||
|
FINISH_WR: begin
|
||||||
|
if (cmd_buff[37:32] == resp_buff[125:120])
|
||||||
|
index_ok_o <= 1;
|
||||||
|
else
|
||||||
|
index_ok_o <= 0;
|
||||||
|
crc_ok_o <= crc_ok;
|
||||||
|
finish_o <= 1;
|
||||||
|
crc_enable <= 0;
|
||||||
|
crc_rst <= 1;
|
||||||
|
counter <= 0;
|
||||||
|
cmd_oe_o <= 0;
|
||||||
|
response_o <= resp_buff[119:0];
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,195 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// WISHBONE SD Card Controller IP Core ////
|
||||||
|
//// ////
|
||||||
|
//// sd_controller_wb.v ////
|
||||||
|
//// ////
|
||||||
|
//// This file is part of the WISHBONE SD Card ////
|
||||||
|
//// Controller IP Core project ////
|
||||||
|
//// http://opencores.org/project,sd_card_controller ////
|
||||||
|
//// ////
|
||||||
|
//// Description ////
|
||||||
|
//// Wishbone interface responsible for comunication with core ////
|
||||||
|
//// ////
|
||||||
|
//// Author(s): ////
|
||||||
|
//// - Marek Czerski, ma.czerski@gmail.com ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2013 Authors ////
|
||||||
|
//// ////
|
||||||
|
//// Based on original work by ////
|
||||||
|
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||||
|
//// ////
|
||||||
|
//// Copyright (C) 2009 Authors ////
|
||||||
|
//// ////
|
||||||
|
//// This source file may be used and distributed without ////
|
||||||
|
//// restriction provided that this copyright statement is not ////
|
||||||
|
//// removed from the file and that any derivative work contains ////
|
||||||
|
//// the original copyright notice and the associated disclaimer. ////
|
||||||
|
//// ////
|
||||||
|
//// This source file is free software; you can redistribute it ////
|
||||||
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||||
|
//// Public License as published by the Free Software Foundation; ////
|
||||||
|
//// either version 2.1 of the License, or (at your option) any ////
|
||||||
|
//// later version. ////
|
||||||
|
//// ////
|
||||||
|
//// This source is distributed in the hope that it will be ////
|
||||||
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||||
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||||
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||||
|
//// details. ////
|
||||||
|
//// ////
|
||||||
|
//// You should have received a copy of the GNU Lesser General ////
|
||||||
|
//// Public License along with this source; if not, download it ////
|
||||||
|
//// from http://www.opencores.org/lgpl.shtml ////
|
||||||
|
//// ////
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
`include "sd_defines.v"
|
||||||
|
|
||||||
|
module sd_controller_wb(
|
||||||
|
// WISHBONE slave
|
||||||
|
wb_clk_i, wb_rst_i, wb_dat_i, wb_dat_o,
|
||||||
|
wb_adr_i, wb_sel_i, wb_we_i, wb_cyc_i, wb_stb_i, wb_ack_o,
|
||||||
|
cmd_start,
|
||||||
|
data_int_rst,
|
||||||
|
cmd_int_rst,
|
||||||
|
argument_reg,
|
||||||
|
command_reg,
|
||||||
|
response_0_reg,
|
||||||
|
response_1_reg,
|
||||||
|
response_2_reg,
|
||||||
|
response_3_reg,
|
||||||
|
software_reset_reg,
|
||||||
|
timeout_reg,
|
||||||
|
block_size_reg,
|
||||||
|
controll_setting_reg,
|
||||||
|
cmd_int_status_reg,
|
||||||
|
cmd_int_enable_reg,
|
||||||
|
clock_divider_reg,
|
||||||
|
block_count_reg,
|
||||||
|
dma_addr_reg,
|
||||||
|
data_int_status_reg,
|
||||||
|
data_int_enable_reg
|
||||||
|
);
|
||||||
|
|
||||||
|
// WISHBONE common
|
||||||
|
input wb_clk_i; // WISHBONE clock
|
||||||
|
input wb_rst_i; // WISHBONE reset
|
||||||
|
input [31:0] wb_dat_i; // WISHBONE data input
|
||||||
|
output reg [31:0] wb_dat_o; // WISHBONE data output
|
||||||
|
// WISHBONE error output
|
||||||
|
|
||||||
|
// WISHBONE slave
|
||||||
|
input [7:0] wb_adr_i; // WISHBONE address input
|
||||||
|
input [3:0] wb_sel_i; // WISHBONE byte select input
|
||||||
|
input wb_we_i; // WISHBONE write enable input
|
||||||
|
input wb_cyc_i; // WISHBONE cycle input
|
||||||
|
input wb_stb_i; // WISHBONE strobe input
|
||||||
|
output reg wb_ack_o; // WISHBONE acknowledge output
|
||||||
|
output reg cmd_start;
|
||||||
|
//Buss accessible registers
|
||||||
|
output reg [31:0] argument_reg;
|
||||||
|
output reg [`CMD_REG_SIZE-1:0] command_reg;
|
||||||
|
input wire [31:0] response_0_reg;
|
||||||
|
input wire [31:0] response_1_reg;
|
||||||
|
input wire [31:0] response_2_reg;
|
||||||
|
input wire [31:0] response_3_reg;
|
||||||
|
output reg [0:0] software_reset_reg;
|
||||||
|
output reg [15:0] timeout_reg;
|
||||||
|
output reg [`BLKSIZE_W-1:0] block_size_reg;
|
||||||
|
output reg [15:0] controll_setting_reg;
|
||||||
|
input wire [`INT_CMD_SIZE-1:0] cmd_int_status_reg;
|
||||||
|
output reg [`INT_CMD_SIZE-1:0] cmd_int_enable_reg;
|
||||||
|
output reg [7:0] clock_divider_reg;
|
||||||
|
input wire [`INT_DATA_SIZE-1:0] data_int_status_reg;
|
||||||
|
output reg [`INT_DATA_SIZE-1:0] data_int_enable_reg;
|
||||||
|
//Register Controll
|
||||||
|
output reg data_int_rst;
|
||||||
|
output reg cmd_int_rst;
|
||||||
|
output reg [`BLKCNT_W-1:0]block_count_reg;
|
||||||
|
output reg [31:0] dma_addr_reg;
|
||||||
|
|
||||||
|
parameter voltage_controll_reg = `SUPPLY_VOLTAGE_mV;
|
||||||
|
parameter capabilies_reg = 16'b0000_0000_0000_0000;
|
||||||
|
|
||||||
|
always @(posedge wb_clk_i or posedge wb_rst_i)
|
||||||
|
begin
|
||||||
|
if (wb_rst_i)begin
|
||||||
|
argument_reg <= 0;
|
||||||
|
command_reg <= 0;
|
||||||
|
software_reset_reg <= 0;
|
||||||
|
timeout_reg <= 0;
|
||||||
|
block_size_reg <= `RESET_BLOCK_SIZE;
|
||||||
|
controll_setting_reg <= 0;
|
||||||
|
cmd_int_enable_reg <= 0;
|
||||||
|
clock_divider_reg <= `RESET_CLK_DIV;
|
||||||
|
wb_ack_o <= 0;
|
||||||
|
cmd_start <= 0;
|
||||||
|
data_int_rst <= 0;
|
||||||
|
data_int_enable_reg <= 0;
|
||||||
|
cmd_int_rst <= 0;
|
||||||
|
block_count_reg <= 0;
|
||||||
|
dma_addr_reg <= 0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
cmd_start <= 1'b0;
|
||||||
|
data_int_rst <= 0;
|
||||||
|
cmd_int_rst <= 0;
|
||||||
|
if ((wb_stb_i & wb_cyc_i) || wb_ack_o)begin
|
||||||
|
if (wb_we_i) begin
|
||||||
|
case (wb_adr_i)
|
||||||
|
`argument: begin
|
||||||
|
argument_reg <= wb_dat_i;
|
||||||
|
cmd_start <= 1'b1;
|
||||||
|
end
|
||||||
|
`command: command_reg <= wb_dat_i[`CMD_REG_SIZE-1:0];
|
||||||
|
`reset: software_reset_reg <= wb_dat_i[0];
|
||||||
|
`timeout: timeout_reg <= wb_dat_i[15:0];
|
||||||
|
`blksize: block_size_reg <= wb_dat_i[`BLKSIZE_W-1:0];
|
||||||
|
`controller: controll_setting_reg <= wb_dat_i[15:0];
|
||||||
|
`cmd_iser: cmd_int_enable_reg <= wb_dat_i[4:0];
|
||||||
|
`cmd_isr: cmd_int_rst <= 1;
|
||||||
|
`clock_d: clock_divider_reg <= wb_dat_i[7:0];
|
||||||
|
`data_isr: data_int_rst <= 1;
|
||||||
|
`data_iser: data_int_enable_reg <= wb_dat_i[`INT_DATA_SIZE-1:0];
|
||||||
|
`dst_src_addr: dma_addr_reg <= wb_dat_i;
|
||||||
|
`blkcnt: block_count_reg <= wb_dat_i[`BLKCNT_W-1:0];
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
wb_ack_o <= wb_cyc_i & wb_stb_i & ~wb_ack_o;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge wb_clk_i or posedge wb_rst_i)begin
|
||||||
|
if (wb_rst_i == 1)
|
||||||
|
wb_dat_o <= 0;
|
||||||
|
else
|
||||||
|
if (wb_stb_i & wb_cyc_i) begin //CS
|
||||||
|
case (wb_adr_i)
|
||||||
|
`argument: wb_dat_o <= argument_reg;
|
||||||
|
`command: wb_dat_o <= command_reg;
|
||||||
|
`resp0: wb_dat_o <= response_0_reg;
|
||||||
|
`resp1: wb_dat_o <= response_1_reg;
|
||||||
|
`resp2: wb_dat_o <= response_2_reg;
|
||||||
|
`resp3: wb_dat_o <= response_3_reg;
|
||||||
|
`controller: wb_dat_o <= controll_setting_reg;
|
||||||
|
`blksize: wb_dat_o <= block_size_reg;
|
||||||
|
`voltage: wb_dat_o <= voltage_controll_reg;
|
||||||
|
`reset: wb_dat_o <= software_reset_reg;
|
||||||
|
`timeout: wb_dat_o <= timeout_reg;
|
||||||
|
`cmd_isr: wb_dat_o <= cmd_int_status_reg;
|
||||||
|
`cmd_iser: wb_dat_o <= cmd_int_enable_reg;
|
||||||
|
`clock_d: wb_dat_o <= clock_divider_reg;
|
||||||
|
`capa: wb_dat_o <= capabilies_reg;
|
||||||
|
`data_isr: wb_dat_o <= data_int_status_reg;
|
||||||
|
`blkcnt: wb_dat_o <= block_count_reg;
|
||||||
|
`data_iser: wb_dat_o <= data_int_enable_reg;
|
||||||
|
`dst_src_addr: wb_dat_o <= dma_addr_reg;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,43 @@
|
||||||
|
// ==========================================================================
|
||||||
|
// CRC Generation Unit - Linear Feedback Shift Register implementation
|
||||||
|
// (c) Kay Gorontzi, GHSi.de, distributed under the terms of LGPL
|
||||||
|
// ==========================================================================
|
||||||
|
module sd_crc_16(BITVAL, ENABLE, BITSTRB, CLEAR, CRC);
|
||||||
|
input BITVAL; // Next input bit
|
||||||
|
input ENABLE; // Enable calculation
|
||||||
|
input BITSTRB; // Current bit valid (Clock)
|
||||||
|
input CLEAR; // Init CRC value
|
||||||
|
output [15:0] CRC; // Current output CRC value
|
||||||
|
|
||||||
|
reg [15:0] CRC; // We need output registers
|
||||||
|
wire inv;
|
||||||
|
|
||||||
|
assign inv = BITVAL ^ CRC[15]; // XOR required?
|
||||||
|
|
||||||
|
always @(posedge BITSTRB or posedge CLEAR) begin
|
||||||
|
if (CLEAR) begin
|
||||||
|
CRC <= 0; // Init before calculation
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (ENABLE == 1) begin
|
||||||
|
CRC[15] <= CRC[14];
|
||||||
|
CRC[14] <= CRC[13];
|
||||||
|
CRC[13] <= CRC[12];
|
||||||
|
CRC[12] <= CRC[11] ^ inv;
|
||||||
|
CRC[11] <= CRC[10];
|
||||||
|
CRC[10] <= CRC[9];
|
||||||
|
CRC[9] <= CRC[8];
|
||||||
|
CRC[8] <= CRC[7];
|
||||||
|
CRC[7] <= CRC[6];
|
||||||
|
CRC[6] <= CRC[5];
|
||||||
|
CRC[5] <= CRC[4] ^ inv;
|
||||||
|
CRC[4] <= CRC[3];
|
||||||
|
CRC[3] <= CRC[2];
|
||||||
|
CRC[2] <= CRC[1];
|
||||||
|
CRC[1] <= CRC[0];
|
||||||
|
CRC[0] <= inv;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,34 @@
|
||||||
|
// ==========================================================================
|
||||||
|
// CRC Generation Unit - Linear Feedback Shift Register implementation
|
||||||
|
// (c) Kay Gorontzi, GHSi.de, distributed under the terms of LGPL
|
||||||
|
// ==========================================================================
|
||||||
|
module sd_crc_7(BITVAL, ENABLE, BITSTRB, CLEAR, CRC);
|
||||||
|
input BITVAL; // Next input bit
|
||||||
|
input ENABLE; // Enable calculation
|
||||||
|
input BITSTRB; // Current bit valid (Clock)
|
||||||
|
input CLEAR; // Init CRC value
|
||||||
|
output [6:0] CRC; // Current output CRC value
|
||||||
|
|
||||||
|
reg [6:0] CRC; // We need output registers
|
||||||
|
wire inv;
|
||||||
|
|
||||||
|
assign inv = BITVAL ^ CRC[6]; // XOR required?
|
||||||
|
|
||||||
|
always @(posedge BITSTRB or posedge CLEAR) begin
|
||||||
|
if (CLEAR) begin
|
||||||
|
CRC <= 0; // Init before calculation
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (ENABLE == 1) begin
|
||||||
|
CRC[6] <= CRC[5];
|
||||||
|
CRC[5] <= CRC[4];
|
||||||
|
CRC[4] <= CRC[3];
|
||||||
|
CRC[3] <= CRC[2] ^ inv;
|
||||||
|
CRC[2] <= CRC[1];
|
||||||
|
CRC[1] <= CRC[0];
|
||||||
|
CRC[0] <= inv;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue