├── .gitignore ├── LICENSE ├── README.md ├── example_demo ├── alinx_ax7103b │ ├── Makefile │ ├── ax7103_ddr3.v │ ├── ax7103_ddr3.xdc │ ├── ax7103_ddr3_openxc7.bit │ ├── clk_wiz.v │ ├── uart_rx.v │ └── uart_tx.v ├── alinx_ax7325b │ ├── Makefile │ ├── ax7325b_ddr3.v │ ├── ax7325b_ddr3.xdc │ ├── ax7325b_ddr3_openxc7.bit │ ├── ax7325b_spd_reader.xdc │ ├── clk_wiz.v │ ├── uart_rx.v │ └── uart_tx.v ├── arty_s7 │ ├── Makefile │ ├── arty_ddr3.v │ ├── arty_ddr3.xdc │ ├── arty_ddr3_openxc7.bit │ ├── arty_ddr3_vivado.xdc │ ├── clk_wiz.v │ ├── uart_rx.v │ └── uart_tx.v ├── enclustra_kx2_st1 │ ├── Makefile │ ├── clk_wiz.v │ ├── ddr3_test.c │ ├── ddr3_test.v │ ├── ddr3_test_monitor_axi_1.0 │ │ ├── bd │ │ │ └── bd.tcl │ │ ├── component.xml │ │ ├── drivers │ │ │ └── ddr3_test_monitor_axi_v1_0 │ │ │ │ ├── data │ │ │ │ ├── ddr3_test_monitor_axi.mdd │ │ │ │ └── ddr3_test_monitor_axi.tcl │ │ │ │ └── src │ │ │ │ ├── Makefile │ │ │ │ ├── ddr3_test_monitor_axi.c │ │ │ │ ├── ddr3_test_monitor_axi.h │ │ │ │ └── ddr3_test_monitor_axi_selftest.c │ │ ├── example_designs │ │ │ ├── bfm_design │ │ │ │ ├── ddr3_test_monitor_axi_v1_0_tb.sv │ │ │ │ └── design.tcl │ │ │ └── debug_hw_design │ │ │ │ ├── ddr3_test_monitor_axi_v1_0_hw_test.tcl │ │ │ │ └── design.tcl │ │ ├── hdl │ │ │ ├── ddr3_test_monitor_axi_v1_0.v │ │ │ └── ddr3_test_monitor_axi_v1_0_S00_AXI.v │ │ └── xgui │ │ │ └── ddr3_test_monitor_axi_v1_0.tcl │ ├── ddr3_test_top.v │ ├── ddr3_test_top_tb.v │ ├── enclustra_ddr3.v │ ├── enclustra_ddr3.xdc │ ├── enclustra_ddr3_openxc7.bit │ ├── enclustra_mb.xdc │ ├── uart_rx.v │ └── uart_tx.v ├── klusterlab │ ├── ddr3.txt │ ├── ddr3scope.txt │ ├── ddr3scope1.cpp │ ├── ddr3scope2.cpp │ ├── ddr3scope3.cpp │ └── kluster.xdc ├── nexys_video │ ├── Makefile │ ├── clk_wiz.v │ ├── nexysvideo_ddr3.v │ ├── nexysvideo_ddr3.xdc │ ├── nexysvideo_ddr3_openxc7.bit │ ├── uart_rx.v │ └── uart_tx.v ├── orangecrab_ecp5 │ ├── Makefile │ ├── clk_wiz_ecppll.v │ ├── orangecrab_ecp5_ddr3.dfu │ ├── orangecrab_ecp5_ddr3.pcf │ ├── orangecrab_ecp5_ddr3.v │ ├── uart_rx.v │ └── uart_tx.v ├── qmtech_kintex_7 │ ├── Makefile │ ├── clk_wiz.v │ ├── qmtech_kintex7_ddr3.v │ ├── qmtech_kintex7_ddr3.xdc │ ├── qmtech_kintex7_ddr3_openxc7.bit │ ├── uart_rx.v │ └── uart_tx.v ├── qmtech_wukong │ ├── Makefile │ ├── clk_wiz.v │ ├── uart_rx.v │ ├── uart_tx.v │ ├── wukong_ddr3.v │ ├── wukong_ddr3.xdc │ ├── wukong_ddr3_openxc7.bit │ └── wukong_ddr3_vivado.xdc ├── run_make_all.sh └── sechzig_mx2 │ ├── Makefile │ ├── clk_wiz.v │ ├── sechzig_mx2_ddr3.v │ ├── sechzig_mx2_ddr3.xdc │ ├── sechzig_mx2_ddr3_openxc7.bit │ ├── uart_rx.v │ └── uart_tx.v ├── formal ├── ddr3_multiconfig_default.sby ├── ddr3_multiconfig_ecc.sby ├── ddr3_singleconfig.sby ├── ecc.sby ├── ecc_formal.v └── fwb_slave.v ├── rtl ├── axi │ ├── axi_addr.v │ ├── axim2wbsp.v │ ├── aximrd2wbsp.v │ ├── aximwr2wbsp.v │ ├── ddr3_top_axi.v │ ├── sfifo.v │ ├── skidbuffer.v │ └── wbarbiter.v ├── ddr3_controller.v ├── ddr3_phy.v ├── ddr3_top.v ├── ecc │ ├── ecc_dec.sv │ └── ecc_enc.sv ├── ecp5_phy │ ├── ddr3_phy_ecp5.v │ ├── iserdes_soft.v │ └── oserdes_soft.v └── spd │ ├── i2c_master.sv │ ├── spd_clk_wiz.v │ ├── spd_reader.v │ ├── spd_reader_top.v │ └── uart_tx.v ├── run_compile.sh ├── testbench ├── 8192Mb_ddr3_parameters.vh ├── README.txt ├── axi_tb │ ├── addr.coe │ ├── ctrl.coe │ ├── data.atg │ ├── data.coe │ ├── ddr3_axi_traffic_gen_behav.wcfg │ ├── ddr3_axi_traffic_gen_tb.sv │ └── mask.coe ├── ddr3.sv ├── ddr3_dimm.sv ├── ddr3_dimm_micron_sim.sv ├── ddr3_module.sv ├── design.txt ├── icarus_sim │ ├── regression_test_icarus.sh │ └── sim_icarus.sh ├── models │ ├── IDELAYCTRL_model.v │ ├── IDELAYE2_model.v │ ├── IOBUFDS_DCIEN_model.v │ ├── IOBUFDS_model.v │ ├── IOBUF_DCIEN_model.v │ ├── IOBUF_model.v │ ├── ISERDESE2_model.v │ ├── OBUFDS_model.v │ ├── OBUF_model.v │ ├── ODELAYE2_model.v │ └── OSERDESE2_model.v ├── readme.txt ├── sim_defines.vh ├── spd_tb │ ├── i2c_slave.v │ ├── spd_reader_tb.sv │ └── spd_reader_tb_behav.wcfg └── xsim │ ├── README.txt │ ├── cmd.tcl │ ├── ddr3_dimm_micron_sim.sh │ ├── file_info.txt │ ├── glbl.v │ ├── regression_test_vivado.sh │ ├── test_10_000_ddr3_2_500_odelay_0_lanes_two_lanes_bus_delay_0_bist_2.log │ ├── test_10_000_ddr3_2_500_odelay_1_lanes_eight_lanes_bus_delay_0_bist_2.log │ ├── test_10_000_ddr3_2_500_odelay_1_lanes_eight_lanes_bus_delay_1_bist_1.log │ ├── test_10_000_ddr3_2_500_odelay_1_lanes_two_lanes_bus_delay_1_bist_1.log │ ├── test_12_000_ddr3_3_000_odelay_0_lanes_two_lanes_bus_delay_0_bist_2.log │ ├── test_12_000_ddr3_3_000_odelay_1_lanes_eight_lanes_bus_delay_0_bist_2.log │ ├── test_12_000_ddr3_3_000_odelay_1_lanes_eight_lanes_bus_delay_1_bist_1.log │ ├── test_12_000_ddr3_3_000_odelay_1_lanes_two_lanes_bus_delay_1_bist_1.log │ ├── test_5_000_ddr3_1_250_odelay_0_lanes_two_lanes_bus_delay_0_bist_1.log │ ├── test_5_000_ddr3_1_250_odelay_1_lanes_eight_lanes_bus_delay_0_bist_1.log │ ├── test_5_000_ddr3_1_250_odelay_1_lanes_eight_lanes_bus_delay_1_bist_2.log │ ├── test_5_000_ddr3_1_250_odelay_1_lanes_two_lanes_bus_delay_1_bist_2.log │ ├── test_6_000_ddr3_1_500_odelay_0_lanes_two_lanes_bus_delay_0_bist_1.log │ ├── test_6_000_ddr3_1_500_odelay_1_lanes_eight_lanes_bus_delay_0_bist_1.log │ ├── test_6_000_ddr3_1_500_odelay_1_lanes_eight_lanes_bus_delay_1_bist_2.log │ ├── test_6_000_ddr3_1_500_odelay_1_lanes_two_lanes_bus_delay_1_bist_2.log │ ├── vlog.prj │ └── xsim.ini └── vivado_custom_ip ├── component.xml ├── gui └── uberddr3_axi_v1_0.gtcl └── xgui ├── ddr3_top_axi_v1_0.tcl └── uberddr3_axi_v1_0.tcl /.gitignore: -------------------------------------------------------------------------------- 1 | formal/ddr3_multiconfig*prf* 2 | formal/ddr3_multiconfig_default/ 3 | formal/ddr3_multiconfig_ecc/ 4 | formal/ecc/ 5 | formal/ddr3_singleconfig/ 6 | example_demo/nexys_video/build/ 7 | testbench/xsim/xsim* 8 | testbench/xsim/*backup* 9 | testbench/xsim/*.log 10 | testbench/xsim/*.pb 11 | testbench/xsim/*.wdb 12 | example_demo/*/build/* 13 | example_demo/build_logs* 14 | *.fasm 15 | *.frames 16 | *.bin 17 | *.json 18 | *.bba 19 | *toolchain-nix* 20 | testbench/ddr3_dimm_micron_sim_behav.wcfg 21 | testbench/icarus_sim/*.log 22 | testbench/icarus_sim/uberddr3_sim 23 | 24 | # But do not ignore testbench/xsim/test_*.log 25 | !testbench/xsim/test_*.log 26 | -------------------------------------------------------------------------------- /example_demo/alinx_ax7103b/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT = ax7103_ddr3 2 | FAMILY = artix7 3 | PART = xc7a100tfgg484-2 4 | CHIPDB = ${ARTIX7_CHIPDB} 5 | ADDITIONAL_SOURCES = ../../rtl/ddr3_controller.v ../../rtl/ddr3_phy.v ../../rtl/ddr3_top.v uart_rx.v uart_tx.v clk_wiz.v 6 | 7 | ############################################################################################# 8 | NEXTPNR_XILINX_DIR ?= /snap/openxc7/current/opt/nextpnr-xilinx 9 | NEXTPNR_XILINX_PYTHON_DIR ?= ${NEXTPNR_XILINX_DIR}/python 10 | PRJXRAY_DB_DIR ?= ${NEXTPNR_XILINX_DIR}/external/prjxray-db 11 | 12 | DBPART = $(shell echo ${PART} | sed -e 's/-[0-9]//g') 13 | SPEEDGRADE = $(shell echo ${PART} | sed -e 's/.*\-\([0-9]\)/\1/g') 14 | 15 | CHIPDB ?= ./ 16 | ifeq ($(CHIPDB),) 17 | CHIPDB = ./ 18 | endif 19 | 20 | PYPY3 ?= pypy3 21 | 22 | TOP ?= ${PROJECT} 23 | TOP_MODULE ?= ${TOP} 24 | TOP_VERILOG ?= ${TOP}.v 25 | 26 | PNR_DEBUG ?= # --verbose --debug 27 | 28 | JTAG_LINK ?= -c digilent_hs2 29 | 30 | XDC ?= ${PROJECT}.xdc 31 | 32 | .PHONY: openxc7 33 | openxc7: ${PROJECT}_openxc7.bit 34 | 35 | .PHONY: program 36 | program: ${PROJECT}_openxc7.bit 37 | openFPGALoader ${JTAG_LINK} --bitstream $< 38 | 39 | ${PROJECT}.json: ${TOP_VERILOG} ${ADDITIONAL_SOURCES} 40 | yosys -p "synth_xilinx -flatten -abc9 ${SYNTH_OPTS} -arch xc7 -top ${TOP_MODULE}; write_json ${PROJECT}.json" $< ${ADDITIONAL_SOURCES} 41 | 42 | # The chip database only needs to be generated once 43 | # that is why we don't clean it with make clean 44 | ${CHIPDB}/${DBPART}.bin: 45 | ${PYPY3} ${NEXTPNR_XILINX_PYTHON_DIR}/bbaexport.py --device ${PART} --bba ${DBPART}.bba 46 | bbasm -l ${DBPART}.bba ${CHIPDB}/${DBPART}.bin 47 | rm -f ${DBPART}.bba 48 | 49 | ${PROJECT}.fasm: ${PROJECT}.json ${CHIPDB}/${DBPART}.bin ${XDC} 50 | nextpnr-xilinx --chipdb ${CHIPDB}/${DBPART}.bin --xdc ${XDC} --json ${PROJECT}.json --fasm $@ ${PNR_ARGS} ${PNR_DEBUG} 51 | 52 | ${PROJECT}.frames: ${PROJECT}.fasm 53 | fasm2frames --part ${PART} --db-root ${PRJXRAY_DB_DIR}/${FAMILY} $< > $@ 54 | 55 | ${PROJECT}_openxc7.bit: ${PROJECT}.frames 56 | xc7frames2bit --part_file ${PRJXRAY_DB_DIR}/${FAMILY}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@ 57 | 58 | 59 | ############################################################################################# 60 | # SPDX-License-Identifier: MIT 61 | # Generated from https://github.com/FPGAOL-CE/caas-wizard 62 | # 63 | BUILDDIR := ${CURDIR}/build 64 | 65 | LOGFILE := ${BUILDDIR}/top.log 66 | 67 | # Build design 68 | .PHONY: vivado 69 | vivado: ${BUILDDIR}/${PROJECT}_vivado.bit 70 | 71 | ${BUILDDIR}: 72 | mkdir -m 777 -p ${BUILDDIR} && chown -R nobody ${BUILDDIR} | true 73 | 74 | .ONESHELL: 75 | ${BUILDDIR}/vivado.tcl: ${BUILDDIR} 76 | cat << EOF > $@ 77 | # vivado.tcl generated for FPGAOL-CE/caas-wizard 78 | # can be launched from any directory 79 | cd ${BUILDDIR} 80 | create_project -part ${PART} -force v_proj 81 | set_property target_language Verilog [current_project] 82 | cd .. 83 | read_verilog [glob ${PROJECT}.v ${ADDITIONAL_SOURCES}] 84 | read_xdc [glob $(wildcard ${PROJECT}.xdc) ] 85 | cd build 86 | synth_design -top ${PROJECT} 87 | opt_design 88 | place_design 89 | phys_opt_design 90 | route_design 91 | write_bitstream -verbose -force ${PROJECT}_vivado.bit 92 | # report_utilization -file util.rpt 93 | # report_timing_summary -file timing.rpt 94 | EOF 95 | 96 | ${BUILDDIR}/${PROJECT}_vivado.bit: ${BUILDDIR}/vivado.tcl 97 | cd ${BUILDDIR} && vivado -mode batch -source $< > ${LOGFILE} 2>&1 98 | 99 | .PHONY: program_vivado 100 | program_vivado: 101 | openFPGALoader ${JTAG_LINK} --bitstream ${BUILDDIR}/${PROJECT}_vivado.bit 102 | 103 | ############################################################################################# 104 | 105 | .PHONY: clean 106 | clean: 107 | rm -f *.bit 108 | rm -f *.frames 109 | rm -f *.fasm 110 | rm -f *.json 111 | rm -f *.bin 112 | rm -f *.bba 113 | rm -rf ${BUILDDIR} 114 | -------------------------------------------------------------------------------- /example_demo/alinx_ax7103b/ax7103_ddr3_openxc7.bit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AngeloJacobo/UberDDR3/a3efc861dafeec665d0885d6bc2e0c380260fe6b/example_demo/alinx_ax7103b/ax7103_ddr3_openxc7.bit -------------------------------------------------------------------------------- /example_demo/alinx_ax7103b/clk_wiz.v: -------------------------------------------------------------------------------- 1 | `timescale 1ps/1ps 2 | 3 | module clk_wiz 4 | ( 5 | input wire clk_in1, 6 | output wire clk_out1, 7 | output wire clk_out2, 8 | output wire clk_out3, 9 | output wire clk_out4, 10 | input wire reset, 11 | output wire locked 12 | ); 13 | wire clk_out1_clk_wiz_0; 14 | wire clk_out2_clk_wiz_0; 15 | wire clk_out3_clk_wiz_0; 16 | wire clk_out4_clk_wiz_0; 17 | 18 | wire clkfbout; 19 | 20 | PLLE2_ADV 21 | #(.BANDWIDTH ("OPTIMIZED"), 22 | .COMPENSATION ("INTERNAL"), 23 | .STARTUP_WAIT ("FALSE"), 24 | .DIVCLK_DIVIDE (1), 25 | .CLKFBOUT_MULT (5), // 200 MHz * 5 = 1000 MHz 26 | .CLKFBOUT_PHASE (0.000), 27 | .CLKOUT0_DIVIDE (12), // 1000 MHz / 12 = 83.333 MHz 28 | .CLKOUT0_PHASE (0.000), 29 | .CLKOUT0_DUTY_CYCLE (0.500), 30 | .CLKOUT1_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz 31 | .CLKOUT1_PHASE (0.000), 32 | .CLKOUT1_DUTY_CYCLE (0.500), 33 | .CLKOUT2_DIVIDE (5), // 1000 MHz / 5 = 200 MHz 34 | .CLKOUT2_PHASE (0.000), 35 | .CLKOUT2_DUTY_CYCLE (0.500), 36 | .CLKOUT3_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz 37 | .CLKOUT3_PHASE (90), 38 | .CLKOUT3_DUTY_CYCLE (0.500), 39 | .CLKIN1_PERIOD (5.000) // 200 MHz input 40 | ) 41 | plle2_adv_inst 42 | ( 43 | .CLKFBOUT (clkfbout), 44 | .CLKOUT0 (clk_out1_clk_wiz_0), 45 | .CLKOUT1 (clk_out2_clk_wiz_0), 46 | .CLKOUT2 (clk_out3_clk_wiz_0), 47 | .CLKOUT3 (clk_out4_clk_wiz_0), 48 | .CLKFBIN (clkfbout), 49 | .CLKIN1 (clk_in1), 50 | .LOCKED (locked), 51 | .RST (reset) 52 | ); 53 | BUFG clkout1_buf 54 | (.O (clk_out1), 55 | .I (clk_out1_clk_wiz_0)); 56 | BUFG clkout2_buf 57 | (.O (clk_out2), 58 | .I (clk_out2_clk_wiz_0)); 59 | BUFG clkout3_buf 60 | (.O (clk_out3), 61 | .I (clk_out3_clk_wiz_0)); 62 | BUFG clkout4_buf 63 | (.O (clk_out4), 64 | .I (clk_out4_clk_wiz_0)); 65 | 66 | endmodule 67 | -------------------------------------------------------------------------------- /example_demo/alinx_ax7103b/uart_tx.v: -------------------------------------------------------------------------------- 1 | 2 | 3 | // 4 | // Module: uart_tx 5 | // 6 | // Notes: 7 | // - UART transmitter module. 8 | // 9 | 10 | module uart_tx( 11 | input wire clk , // Top level system clock input. 12 | input wire resetn , // Asynchronous active low reset. 13 | output wire uart_txd , // UART transmit pin. 14 | output wire uart_tx_busy, // Module busy sending previous item. 15 | input wire uart_tx_en , // Send the data on uart_tx_data 16 | input wire [PAYLOAD_BITS-1:0] uart_tx_data // The data to be sent 17 | ); 18 | 19 | // --------------------------------------------------------------------------- 20 | // External parameters. 21 | // 22 | 23 | // 24 | // Input bit rate of the UART line. 25 | parameter BIT_RATE = 9600; // bits / sec 26 | localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds 27 | 28 | // 29 | // Clock frequency in hertz. 30 | parameter CLK_HZ = 50_000_000; 31 | localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds 32 | 33 | // 34 | // Number of data bits recieved per UART packet. 35 | parameter PAYLOAD_BITS = 8; 36 | 37 | // 38 | // Number of stop bits indicating the end of a packet. 39 | parameter STOP_BITS = 1; 40 | 41 | // --------------------------------------------------------------------------- 42 | // Internal parameters. 43 | // 44 | 45 | // 46 | // Number of clock cycles per uart bit. 47 | localparam CYCLES_PER_BIT = BIT_P / CLK_P; 48 | 49 | // 50 | // Size of the registers which store sample counts and bit durations. 51 | localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT); 52 | 53 | // --------------------------------------------------------------------------- 54 | // Internal registers. 55 | // 56 | 57 | // 58 | // Internally latched value of the uart_txd line. Helps break long timing 59 | // paths from the logic to the output pins. 60 | reg txd_reg; 61 | 62 | // 63 | // Storage for the serial data to be sent. 64 | reg [PAYLOAD_BITS-1:0] data_to_send; 65 | 66 | // 67 | // Counter for the number of cycles over a packet bit. 68 | reg [COUNT_REG_LEN-1:0] cycle_counter; 69 | 70 | // 71 | // Counter for the number of sent bits of the packet. 72 | reg [3:0] bit_counter; 73 | 74 | // 75 | // Current and next states of the internal FSM. 76 | reg [2:0] fsm_state; 77 | reg [2:0] n_fsm_state; 78 | 79 | localparam FSM_IDLE = 0; 80 | localparam FSM_START= 1; 81 | localparam FSM_SEND = 2; 82 | localparam FSM_STOP = 3; 83 | 84 | 85 | // --------------------------------------------------------------------------- 86 | // FSM next state selection. 87 | // 88 | 89 | assign uart_tx_busy = fsm_state != FSM_IDLE; 90 | assign uart_txd = txd_reg; 91 | 92 | wire next_bit = cycle_counter == CYCLES_PER_BIT; 93 | wire payload_done = bit_counter == PAYLOAD_BITS ; 94 | wire stop_done = bit_counter == STOP_BITS && fsm_state == FSM_STOP; 95 | 96 | // 97 | // Handle picking the next state. 98 | always @(*) begin : p_n_fsm_state 99 | case(fsm_state) 100 | FSM_IDLE : n_fsm_state = uart_tx_en ? FSM_START: FSM_IDLE ; 101 | FSM_START: n_fsm_state = next_bit ? FSM_SEND : FSM_START; 102 | FSM_SEND : n_fsm_state = payload_done ? FSM_STOP : FSM_SEND ; 103 | FSM_STOP : n_fsm_state = stop_done ? FSM_IDLE : FSM_STOP ; 104 | default : n_fsm_state = FSM_IDLE; 105 | endcase 106 | end 107 | 108 | // --------------------------------------------------------------------------- 109 | // Internal register setting and re-setting. 110 | // 111 | 112 | // 113 | // Handle updates to the sent data register. 114 | integer i = 0; 115 | always @(posedge clk) begin : p_data_to_send 116 | if(!resetn) begin 117 | data_to_send <= {PAYLOAD_BITS{1'b0}}; 118 | end else if(fsm_state == FSM_IDLE && uart_tx_en) begin 119 | data_to_send <= uart_tx_data; 120 | end else if(fsm_state == FSM_SEND && next_bit ) begin 121 | for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin 122 | data_to_send[i] <= data_to_send[i+1]; 123 | end 124 | end 125 | end 126 | 127 | 128 | // 129 | // Increments the bit counter each time a new bit frame is sent. 130 | always @(posedge clk) begin : p_bit_counter 131 | if(!resetn) begin 132 | bit_counter <= 4'b0; 133 | end else if(fsm_state != FSM_SEND && fsm_state != FSM_STOP) begin 134 | bit_counter <= {COUNT_REG_LEN{1'b0}}; 135 | end else if(fsm_state == FSM_SEND && n_fsm_state == FSM_STOP) begin 136 | bit_counter <= {COUNT_REG_LEN{1'b0}}; 137 | end else if(fsm_state == FSM_STOP&& next_bit) begin 138 | bit_counter <= bit_counter + 1'b1; 139 | end else if(fsm_state == FSM_SEND && next_bit) begin 140 | bit_counter <= bit_counter + 1'b1; 141 | end 142 | end 143 | 144 | 145 | // 146 | // Increments the cycle counter when sending. 147 | always @(posedge clk) begin : p_cycle_counter 148 | if(!resetn) begin 149 | cycle_counter <= {COUNT_REG_LEN{1'b0}}; 150 | end else if(next_bit) begin 151 | cycle_counter <= {COUNT_REG_LEN{1'b0}}; 152 | end else if(fsm_state == FSM_START || 153 | fsm_state == FSM_SEND || 154 | fsm_state == FSM_STOP ) begin 155 | cycle_counter <= cycle_counter + 1'b1; 156 | end 157 | end 158 | 159 | 160 | // 161 | // Progresses the next FSM state. 162 | always @(posedge clk) begin : p_fsm_state 163 | if(!resetn) begin 164 | fsm_state <= FSM_IDLE; 165 | end else begin 166 | fsm_state <= n_fsm_state; 167 | end 168 | end 169 | 170 | 171 | // 172 | // Responsible for updating the internal value of the txd_reg. 173 | always @(posedge clk) begin : p_txd_reg 174 | if(!resetn) begin 175 | txd_reg <= 1'b1; 176 | end else if(fsm_state == FSM_IDLE) begin 177 | txd_reg <= 1'b1; 178 | end else if(fsm_state == FSM_START) begin 179 | txd_reg <= 1'b0; 180 | end else if(fsm_state == FSM_SEND) begin 181 | txd_reg <= data_to_send[0]; 182 | end else if(fsm_state == FSM_STOP) begin 183 | txd_reg <= 1'b1; 184 | end 185 | end 186 | 187 | endmodule 188 | -------------------------------------------------------------------------------- /example_demo/alinx_ax7325b/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT = ax7325b_ddr3 2 | FAMILY = kintex7 3 | PART = xc7k325tffg900-2 4 | CHIPDB = ${KINTEX7_CHIPDB} 5 | ADDITIONAL_SOURCES = ../../rtl/ddr3_controller.v ../../rtl/ddr3_phy.v ../../rtl/ddr3_top.v uart_rx.v uart_tx.v clk_wiz.v 6 | 7 | 8 | ############################################################################################# 9 | NEXTPNR_XILINX_DIR ?= /snap/openxc7/current/opt/nextpnr-xilinx 10 | NEXTPNR_XILINX_PYTHON_DIR ?= ${NEXTPNR_XILINX_DIR}/python 11 | PRJXRAY_DB_DIR ?= ${NEXTPNR_XILINX_DIR}/external/prjxray-db 12 | 13 | DBPART = $(shell echo ${PART} | sed -e 's/-[0-9]//g') 14 | SPEEDGRADE = $(shell echo ${PART} | sed -e 's/.*\-\([0-9]\)/\1/g') 15 | 16 | CHIPDB ?= ./ 17 | ifeq ($(CHIPDB),) 18 | CHIPDB = ./ 19 | endif 20 | 21 | PYPY3 ?= pypy3 22 | 23 | TOP ?= ${PROJECT} 24 | TOP_MODULE ?= ${TOP} 25 | TOP_VERILOG ?= ${TOP}.v 26 | 27 | PNR_DEBUG ?= # --verbose --debug 28 | 29 | JTAG_LINK ?= -c digilent_hs2 30 | 31 | XDC ?= ${PROJECT}.xdc 32 | 33 | .PHONY: openxc7 34 | openxc7: ${PROJECT}_openxc7.bit 35 | 36 | .PHONY: program 37 | program: ${PROJECT}_openxc7.bit 38 | openFPGALoader ${JTAG_LINK} --bitstream $< 39 | 40 | ${PROJECT}.json: ${TOP_VERILOG} ${ADDITIONAL_SOURCES} 41 | yosys -p "synth_xilinx -flatten -abc9 ${SYNTH_OPTS} -arch xc7 -top ${TOP_MODULE}; write_json ${PROJECT}.json" $< ${ADDITIONAL_SOURCES} 42 | 43 | # The chip database only needs to be generated once 44 | # that is why we don't clean it with make clean 45 | ${CHIPDB}/${DBPART}.bin: 46 | ${PYPY3} ${NEXTPNR_XILINX_PYTHON_DIR}/bbaexport.py --device ${PART} --bba ${DBPART}.bba 47 | bbasm -l ${DBPART}.bba ${CHIPDB}/${DBPART}.bin 48 | rm -f ${DBPART}.bba 49 | 50 | ${PROJECT}.fasm: ${PROJECT}.json ${CHIPDB}/${DBPART}.bin ${XDC} 51 | nextpnr-xilinx --chipdb ${CHIPDB}/${DBPART}.bin --xdc ${XDC} --json ${PROJECT}.json --fasm $@ ${PNR_ARGS} ${PNR_DEBUG} 52 | 53 | ${PROJECT}.frames: ${PROJECT}.fasm 54 | fasm2frames --part ${PART} --db-root ${PRJXRAY_DB_DIR}/${FAMILY} $< > $@ 55 | 56 | ${PROJECT}_openxc7.bit: ${PROJECT}.frames 57 | xc7frames2bit --part_file ${PRJXRAY_DB_DIR}/${FAMILY}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@ 58 | 59 | 60 | ############################################################################################# 61 | # SPDX-License-Identifier: MIT 62 | # Generated from https://github.com/FPGAOL-CE/caas-wizard 63 | # 64 | BUILDDIR := ${CURDIR}/build 65 | 66 | LOGFILE := ${BUILDDIR}/top.log 67 | 68 | # Build design 69 | .PHONY: vivado 70 | vivado: ${BUILDDIR}/${PROJECT}_vivado.bit 71 | 72 | ${BUILDDIR}: 73 | mkdir -m 777 -p ${BUILDDIR} && chown -R nobody ${BUILDDIR} | true 74 | 75 | .ONESHELL: 76 | ${BUILDDIR}/vivado.tcl: ${BUILDDIR} 77 | cat << EOF > $@ 78 | # vivado.tcl generated for FPGAOL-CE/caas-wizard 79 | # can be launched from any directory 80 | cd ${BUILDDIR} 81 | create_project -part ${PART} -force v_proj 82 | set_property target_language Verilog [current_project] 83 | cd .. 84 | read_verilog [glob ${PROJECT}.v ${ADDITIONAL_SOURCES}] 85 | read_xdc [glob $(wildcard ${PROJECT}.xdc) ] 86 | cd build 87 | synth_design -top ${PROJECT} 88 | opt_design 89 | place_design 90 | phys_opt_design 91 | route_design 92 | write_bitstream -verbose -force ${PROJECT}_vivado.bit 93 | # report_utilization -file util.rpt 94 | # report_timing_summary -file timing.rpt 95 | EOF 96 | 97 | ${BUILDDIR}/${PROJECT}_vivado.bit: ${BUILDDIR}/vivado.tcl 98 | cd ${BUILDDIR} && vivado -mode batch -source $< > ${LOGFILE} 2>&1 99 | 100 | .PHONY: program_vivado 101 | program_vivado: 102 | openFPGALoader ${JTAG_LINK} --bitstream ${BUILDDIR}/${PROJECT}_vivado.bit 103 | 104 | 105 | ############################################################################################# 106 | 107 | .PHONY: clean 108 | clean: 109 | rm -f *.bit 110 | rm -f *.frames 111 | rm -f *.fasm 112 | rm -f *.json 113 | rm -f *.bin 114 | rm -f *.bba 115 | rm -rf ${BUILDDIR} 116 | -------------------------------------------------------------------------------- /example_demo/alinx_ax7325b/ax7325b_ddr3_openxc7.bit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AngeloJacobo/UberDDR3/a3efc861dafeec665d0885d6bc2e0c380260fe6b/example_demo/alinx_ax7325b/ax7325b_ddr3_openxc7.bit -------------------------------------------------------------------------------- /example_demo/alinx_ax7325b/ax7325b_spd_reader.xdc: -------------------------------------------------------------------------------- 1 | ############## clock define################## 2 | create_clock -period 5.000 [get_ports sys_clk_p] 3 | set_property IOSTANDARD DIFF_SSTL15 [get_ports sys_clk_p] 4 | # no need to create_clock for N side (only P side) or else tool will analyze interclock oaths and show failure in timing 5 | # https://support.xilinx.com/s/article/57109?language=en_US 6 | #create_clock -period 5.000 [get_ports sys_clk_n] 7 | set_property PACKAGE_PIN AE10 [get_ports sys_clk_p] 8 | set_property PACKAGE_PIN AF10 [get_ports sys_clk_n] 9 | set_property IOSTANDARD DIFF_SSTL15 [get_ports sys_clk_n] 10 | 11 | ############## SODIMM SPD define################## 12 | set_property IOSTANDARD LVCMOS33 [get_ports i2c_scl] 13 | set_property PACKAGE_PIN B20 [get_ports i2c_scl] 14 | set_property IOSTANDARD LVCMOS33 [get_ports i2c_sda] 15 | set_property PACKAGE_PIN C20 [get_ports i2c_sda] 16 | 17 | ############## fan define################## 18 | set_property IOSTANDARD LVCMOS25 [get_ports fan_pwm] 19 | set_property PACKAGE_PIN AE26 [get_ports fan_pwm] 20 | 21 | ############## key define################## 22 | set_property PACKAGE_PIN AG27 [get_ports i_rst_n] 23 | set_property IOSTANDARD LVCMOS25 [get_ports i_rst_n] 24 | 25 | ##############LED define################## 26 | set_property PACKAGE_PIN A22 [get_ports {led[0]}] 27 | set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}] 28 | set_property PACKAGE_PIN C19 [get_ports {led[1]}] 29 | set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}] 30 | set_property PACKAGE_PIN B19 [get_ports {led[2]}] 31 | set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}] 32 | set_property PACKAGE_PIN E18 [get_ports {led[3]}] 33 | set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}] 34 | 35 | ##############uart define########################### 36 | set_property IOSTANDARD LVCMOS25 [get_ports uart_tx] 37 | set_property PACKAGE_PIN AK26 [get_ports uart_tx] -------------------------------------------------------------------------------- /example_demo/alinx_ax7325b/clk_wiz.v: -------------------------------------------------------------------------------- 1 | `timescale 1ps/1ps 2 | 3 | module clk_wiz 4 | ( 5 | input wire clk_in1, 6 | output wire clk_out1, 7 | output wire clk_out2, 8 | output wire clk_out3, 9 | output wire clk_out4, 10 | input wire reset, 11 | output wire locked 12 | ); 13 | wire clk_out1_clk_wiz_0; 14 | wire clk_out2_clk_wiz_0; 15 | wire clk_out3_clk_wiz_0; 16 | wire clk_out4_clk_wiz_0; 17 | 18 | 19 | wire clkfbout; 20 | 21 | PLLE2_ADV 22 | #(.BANDWIDTH ("OPTIMIZED"), 23 | .COMPENSATION ("INTERNAL"), 24 | .STARTUP_WAIT ("FALSE"), 25 | .DIVCLK_DIVIDE (1), 26 | .CLKFBOUT_MULT (5), // 200 MHz * 5 = 1000 MHz 27 | .CLKFBOUT_PHASE (0.000), 28 | .CLKOUT0_DIVIDE (12), // 1000 MHz / 12 = 83.333 MHz 29 | .CLKOUT0_PHASE (0.000), 30 | .CLKOUT0_DUTY_CYCLE (0.500), 31 | .CLKOUT1_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz, 0 phase 32 | .CLKOUT1_PHASE (0.000), 33 | .CLKOUT1_DUTY_CYCLE (0.500), 34 | .CLKOUT2_DIVIDE (5), // 1000 MHz / 5 = 200 MHz 35 | .CLKOUT2_PHASE (0.000), 36 | .CLKOUT2_DUTY_CYCLE (0.500), 37 | .CLKOUT3_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz, 90 phase 38 | .CLKOUT3_PHASE (90.000), 39 | .CLKOUT3_DUTY_CYCLE (0.500), 40 | .CLKIN1_PERIOD (5.000) // 200 MHz input 41 | ) 42 | plle2_adv_inst 43 | ( 44 | .CLKFBOUT (clkfbout), 45 | .CLKOUT0 (clk_out1_clk_wiz_0), 46 | .CLKOUT1 (clk_out2_clk_wiz_0), 47 | .CLKOUT2 (clk_out3_clk_wiz_0), 48 | .CLKOUT3 (clk_out4_clk_wiz_0), 49 | .CLKFBIN (clkfbout), 50 | .CLKIN1 (clk_in1), 51 | .LOCKED (locked), 52 | .RST (reset) 53 | ); 54 | BUFG clkout1_buf 55 | (.O (clk_out1), 56 | .I (clk_out1_clk_wiz_0)); 57 | BUFG clkout2_buf 58 | (.O (clk_out2), 59 | .I (clk_out2_clk_wiz_0)); 60 | BUFG clkout3_buf 61 | (.O (clk_out3), 62 | .I (clk_out3_clk_wiz_0)); 63 | BUFG clkout4_buf 64 | (.O (clk_out4), 65 | .I (clk_out4_clk_wiz_0)); 66 | endmodule 67 | -------------------------------------------------------------------------------- /example_demo/alinx_ax7325b/uart_tx.v: -------------------------------------------------------------------------------- 1 | 2 | 3 | // 4 | // Module: uart_tx 5 | // 6 | // Notes: 7 | // - UART transmitter module. 8 | // 9 | 10 | module uart_tx( 11 | input wire clk , // Top level system clock input. 12 | input wire resetn , // Asynchronous active low reset. 13 | output wire uart_txd , // UART transmit pin. 14 | output wire uart_tx_busy, // Module busy sending previous item. 15 | input wire uart_tx_en , // Send the data on uart_tx_data 16 | input wire [PAYLOAD_BITS-1:0] uart_tx_data // The data to be sent 17 | ); 18 | 19 | // --------------------------------------------------------------------------- 20 | // External parameters. 21 | // 22 | 23 | // 24 | // Input bit rate of the UART line. 25 | parameter BIT_RATE = 9600; // bits / sec 26 | localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds 27 | 28 | // 29 | // Clock frequency in hertz. 30 | parameter CLK_HZ = 50_000_000; 31 | localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds 32 | 33 | // 34 | // Number of data bits recieved per UART packet. 35 | parameter PAYLOAD_BITS = 8; 36 | 37 | // 38 | // Number of stop bits indicating the end of a packet. 39 | parameter STOP_BITS = 1; 40 | 41 | // --------------------------------------------------------------------------- 42 | // Internal parameters. 43 | // 44 | 45 | // 46 | // Number of clock cycles per uart bit. 47 | localparam CYCLES_PER_BIT = BIT_P / CLK_P; 48 | 49 | // 50 | // Size of the registers which store sample counts and bit durations. 51 | localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT); 52 | 53 | // --------------------------------------------------------------------------- 54 | // Internal registers. 55 | // 56 | 57 | // 58 | // Internally latched value of the uart_txd line. Helps break long timing 59 | // paths from the logic to the output pins. 60 | reg txd_reg; 61 | 62 | // 63 | // Storage for the serial data to be sent. 64 | reg [PAYLOAD_BITS-1:0] data_to_send; 65 | 66 | // 67 | // Counter for the number of cycles over a packet bit. 68 | reg [COUNT_REG_LEN-1:0] cycle_counter; 69 | 70 | // 71 | // Counter for the number of sent bits of the packet. 72 | reg [3:0] bit_counter; 73 | 74 | // 75 | // Current and next states of the internal FSM. 76 | reg [2:0] fsm_state; 77 | reg [2:0] n_fsm_state; 78 | 79 | localparam FSM_IDLE = 0; 80 | localparam FSM_START= 1; 81 | localparam FSM_SEND = 2; 82 | localparam FSM_STOP = 3; 83 | 84 | 85 | // --------------------------------------------------------------------------- 86 | // FSM next state selection. 87 | // 88 | 89 | assign uart_tx_busy = fsm_state != FSM_IDLE; 90 | assign uart_txd = txd_reg; 91 | 92 | wire next_bit = cycle_counter == CYCLES_PER_BIT; 93 | wire payload_done = bit_counter == PAYLOAD_BITS ; 94 | wire stop_done = bit_counter == STOP_BITS && fsm_state == FSM_STOP; 95 | 96 | // 97 | // Handle picking the next state. 98 | always @(*) begin : p_n_fsm_state 99 | case(fsm_state) 100 | FSM_IDLE : n_fsm_state = uart_tx_en ? FSM_START: FSM_IDLE ; 101 | FSM_START: n_fsm_state = next_bit ? FSM_SEND : FSM_START; 102 | FSM_SEND : n_fsm_state = payload_done ? FSM_STOP : FSM_SEND ; 103 | FSM_STOP : n_fsm_state = stop_done ? FSM_IDLE : FSM_STOP ; 104 | default : n_fsm_state = FSM_IDLE; 105 | endcase 106 | end 107 | 108 | // --------------------------------------------------------------------------- 109 | // Internal register setting and re-setting. 110 | // 111 | 112 | // 113 | // Handle updates to the sent data register. 114 | integer i = 0; 115 | always @(posedge clk) begin : p_data_to_send 116 | if(!resetn) begin 117 | data_to_send <= {PAYLOAD_BITS{1'b0}}; 118 | end else if(fsm_state == FSM_IDLE && uart_tx_en) begin 119 | data_to_send <= uart_tx_data; 120 | end else if(fsm_state == FSM_SEND && next_bit ) begin 121 | for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin 122 | data_to_send[i] <= data_to_send[i+1]; 123 | end 124 | end 125 | end 126 | 127 | 128 | // 129 | // Increments the bit counter each time a new bit frame is sent. 130 | always @(posedge clk) begin : p_bit_counter 131 | if(!resetn) begin 132 | bit_counter <= 4'b0; 133 | end else if(fsm_state != FSM_SEND && fsm_state != FSM_STOP) begin 134 | bit_counter <= {COUNT_REG_LEN{1'b0}}; 135 | end else if(fsm_state == FSM_SEND && n_fsm_state == FSM_STOP) begin 136 | bit_counter <= {COUNT_REG_LEN{1'b0}}; 137 | end else if(fsm_state == FSM_STOP&& next_bit) begin 138 | bit_counter <= bit_counter + 1'b1; 139 | end else if(fsm_state == FSM_SEND && next_bit) begin 140 | bit_counter <= bit_counter + 1'b1; 141 | end 142 | end 143 | 144 | 145 | // 146 | // Increments the cycle counter when sending. 147 | always @(posedge clk) begin : p_cycle_counter 148 | if(!resetn) begin 149 | cycle_counter <= {COUNT_REG_LEN{1'b0}}; 150 | end else if(next_bit) begin 151 | cycle_counter <= {COUNT_REG_LEN{1'b0}}; 152 | end else if(fsm_state == FSM_START || 153 | fsm_state == FSM_SEND || 154 | fsm_state == FSM_STOP ) begin 155 | cycle_counter <= cycle_counter + 1'b1; 156 | end 157 | end 158 | 159 | 160 | // 161 | // Progresses the next FSM state. 162 | always @(posedge clk) begin : p_fsm_state 163 | if(!resetn) begin 164 | fsm_state <= FSM_IDLE; 165 | end else begin 166 | fsm_state <= n_fsm_state; 167 | end 168 | end 169 | 170 | 171 | // 172 | // Responsible for updating the internal value of the txd_reg. 173 | always @(posedge clk) begin : p_txd_reg 174 | if(!resetn) begin 175 | txd_reg <= 1'b1; 176 | end else if(fsm_state == FSM_IDLE) begin 177 | txd_reg <= 1'b1; 178 | end else if(fsm_state == FSM_START) begin 179 | txd_reg <= 1'b0; 180 | end else if(fsm_state == FSM_SEND) begin 181 | txd_reg <= data_to_send[0]; 182 | end else if(fsm_state == FSM_STOP) begin 183 | txd_reg <= 1'b1; 184 | end 185 | end 186 | 187 | endmodule 188 | -------------------------------------------------------------------------------- /example_demo/arty_s7/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT = arty_ddr3 2 | BOARD = arty_s7_50 3 | FAMILY = spartan7 4 | PART = xc7s50csga324-1 5 | CHIPDB = ${SPARTAN7_CHIPDB} 6 | ADDITIONAL_SOURCES = ../../rtl/ddr3_controller.v ../../rtl/ddr3_phy.v ../../rtl/ddr3_top.v uart_rx.v uart_tx.v clk_wiz.v 7 | 8 | 9 | ############################################################################################# 10 | NEXTPNR_XILINX_DIR ?= /snap/openxc7/current/opt/nextpnr-xilinx 11 | NEXTPNR_XILINX_PYTHON_DIR ?= ${NEXTPNR_XILINX_DIR}/python 12 | PRJXRAY_DB_DIR ?= ${NEXTPNR_XILINX_DIR}/external/prjxray-db 13 | 14 | DBPART = $(shell echo ${PART} | sed -e 's/-[0-9]//g') 15 | SPEEDGRADE = $(shell echo ${PART} | sed -e 's/.*\-\([0-9]\)/\1/g') 16 | 17 | CHIPDB ?= ./ 18 | ifeq ($(CHIPDB),) 19 | CHIPDB = ./ 20 | endif 21 | 22 | PYPY3 ?= pypy3 23 | 24 | TOP ?= ${PROJECT} 25 | TOP_MODULE ?= ${TOP} 26 | TOP_VERILOG ?= ${TOP}.v 27 | 28 | PNR_DEBUG ?= # --verbose --debug 29 | 30 | JTAG_LINK ?= --board ${BOARD} 31 | 32 | XDC ?= ${PROJECT}.xdc 33 | 34 | .PHONY: openxc7 35 | openxc7: ${PROJECT}_openxc7.bit 36 | 37 | .PHONY: program 38 | program: ${PROJECT}_openxc7.bit 39 | openFPGALoader ${JTAG_LINK} --bitstream $< 40 | 41 | ${PROJECT}.json: ${TOP_VERILOG} ${ADDITIONAL_SOURCES} 42 | yosys -p "synth_xilinx -flatten -abc9 ${SYNTH_OPTS} -arch xc7 -top ${TOP_MODULE}; write_json ${PROJECT}.json" $< ${ADDITIONAL_SOURCES} 43 | 44 | # The chip database only needs to be generated once 45 | # that is why we don't clean it with make clean 46 | ${CHIPDB}/${DBPART}.bin: 47 | ${PYPY3} ${NEXTPNR_XILINX_PYTHON_DIR}/bbaexport.py --device ${PART} --bba ${DBPART}.bba 48 | bbasm -l ${DBPART}.bba ${CHIPDB}/${DBPART}.bin 49 | rm -f ${DBPART}.bba 50 | 51 | ${PROJECT}.fasm: ${PROJECT}.json ${CHIPDB}/${DBPART}.bin ${XDC} 52 | nextpnr-xilinx --chipdb ${CHIPDB}/${DBPART}.bin --xdc ${XDC} --json ${PROJECT}.json --fasm $@ ${PNR_ARGS} ${PNR_DEBUG} 53 | 54 | ${PROJECT}.frames: ${PROJECT}.fasm 55 | fasm2frames --part ${PART} --db-root ${PRJXRAY_DB_DIR}/${FAMILY} $< > $@ 56 | 57 | ${PROJECT}_openxc7.bit: ${PROJECT}.frames 58 | xc7frames2bit --part_file ${PRJXRAY_DB_DIR}/${FAMILY}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@ 59 | 60 | 61 | ############################################################################################# 62 | # SPDX-License-Identifier: MIT 63 | # Generated from https://github.com/FPGAOL-CE/caas-wizard 64 | # 65 | BUILDDIR := ${CURDIR}/build 66 | 67 | LOGFILE := ${BUILDDIR}/top.log 68 | 69 | # Build design 70 | .PHONY: vivado 71 | vivado: ${BUILDDIR}/${PROJECT}_vivado.bit 72 | 73 | ${BUILDDIR}: 74 | mkdir -m 777 -p ${BUILDDIR} && chown -R nobody ${BUILDDIR} | true 75 | 76 | .ONESHELL: 77 | ${BUILDDIR}/vivado.tcl: ${BUILDDIR} 78 | cat << EOF > $@ 79 | # vivado.tcl generated for FPGAOL-CE/caas-wizard 80 | # can be launched from any directory 81 | cd ${BUILDDIR} 82 | create_project -part ${PART} -force v_proj 83 | set_property target_language Verilog [current_project] 84 | cd .. 85 | read_verilog [glob ${PROJECT}.v ${ADDITIONAL_SOURCES}] 86 | read_xdc [glob $(wildcard ${PROJECT}_vivado.xdc) ] 87 | cd build 88 | synth_design -top ${PROJECT} 89 | opt_design 90 | place_design 91 | phys_opt_design 92 | route_design 93 | write_bitstream -verbose -force ${PROJECT}_vivado.bit 94 | # report_utilization -file util.rpt 95 | # report_timing_summary -file timing.rpt 96 | EOF 97 | 98 | ${BUILDDIR}/${PROJECT}_vivado.bit: ${BUILDDIR}/vivado.tcl 99 | cd ${BUILDDIR} && vivado -mode batch -source $< > ${LOGFILE} 2>&1 100 | 101 | .PHONY: program_vivado 102 | program_vivado: 103 | openFPGALoader ${JTAG_LINK} --bitstream ${BUILDDIR}/${PROJECT}_vivado.bit 104 | 105 | 106 | ############################################################################################# 107 | 108 | .PHONY: clean 109 | clean: 110 | rm -f *.bit 111 | rm -f *.frames 112 | rm -f *.fasm 113 | rm -f *.json 114 | rm -f *.bin 115 | rm -f *.bba 116 | rm -rf ${BUILDDIR} 117 | -------------------------------------------------------------------------------- /example_demo/arty_s7/arty_ddr3_openxc7.bit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AngeloJacobo/UberDDR3/a3efc861dafeec665d0885d6bc2e0c380260fe6b/example_demo/arty_s7/arty_ddr3_openxc7.bit -------------------------------------------------------------------------------- /example_demo/arty_s7/clk_wiz.v: -------------------------------------------------------------------------------- 1 | `timescale 1ps/1ps 2 | 3 | module clk_wiz 4 | ( 5 | input wire clk_in1, 6 | output wire clk_out1, 7 | output wire clk_out2, 8 | output wire clk_out3, 9 | output wire clk_out4, 10 | input wire reset, 11 | output wire locked 12 | ); 13 | wire clk_out1_clk_wiz_0; 14 | wire clk_out2_clk_wiz_0; 15 | wire clk_out3_clk_wiz_0; 16 | wire clk_out4_clk_wiz_0; 17 | 18 | wire clkfbout; 19 | 20 | PLLE2_ADV 21 | #(.BANDWIDTH ("OPTIMIZED"), 22 | .COMPENSATION ("INTERNAL"), 23 | .STARTUP_WAIT ("FALSE"), 24 | .DIVCLK_DIVIDE (1), 25 | .CLKFBOUT_MULT (10), // 100 MHz * 10 = 1000 MHz 26 | .CLKFBOUT_PHASE (0.000), 27 | .CLKOUT0_DIVIDE (12), // 1000 MHz / 12 = 83.333 MHz 28 | .CLKOUT0_PHASE (0.000), 29 | .CLKOUT0_DUTY_CYCLE (0.500), 30 | .CLKOUT1_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz 31 | .CLKOUT1_PHASE (0.000), 32 | .CLKOUT1_DUTY_CYCLE (0.500), 33 | .CLKOUT2_DIVIDE (5), // 1000 MHz / 5 = 200 MHz 34 | .CLKOUT2_PHASE (0.000), 35 | .CLKOUT2_DUTY_CYCLE (0.500), 36 | .CLKOUT3_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz, 90 phase 37 | .CLKOUT3_PHASE (90.000), 38 | .CLKOUT3_DUTY_CYCLE (0.500), 39 | .CLKIN1_PERIOD (10.000) // 100 MHz input 40 | ) 41 | plle2_adv_inst 42 | ( 43 | .CLKFBOUT (clkfbout), 44 | .CLKOUT0 (clk_out1_clk_wiz_0), 45 | .CLKOUT1 (clk_out2_clk_wiz_0), 46 | .CLKOUT2 (clk_out3_clk_wiz_0), 47 | .CLKOUT3 (clk_out4_clk_wiz_0), 48 | .CLKFBIN (clkfbout), 49 | .CLKIN1 (clk_in1), 50 | .LOCKED (locked), 51 | .RST (reset) 52 | ); 53 | BUFG clkout1_buf 54 | (.O (clk_out1), 55 | .I (clk_out1_clk_wiz_0)); 56 | BUFG clkout2_buf 57 | (.O (clk_out2), 58 | .I (clk_out2_clk_wiz_0)); 59 | BUFG clkout3_buf 60 | (.O (clk_out3), 61 | .I (clk_out3_clk_wiz_0)); 62 | BUFG clkout4_buf 63 | (.O (clk_out4), 64 | .I (clk_out4_clk_wiz_0)); 65 | 66 | endmodule 67 | -------------------------------------------------------------------------------- /example_demo/arty_s7/uart_tx.v: -------------------------------------------------------------------------------- 1 | 2 | 3 | // 4 | // Module: uart_tx 5 | // 6 | // Notes: 7 | // - UART transmitter module. 8 | // 9 | 10 | module uart_tx( 11 | input wire clk , // Top level system clock input. 12 | input wire resetn , // Asynchronous active low reset. 13 | output wire uart_txd , // UART transmit pin. 14 | output wire uart_tx_busy, // Module busy sending previous item. 15 | input wire uart_tx_en , // Send the data on uart_tx_data 16 | input wire [PAYLOAD_BITS-1:0] uart_tx_data // The data to be sent 17 | ); 18 | 19 | // --------------------------------------------------------------------------- 20 | // External parameters. 21 | // 22 | 23 | // 24 | // Input bit rate of the UART line. 25 | parameter BIT_RATE = 9600; // bits / sec 26 | localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds 27 | 28 | // 29 | // Clock frequency in hertz. 30 | parameter CLK_HZ = 50_000_000; 31 | localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds 32 | 33 | // 34 | // Number of data bits recieved per UART packet. 35 | parameter PAYLOAD_BITS = 8; 36 | 37 | // 38 | // Number of stop bits indicating the end of a packet. 39 | parameter STOP_BITS = 1; 40 | 41 | // --------------------------------------------------------------------------- 42 | // Internal parameters. 43 | // 44 | 45 | // 46 | // Number of clock cycles per uart bit. 47 | localparam CYCLES_PER_BIT = BIT_P / CLK_P; 48 | 49 | // 50 | // Size of the registers which store sample counts and bit durations. 51 | localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT); 52 | 53 | // --------------------------------------------------------------------------- 54 | // Internal registers. 55 | // 56 | 57 | // 58 | // Internally latched value of the uart_txd line. Helps break long timing 59 | // paths from the logic to the output pins. 60 | reg txd_reg; 61 | 62 | // 63 | // Storage for the serial data to be sent. 64 | reg [PAYLOAD_BITS-1:0] data_to_send; 65 | 66 | // 67 | // Counter for the number of cycles over a packet bit. 68 | reg [COUNT_REG_LEN-1:0] cycle_counter; 69 | 70 | // 71 | // Counter for the number of sent bits of the packet. 72 | reg [3:0] bit_counter; 73 | 74 | // 75 | // Current and next states of the internal FSM. 76 | reg [2:0] fsm_state; 77 | reg [2:0] n_fsm_state; 78 | 79 | localparam FSM_IDLE = 0; 80 | localparam FSM_START= 1; 81 | localparam FSM_SEND = 2; 82 | localparam FSM_STOP = 3; 83 | 84 | 85 | // --------------------------------------------------------------------------- 86 | // FSM next state selection. 87 | // 88 | 89 | assign uart_tx_busy = fsm_state != FSM_IDLE; 90 | assign uart_txd = txd_reg; 91 | 92 | wire next_bit = cycle_counter == CYCLES_PER_BIT; 93 | wire payload_done = bit_counter == PAYLOAD_BITS ; 94 | wire stop_done = bit_counter == STOP_BITS && fsm_state == FSM_STOP; 95 | 96 | // 97 | // Handle picking the next state. 98 | always @(*) begin : p_n_fsm_state 99 | case(fsm_state) 100 | FSM_IDLE : n_fsm_state = uart_tx_en ? FSM_START: FSM_IDLE ; 101 | FSM_START: n_fsm_state = next_bit ? FSM_SEND : FSM_START; 102 | FSM_SEND : n_fsm_state = payload_done ? FSM_STOP : FSM_SEND ; 103 | FSM_STOP : n_fsm_state = stop_done ? FSM_IDLE : FSM_STOP ; 104 | default : n_fsm_state = FSM_IDLE; 105 | endcase 106 | end 107 | 108 | // --------------------------------------------------------------------------- 109 | // Internal register setting and re-setting. 110 | // 111 | 112 | // 113 | // Handle updates to the sent data register. 114 | integer i = 0; 115 | always @(posedge clk) begin : p_data_to_send 116 | if(!resetn) begin 117 | data_to_send <= {PAYLOAD_BITS{1'b0}}; 118 | end else if(fsm_state == FSM_IDLE && uart_tx_en) begin 119 | data_to_send <= uart_tx_data; 120 | end else if(fsm_state == FSM_SEND && next_bit ) begin 121 | for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin 122 | data_to_send[i] <= data_to_send[i+1]; 123 | end 124 | end 125 | end 126 | 127 | 128 | // 129 | // Increments the bit counter each time a new bit frame is sent. 130 | always @(posedge clk) begin : p_bit_counter 131 | if(!resetn) begin 132 | bit_counter <= 4'b0; 133 | end else if(fsm_state != FSM_SEND && fsm_state != FSM_STOP) begin 134 | bit_counter <= {COUNT_REG_LEN{1'b0}}; 135 | end else if(fsm_state == FSM_SEND && n_fsm_state == FSM_STOP) begin 136 | bit_counter <= {COUNT_REG_LEN{1'b0}}; 137 | end else if(fsm_state == FSM_STOP&& next_bit) begin 138 | bit_counter <= bit_counter + 1'b1; 139 | end else if(fsm_state == FSM_SEND && next_bit) begin 140 | bit_counter <= bit_counter + 1'b1; 141 | end 142 | end 143 | 144 | 145 | // 146 | // Increments the cycle counter when sending. 147 | always @(posedge clk) begin : p_cycle_counter 148 | if(!resetn) begin 149 | cycle_counter <= {COUNT_REG_LEN{1'b0}}; 150 | end else if(next_bit) begin 151 | cycle_counter <= {COUNT_REG_LEN{1'b0}}; 152 | end else if(fsm_state == FSM_START || 153 | fsm_state == FSM_SEND || 154 | fsm_state == FSM_STOP ) begin 155 | cycle_counter <= cycle_counter + 1'b1; 156 | end 157 | end 158 | 159 | 160 | // 161 | // Progresses the next FSM state. 162 | always @(posedge clk) begin : p_fsm_state 163 | if(!resetn) begin 164 | fsm_state <= FSM_IDLE; 165 | end else begin 166 | fsm_state <= n_fsm_state; 167 | end 168 | end 169 | 170 | 171 | // 172 | // Responsible for updating the internal value of the txd_reg. 173 | always @(posedge clk) begin : p_txd_reg 174 | if(!resetn) begin 175 | txd_reg <= 1'b1; 176 | end else if(fsm_state == FSM_IDLE) begin 177 | txd_reg <= 1'b1; 178 | end else if(fsm_state == FSM_START) begin 179 | txd_reg <= 1'b0; 180 | end else if(fsm_state == FSM_SEND) begin 181 | txd_reg <= data_to_send[0]; 182 | end else if(fsm_state == FSM_STOP) begin 183 | txd_reg <= 1'b1; 184 | end 185 | end 186 | 187 | endmodule 188 | -------------------------------------------------------------------------------- /example_demo/enclustra_kx2_st1/Makefile: -------------------------------------------------------------------------------- 1 | FAMILY = kintex7 2 | PART = xc7k160tffg676-2 3 | BOARD = qmtechKintex7 4 | PROJECT = enclustra_ddr3 5 | CHIPDB = ${KINTEX7_CHIPDB} 6 | ADDITIONAL_SOURCES = ../../rtl/ddr3_controller.v ../../rtl/ddr3_phy.v ../../rtl/ddr3_top.v uart_rx.v uart_tx.v clk_wiz.v 7 | 8 | ############################################################################################# 9 | NEXTPNR_XILINX_DIR ?= /snap/openxc7/current/opt/nextpnr-xilinx 10 | NEXTPNR_XILINX_PYTHON_DIR ?= ${NEXTPNR_XILINX_DIR}/python 11 | PRJXRAY_DB_DIR ?= ${NEXTPNR_XILINX_DIR}/external/prjxray-db 12 | 13 | DBPART = $(shell echo ${PART} | sed -e 's/-[0-9]//g') 14 | SPEEDGRADE = $(shell echo ${PART} | sed -e 's/.*\-\([0-9]\)/\1/g') 15 | 16 | CHIPDB ?= ./ 17 | ifeq ($(CHIPDB),) 18 | CHIPDB = ./ 19 | endif 20 | 21 | PYPY3 ?= pypy3 22 | 23 | TOP ?= ${PROJECT} 24 | TOP_MODULE ?= ${TOP} 25 | TOP_VERILOG ?= ${TOP}.v 26 | 27 | PNR_DEBUG ?= # --verbose --debug 28 | 29 | JTAG_LINK ?= -c digilent_hs2 30 | 31 | XDC ?= ${PROJECT}.xdc 32 | 33 | .PHONY: openxc7 34 | openxc7: ${PROJECT}_openxc7.bit 35 | 36 | .PHONY: program 37 | program: ${PROJECT}_openxc7.bit 38 | openFPGALoader ${JTAG_LINK} --bitstream $< 39 | 40 | ${PROJECT}.json: ${TOP_VERILOG} ${ADDITIONAL_SOURCES} 41 | yosys -p "synth_xilinx -flatten -abc9 ${SYNTH_OPTS} -arch xc7 -top ${TOP_MODULE}; write_json ${PROJECT}.json" $< ${ADDITIONAL_SOURCES} 42 | 43 | # The chip database only needs to be generated once 44 | # that is why we don't clean it with make clean 45 | ${CHIPDB}/${DBPART}.bin: 46 | ${PYPY3} ${NEXTPNR_XILINX_PYTHON_DIR}/bbaexport.py --device ${PART} --bba ${DBPART}.bba 47 | bbasm -l ${DBPART}.bba ${CHIPDB}/${DBPART}.bin 48 | rm -f ${DBPART}.bba 49 | 50 | ${PROJECT}.fasm: ${PROJECT}.json ${CHIPDB}/${DBPART}.bin ${XDC} 51 | nextpnr-xilinx --chipdb ${CHIPDB}/${DBPART}.bin --xdc ${XDC} --json ${PROJECT}.json --fasm $@ ${PNR_ARGS} ${PNR_DEBUG} 52 | 53 | ${PROJECT}.frames: ${PROJECT}.fasm 54 | fasm2frames --part ${PART} --db-root ${PRJXRAY_DB_DIR}/${FAMILY} $< > $@ 55 | 56 | ${PROJECT}_openxc7.bit: ${PROJECT}.frames 57 | xc7frames2bit --part_file ${PRJXRAY_DB_DIR}/${FAMILY}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@ 58 | 59 | 60 | ############################################################################################# 61 | # SPDX-License-Identifier: MIT 62 | # Generated from https://github.com/FPGAOL-CE/caas-wizard 63 | # 64 | BUILDDIR := ${CURDIR}/build 65 | 66 | LOGFILE := ${BUILDDIR}/top.log 67 | 68 | # Build design 69 | .PHONY: vivado 70 | vivado: ${BUILDDIR}/${PROJECT}_vivado.bit 71 | 72 | ${BUILDDIR}: 73 | mkdir -m 777 -p ${BUILDDIR} && chown -R nobody ${BUILDDIR} | true 74 | 75 | .ONESHELL: 76 | ${BUILDDIR}/vivado.tcl: ${BUILDDIR} 77 | cat << EOF > $@ 78 | # vivado.tcl generated for FPGAOL-CE/caas-wizard 79 | # can be launched from any directory 80 | cd ${BUILDDIR} 81 | create_project -part ${PART} -force v_proj 82 | set_property target_language Verilog [current_project] 83 | cd .. 84 | read_verilog [glob ${PROJECT}.v ${ADDITIONAL_SOURCES}] 85 | read_xdc [glob $(wildcard ${PROJECT}.xdc) ] 86 | cd build 87 | synth_design -top ${PROJECT} 88 | opt_design 89 | place_design 90 | phys_opt_design 91 | route_design 92 | write_bitstream -verbose -force ${PROJECT}_vivado.bit 93 | # report_utilization -file util.rpt 94 | # report_timing_summary -file timing.rpt 95 | EOF 96 | 97 | ${BUILDDIR}/${PROJECT}_vivado.bit: ${BUILDDIR}/vivado.tcl 98 | cd ${BUILDDIR} && vivado -mode batch -source $< > ${LOGFILE} 2>&1 99 | 100 | .PHONY: program_vivado 101 | program_vivado: 102 | openFPGALoader ${JTAG_LINK} --bitstream ${BUILDDIR}/${PROJECT}_vivado.bit 103 | 104 | ############################################################################################# 105 | 106 | .PHONY: clean 107 | clean: 108 | rm -f *.bit 109 | rm -f *.frames 110 | rm -f *.fasm 111 | rm -f *.json 112 | rm -f *.bin 113 | rm -f *.bba 114 | rm -rf ${BUILDDIR} 115 | -------------------------------------------------------------------------------- /example_demo/enclustra_kx2_st1/clk_wiz.v: -------------------------------------------------------------------------------- 1 | `timescale 1ps/1ps 2 | 3 | module clk_wiz 4 | ( 5 | input wire clk_in1, 6 | output wire clk_out1, 7 | output wire clk_out2, 8 | output wire clk_out3, 9 | output wire clk_out4, 10 | output wire clk_out5, 11 | input wire reset, 12 | output wire locked 13 | ); 14 | wire clk_out1_clk_wiz_0; 15 | wire clk_out2_clk_wiz_0; 16 | wire clk_out3_clk_wiz_0; 17 | // wire clk_out4_clk_wiz_0; 18 | // wire clk_out5_clk_wiz_0; 19 | 20 | wire clkfbout; 21 | 22 | PLLE2_ADV 23 | #(.BANDWIDTH ("OPTIMIZED"), 24 | .COMPENSATION ("INTERNAL"), 25 | .STARTUP_WAIT ("FALSE"), 26 | .DIVCLK_DIVIDE (1), 27 | .CLKFBOUT_MULT (5), // 200 MHz * 5 = 1000 MHz 28 | .CLKFBOUT_PHASE (0.000), 29 | .CLKOUT0_DIVIDE (12), // 1000 MHz / 12 = 83.333 MHz 30 | .CLKOUT0_PHASE (0.000), 31 | .CLKOUT0_DUTY_CYCLE (0.500), 32 | .CLKOUT1_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz 33 | .CLKOUT1_PHASE (0.000), 34 | .CLKOUT1_DUTY_CYCLE (0.500), 35 | .CLKOUT2_DIVIDE (5), // 1000 MHz / 5 = 200 MHz 36 | .CLKOUT2_PHASE (0.000), 37 | .CLKOUT2_DUTY_CYCLE (0.500), 38 | // .CLKOUT3_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz, 90 phase 39 | // .CLKOUT3_PHASE (90.000), 40 | // .CLKOUT3_DUTY_CYCLE (0.500), 41 | // .CLKOUT4_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz, 180 phase 42 | // .CLKOUT4_PHASE (180), 43 | // .CLKOUT4_DUTY_CYCLE (0.500), 44 | .CLKIN1_PERIOD (5) // 200 MHz input 45 | ) 46 | plle2_adv_inst 47 | ( 48 | .CLKFBOUT (clkfbout), 49 | .CLKOUT0 (clk_out1_clk_wiz_0), 50 | .CLKOUT1 (clk_out2_clk_wiz_0), 51 | .CLKOUT2 (clk_out3_clk_wiz_0), 52 | // .CLKOUT3 (clk_out4_clk_wiz_0), 53 | // .CLKOUT4 (clk_out5_clk_wiz_0), 54 | .CLKFBIN (clkfbout), 55 | .CLKIN1 (clk_in1), 56 | .LOCKED (locked), 57 | .RST (reset) 58 | ); 59 | BUFG clkout1_buf 60 | (.O (clk_out1), 61 | .I (clk_out1_clk_wiz_0)); 62 | BUFG clkout2_buf 63 | (.O (clk_out2), 64 | .I (clk_out2_clk_wiz_0)); 65 | BUFG clkout3_buf 66 | (.O (clk_out3), 67 | .I (clk_out3_clk_wiz_0)); 68 | // BUFG clkout4_buf 69 | // (.O (clk_out4), 70 | // .I (clk_out4_clk_wiz_0)); 71 | // BUFG clkout5_buf 72 | // (.O (clk_out5), 73 | // .I (clk_out5_clk_wiz_0)); 74 | endmodule 75 | -------------------------------------------------------------------------------- /example_demo/enclustra_kx2_st1/ddr3_test.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * Use of the Software is limited solely to applications: 16 | * (a) running on a Xilinx device, or 17 | * (b) that interact with a Xilinx device through a bus or interconnect. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 | * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 24 | * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | * SOFTWARE. 26 | * 27 | * Except as contained in this notice, the name of the Xilinx shall not be used 28 | * in advertising or otherwise to promote the sale, use or other dealings in 29 | * this Software without prior written authorization from Xilinx. 30 | * 31 | ******************************************************************************/ 32 | 33 | /* 34 | * helloworld.c: simple test application 35 | * 36 | * This application configures UART 16550 to baud rate 9600. 37 | * PS7 UART (Zynq) is not initialized by this application, since 38 | * bootrom/bsp configures it to baud rate 115200 39 | * 40 | * ------------------------------------------------ 41 | * | UART TYPE BAUD RATE | 42 | * ------------------------------------------------ 43 | * uartns550 9600 44 | * uartlite Configurable only in HW design 45 | * ps7_uart 115200 (configured by bootrom/bsp) 46 | */ 47 | #include 48 | #include 49 | #include "xparameters.h" 50 | #include "platform.h" 51 | #include "xil_printf.h" 52 | #include "xil_io.h" 53 | #include "sleep.h" 54 | 55 | #define DDR3_MONITOR_BASE 0x00010000 56 | 57 | #define REG_MATCH_LOW 0x00 58 | #define REG_MATCH_HIGH 0x04 59 | #define REG_MISMATCH_LOW 0x08 60 | #define REG_MISMATCH_HIGH 0x0C 61 | #define REG_TIMER_LOW 0x10 62 | #define REG_TIMER_HIGH 0x14 63 | #define REG_FAULTS 0x18 64 | 65 | #define TIMER_FREQ_HZ 100000000 // Adjust based on actual hardware clock 66 | 67 | int main() 68 | { 69 | init_platform(); 70 | print("Hello World\n\r"); 71 | print("Successfully ran Hello World application\n\r"); 72 | 73 | while (1) // Infinite loop 74 | { 75 | // Read 64-bit counters 76 | uint32_t correct_lower_32 = *(volatile uint32_t *)(DDR3_MONITOR_BASE + REG_MATCH_LOW); 77 | uint32_t correct_upper_32 = *(volatile uint32_t *)(DDR3_MONITOR_BASE + REG_MATCH_HIGH); 78 | uint32_t wrong_lower_32 = *(volatile uint32_t *)(DDR3_MONITOR_BASE + REG_MISMATCH_LOW); 79 | uint32_t wrong_upper_32 = *(volatile uint32_t *)(DDR3_MONITOR_BASE + REG_MISMATCH_HIGH); 80 | uint32_t timer_lower_32 = *(volatile uint32_t *)(DDR3_MONITOR_BASE + REG_TIMER_LOW); 81 | uint32_t timer_upper_32 = *(volatile uint32_t *)(DDR3_MONITOR_BASE + REG_TIMER_HIGH); 82 | uint32_t injected_faults = *(volatile uint32_t *)(DDR3_MONITOR_BASE + REG_FAULTS); 83 | 84 | // Combine into 64-bit values 85 | long long match_count = ((long long) correct_upper_32 << 32) | correct_lower_32; 86 | long long mismatch_count = ((long long) wrong_upper_32 << 32) | wrong_lower_32; 87 | long long timer_count = ((long long) timer_upper_32 << 32) | timer_lower_32; 88 | 89 | // Convert timer count to time in days, hours, and minutes 90 | long long elapsed_seconds = timer_count / TIMER_FREQ_HZ; 91 | uint32_t days = elapsed_seconds / (24 * 3600); 92 | uint32_t hours = (elapsed_seconds % (24 * 3600)) / 3600; 93 | uint32_t minutes = (elapsed_seconds % 3600) / 60; 94 | 95 | // Print results 96 | xil_printf("\n=============================\n\r"); 97 | xil_printf(" SYSTEM STATUS \n\r"); 98 | xil_printf("=============================\n\r"); 99 | xil_printf(" Matched Reads : %u M\n\r", match_count / 1000000); 100 | xil_printf(" Mismatched Reads: %u \n\r", mismatch_count); 101 | xil_printf(" Injected Faults : %u\n\r", injected_faults); 102 | xil_printf("-----------------------------\n\r"); 103 | xil_printf(" Elapsed Time : %u days, %u hours, %u minutes\n\r", days, hours, minutes); 104 | xil_printf("=============================\n\r\n"); 105 | 106 | 107 | 108 | // Wait 1 second 109 | usleep(1000000); 110 | } 111 | 112 | cleanup_platform(); 113 | return 0; // (Will never reach here due to infinite loop) 114 | } 115 | -------------------------------------------------------------------------------- /example_demo/enclustra_kx2_st1/ddr3_test_monitor_axi_1.0/drivers/ddr3_test_monitor_axi_v1_0/data/ddr3_test_monitor_axi.mdd: -------------------------------------------------------------------------------- 1 | 2 | 3 | OPTION psf_version = 2.1; 4 | 5 | BEGIN DRIVER ddr3_test_monitor_axi 6 | OPTION supported_peripherals = (ddr3_test_monitor_axi); 7 | OPTION copyfiles = all; 8 | OPTION VERSION = 1.0; 9 | OPTION NAME = ddr3_test_monitor_axi; 10 | END DRIVER 11 | -------------------------------------------------------------------------------- /example_demo/enclustra_kx2_st1/ddr3_test_monitor_axi_1.0/drivers/ddr3_test_monitor_axi_v1_0/data/ddr3_test_monitor_axi.tcl: -------------------------------------------------------------------------------- 1 | 2 | 3 | proc generate {drv_handle} { 4 | xdefine_include_file $drv_handle "xparameters.h" "ddr3_test_monitor_axi" "NUM_INSTANCES" "DEVICE_ID" "C_S00_AXI_BASEADDR" "C_S00_AXI_HIGHADDR" 5 | } 6 | -------------------------------------------------------------------------------- /example_demo/enclustra_kx2_st1/ddr3_test_monitor_axi_1.0/drivers/ddr3_test_monitor_axi_v1_0/src/Makefile: -------------------------------------------------------------------------------- 1 | COMPILER= 2 | ARCHIVER= 3 | CP=cp 4 | COMPILER_FLAGS= 5 | EXTRA_COMPILER_FLAGS= 6 | LIB=libxil.a 7 | 8 | RELEASEDIR=../../../lib 9 | INCLUDEDIR=../../../include 10 | INCLUDES=-I./. -I${INCLUDEDIR} 11 | 12 | INCLUDEFILES=*.h 13 | LIBSOURCES=*.c 14 | OUTS = *.o 15 | 16 | libs: 17 | echo "Compiling ddr3_test_monitor_axi..." 18 | $(COMPILER) $(COMPILER_FLAGS) $(EXTRA_COMPILER_FLAGS) $(INCLUDES) $(LIBSOURCES) 19 | $(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OUTS} 20 | make clean 21 | 22 | include: 23 | ${CP} $(INCLUDEFILES) $(INCLUDEDIR) 24 | 25 | clean: 26 | rm -rf ${OUTS} 27 | -------------------------------------------------------------------------------- /example_demo/enclustra_kx2_st1/ddr3_test_monitor_axi_1.0/drivers/ddr3_test_monitor_axi_v1_0/src/ddr3_test_monitor_axi.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | /***************************** Include Files *******************************/ 4 | #include "ddr3_test_monitor_axi.h" 5 | 6 | /************************** Function Definitions ***************************/ 7 | -------------------------------------------------------------------------------- /example_demo/enclustra_kx2_st1/ddr3_test_monitor_axi_1.0/drivers/ddr3_test_monitor_axi_v1_0/src/ddr3_test_monitor_axi.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef DDR3_TEST_MONITOR_AXI_H 3 | #define DDR3_TEST_MONITOR_AXI_H 4 | 5 | 6 | /****************** Include Files ********************/ 7 | #include "xil_types.h" 8 | #include "xstatus.h" 9 | 10 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG0_OFFSET 0 11 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG1_OFFSET 4 12 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG2_OFFSET 8 13 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG3_OFFSET 12 14 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG4_OFFSET 16 15 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG5_OFFSET 20 16 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG6_OFFSET 24 17 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG7_OFFSET 28 18 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG8_OFFSET 32 19 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG9_OFFSET 36 20 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG10_OFFSET 40 21 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG11_OFFSET 44 22 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG12_OFFSET 48 23 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG13_OFFSET 52 24 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG14_OFFSET 56 25 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG15_OFFSET 60 26 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG16_OFFSET 64 27 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG17_OFFSET 68 28 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG18_OFFSET 72 29 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG19_OFFSET 76 30 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG20_OFFSET 80 31 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG21_OFFSET 84 32 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG22_OFFSET 88 33 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG23_OFFSET 92 34 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG24_OFFSET 96 35 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG25_OFFSET 100 36 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG26_OFFSET 104 37 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG27_OFFSET 108 38 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG28_OFFSET 112 39 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG29_OFFSET 116 40 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG30_OFFSET 120 41 | #define DDR3_TEST_MONITOR_AXI_S00_AXI_SLV_REG31_OFFSET 124 42 | 43 | 44 | /**************************** Type Definitions *****************************/ 45 | /** 46 | * 47 | * Write a value to a DDR3_TEST_MONITOR_AXI register. A 32 bit write is performed. 48 | * If the component is implemented in a smaller width, only the least 49 | * significant data is written. 50 | * 51 | * @param BaseAddress is the base address of the DDR3_TEST_MONITOR_AXIdevice. 52 | * @param RegOffset is the register offset from the base to write to. 53 | * @param Data is the data written to the register. 54 | * 55 | * @return None. 56 | * 57 | * @note 58 | * C-style signature: 59 | * void DDR3_TEST_MONITOR_AXI_mWriteReg(u32 BaseAddress, unsigned RegOffset, u32 Data) 60 | * 61 | */ 62 | #define DDR3_TEST_MONITOR_AXI_mWriteReg(BaseAddress, RegOffset, Data) \ 63 | Xil_Out32((BaseAddress) + (RegOffset), (u32)(Data)) 64 | 65 | /** 66 | * 67 | * Read a value from a DDR3_TEST_MONITOR_AXI register. A 32 bit read is performed. 68 | * If the component is implemented in a smaller width, only the least 69 | * significant data is read from the register. The most significant data 70 | * will be read as 0. 71 | * 72 | * @param BaseAddress is the base address of the DDR3_TEST_MONITOR_AXI device. 73 | * @param RegOffset is the register offset from the base to write to. 74 | * 75 | * @return Data is the data from the register. 76 | * 77 | * @note 78 | * C-style signature: 79 | * u32 DDR3_TEST_MONITOR_AXI_mReadReg(u32 BaseAddress, unsigned RegOffset) 80 | * 81 | */ 82 | #define DDR3_TEST_MONITOR_AXI_mReadReg(BaseAddress, RegOffset) \ 83 | Xil_In32((BaseAddress) + (RegOffset)) 84 | 85 | /************************** Function Prototypes ****************************/ 86 | /** 87 | * 88 | * Run a self-test on the driver/device. Note this may be a destructive test if 89 | * resets of the device are performed. 90 | * 91 | * If the hardware system is not built correctly, this function may never 92 | * return to the caller. 93 | * 94 | * @param baseaddr_p is the base address of the DDR3_TEST_MONITOR_AXI instance to be worked on. 95 | * 96 | * @return 97 | * 98 | * - XST_SUCCESS if all self-test code passed 99 | * - XST_FAILURE if any self-test code failed 100 | * 101 | * @note Caching must be turned off for this function to work. 102 | * @note Self test may fail if data memory and device are not on the same bus. 103 | * 104 | */ 105 | XStatus DDR3_TEST_MONITOR_AXI_Reg_SelfTest(void * baseaddr_p); 106 | 107 | #endif // DDR3_TEST_MONITOR_AXI_H 108 | -------------------------------------------------------------------------------- /example_demo/enclustra_kx2_st1/ddr3_test_monitor_axi_1.0/drivers/ddr3_test_monitor_axi_v1_0/src/ddr3_test_monitor_axi_selftest.c: -------------------------------------------------------------------------------- 1 | 2 | /***************************** Include Files *******************************/ 3 | #include "ddr3_test_monitor_axi.h" 4 | #include "xparameters.h" 5 | #include "stdio.h" 6 | #include "xil_io.h" 7 | 8 | /************************** Constant Definitions ***************************/ 9 | #define READ_WRITE_MUL_FACTOR 0x10 10 | 11 | /************************** Function Definitions ***************************/ 12 | /** 13 | * 14 | * Run a self-test on the driver/device. Note this may be a destructive test if 15 | * resets of the device are performed. 16 | * 17 | * If the hardware system is not built correctly, this function may never 18 | * return to the caller. 19 | * 20 | * @param baseaddr_p is the base address of the DDR3_TEST_MONITOR_AXIinstance to be worked on. 21 | * 22 | * @return 23 | * 24 | * - XST_SUCCESS if all self-test code passed 25 | * - XST_FAILURE if any self-test code failed 26 | * 27 | * @note Caching must be turned off for this function to work. 28 | * @note Self test may fail if data memory and device are not on the same bus. 29 | * 30 | */ 31 | XStatus DDR3_TEST_MONITOR_AXI_Reg_SelfTest(void * baseaddr_p) 32 | { 33 | u32 baseaddr; 34 | int write_loop_index; 35 | int read_loop_index; 36 | int Index; 37 | 38 | baseaddr = (u32) baseaddr_p; 39 | 40 | xil_printf("******************************\n\r"); 41 | xil_printf("* User Peripheral Self Test\n\r"); 42 | xil_printf("******************************\n\n\r"); 43 | 44 | /* 45 | * Write to user logic slave module register(s) and read back 46 | */ 47 | xil_printf("User logic slave module test...\n\r"); 48 | 49 | for (write_loop_index = 0 ; write_loop_index < 4; write_loop_index++) 50 | DDR3_TEST_MONITOR_AXI_mWriteReg (baseaddr, write_loop_index*4, (write_loop_index+1)*READ_WRITE_MUL_FACTOR); 51 | for (read_loop_index = 0 ; read_loop_index < 4; read_loop_index++) 52 | if ( DDR3_TEST_MONITOR_AXI_mReadReg (baseaddr, read_loop_index*4) != (read_loop_index+1)*READ_WRITE_MUL_FACTOR){ 53 | xil_printf ("Error reading register value at address %x\n", (int)baseaddr + read_loop_index*4); 54 | return XST_FAILURE; 55 | } 56 | 57 | xil_printf(" - slave register write/read passed\n\n\r"); 58 | 59 | return XST_SUCCESS; 60 | } 61 | -------------------------------------------------------------------------------- /example_demo/enclustra_kx2_st1/ddr3_test_monitor_axi_1.0/example_designs/bfm_design/design.tcl: -------------------------------------------------------------------------------- 1 | proc create_ipi_design { offsetfile design_name } { 2 | create_bd_design $design_name 3 | open_bd_design $design_name 4 | 5 | # Create Clock and Reset Ports 6 | set ACLK [ create_bd_port -dir I -type clk ACLK ] 7 | set_property -dict [ list CONFIG.FREQ_HZ {100000000} CONFIG.PHASE {0.000} CONFIG.CLK_DOMAIN "${design_name}_ACLK" ] $ACLK 8 | set ARESETN [ create_bd_port -dir I -type rst ARESETN ] 9 | set_property -dict [ list CONFIG.POLARITY {ACTIVE_LOW} ] $ARESETN 10 | set_property CONFIG.ASSOCIATED_RESET ARESETN $ACLK 11 | 12 | # Create instance: ddr3_test_monitor_axi_0, and set properties 13 | set ddr3_test_monitor_axi_0 [ create_bd_cell -type ip -vlnv user.org:user:ddr3_test_monitor_axi:1.0 ddr3_test_monitor_axi_0] 14 | 15 | # Create instance: master_0, and set properties 16 | set master_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_vip master_0] 17 | set_property -dict [ list CONFIG.PROTOCOL {AXI4LITE} CONFIG.INTERFACE_MODE {MASTER} ] $master_0 18 | 19 | # Create interface connections 20 | connect_bd_intf_net [get_bd_intf_pins master_0/M_AXI ] [get_bd_intf_pins ddr3_test_monitor_axi_0/S00_AXI] 21 | 22 | # Create port connections 23 | connect_bd_net -net aclk_net [get_bd_ports ACLK] [get_bd_pins master_0/ACLK] [get_bd_pins ddr3_test_monitor_axi_0/S00_AXI_ACLK] 24 | connect_bd_net -net aresetn_net [get_bd_ports ARESETN] [get_bd_pins master_0/ARESETN] [get_bd_pins ddr3_test_monitor_axi_0/S00_AXI_ARESETN] 25 | set_property target_simulator XSim [current_project] 26 | set_property -name {xsim.simulate.runtime} -value {100ms} -objects [get_filesets sim_1] 27 | 28 | # Auto assign address 29 | assign_bd_address 30 | 31 | # Copy all address to interface_address.vh file 32 | set bd_path [file dirname [get_property NAME [get_files ${design_name}.bd]]] 33 | upvar 1 $offsetfile offset_file 34 | set offset_file "${bd_path}/ddr3_test_monitor_axi_v1_0_tb_include.svh" 35 | set fp [open $offset_file "w"] 36 | puts $fp "`ifndef ddr3_test_monitor_axi_v1_0_tb_include_vh_" 37 | puts $fp "`define ddr3_test_monitor_axi_v1_0_tb_include_vh_\n" 38 | puts $fp "//Configuration current bd names" 39 | puts $fp "`define BD_NAME ${design_name}" 40 | puts $fp "`define BD_INST_NAME ${design_name}_i" 41 | puts $fp "`define BD_WRAPPER ${design_name}_wrapper\n" 42 | puts $fp "//Configuration address parameters" 43 | 44 | puts $fp "`endif" 45 | close $fp 46 | } 47 | 48 | set ip_path [file dirname [file normalize [get_property XML_FILE_NAME [ipx::get_cores user.org:user:ddr3_test_monitor_axi:1.0]]]] 49 | set test_bench_file ${ip_path}/example_designs/bfm_design/ddr3_test_monitor_axi_v1_0_tb.sv 50 | set interface_address_vh_file "" 51 | 52 | # Set IP Repository and Update IP Catalogue 53 | set repo_paths [get_property ip_repo_paths [current_fileset]] 54 | if { [lsearch -exact -nocase $repo_paths $ip_path ] == -1 } { 55 | set_property ip_repo_paths "$ip_path [get_property ip_repo_paths [current_fileset]]" [current_fileset] 56 | update_ip_catalog 57 | } 58 | 59 | set design_name "" 60 | set all_bd {} 61 | set all_bd_files [get_files *.bd -quiet] 62 | foreach file $all_bd_files { 63 | set file_name [string range $file [expr {[string last "/" $file] + 1}] end] 64 | set bd_name [string range $file_name 0 [expr {[string last "." $file_name] -1}]] 65 | lappend all_bd $bd_name 66 | } 67 | 68 | for { set i 1 } { 1 } { incr i } { 69 | set design_name "ddr3_test_monitor_axi_v1_0_bfm_${i}" 70 | if { [lsearch -exact -nocase $all_bd $design_name ] == -1 } { 71 | break 72 | } 73 | } 74 | 75 | create_ipi_design interface_address_vh_file ${design_name} 76 | validate_bd_design 77 | 78 | set wrapper_file [make_wrapper -files [get_files ${design_name}.bd] -top -force] 79 | import_files -force -norecurse $wrapper_file 80 | 81 | set_property SOURCE_SET sources_1 [get_filesets sim_1] 82 | import_files -fileset sim_1 -norecurse -force $test_bench_file 83 | remove_files -quiet -fileset sim_1 ddr3_test_monitor_axi_v1_0_tb_include.vh 84 | import_files -fileset sim_1 -norecurse -force $interface_address_vh_file 85 | set_property top ddr3_test_monitor_axi_v1_0_tb [get_filesets sim_1] 86 | set_property top_lib {} [get_filesets sim_1] 87 | set_property top_file {} [get_filesets sim_1] 88 | launch_simulation -simset sim_1 -mode behavioral 89 | -------------------------------------------------------------------------------- /example_demo/enclustra_kx2_st1/ddr3_test_monitor_axi_1.0/example_designs/debug_hw_design/ddr3_test_monitor_axi_v1_0_hw_test.tcl: -------------------------------------------------------------------------------- 1 | # Runtime Tcl commands to interact with - ddr3_test_monitor_axi_v1_0 2 | 3 | # Sourcing design address info tcl 4 | set bd_path [get_property DIRECTORY [current_project]]/[current_project].srcs/[current_fileset]/bd 5 | source ${bd_path}/ddr3_test_monitor_axi_v1_0_include.tcl 6 | 7 | # jtag axi master interface hardware name, change as per your design. 8 | set jtag_axi_master hw_axi_1 9 | set ec 0 10 | 11 | # hw test script 12 | # Delete all previous axis transactions 13 | if { [llength [get_hw_axi_txns -quiet]] } { 14 | delete_hw_axi_txn [get_hw_axi_txns -quiet] 15 | } 16 | 17 | 18 | # Test all lite slaves. 19 | set wdata_1 abcd1234 20 | 21 | # Test: S00_AXI 22 | # Create a write transaction at s00_axi_addr address 23 | create_hw_axi_txn w_s00_axi_addr [get_hw_axis $jtag_axi_master] -type write -address $s00_axi_addr -data $wdata_1 24 | # Create a read transaction at s00_axi_addr address 25 | create_hw_axi_txn r_s00_axi_addr [get_hw_axis $jtag_axi_master] -type read -address $s00_axi_addr 26 | # Initiate transactions 27 | run_hw_axi r_s00_axi_addr 28 | run_hw_axi w_s00_axi_addr 29 | run_hw_axi r_s00_axi_addr 30 | set rdata_tmp [get_property DATA [get_hw_axi_txn r_s00_axi_addr]] 31 | # Compare read data 32 | if { $rdata_tmp == $wdata_1 } { 33 | puts "Data comparison test pass for - S00_AXI" 34 | } else { 35 | puts "Data comparison test fail for - S00_AXI, expected-$wdata_1 actual-$rdata_tmp" 36 | inc ec 37 | } 38 | 39 | # Check error flag 40 | if { $ec == 0 } { 41 | puts "PTGEN_TEST: PASSED!" 42 | } else { 43 | puts "PTGEN_TEST: FAILED!" 44 | } 45 | 46 | -------------------------------------------------------------------------------- /example_demo/enclustra_kx2_st1/ddr3_test_monitor_axi_1.0/hdl/ddr3_test_monitor_axi_v1_0.v: -------------------------------------------------------------------------------- 1 | 2 | `timescale 1 ns / 1 ps 3 | 4 | module ddr3_test_monitor_axi_v1_0 # 5 | ( 6 | // Users to add parameters here 7 | 8 | // User parameters ends 9 | // Do not modify the parameters beyond this line 10 | 11 | 12 | // Parameters of Axi Slave Bus Interface S00_AXI 13 | parameter integer C_S00_AXI_DATA_WIDTH = 32, 14 | parameter integer C_S00_AXI_ADDR_WIDTH = 7 15 | ) 16 | ( 17 | // Users to add ports here 18 | input wire[63:0] correct_read_data_counter, // address x0 = [31:0], x1 = [63:32] 19 | input wire[63:0] wrong_read_data_counter, // address x2 = [31:0], x3 = [63:32] 20 | input wire[63:0] time_counter, // address x4 = [31:0], x5 = [63:32] 21 | input wire[31:0] injected_faults_counter, 22 | // User ports ends 23 | // Do not modify the ports beyond this line 24 | 25 | 26 | // Ports of Axi Slave Bus Interface S00_AXI 27 | input wire s00_axi_aclk, 28 | input wire s00_axi_aresetn, 29 | input wire [C_S00_AXI_ADDR_WIDTH-1 : 0] s00_axi_awaddr, 30 | input wire [2 : 0] s00_axi_awprot, 31 | input wire s00_axi_awvalid, 32 | output wire s00_axi_awready, 33 | input wire [C_S00_AXI_DATA_WIDTH-1 : 0] s00_axi_wdata, 34 | input wire [(C_S00_AXI_DATA_WIDTH/8)-1 : 0] s00_axi_wstrb, 35 | input wire s00_axi_wvalid, 36 | output wire s00_axi_wready, 37 | output wire [1 : 0] s00_axi_bresp, 38 | output wire s00_axi_bvalid, 39 | input wire s00_axi_bready, 40 | input wire [C_S00_AXI_ADDR_WIDTH-1 : 0] s00_axi_araddr, 41 | input wire [2 : 0] s00_axi_arprot, 42 | input wire s00_axi_arvalid, 43 | output wire s00_axi_arready, 44 | output wire [C_S00_AXI_DATA_WIDTH-1 : 0] s00_axi_rdata, 45 | output wire [1 : 0] s00_axi_rresp, 46 | output wire s00_axi_rvalid, 47 | input wire s00_axi_rready 48 | ); 49 | // Instantiation of Axi Bus Interface S00_AXI 50 | ddr3_test_monitor_axi_v1_0_S00_AXI # ( 51 | .C_S_AXI_DATA_WIDTH(C_S00_AXI_DATA_WIDTH), 52 | .C_S_AXI_ADDR_WIDTH(C_S00_AXI_ADDR_WIDTH) 53 | ) ddr3_test_monitor_axi_v1_0_S00_AXI_inst ( 54 | .correct_read_data_counter(correct_read_data_counter), 55 | .wrong_read_data_counter(wrong_read_data_counter), 56 | .timer_counter(time_counter), 57 | .injected_faults_counter(injected_faults_counter), 58 | .S_AXI_ACLK(s00_axi_aclk), 59 | .S_AXI_ARESETN(s00_axi_aresetn), 60 | .S_AXI_AWADDR(s00_axi_awaddr), 61 | .S_AXI_AWPROT(s00_axi_awprot), 62 | .S_AXI_AWVALID(s00_axi_awvalid), 63 | .S_AXI_AWREADY(s00_axi_awready), 64 | .S_AXI_WDATA(s00_axi_wdata), 65 | .S_AXI_WSTRB(s00_axi_wstrb), 66 | .S_AXI_WVALID(s00_axi_wvalid), 67 | .S_AXI_WREADY(s00_axi_wready), 68 | .S_AXI_BRESP(s00_axi_bresp), 69 | .S_AXI_BVALID(s00_axi_bvalid), 70 | .S_AXI_BREADY(s00_axi_bready), 71 | .S_AXI_ARADDR(s00_axi_araddr), 72 | .S_AXI_ARPROT(s00_axi_arprot), 73 | .S_AXI_ARVALID(s00_axi_arvalid), 74 | .S_AXI_ARREADY(s00_axi_arready), 75 | .S_AXI_RDATA(s00_axi_rdata), 76 | .S_AXI_RRESP(s00_axi_rresp), 77 | .S_AXI_RVALID(s00_axi_rvalid), 78 | .S_AXI_RREADY(s00_axi_rready) 79 | ); 80 | 81 | // Add user logic here 82 | 83 | // User logic ends 84 | 85 | endmodule 86 | -------------------------------------------------------------------------------- /example_demo/enclustra_kx2_st1/ddr3_test_monitor_axi_1.0/xgui/ddr3_test_monitor_axi_v1_0.tcl: -------------------------------------------------------------------------------- 1 | # Definitional proc to organize widgets for parameters. 2 | proc init_gui { IPINST } { 3 | ipgui::add_param $IPINST -name "Component_Name" 4 | #Adding Page 5 | set Page_0 [ipgui::add_page $IPINST -name "Page 0"] 6 | ipgui::add_param $IPINST -name "C_S00_AXI_DATA_WIDTH" -parent ${Page_0} -widget comboBox 7 | ipgui::add_param $IPINST -name "C_S00_AXI_ADDR_WIDTH" -parent ${Page_0} 8 | ipgui::add_param $IPINST -name "C_S00_AXI_BASEADDR" -parent ${Page_0} 9 | ipgui::add_param $IPINST -name "C_S00_AXI_HIGHADDR" -parent ${Page_0} 10 | 11 | 12 | } 13 | 14 | proc update_PARAM_VALUE.C_S00_AXI_DATA_WIDTH { PARAM_VALUE.C_S00_AXI_DATA_WIDTH } { 15 | # Procedure called to update C_S00_AXI_DATA_WIDTH when any of the dependent parameters in the arguments change 16 | } 17 | 18 | proc validate_PARAM_VALUE.C_S00_AXI_DATA_WIDTH { PARAM_VALUE.C_S00_AXI_DATA_WIDTH } { 19 | # Procedure called to validate C_S00_AXI_DATA_WIDTH 20 | return true 21 | } 22 | 23 | proc update_PARAM_VALUE.C_S00_AXI_ADDR_WIDTH { PARAM_VALUE.C_S00_AXI_ADDR_WIDTH } { 24 | # Procedure called to update C_S00_AXI_ADDR_WIDTH when any of the dependent parameters in the arguments change 25 | } 26 | 27 | proc validate_PARAM_VALUE.C_S00_AXI_ADDR_WIDTH { PARAM_VALUE.C_S00_AXI_ADDR_WIDTH } { 28 | # Procedure called to validate C_S00_AXI_ADDR_WIDTH 29 | return true 30 | } 31 | 32 | proc update_PARAM_VALUE.C_S00_AXI_BASEADDR { PARAM_VALUE.C_S00_AXI_BASEADDR } { 33 | # Procedure called to update C_S00_AXI_BASEADDR when any of the dependent parameters in the arguments change 34 | } 35 | 36 | proc validate_PARAM_VALUE.C_S00_AXI_BASEADDR { PARAM_VALUE.C_S00_AXI_BASEADDR } { 37 | # Procedure called to validate C_S00_AXI_BASEADDR 38 | return true 39 | } 40 | 41 | proc update_PARAM_VALUE.C_S00_AXI_HIGHADDR { PARAM_VALUE.C_S00_AXI_HIGHADDR } { 42 | # Procedure called to update C_S00_AXI_HIGHADDR when any of the dependent parameters in the arguments change 43 | } 44 | 45 | proc validate_PARAM_VALUE.C_S00_AXI_HIGHADDR { PARAM_VALUE.C_S00_AXI_HIGHADDR } { 46 | # Procedure called to validate C_S00_AXI_HIGHADDR 47 | return true 48 | } 49 | 50 | 51 | proc update_MODELPARAM_VALUE.C_S00_AXI_DATA_WIDTH { MODELPARAM_VALUE.C_S00_AXI_DATA_WIDTH PARAM_VALUE.C_S00_AXI_DATA_WIDTH } { 52 | # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value 53 | set_property value [get_property value ${PARAM_VALUE.C_S00_AXI_DATA_WIDTH}] ${MODELPARAM_VALUE.C_S00_AXI_DATA_WIDTH} 54 | } 55 | 56 | proc update_MODELPARAM_VALUE.C_S00_AXI_ADDR_WIDTH { MODELPARAM_VALUE.C_S00_AXI_ADDR_WIDTH PARAM_VALUE.C_S00_AXI_ADDR_WIDTH } { 57 | # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value 58 | set_property value [get_property value ${PARAM_VALUE.C_S00_AXI_ADDR_WIDTH}] ${MODELPARAM_VALUE.C_S00_AXI_ADDR_WIDTH} 59 | } 60 | 61 | -------------------------------------------------------------------------------- /example_demo/enclustra_kx2_st1/ddr3_test_top_tb.v: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Filename: ddr3_test_top.v 4 | // Project: Testbench for ddr3_test_top.v 5 | // 6 | // Engineer: Angelo C. Jacobo 7 | // 8 | //////////////////////////////////////////////////////////////////////////////// 9 | // 10 | // Copyright (C) 2023-2025 Angelo Jacobo 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //////////////////////////////////////////////////////////////////////////////// 26 | 27 | `timescale 1ps / 1ps 28 | 29 | module ddr3_test_top_tb; 30 | // PHY Interface to DDR3 Device 31 | wire[1:0] ddr3_cke; // CKE 32 | wire[1:0] ddr3_cs_n; // chip select signal 33 | wire[1:0] ddr3_odt; // on-die termination 34 | wire ddr3_ras_n; // RAS# 35 | wire ddr3_cas_n; // CAS# 36 | wire ddr3_we_n; // WE# 37 | wire ddr3_reset_n; 38 | wire[$bits(DUT.ddr3_addr)-1:0] ddr3_addr; 39 | wire[$bits(DUT.ddr3_ba)-1:0] ddr3_ba; 40 | wire[$bits(DUT.ddr3_dm)-1:0] ddr3_dm; 41 | wire[$bits(DUT.ddr3_dq)-1:0] ddr3_dq; 42 | wire[$bits(DUT.ddr3_dqs_p)-1:0] ddr3_dqs_p; 43 | wire[$bits(DUT.ddr3_dqs_n)-1:0] ddr3_dqs_n; 44 | wire[1:0] ddr3_clk_p, ddr3_clk_n; 45 | // clocks and reset 46 | reg i_clk200_p; 47 | reg i_rst_n; 48 | initial begin 49 | i_clk200_p = 0; 50 | i_rst_n = 0; 51 | #1000; 52 | i_rst_n = 1; 53 | end 54 | always #2_500 i_clk200_p = !i_clk200_p; // 200MHz 55 | 56 | 57 | enclustra_ddr3_test #( 58 | .MICRON_SIM(1), 59 | .ODELAY_SUPPORTED(1), 60 | .DATA_MASK(1) 61 | ) 62 | DUT ( 63 | .i_clk200_p(i_clk200_p), 64 | .i_clk200_n(!i_clk200_p), 65 | .i_rst_n(i_rst_n), 66 | // DDR3 I/O Interface 67 | .ddr3_clk_p(ddr3_clk_p), 68 | .ddr3_clk_n(ddr3_clk_n), 69 | .ddr3_reset_n(ddr3_reset_n), 70 | .ddr3_cke(ddr3_cke), 71 | .ddr3_cs_n(ddr3_cs_n), 72 | .ddr3_ras_n(ddr3_ras_n), 73 | .ddr3_cas_n(ddr3_cas_n), 74 | .ddr3_we_n(ddr3_we_n), 75 | .ddr3_addr(ddr3_addr), 76 | .ddr3_ba(ddr3_ba), 77 | .ddr3_dq(ddr3_dq), 78 | .ddr3_dqs_p(ddr3_dqs_p), 79 | .ddr3_dqs_n(ddr3_dqs_n), 80 | .ddr3_dm(ddr3_dm), 81 | .ddr3_odt(ddr3_odt), 82 | // UART line 83 | .rx(0), 84 | .tx(), 85 | // Debug LEDs 86 | .led() 87 | ); 88 | 89 | // DDR3 Device 90 | ddr3_module ddr3_module( 91 | .reset_n(ddr3_reset_n), 92 | .ck(ddr3_clk_p), //[1:0] 93 | .ck_n(ddr3_clk_n), //[1:0] 94 | .cke(ddr3_cke), //[1:0] 95 | .s_n(ddr3_cs_n), //[1:0] 96 | .ras_n(ddr3_ras_n), 97 | .cas_n(ddr3_cas_n), 98 | .we_n(ddr3_we_n), 99 | .ba(ddr3_ba), 100 | .addr({0,ddr3_addr}), 101 | .odt(ddr3_odt), //[1:0] 102 | .dqs({ddr3_dm[0], ddr3_dm,ddr3_dm[0],ddr3_dqs_p}), //ddr3_module uses last 8 MSB [16:9] as datamask 103 | .dqs_n(ddr3_dqs_n), 104 | .dq(ddr3_dq) 105 | ); 106 | assign ddr3_cke[1]=0, 107 | ddr3_cs_n[1]=1, 108 | ddr3_odt[1]=0, 109 | ddr3_clk_p[1]=0, 110 | ddr3_clk_n[1]=0; 111 | 112 | endmodule 113 | 114 | -------------------------------------------------------------------------------- /example_demo/enclustra_kx2_st1/enclustra_ddr3_openxc7.bit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AngeloJacobo/UberDDR3/a3efc861dafeec665d0885d6bc2e0c380260fe6b/example_demo/enclustra_kx2_st1/enclustra_ddr3_openxc7.bit -------------------------------------------------------------------------------- /example_demo/enclustra_kx2_st1/uart_tx.v: -------------------------------------------------------------------------------- 1 | 2 | 3 | // 4 | // Module: uart_tx 5 | // 6 | // Notes: 7 | // - UART transmitter module. 8 | // 9 | 10 | module uart_tx( 11 | input wire clk , // Top level system clock input. 12 | input wire resetn , // Asynchronous active low reset. 13 | output wire uart_txd , // UART transmit pin. 14 | output wire uart_tx_busy, // Module busy sending previous item. 15 | input wire uart_tx_en , // Send the data on uart_tx_data 16 | input wire [PAYLOAD_BITS-1:0] uart_tx_data // The data to be sent 17 | ); 18 | 19 | // --------------------------------------------------------------------------- 20 | // External parameters. 21 | // 22 | 23 | // 24 | // Input bit rate of the UART line. 25 | parameter BIT_RATE = 9600; // bits / sec 26 | localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds 27 | 28 | // 29 | // Clock frequency in hertz. 30 | parameter CLK_HZ = 50_000_000; 31 | localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds 32 | 33 | // 34 | // Number of data bits recieved per UART packet. 35 | parameter PAYLOAD_BITS = 8; 36 | 37 | // 38 | // Number of stop bits indicating the end of a packet. 39 | parameter STOP_BITS = 1; 40 | 41 | // --------------------------------------------------------------------------- 42 | // Internal parameters. 43 | // 44 | 45 | // 46 | // Number of clock cycles per uart bit. 47 | localparam CYCLES_PER_BIT = BIT_P / CLK_P; 48 | 49 | // 50 | // Size of the registers which store sample counts and bit durations. 51 | localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT); 52 | 53 | // --------------------------------------------------------------------------- 54 | // Internal registers. 55 | // 56 | 57 | // 58 | // Internally latched value of the uart_txd line. Helps break long timing 59 | // paths from the logic to the output pins. 60 | reg txd_reg; 61 | 62 | // 63 | // Storage for the serial data to be sent. 64 | reg [PAYLOAD_BITS-1:0] data_to_send; 65 | 66 | // 67 | // Counter for the number of cycles over a packet bit. 68 | reg [COUNT_REG_LEN-1:0] cycle_counter; 69 | 70 | // 71 | // Counter for the number of sent bits of the packet. 72 | reg [3:0] bit_counter; 73 | 74 | // 75 | // Current and next states of the internal FSM. 76 | reg [2:0] fsm_state; 77 | reg [2:0] n_fsm_state; 78 | 79 | localparam FSM_IDLE = 0; 80 | localparam FSM_START= 1; 81 | localparam FSM_SEND = 2; 82 | localparam FSM_STOP = 3; 83 | 84 | 85 | // --------------------------------------------------------------------------- 86 | // FSM next state selection. 87 | // 88 | 89 | assign uart_tx_busy = fsm_state != FSM_IDLE; 90 | assign uart_txd = txd_reg; 91 | 92 | wire next_bit = cycle_counter == CYCLES_PER_BIT; 93 | wire payload_done = bit_counter == PAYLOAD_BITS ; 94 | wire stop_done = bit_counter == STOP_BITS && fsm_state == FSM_STOP; 95 | 96 | // 97 | // Handle picking the next state. 98 | always @(*) begin : p_n_fsm_state 99 | case(fsm_state) 100 | FSM_IDLE : n_fsm_state = uart_tx_en ? FSM_START: FSM_IDLE ; 101 | FSM_START: n_fsm_state = next_bit ? FSM_SEND : FSM_START; 102 | FSM_SEND : n_fsm_state = payload_done ? FSM_STOP : FSM_SEND ; 103 | FSM_STOP : n_fsm_state = stop_done ? FSM_IDLE : FSM_STOP ; 104 | default : n_fsm_state = FSM_IDLE; 105 | endcase 106 | end 107 | 108 | // --------------------------------------------------------------------------- 109 | // Internal register setting and re-setting. 110 | // 111 | 112 | // 113 | // Handle updates to the sent data register. 114 | integer i = 0; 115 | always @(posedge clk) begin : p_data_to_send 116 | if(!resetn) begin 117 | data_to_send <= {PAYLOAD_BITS{1'b0}}; 118 | end else if(fsm_state == FSM_IDLE && uart_tx_en) begin 119 | data_to_send <= uart_tx_data; 120 | end else if(fsm_state == FSM_SEND && next_bit ) begin 121 | for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin 122 | data_to_send[i] <= data_to_send[i+1]; 123 | end 124 | end 125 | end 126 | 127 | 128 | // 129 | // Increments the bit counter each time a new bit frame is sent. 130 | always @(posedge clk) begin : p_bit_counter 131 | if(!resetn) begin 132 | bit_counter <= 4'b0; 133 | end else if(fsm_state != FSM_SEND && fsm_state != FSM_STOP) begin 134 | bit_counter <= {COUNT_REG_LEN{1'b0}}; 135 | end else if(fsm_state == FSM_SEND && n_fsm_state == FSM_STOP) begin 136 | bit_counter <= {COUNT_REG_LEN{1'b0}}; 137 | end else if(fsm_state == FSM_STOP&& next_bit) begin 138 | bit_counter <= bit_counter + 1'b1; 139 | end else if(fsm_state == FSM_SEND && next_bit) begin 140 | bit_counter <= bit_counter + 1'b1; 141 | end 142 | end 143 | 144 | 145 | // 146 | // Increments the cycle counter when sending. 147 | always @(posedge clk) begin : p_cycle_counter 148 | if(!resetn) begin 149 | cycle_counter <= {COUNT_REG_LEN{1'b0}}; 150 | end else if(next_bit) begin 151 | cycle_counter <= {COUNT_REG_LEN{1'b0}}; 152 | end else if(fsm_state == FSM_START || 153 | fsm_state == FSM_SEND || 154 | fsm_state == FSM_STOP ) begin 155 | cycle_counter <= cycle_counter + 1'b1; 156 | end 157 | end 158 | 159 | 160 | // 161 | // Progresses the next FSM state. 162 | always @(posedge clk) begin : p_fsm_state 163 | if(!resetn) begin 164 | fsm_state <= FSM_IDLE; 165 | end else begin 166 | fsm_state <= n_fsm_state; 167 | end 168 | end 169 | 170 | 171 | // 172 | // Responsible for updating the internal value of the txd_reg. 173 | always @(posedge clk) begin : p_txd_reg 174 | if(!resetn) begin 175 | txd_reg <= 1'b1; 176 | end else if(fsm_state == FSM_IDLE) begin 177 | txd_reg <= 1'b1; 178 | end else if(fsm_state == FSM_START) begin 179 | txd_reg <= 1'b0; 180 | end else if(fsm_state == FSM_SEND) begin 181 | txd_reg <= data_to_send[0]; 182 | end else if(fsm_state == FSM_STOP) begin 183 | txd_reg <= 1'b1; 184 | end 185 | end 186 | 187 | endmodule 188 | -------------------------------------------------------------------------------- /example_demo/klusterlab/ddr3scope.txt: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ## 3 | ## Filename: sdscope.txt 4 | ## {{{ 5 | ## Project: 10Gb Ethernet switch 6 | ## 7 | ## Purpose: Describes how to connect the SMI controller's debugging port to 8 | ## a wishbone scope, then to be connected to the bus by autofpga. 9 | ## 10 | ## Creator: Dan Gisselquist, Ph.D. 11 | ## Gisselquist Technology, LLC 12 | ## 13 | ################################################################################ 14 | ## }}} 15 | ## Copyright (C) 2023, Gisselquist Technology, LLC 16 | ## {{{ 17 | ## This file is part of the ETH10G project. 18 | ## 19 | ## The ETH10G project contains free software and gateware, licensed under the 20 | ## Apache License, Version 2.0 (the "License"). You may not use this project, 21 | ## or this file, except in compliance with the License. You may obtain a copy 22 | ## of the License at 23 | ## }}} 24 | ## http://www.apache.org/licenses/LICENSE-2.0 25 | ## {{{ 26 | ## Unless required by applicable law or agreed to in writing, files 27 | ## distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 28 | ## WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 29 | ## License for the specific language governing permissions and limitations 30 | ## under the License. 31 | ## 32 | ################################################################################ 33 | ## 34 | ## }}} 35 | @PREFIX=scope1_ddr3 36 | @DEVID=DDR3SCOPE1 37 | @TARGET=ddr3_controller 38 | @TRIGGER=ddr3_controller_debug1[31] 39 | @DEBUG=@$(TARGET)_debug1[30:0] 40 | @$LOG_CAPTURE_SIZE=10 41 | @INCLUDEFILE=wbscopc.txt 42 | @INT.DDR3SCOPE1.PIC=altpic 43 | @INT.DDR3SCOPE1.WIRE=@$(PREFIX)_int 44 | @MAIN.DEFNS= 45 | # 46 | # 47 | @PREFIX=scope2_ddr3 48 | @DEVID=DDR3SCOPE2 49 | @TARGET=ddr3_controller 50 | @TRIGGER=ddr3_controller_debug2[31] 51 | @DEBUG=@$(TARGET)_debug2[30:0] 52 | @$LOG_CAPTURE_SIZE=10 53 | @INCLUDEFILE=wbscopc.txt 54 | @INT.DDR3SCOPE2.PIC=altpic 55 | @INT.DDR3SCOPE2.WIRE=@$(PREFIX)_int 56 | @MAIN.DEFNS= 57 | # 58 | # 59 | @PREFIX=scope3_ddr3 60 | @DEVID=DDR3SCOPE3 61 | @TARGET=ddr3_controller 62 | @TRIGGER=ddr3_controller_debug3[31] 63 | @DEBUG=@$(TARGET)_debug3[30:0] 64 | @$LOG_CAPTURE_SIZE=10 65 | @INCLUDEFILE=wbscopc.txt 66 | @INT.DDR3SCOPE2.PIC=altpic 67 | @INT.DDR3SCOPE2.WIRE=@$(PREFIX)_int 68 | @MAIN.DEFNS= 69 | -------------------------------------------------------------------------------- /example_demo/klusterlab/ddr3scope1.cpp: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Filename: ddr3scope.cpp 4 | // {{{ 5 | // Project: 10Gb Ethernet switch 6 | // 7 | // Purpose: This file decodes the debug bits produced by the SMI IP and 8 | // stored in a (compressed) WB scope. It is useful for determining 9 | // if the SMI IP is working, or even if/how the RPi is toggling the 10 | // associated SMI bits. 11 | // 12 | // Creator: Dan Gisselquist, Ph.D. 13 | // Gisselquist Technology, LLC 14 | // 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // }}} 17 | // Copyright (C) 2023, Gisselquist Technology, LLC 18 | // {{{ 19 | // This file is part of the ETH10G project. 20 | // 21 | // The ETH10G project contains free software and gateware, licensed under the 22 | // Apache License, Version 2.0 (the "License"). You may not use this project, 23 | // or this file, except in compliance with the License. You may obtain a copy 24 | // of the License at 25 | // }}} 26 | // http://www.apache.org/licenses/LICENSE-2.0 27 | // {{{ 28 | // Unless required by applicable law or agreed to in writing, files 29 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 30 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 31 | // License for the specific language governing permissions and limitations 32 | // under the License. 33 | // 34 | //////////////////////////////////////////////////////////////////////////////// 35 | // 36 | // }}} 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | #include "regdefs.h" 47 | #include "devbus.h" 48 | #include "scopecls.h" 49 | 50 | #ifndef R_DDR3SCOPE1 51 | int main(int argc, char **argv) { 52 | printf("This design was not built with a NET scope within it.\n"); 53 | } 54 | #else 55 | 56 | #define WBSCOPE R_DDR3SCOPE1 57 | #define WBSCOPEDATA R_DDR3SCOPE1D 58 | 59 | DEVBUS *m_fpga; 60 | void closeup(int v) { 61 | m_fpga->kill(); 62 | exit(0); 63 | } 64 | 65 | class DDR3SCOPE1 : public SCOPE { 66 | public: 67 | DDR3SCOPE1(DEVBUS *fpga, unsigned addr, bool vecread = true) 68 | : SCOPE(fpga, addr, true, vecread) {}; 69 | ~DDR3SCOPE1(void) {} 70 | 71 | virtual void decode(DEVBUS::BUSW val) const { 72 | int trigger; 73 | 74 | trigger = (val>>31)&1; 75 | 76 | printf("%6s", (trigger) ? "TRIGGERED at state_calibrate == MPR_READ! ":""); 77 | } 78 | 79 | virtual void define_traces(void) { 80 | /* 81 | assign o_debug1 = {debug_trigger, 2'b00, delay_before_read_data[3:0] ,i_phy_idelayctrl_rdy, lane[2:0], dqs_start_index_stored[4:0], 82 | dqs_target_index[4:0], instruction_address[4:0], state_calibrate[4:0], o_wb2_stall}; 83 | 84 | register_trace("delay_before_read_data",4,25); 85 | register_trace("i_phy_idelayctrl_rdy",1,24); 86 | register_trace("lane",3,21); 87 | register_trace("dqs_start_index_stored",5,16); 88 | register_trace("dqs_target_index",5,11); 89 | register_trace("instruction_address",5,6); 90 | register_trace("state_calibrate",5,1); 91 | register_trace("o_wb2_stall",1,0); 92 | */ 93 | /* 94 | assign o_debug1 = {debug_trigger,stage1_we,stage1_col[5:0],stage1_data[7:0],stage1_dm[15:0]}; 95 | 96 | register_trace("stage1_we",1,30); 97 | register_trace("stage1_col",6,24); 98 | register_trace("stage1_data",8,16); 99 | register_trace("stage1_dm",16,0); 100 | */ 101 | /* 102 | assign o_debug1 = {debug_trigger,i_phy_iserdes_dqs[7:0],state_calibrate[4:0], instruction_address[4:0],o_phy_idelay_dqs_ld,o_phy_idelay_data_ld,o_phy_odelay_data_ld,o_phy_odelay_dqs_ld, 103 | delay_before_read_data[2:0],delay_before_write_level_feedback[4:0],lane}; 104 | assign o_debug1 = {debug_trigger,i_phy_iserdes_dqs[7:0],state_calibrate[4:0], instruction_address[4:0],reset_from_wb2, 105 | repeat_test, delay_before_read_data[2:0], delay_before_write_level_feedback[4:0],lane[2:0]}; 106 | */ 107 | register_trace("i_phy_iserdes_dqs",8,23); 108 | register_trace("state_calibrate",5,18); 109 | register_trace("instruction_address",5,13); 110 | register_trace("reset_from_wb2",1,12); 111 | register_trace("repeat_test",1,11); 112 | register_trace("delay_before_read_data",3,8); 113 | register_trace("delay_before_write_level_feedback",5,3); 114 | register_trace("lane",3,0); 115 | } 116 | }; 117 | 118 | int main(int argc, char **argv) { 119 | m_fpga = connect_devbus(NULL); 120 | 121 | signal(SIGSTOP, closeup); 122 | signal(SIGHUP, closeup); 123 | 124 | DDR3SCOPE1 *scope = new DDR3SCOPE1(m_fpga, WBSCOPE); 125 | // scope->set_clkfreq_hz(ENETCLKFREQHZ); 126 | scope->set_clkfreq_hz(100000000); 127 | if (!scope->ready()) { 128 | printf("Scope is not yet ready:\n"); 129 | scope->decode_control(); 130 | } else { 131 | scope->print(); 132 | scope->writevcd("ddr3scope1.vcd"); 133 | } 134 | } 135 | 136 | #endif 137 | -------------------------------------------------------------------------------- /example_demo/klusterlab/ddr3scope2.cpp: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Filename: ddr3scope.cpp 4 | // {{{ 5 | // Project: 10Gb Ethernet switch 6 | // 7 | // Purpose: This file decodes the debug bits produced by the SMI IP and 8 | // stored in a (compressed) WB scope. It is useful for determining 9 | // if the SMI IP is working, or even if/how the RPi is toggling the 10 | // associated SMI bits. 11 | // 12 | // Creator: Dan Gisselquist, Ph.D. 13 | // Gisselquist Technology, LLC 14 | // 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // }}} 17 | // Copyright (C) 2023, Gisselquist Technology, LLC 18 | // {{{ 19 | // This file is part of the ETH10G project. 20 | // 21 | // The ETH10G project contains free software and gateware, licensed under the 22 | // Apache License, Version 2.0 (the "License"). You may not use this project, 23 | // or this file, except in compliance with the License. You may obtain a copy 24 | // of the License at 25 | // }}} 26 | // http://www.apache.org/licenses/LICENSE-2.0 27 | // {{{ 28 | // Unless required by applicable law or agreed to in writing, files 29 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 30 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 31 | // License for the specific language governing permissions and limitations 32 | // under the License. 33 | // 34 | //////////////////////////////////////////////////////////////////////////////// 35 | // 36 | // }}} 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | #include "regdefs.h" 47 | #include "devbus.h" 48 | #include "scopecls.h" 49 | 50 | #ifndef R_DDR3SCOPE2 51 | int main(int argc, char **argv) { 52 | printf("This design was not built with a NET scope within it.\n"); 53 | } 54 | #else 55 | 56 | #define WBSCOPE R_DDR3SCOPE2 57 | #define WBSCOPEDATA R_DDR3SCOPE2D 58 | 59 | DEVBUS *m_fpga; 60 | void closeup(int v) { 61 | m_fpga->kill(); 62 | exit(0); 63 | } 64 | 65 | class DDR3SCOPE2 : public SCOPE { 66 | public: 67 | DDR3SCOPE2(DEVBUS *fpga, unsigned addr, bool vecread = true) 68 | : SCOPE(fpga, addr, true, vecread) {}; 69 | ~DDR3SCOPE2(void) {} 70 | 71 | virtual void decode(DEVBUS::BUSW val) const { 72 | int trigger; 73 | 74 | trigger = (val>>31)&1; 75 | 76 | printf("%6s", (trigger) ? "TRIGGERED at state_calibrate == MPR_READ! ":""); 77 | } 78 | 79 | virtual void define_traces(void) { 80 | /* 81 | assign o_debug2 = {debug_trigger, idelay_dqs_cntvaluein[lane][4:0], idelay_data_cntvaluein[lane][4:0], i_phy_iserdes_dqs[15:0], 82 | o_phy_dqs_tri_control, o_phy_dq_tri_control, 83 | (i_phy_iserdes_data == 0), (i_phy_iserdes_data == {(DQ_BITS*LANES*8){1'b1}}), (i_phy_iserdes_data < { {(DQ_BITS*LANES*4){1'b0}}, {(DQ_BITS*LANES*4){1'b1}} } ) 84 | }; 85 | 86 | 87 | register_trace("idelay_dqs_cntvaluein",5,26); 88 | register_trace("idelay_data_cntvaluein",5,21); 89 | register_trace("i_phy_iserdes_dqs_lane1",8,13); 90 | register_trace("i_phy_iserdes_dqs_lane0",8,5); 91 | register_trace("o_phy_dqs_tri_control",1,4); 92 | register_trace("o_phy_dq_tri_control",1,3); 93 | register_trace("i_phy_iserdes_data_is_zero",1,2); 94 | register_trace("i_phy_iserdes_data_all_1s",1,1); 95 | register_trace("i_phy_iserdes_data_less_than_half",1,0); 96 | */ 97 | /* 98 | assign o_debug2 = {debug_trigger,i_phy_iserdes_data[62:32]}; 99 | */ 100 | register_trace("i_phy_iserdes_data_62_32",31,0); 101 | } 102 | }; 103 | 104 | int main(int argc, char **argv) { 105 | m_fpga = connect_devbus(NULL); 106 | 107 | signal(SIGSTOP, closeup); 108 | signal(SIGHUP, closeup); 109 | 110 | DDR3SCOPE2 *scope = new DDR3SCOPE2(m_fpga, WBSCOPE); 111 | // scope->set_clkfreq_hz(ENETCLKFREQHZ); 112 | scope->set_clkfreq_hz(100000000); 113 | if (!scope->ready()) { 114 | printf("Scope is not yet ready:\n"); 115 | scope->decode_control(); 116 | } else { 117 | scope->print(); 118 | scope->writevcd("ddr3scope2.vcd"); 119 | } 120 | } 121 | 122 | #endif 123 | -------------------------------------------------------------------------------- /example_demo/klusterlab/ddr3scope3.cpp: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Filename: ddr3scope.cpp 4 | // {{{ 5 | // Project: 10Gb Ethernet switch 6 | // 7 | // Purpose: This file decodes the debug bits produced by the SMI IP and 8 | // stored in a (compressed) WB scope. It is useful for determining 9 | // if the SMI IP is working, or even if/how the RPi is toggling the 10 | // associated SMI bits. 11 | // 12 | // Creator: Dan Gisselquist, Ph.D. 13 | // Gisselquist Technology, LLC 14 | // 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // }}} 17 | // Copyright (C) 2023, Gisselquist Technology, LLC 18 | // {{{ 19 | // This file is part of the ETH10G project. 20 | // 21 | // The ETH10G project contains free software and gateware, licensed under the 22 | // Apache License, Version 2.0 (the "License"). You may not use this project, 23 | // or this file, except in compliance with the License. You may obtain a copy 24 | // of the License at 25 | // }}} 26 | // http://www.apache.org/licenses/LICENSE-2.0 27 | // {{{ 28 | // Unless required by applicable law or agreed to in writing, files 29 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 30 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 31 | // License for the specific language governing permissions and limitations 32 | // under the License. 33 | // 34 | //////////////////////////////////////////////////////////////////////////////// 35 | // 36 | // }}} 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | #include "regdefs.h" 47 | #include "devbus.h" 48 | #include "scopecls.h" 49 | 50 | #ifndef R_DDR3SCOPE3 51 | int main(int argc, char **argv) { 52 | printf("This design was not built with a NET scope within it.\n"); 53 | } 54 | #else 55 | 56 | #define WBSCOPE R_DDR3SCOPE3 57 | #define WBSCOPEDATA R_DDR3SCOPE3D 58 | 59 | DEVBUS *m_fpga; 60 | void closeup(int v) { 61 | m_fpga->kill(); 62 | exit(0); 63 | } 64 | 65 | class DDR3SCOPE3 : public SCOPE { 66 | public: 67 | DDR3SCOPE3(DEVBUS *fpga, unsigned addr, bool vecread = true) 68 | : SCOPE(fpga, addr, true, vecread) {}; 69 | ~DDR3SCOPE3(void) {} 70 | 71 | virtual void decode(DEVBUS::BUSW val) const { 72 | int trigger; 73 | 74 | trigger = (val>>31)&1; 75 | 76 | printf("%6s", (trigger) ? "TRIGGERED at state_calibrate == MPR_READ! ":""); 77 | } 78 | 79 | virtual void define_traces(void) { 80 | /* 81 | assign o_debug3 = {debug_trigger, delay_before_write_level_feedback[4:0], odelay_data_cntvaluein[lane][4:0], odelay_dqs_cntvaluein[lane][4:0], 82 | state_calibrate[4:0], prev_write_level_feedback, i_phy_iserdes_data[48], i_phy_iserdes_data[40], i_phy_iserdes_data[32], i_phy_iserdes_data[24] 83 | , i_phy_iserdes_data[16], i_phy_iserdes_data[8], i_phy_iserdes_data[0], lane[2:0] }; 84 | 85 | 86 | register_trace("delay_before_write_level_feedback",5,26); 87 | register_trace("odelay_data_cntvaluein",5,21); 88 | register_trace("odelay_dqs_cntvaluein",5,16); 89 | register_trace("state_calibrate",5,11); 90 | register_trace("prev_write_level_feedback",1,10); 91 | 92 | register_trace("i_phy_iserdes_data_lane6",1,9); 93 | register_trace("i_phy_iserdes_data_lane5",1,8); 94 | register_trace("i_phy_iserdes_data_lane4",1,7); 95 | register_trace("i_phy_iserdes_data_lane3",1,6); 96 | register_trace("i_phy_iserdes_data_lane2",1,5); 97 | register_trace("i_phy_iserdes_data_lane1",1,4); 98 | register_trace("i_phy_iserdes_data_lane0",1,3); 99 | register_trace("lane",3,0); 100 | */ 101 | /* 102 | assign o_debug3 = {debug_trigger, lane[2:0], delay_before_read_data[3:0], i_phy_iserdes_data[448 +: 3], i_phy_iserdes_data[384 +: 3], i_phy_iserdes_data[320 +: 3], 103 | i_phy_iserdes_data[256 +: 3], i_phy_iserdes_data[192 +: 3], i_phy_iserdes_data[128 +: 3], i_phy_iserdes_data[64 +: 3], i_phy_iserdes_data[0 +: 3]}; 104 | 105 | register_trace("lane",3,28); 106 | register_trace("delay_before_read_data",4,24); 107 | register_trace("i_phy_iserdes_data_burst7",3,21); 108 | register_trace("i_phy_iserdes_data_burst6",3,18); 109 | register_trace("i_phy_iserdes_data_burst5",3,15); 110 | register_trace("i_phy_iserdes_data_burst4",3,12); 111 | register_trace("i_phy_iserdes_data_burst3",3,9); 112 | register_trace("i_phy_iserdes_data_burst2",3,6); 113 | register_trace("i_phy_iserdes_data_burst1",3,3); 114 | register_trace("i_phy_iserdes_data_burst0",3,0); 115 | */ 116 | /* 117 | assign o_debug3 = {debug_trigger, i_phy_iserdes_data[128 +: 7], i_phy_iserdes_data[128 +: 8], i_phy_iserdes_data[64 +: 8], i_phy_iserdes_data[0 +: 8]}; 118 | 119 | 120 | register_trace("i_phy_iserdes_data_burst3",7,24); 121 | register_trace("i_phy_iserdes_data_burst2",8,16); 122 | register_trace("i_phy_iserdes_data_burst1",8,8); 123 | register_trace("i_phy_iserdes_data_burst0",8,0); 124 | */ 125 | /* 126 | assign o_debug3 = {debug_trigger,i_phy_iserdes_data[30:0]}; 127 | */ 128 | register_trace("i_phy_iserdes_data_30_0",31,0); 129 | } 130 | }; 131 | 132 | int main(int argc, char **argv) { 133 | m_fpga = connect_devbus(NULL); 134 | 135 | signal(SIGSTOP, closeup); 136 | signal(SIGHUP, closeup); 137 | 138 | DDR3SCOPE3 *scope = new DDR3SCOPE3(m_fpga, WBSCOPE); 139 | // scope->set_clkfreq_hz(ENETCLKFREQHZ); 140 | scope->set_clkfreq_hz(100000000); 141 | if (!scope->ready()) { 142 | printf("Scope is not yet ready:\n"); 143 | scope->decode_control(); 144 | } else { 145 | scope->print(); 146 | scope->writevcd("ddr3scope3.vcd"); 147 | } 148 | } 149 | 150 | #endif 151 | -------------------------------------------------------------------------------- /example_demo/nexys_video/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT = nexysvideo_ddr3 2 | FAMILY = artix7 3 | PART = xc7a200tsbg484-1 4 | CHIPDB = ${ARTIX7_CHIPDB} 5 | ADDITIONAL_SOURCES = ../../rtl/ddr3_controller.v ../../rtl/ddr3_phy.v ../../rtl/ddr3_top.v uart_rx.v uart_tx.v clk_wiz.v 6 | 7 | 8 | ############################################################################################# 9 | NEXTPNR_XILINX_DIR ?= /snap/openxc7/current/opt/nextpnr-xilinx 10 | NEXTPNR_XILINX_PYTHON_DIR ?= ${NEXTPNR_XILINX_DIR}/python 11 | PRJXRAY_DB_DIR ?= ${NEXTPNR_XILINX_DIR}/external/prjxray-db 12 | 13 | DBPART = $(shell echo ${PART} | sed -e 's/-[0-9]//g') 14 | SPEEDGRADE = $(shell echo ${PART} | sed -e 's/.*\-\([0-9]\)/\1/g') 15 | 16 | CHIPDB ?= ./ 17 | ifeq ($(CHIPDB),) 18 | CHIPDB = ./ 19 | endif 20 | 21 | PYPY3 ?= pypy3 22 | 23 | TOP ?= ${PROJECT} 24 | TOP_MODULE ?= ${TOP} 25 | TOP_VERILOG ?= ${TOP}.v 26 | 27 | PNR_DEBUG ?= # --verbose --debug 28 | 29 | JTAG_LINK ?= -c digilent_hs2 30 | 31 | XDC ?= ${PROJECT}.xdc 32 | 33 | .PHONY: openxc7 34 | openxc7: ${PROJECT}_openxc7.bit 35 | 36 | .PHONY: program 37 | program: ${PROJECT}_openxc7.bit 38 | openFPGALoader ${JTAG_LINK} --bitstream $< 39 | 40 | ${PROJECT}.json: ${TOP_VERILOG} ${ADDITIONAL_SOURCES} 41 | yosys -p "synth_xilinx -flatten -abc9 ${SYNTH_OPTS} -arch xc7 -top ${TOP_MODULE}; write_json ${PROJECT}.json" $< ${ADDITIONAL_SOURCES} 42 | 43 | # The chip database only needs to be generated once 44 | # that is why we don't clean it with make clean 45 | ${CHIPDB}/${DBPART}.bin: 46 | ${PYPY3} ${NEXTPNR_XILINX_PYTHON_DIR}/bbaexport.py --device ${PART} --bba ${DBPART}.bba 47 | bbasm -l ${DBPART}.bba ${CHIPDB}/${DBPART}.bin 48 | rm -f ${DBPART}.bba 49 | 50 | ${PROJECT}.fasm: ${PROJECT}.json ${CHIPDB}/${DBPART}.bin ${XDC} 51 | nextpnr-xilinx --chipdb ${CHIPDB}/${DBPART}.bin --xdc ${XDC} --json ${PROJECT}.json --fasm $@ ${PNR_ARGS} ${PNR_DEBUG} 52 | 53 | ${PROJECT}.frames: ${PROJECT}.fasm 54 | fasm2frames --part ${PART} --db-root ${PRJXRAY_DB_DIR}/${FAMILY} $< > $@ 55 | 56 | ${PROJECT}_openxc7.bit: ${PROJECT}.frames 57 | xc7frames2bit --part_file ${PRJXRAY_DB_DIR}/${FAMILY}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@ 58 | 59 | 60 | ############################################################################################# 61 | # SPDX-License-Identifier: MIT 62 | # Generated from https://github.com/FPGAOL-CE/caas-wizard 63 | # 64 | BUILDDIR := ${CURDIR}/build 65 | 66 | LOGFILE := ${BUILDDIR}/top.log 67 | 68 | # Build design 69 | .PHONY: vivado 70 | vivado: ${BUILDDIR}/${PROJECT}_vivado.bit 71 | 72 | ${BUILDDIR}: 73 | mkdir -m 777 -p ${BUILDDIR} && chown -R nobody ${BUILDDIR} | true 74 | 75 | .ONESHELL: 76 | ${BUILDDIR}/vivado.tcl: ${BUILDDIR} 77 | cat << EOF > $@ 78 | # vivado.tcl generated for FPGAOL-CE/caas-wizard 79 | # can be launched from any directory 80 | cd ${BUILDDIR} 81 | create_project -part ${PART} -force v_proj 82 | set_property target_language Verilog [current_project] 83 | cd .. 84 | read_verilog [glob ${PROJECT}.v ${ADDITIONAL_SOURCES}] 85 | read_xdc [glob $(wildcard ${PROJECT}.xdc) ] 86 | cd build 87 | synth_design -top ${PROJECT} 88 | opt_design 89 | place_design 90 | phys_opt_design 91 | route_design 92 | write_bitstream -verbose -force ${PROJECT}_vivado.bit 93 | # report_utilization -file util.rpt 94 | # report_timing_summary -file timing.rpt 95 | EOF 96 | 97 | ${BUILDDIR}/${PROJECT}_vivado.bit: ${BUILDDIR}/vivado.tcl 98 | cd ${BUILDDIR} && vivado -mode batch -source $< > ${LOGFILE} 2>&1 99 | 100 | .PHONY: program_vivado 101 | program_vivado: 102 | openFPGALoader ${JTAG_LINK} --bitstream ${BUILDDIR}/${PROJECT}_vivado.bit 103 | 104 | ############################################################################################# 105 | 106 | .PHONY: clean 107 | clean: 108 | rm -f *.bit 109 | rm -f *.frames 110 | rm -f *.fasm 111 | rm -f *.json 112 | rm -f *.bin 113 | rm -f *.bba 114 | rm -rf ${BUILDDIR} 115 | -------------------------------------------------------------------------------- /example_demo/nexys_video/clk_wiz.v: -------------------------------------------------------------------------------- 1 | `timescale 1ps/1ps 2 | 3 | module clk_wiz 4 | ( 5 | input wire clk_in1, 6 | output wire clk_out1, 7 | output wire clk_out2, 8 | output wire clk_out3, 9 | output wire clk_out4, 10 | input wire reset, 11 | output wire locked 12 | ); 13 | wire clk_out1_clk_wiz_0; 14 | wire clk_out2_clk_wiz_0; 15 | wire clk_out3_clk_wiz_0; 16 | wire clk_out4_clk_wiz_0; 17 | 18 | wire clkfbout; 19 | 20 | PLLE2_ADV 21 | #(.BANDWIDTH ("OPTIMIZED"), 22 | .COMPENSATION ("INTERNAL"), 23 | .STARTUP_WAIT ("FALSE"), 24 | .DIVCLK_DIVIDE (1), 25 | .CLKFBOUT_MULT (10), // 100 MHz * 10 = 1000 MHz 26 | .CLKFBOUT_PHASE (0.000), 27 | .CLKOUT0_DIVIDE (12), // 1000 MHz / 12 = 83.333 MHz 28 | .CLKOUT0_PHASE (0.000), 29 | .CLKOUT0_DUTY_CYCLE (0.500), 30 | .CLKOUT1_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz 31 | .CLKOUT1_PHASE (0.000), 32 | .CLKOUT1_DUTY_CYCLE (0.500), 33 | .CLKOUT2_DIVIDE (5), // 1000 MHz / 5 = 200 MHz 34 | .CLKOUT2_PHASE (0.000), 35 | .CLKOUT2_DUTY_CYCLE (0.500), 36 | .CLKOUT3_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz, 90 phase 37 | .CLKOUT3_PHASE (90.000), 38 | .CLKOUT3_DUTY_CYCLE (0.500), 39 | .CLKIN1_PERIOD (10.000) // 100 MHz input 40 | ) 41 | plle2_adv_inst 42 | ( 43 | .CLKFBOUT (clkfbout), 44 | .CLKOUT0 (clk_out1_clk_wiz_0), 45 | .CLKOUT1 (clk_out2_clk_wiz_0), 46 | .CLKOUT2 (clk_out3_clk_wiz_0), 47 | .CLKOUT3 (clk_out4_clk_wiz_0), 48 | .CLKFBIN (clkfbout), 49 | .CLKIN1 (clk_in1), 50 | .LOCKED (locked), 51 | .RST (reset) 52 | ); 53 | BUFG clkout1_buf 54 | (.O (clk_out1), 55 | .I (clk_out1_clk_wiz_0)); 56 | BUFG clkout2_buf 57 | (.O (clk_out2), 58 | .I (clk_out2_clk_wiz_0)); 59 | BUFG clkout3_buf 60 | (.O (clk_out3), 61 | .I (clk_out3_clk_wiz_0)); 62 | BUFG clkout4_buf 63 | (.O (clk_out4), 64 | .I (clk_out4_clk_wiz_0)); 65 | 66 | endmodule 67 | -------------------------------------------------------------------------------- /example_demo/nexys_video/nexysvideo_ddr3_openxc7.bit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AngeloJacobo/UberDDR3/a3efc861dafeec665d0885d6bc2e0c380260fe6b/example_demo/nexys_video/nexysvideo_ddr3_openxc7.bit -------------------------------------------------------------------------------- /example_demo/nexys_video/uart_tx.v: -------------------------------------------------------------------------------- 1 | 2 | 3 | // 4 | // Module: uart_tx 5 | // 6 | // Notes: 7 | // - UART transmitter module. 8 | // 9 | 10 | module uart_tx( 11 | input wire clk , // Top level system clock input. 12 | input wire resetn , // Asynchronous active low reset. 13 | output wire uart_txd , // UART transmit pin. 14 | output wire uart_tx_busy, // Module busy sending previous item. 15 | input wire uart_tx_en , // Send the data on uart_tx_data 16 | input wire [PAYLOAD_BITS-1:0] uart_tx_data // The data to be sent 17 | ); 18 | 19 | // --------------------------------------------------------------------------- 20 | // External parameters. 21 | // 22 | 23 | // 24 | // Input bit rate of the UART line. 25 | parameter BIT_RATE = 9600; // bits / sec 26 | localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds 27 | 28 | // 29 | // Clock frequency in hertz. 30 | parameter CLK_HZ = 50_000_000; 31 | localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds 32 | 33 | // 34 | // Number of data bits recieved per UART packet. 35 | parameter PAYLOAD_BITS = 8; 36 | 37 | // 38 | // Number of stop bits indicating the end of a packet. 39 | parameter STOP_BITS = 1; 40 | 41 | // --------------------------------------------------------------------------- 42 | // Internal parameters. 43 | // 44 | 45 | // 46 | // Number of clock cycles per uart bit. 47 | localparam CYCLES_PER_BIT = BIT_P / CLK_P; 48 | 49 | // 50 | // Size of the registers which store sample counts and bit durations. 51 | localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT); 52 | 53 | // --------------------------------------------------------------------------- 54 | // Internal registers. 55 | // 56 | 57 | // 58 | // Internally latched value of the uart_txd line. Helps break long timing 59 | // paths from the logic to the output pins. 60 | reg txd_reg; 61 | 62 | // 63 | // Storage for the serial data to be sent. 64 | reg [PAYLOAD_BITS-1:0] data_to_send; 65 | 66 | // 67 | // Counter for the number of cycles over a packet bit. 68 | reg [COUNT_REG_LEN-1:0] cycle_counter; 69 | 70 | // 71 | // Counter for the number of sent bits of the packet. 72 | reg [3:0] bit_counter; 73 | 74 | // 75 | // Current and next states of the internal FSM. 76 | reg [2:0] fsm_state; 77 | reg [2:0] n_fsm_state; 78 | 79 | localparam FSM_IDLE = 0; 80 | localparam FSM_START= 1; 81 | localparam FSM_SEND = 2; 82 | localparam FSM_STOP = 3; 83 | 84 | 85 | // --------------------------------------------------------------------------- 86 | // FSM next state selection. 87 | // 88 | 89 | assign uart_tx_busy = fsm_state != FSM_IDLE; 90 | assign uart_txd = txd_reg; 91 | 92 | wire next_bit = cycle_counter == CYCLES_PER_BIT; 93 | wire payload_done = bit_counter == PAYLOAD_BITS ; 94 | wire stop_done = bit_counter == STOP_BITS && fsm_state == FSM_STOP; 95 | 96 | // 97 | // Handle picking the next state. 98 | always @(*) begin : p_n_fsm_state 99 | case(fsm_state) 100 | FSM_IDLE : n_fsm_state = uart_tx_en ? FSM_START: FSM_IDLE ; 101 | FSM_START: n_fsm_state = next_bit ? FSM_SEND : FSM_START; 102 | FSM_SEND : n_fsm_state = payload_done ? FSM_STOP : FSM_SEND ; 103 | FSM_STOP : n_fsm_state = stop_done ? FSM_IDLE : FSM_STOP ; 104 | default : n_fsm_state = FSM_IDLE; 105 | endcase 106 | end 107 | 108 | // --------------------------------------------------------------------------- 109 | // Internal register setting and re-setting. 110 | // 111 | 112 | // 113 | // Handle updates to the sent data register. 114 | integer i = 0; 115 | always @(posedge clk) begin : p_data_to_send 116 | if(!resetn) begin 117 | data_to_send <= {PAYLOAD_BITS{1'b0}}; 118 | end else if(fsm_state == FSM_IDLE && uart_tx_en) begin 119 | data_to_send <= uart_tx_data; 120 | end else if(fsm_state == FSM_SEND && next_bit ) begin 121 | for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin 122 | data_to_send[i] <= data_to_send[i+1]; 123 | end 124 | end 125 | end 126 | 127 | 128 | // 129 | // Increments the bit counter each time a new bit frame is sent. 130 | always @(posedge clk) begin : p_bit_counter 131 | if(!resetn) begin 132 | bit_counter <= 4'b0; 133 | end else if(fsm_state != FSM_SEND && fsm_state != FSM_STOP) begin 134 | bit_counter <= {COUNT_REG_LEN{1'b0}}; 135 | end else if(fsm_state == FSM_SEND && n_fsm_state == FSM_STOP) begin 136 | bit_counter <= {COUNT_REG_LEN{1'b0}}; 137 | end else if(fsm_state == FSM_STOP&& next_bit) begin 138 | bit_counter <= bit_counter + 1'b1; 139 | end else if(fsm_state == FSM_SEND && next_bit) begin 140 | bit_counter <= bit_counter + 1'b1; 141 | end 142 | end 143 | 144 | 145 | // 146 | // Increments the cycle counter when sending. 147 | always @(posedge clk) begin : p_cycle_counter 148 | if(!resetn) begin 149 | cycle_counter <= {COUNT_REG_LEN{1'b0}}; 150 | end else if(next_bit) begin 151 | cycle_counter <= {COUNT_REG_LEN{1'b0}}; 152 | end else if(fsm_state == FSM_START || 153 | fsm_state == FSM_SEND || 154 | fsm_state == FSM_STOP ) begin 155 | cycle_counter <= cycle_counter + 1'b1; 156 | end 157 | end 158 | 159 | 160 | // 161 | // Progresses the next FSM state. 162 | always @(posedge clk) begin : p_fsm_state 163 | if(!resetn) begin 164 | fsm_state <= FSM_IDLE; 165 | end else begin 166 | fsm_state <= n_fsm_state; 167 | end 168 | end 169 | 170 | 171 | // 172 | // Responsible for updating the internal value of the txd_reg. 173 | always @(posedge clk) begin : p_txd_reg 174 | if(!resetn) begin 175 | txd_reg <= 1'b1; 176 | end else if(fsm_state == FSM_IDLE) begin 177 | txd_reg <= 1'b1; 178 | end else if(fsm_state == FSM_START) begin 179 | txd_reg <= 1'b0; 180 | end else if(fsm_state == FSM_SEND) begin 181 | txd_reg <= data_to_send[0]; 182 | end else if(fsm_state == FSM_STOP) begin 183 | txd_reg <= 1'b1; 184 | end 185 | end 186 | 187 | endmodule 188 | -------------------------------------------------------------------------------- /example_demo/orangecrab_ecp5/Makefile: -------------------------------------------------------------------------------- 1 | PROJ=orangecrab_ecp5_ddr3 2 | EXTRA_VERILOG_FILES= uart_rx.v uart_tx.v clk_wiz_ecppll.v ../../rtl/ddr3_top.v ../../rtl/ddr3_controller.v ../../rtl/ecp5_phy/ddr3_phy_ecp5.v ../../rtl/ecp5_phy/iserdes_soft.v ../../rtl/ecp5_phy/oserdes_soft.v 3 | # `r0.1` or `r0.2` or `r0.2.1` 4 | VERSION:=r0.2.1 5 | # `25F` or `85F` 6 | DENSITY=85F 7 | 8 | ifneq (,$(findstring 85,$(DENSITY))) 9 | NEXTPNR_DENSITY:=--85k 10 | else 11 | NEXTPNR_DENSITY:=--25k 12 | endif 13 | 14 | # Add Windows and Unix support 15 | RM = rm -rf 16 | COPY = cp -a 17 | PATH_SEP = / 18 | ifeq ($(OS),Windows_NT) 19 | # When SHELL=sh.exe and this actually exists, make will silently 20 | # switch to using that instead of cmd.exe. Unfortunately, there's 21 | # no way to tell which environment we're running under without either 22 | # (1) printing out an error message, or (2) finding something that 23 | # works everywhere. 24 | # As a result, we force the shell to be cmd.exe, so it works both 25 | # under cygwin and normal Windows. 26 | SHELL = cmd.exe 27 | COPY = copy 28 | RM = del 29 | PATH_SEP = \\ 30 | endif 31 | 32 | 33 | all: ${PROJ}.dfu 34 | 35 | dfu: ${PROJ}.dfu 36 | dfu-util --alt 0 -D $< 37 | 38 | 39 | %.json: %.v 40 | yosys -p "read_verilog -D LATTICE_ECP5_PHY $< ${EXTRA_VERILOG_FILES} ; synth_ecp5 -json $@ -top ${PROJ}" 41 | 42 | %_out.config: %.json 43 | nextpnr-ecp5 --json $< --textcfg $@ $(NEXTPNR_DENSITY) --package CSFBGA285 --lpf ${PROJ}.pcf 44 | 45 | %.bit: %_out.config 46 | ecppack --compress --freq 38.8 --input $< --bit $@ 47 | 48 | %.dfu : %.bit 49 | $(COPY) $< $@ 50 | dfu-suffix -v 1209 -p 5af0 -a $@ 51 | 52 | clean: 53 | $(RM) -f ${PROJ}.bit ${PROJ}_out.config ${PROJ}.json ${PROJ}.dfu 54 | 55 | .PHONY: prog clean 56 | -------------------------------------------------------------------------------- /example_demo/orangecrab_ecp5/clk_wiz_ecppll.v: -------------------------------------------------------------------------------- 1 | // diamond 3.7 accepts this PLL 2 | // diamond 3.8-3.9 is untested 3 | // diamond 3.10 or higher is likely to abort with error about unable to use feedback signal 4 | // cause of this could be from wrong CPHASE/FPHASE parameters 5 | module clk_wiz 6 | ( 7 | input reset, // 0:inactive, 1:reset 8 | input CLKI, // 48 MHz, 0 deg 9 | output CLKOP, // 160 MHz, 0 deg 10 | output CLKOS, // 160 MHz, 90 deg 11 | output CLKOS2, // 40 MHz, 0 deg 12 | output locked 13 | ); 14 | (* FREQUENCY_PIN_CLKI="48" *) 15 | (* FREQUENCY_PIN_CLKOP="160" *) 16 | (* FREQUENCY_PIN_CLKOS="160" *) 17 | (* FREQUENCY_PIN_CLKOS2="40" *) 18 | (* ICP_CURRENT="12" *) (* LPF_RESISTOR="8" *) (* MFG_ENABLE_FILTEROPAMP="1" *) (* MFG_GMCREF_SEL="2" *) 19 | EHXPLLL #( 20 | .PLLRST_ENA("ENABLED"), 21 | .INTFB_WAKE("DISABLED"), 22 | .STDBY_ENABLE("DISABLED"), 23 | .DPHASE_SOURCE("DISABLED"), 24 | .OUTDIVIDER_MUXA("DIVA"), 25 | .OUTDIVIDER_MUXB("DIVB"), 26 | .OUTDIVIDER_MUXC("DIVC"), 27 | .OUTDIVIDER_MUXD("DIVD"), 28 | .CLKI_DIV(3), 29 | .CLKOP_ENABLE("ENABLED"), 30 | .CLKOP_DIV(4), 31 | .CLKOP_CPHASE(2), 32 | .CLKOP_FPHASE(0), 33 | .CLKOS_ENABLE("ENABLED"), 34 | .CLKOS_DIV(4), 35 | .CLKOS_CPHASE(3), 36 | .CLKOS_FPHASE(0), 37 | .CLKOS2_ENABLE("ENABLED"), 38 | .CLKOS2_DIV(16), 39 | .CLKOS2_CPHASE(2), 40 | .CLKOS2_FPHASE(0), 41 | .FEEDBK_PATH("CLKOP"), 42 | .CLKFB_DIV(10) 43 | ) pll_i ( 44 | .RST(reset), 45 | .STDBY(1'b0), 46 | .CLKI(CLKI), 47 | .CLKOP(CLKOP), 48 | .CLKOS(CLKOS), 49 | .CLKOS2(CLKOS2), 50 | .CLKFB(CLKOP), 51 | .CLKINTFB(), 52 | .PHASESEL0(1'b0), 53 | .PHASESEL1(1'b0), 54 | .PHASEDIR(1'b1), 55 | .PHASESTEP(1'b1), 56 | .PHASELOADREG(1'b1), 57 | .PLLWAKESYNC(1'b0), 58 | .ENCLKOP(1'b0), 59 | .LOCK(locked) 60 | ); 61 | endmodule 62 | -------------------------------------------------------------------------------- /example_demo/orangecrab_ecp5/orangecrab_ecp5_ddr3.dfu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AngeloJacobo/UberDDR3/a3efc861dafeec665d0885d6bc2e0c380260fe6b/example_demo/orangecrab_ecp5/orangecrab_ecp5_ddr3.dfu -------------------------------------------------------------------------------- /example_demo/qmtech_kintex_7/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT = qmtech_kintex7_ddr3 2 | FAMILY = kintex7 3 | PART = xc7k325tffg676-1 4 | CHIPDB = ${KINTEX7_CHIPDB} 5 | ADDITIONAL_SOURCES = ../../rtl/ddr3_controller.v ../../rtl/ddr3_phy.v ../../rtl/ddr3_top.v uart_rx.v uart_tx.v clk_wiz.v 6 | 7 | 8 | ############################################################################################# 9 | NEXTPNR_XILINX_DIR ?= /snap/openxc7/current/opt/nextpnr-xilinx 10 | NEXTPNR_XILINX_PYTHON_DIR ?= ${NEXTPNR_XILINX_DIR}/python 11 | PRJXRAY_DB_DIR ?= ${NEXTPNR_XILINX_DIR}/external/prjxray-db 12 | 13 | DBPART = $(shell echo ${PART} | sed -e 's/-[0-9]//g') 14 | SPEEDGRADE = $(shell echo ${PART} | sed -e 's/.*\-\([0-9]\)/\1/g') 15 | 16 | CHIPDB ?= ./ 17 | ifeq ($(CHIPDB),) 18 | CHIPDB = ./ 19 | endif 20 | 21 | PYPY3 ?= pypy3 22 | 23 | TOP ?= ${PROJECT} 24 | TOP_MODULE ?= ${TOP} 25 | TOP_VERILOG ?= ${TOP}.v 26 | 27 | PNR_DEBUG ?= # --verbose --debug 28 | 29 | JTAG_LINK ?= -c digilent_hs2 30 | 31 | XDC ?= ${PROJECT}.xdc 32 | 33 | .PHONY: openxc7 34 | openxc7: ${PROJECT}_openxc7.bit 35 | 36 | .PHONY: program 37 | program: ${PROJECT}_openxc7.bit 38 | openFPGALoader ${JTAG_LINK} --bitstream $< 39 | 40 | ${PROJECT}.json: ${TOP_VERILOG} ${ADDITIONAL_SOURCES} 41 | yosys -p "synth_xilinx -flatten -abc9 ${SYNTH_OPTS} -arch xc7 -top ${TOP_MODULE}; write_json ${PROJECT}.json" $< ${ADDITIONAL_SOURCES} 42 | 43 | # The chip database only needs to be generated once 44 | # that is why we don't clean it with make clean 45 | ${CHIPDB}/${DBPART}.bin: 46 | ${PYPY3} ${NEXTPNR_XILINX_PYTHON_DIR}/bbaexport.py --device ${PART} --bba ${DBPART}.bba 47 | bbasm -l ${DBPART}.bba ${CHIPDB}/${DBPART}.bin 48 | rm -f ${DBPART}.bba 49 | 50 | ${PROJECT}.fasm: ${PROJECT}.json ${CHIPDB}/${DBPART}.bin ${XDC} 51 | nextpnr-xilinx --chipdb ${CHIPDB}/${DBPART}.bin --xdc ${XDC} --json ${PROJECT}.json --fasm $@ ${PNR_ARGS} ${PNR_DEBUG} 52 | 53 | ${PROJECT}.frames: ${PROJECT}.fasm 54 | fasm2frames --part ${PART} --db-root ${PRJXRAY_DB_DIR}/${FAMILY} $< > $@ 55 | 56 | ${PROJECT}_openxc7.bit: ${PROJECT}.frames 57 | xc7frames2bit --part_file ${PRJXRAY_DB_DIR}/${FAMILY}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@ 58 | 59 | 60 | ############################################################################################# 61 | # SPDX-License-Identifier: MIT 62 | # Generated from https://github.com/FPGAOL-CE/caas-wizard 63 | # 64 | BUILDDIR := ${CURDIR}/build 65 | 66 | LOGFILE := ${BUILDDIR}/top.log 67 | 68 | # Build design 69 | .PHONY: vivado 70 | vivado: ${BUILDDIR}/${PROJECT}_vivado.bit 71 | 72 | ${BUILDDIR}: 73 | mkdir -m 777 -p ${BUILDDIR} && chown -R nobody ${BUILDDIR} | true 74 | 75 | .ONESHELL: 76 | ${BUILDDIR}/vivado.tcl: ${BUILDDIR} 77 | cat << EOF > $@ 78 | # vivado.tcl generated for FPGAOL-CE/caas-wizard 79 | # can be launched from any directory 80 | cd ${BUILDDIR} 81 | create_project -part ${PART} -force v_proj 82 | set_property target_language Verilog [current_project] 83 | cd .. 84 | read_verilog [glob ${PROJECT}.v ${ADDITIONAL_SOURCES}] 85 | read_xdc [glob $(wildcard ${PROJECT}.xdc) ] 86 | cd build 87 | synth_design -top ${PROJECT} 88 | opt_design 89 | place_design 90 | phys_opt_design 91 | route_design 92 | write_bitstream -verbose -force ${PROJECT}_vivado.bit 93 | # report_utilization -file util.rpt 94 | # report_timing_summary -file timing.rpt 95 | EOF 96 | 97 | ${BUILDDIR}/${PROJECT}_vivado.bit: ${BUILDDIR}/vivado.tcl 98 | cd ${BUILDDIR} && vivado -mode batch -source $< > ${LOGFILE} 2>&1 99 | 100 | .PHONY: program_vivado 101 | program_vivado: 102 | openFPGALoader ${JTAG_LINK} --bitstream ${BUILDDIR}/${PROJECT}_vivado.bit 103 | 104 | ############################################################################################# 105 | 106 | .PHONY: clean 107 | clean: 108 | rm -f *.bit 109 | rm -f *.frames 110 | rm -f *.fasm 111 | rm -f *.json 112 | rm -f *.bin 113 | rm -f *.bba 114 | rm -rf ${BUILDDIR} 115 | -------------------------------------------------------------------------------- /example_demo/qmtech_kintex_7/clk_wiz.v: -------------------------------------------------------------------------------- 1 | `timescale 1ps/1ps 2 | 3 | module clk_wiz 4 | ( 5 | input wire clk_in1, 6 | output wire clk_out1, 7 | output wire clk_out2, 8 | output wire clk_out3, 9 | output wire clk_out4, 10 | input wire reset, 11 | output wire locked 12 | ); 13 | wire clk_out1_clk_wiz_0; 14 | wire clk_out2_clk_wiz_0; 15 | wire clk_out3_clk_wiz_0; 16 | wire clk_out4_clk_wiz_0; 17 | 18 | wire clkfbout; 19 | 20 | PLLE2_ADV 21 | #(.BANDWIDTH ("OPTIMIZED"), 22 | .COMPENSATION ("INTERNAL"), 23 | .STARTUP_WAIT ("FALSE"), 24 | .DIVCLK_DIVIDE (1), 25 | .CLKFBOUT_MULT (20), // 50 MHz * 20 = 1000 MHz 26 | .CLKFBOUT_PHASE (0.000), 27 | .CLKOUT0_DIVIDE (12), // 1000 MHz / 12 = 83.333 MHz 28 | .CLKOUT0_PHASE (0.000), 29 | .CLKOUT0_DUTY_CYCLE (0.500), 30 | .CLKOUT1_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz 31 | .CLKOUT1_PHASE (0.000), 32 | .CLKOUT1_DUTY_CYCLE (0.500), 33 | .CLKOUT2_DIVIDE (5), // 1000 MHz / 5 = 200 MHz 34 | .CLKOUT2_PHASE (0.000), 35 | .CLKOUT2_DUTY_CYCLE (0.500), 36 | .CLKOUT3_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz, 90 phase 37 | .CLKOUT3_PHASE (90.000), 38 | .CLKOUT3_DUTY_CYCLE (0.500), 39 | .CLKIN1_PERIOD (20.000) // 50 MHz input 40 | ) 41 | plle2_adv_inst 42 | ( 43 | .CLKFBOUT (clkfbout), 44 | .CLKOUT0 (clk_out1_clk_wiz_0), 45 | .CLKOUT1 (clk_out2_clk_wiz_0), 46 | .CLKOUT2 (clk_out3_clk_wiz_0), 47 | .CLKOUT3 (clk_out4_clk_wiz_0), 48 | .CLKFBIN (clkfbout), 49 | .CLKIN1 (clk_in1), 50 | .LOCKED (locked), 51 | .RST (reset) 52 | ); 53 | BUFG clkout1_buf 54 | (.O (clk_out1), 55 | .I (clk_out1_clk_wiz_0)); 56 | BUFG clkout2_buf 57 | (.O (clk_out2), 58 | .I (clk_out2_clk_wiz_0)); 59 | BUFG clkout3_buf 60 | (.O (clk_out3), 61 | .I (clk_out3_clk_wiz_0)); 62 | BUFG clkout4_buf 63 | (.O (clk_out4), 64 | .I (clk_out4_clk_wiz_0)); 65 | 66 | endmodule 67 | -------------------------------------------------------------------------------- /example_demo/qmtech_kintex_7/qmtech_kintex7_ddr3_openxc7.bit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AngeloJacobo/UberDDR3/a3efc861dafeec665d0885d6bc2e0c380260fe6b/example_demo/qmtech_kintex_7/qmtech_kintex7_ddr3_openxc7.bit -------------------------------------------------------------------------------- /example_demo/qmtech_wukong/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT = wukong_ddr3 2 | FAMILY = artix7 3 | PART = xc7a100tfgg676-2 4 | CHIPDB = ${ARTIX7_CHIPDB} 5 | ADDITIONAL_SOURCES = ../../rtl/ddr3_controller.v ../../rtl/ddr3_phy.v ../../rtl/ddr3_top.v uart_rx.v uart_tx.v clk_wiz.v 6 | 7 | 8 | ############################################################################################# 9 | NEXTPNR_XILINX_DIR ?= /snap/openxc7/current/opt/nextpnr-xilinx 10 | NEXTPNR_XILINX_PYTHON_DIR ?= ${NEXTPNR_XILINX_DIR}/python 11 | PRJXRAY_DB_DIR ?= ${NEXTPNR_XILINX_DIR}/external/prjxray-db 12 | 13 | DBPART = $(shell echo ${PART} | sed -e 's/-[0-9]//g') 14 | SPEEDGRADE = $(shell echo ${PART} | sed -e 's/.*\-\([0-9]\)/\1/g') 15 | 16 | CHIPDB ?= ./ 17 | ifeq ($(CHIPDB),) 18 | CHIPDB = ./ 19 | endif 20 | 21 | PYPY3 ?= pypy3 22 | 23 | TOP ?= ${PROJECT} 24 | TOP_MODULE ?= ${TOP} 25 | TOP_VERILOG ?= ${TOP}.v 26 | 27 | PNR_DEBUG ?= # --verbose --debug 28 | 29 | JTAG_LINK ?= -c digilent_hs2 30 | 31 | XDC ?= ${PROJECT}.xdc 32 | 33 | .PHONY: openxc7 34 | openxc7: ${PROJECT}_openxc7.bit 35 | 36 | .PHONY: program 37 | program: ${PROJECT}_openxc7.bit 38 | openFPGALoader ${JTAG_LINK} --bitstream $< 39 | 40 | ${PROJECT}.json: ${TOP_VERILOG} ${ADDITIONAL_SOURCES} 41 | yosys -p "synth_xilinx -flatten -abc9 ${SYNTH_OPTS} -arch xc7 -top ${TOP_MODULE}; write_json ${PROJECT}.json" $< ${ADDITIONAL_SOURCES} 42 | 43 | # The chip database only needs to be generated once 44 | # that is why we don't clean it with make clean 45 | ${CHIPDB}/${DBPART}.bin: 46 | ${PYPY3} ${NEXTPNR_XILINX_PYTHON_DIR}/bbaexport.py --device ${PART} --bba ${DBPART}.bba 47 | bbasm -l ${DBPART}.bba ${CHIPDB}/${DBPART}.bin 48 | rm -f ${DBPART}.bba 49 | 50 | ${PROJECT}.fasm: ${PROJECT}.json ${CHIPDB}/${DBPART}.bin ${XDC} 51 | nextpnr-xilinx --chipdb ${CHIPDB}/${DBPART}.bin --xdc ${XDC} --json ${PROJECT}.json --fasm $@ ${PNR_ARGS} ${PNR_DEBUG} 52 | 53 | ${PROJECT}.frames: ${PROJECT}.fasm 54 | fasm2frames --part ${PART} --db-root ${PRJXRAY_DB_DIR}/${FAMILY} $< > $@ 55 | 56 | ${PROJECT}_openxc7.bit: ${PROJECT}.frames 57 | xc7frames2bit --part_file ${PRJXRAY_DB_DIR}/${FAMILY}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@ 58 | 59 | 60 | ############################################################################################# 61 | # SPDX-License-Identifier: MIT 62 | # Generated from https://github.com/FPGAOL-CE/caas-wizard 63 | # 64 | BUILDDIR := ${CURDIR}/build 65 | 66 | LOGFILE := ${BUILDDIR}/top.log 67 | 68 | # Build design 69 | .PHONY: vivado 70 | vivado: ${BUILDDIR}/${PROJECT}_vivado.bit 71 | 72 | ${BUILDDIR}: 73 | mkdir -m 777 -p ${BUILDDIR} && chown -R nobody ${BUILDDIR} | true 74 | 75 | .ONESHELL: 76 | ${BUILDDIR}/vivado.tcl: ${BUILDDIR} 77 | cat << EOF > $@ 78 | # vivado.tcl generated for FPGAOL-CE/caas-wizard 79 | # can be launched from any directory 80 | cd ${BUILDDIR} 81 | create_project -part ${PART} -force v_proj 82 | set_property target_language Verilog [current_project] 83 | cd .. 84 | read_verilog [glob ${PROJECT}.v ${ADDITIONAL_SOURCES}] 85 | read_xdc [glob $(wildcard ${PROJECT}_vivado.xdc) ] 86 | cd build 87 | synth_design -top ${PROJECT} 88 | opt_design 89 | place_design 90 | phys_opt_design 91 | route_design 92 | write_bitstream -verbose -force ${PROJECT}_vivado.bit 93 | # report_utilization -file util.rpt 94 | # report_timing_summary -file timing.rpt 95 | EOF 96 | 97 | ${BUILDDIR}/${PROJECT}_vivado.bit: ${BUILDDIR}/vivado.tcl 98 | cd ${BUILDDIR} && vivado -mode batch -source $< > ${LOGFILE} 2>&1 99 | 100 | .PHONY: program_vivado 101 | program_vivado: 102 | openFPGALoader ${JTAG_LINK} --bitstream ${BUILDDIR}/${PROJECT}_vivado.bit 103 | 104 | ############################################################################################# 105 | 106 | .PHONY: clean 107 | clean: 108 | rm -f *.bit 109 | rm -f *.frames 110 | rm -f *.fasm 111 | rm -f *.json 112 | rm -f *.bin 113 | rm -f *.bba 114 | rm -rf ${BUILDDIR} 115 | -------------------------------------------------------------------------------- /example_demo/qmtech_wukong/clk_wiz.v: -------------------------------------------------------------------------------- 1 | `timescale 1ps/1ps 2 | 3 | module clk_wiz 4 | ( 5 | input wire clk_in1, 6 | output wire clk_out1, 7 | output wire clk_out2, 8 | output wire clk_out3, 9 | output wire clk_out4, 10 | input wire reset, 11 | output wire locked 12 | ); 13 | wire clk_out1_clk_wiz_0; 14 | wire clk_out2_clk_wiz_0; 15 | wire clk_out3_clk_wiz_0; 16 | wire clk_out4_clk_wiz_0; 17 | 18 | wire clkfbout; 19 | 20 | PLLE2_ADV 21 | #(.BANDWIDTH ("OPTIMIZED"), 22 | .COMPENSATION ("INTERNAL"), 23 | .STARTUP_WAIT ("FALSE"), 24 | .DIVCLK_DIVIDE (1), 25 | .CLKFBOUT_MULT (20), // 50 MHz * 20 = 1000 MHz 26 | .CLKFBOUT_PHASE (0.000), 27 | .CLKOUT0_DIVIDE (12), // 1000 MHz / 12 = 83.333 MHz 28 | .CLKOUT0_PHASE (0.000), 29 | .CLKOUT0_DUTY_CYCLE (0.500), 30 | .CLKOUT1_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz 31 | .CLKOUT1_PHASE (0.000), 32 | .CLKOUT1_DUTY_CYCLE (0.500), 33 | .CLKOUT2_DIVIDE (5), // 1000 MHz / 5 = 200 MHz 34 | .CLKOUT2_PHASE (0.000), 35 | .CLKOUT2_DUTY_CYCLE (0.500), 36 | .CLKOUT3_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz, 90 phase 37 | .CLKOUT3_PHASE (90.000), 38 | .CLKOUT3_DUTY_CYCLE (0.500), 39 | .CLKIN1_PERIOD (20.000) // 50 MHz input 40 | ) 41 | plle2_adv_inst 42 | ( 43 | .CLKFBOUT (clkfbout), 44 | .CLKOUT0 (clk_out1_clk_wiz_0), 45 | .CLKOUT1 (clk_out2_clk_wiz_0), 46 | .CLKOUT2 (clk_out3_clk_wiz_0), 47 | .CLKOUT3 (clk_out4_clk_wiz_0), 48 | .CLKFBIN (clkfbout), 49 | .CLKIN1 (clk_in1), 50 | .LOCKED (locked), 51 | .RST (reset) 52 | ); 53 | BUFG clkout1_buf 54 | (.O (clk_out1), 55 | .I (clk_out1_clk_wiz_0)); 56 | BUFG clkout2_buf 57 | (.O (clk_out2), 58 | .I (clk_out2_clk_wiz_0)); 59 | BUFG clkout3_buf 60 | (.O (clk_out3), 61 | .I (clk_out3_clk_wiz_0)); 62 | BUFG clkout4_buf 63 | (.O (clk_out4), 64 | .I (clk_out4_clk_wiz_0)); 65 | 66 | endmodule 67 | -------------------------------------------------------------------------------- /example_demo/qmtech_wukong/uart_tx.v: -------------------------------------------------------------------------------- 1 | 2 | 3 | // 4 | // Module: uart_tx 5 | // 6 | // Notes: 7 | // - UART transmitter module. 8 | // 9 | 10 | module uart_tx( 11 | input wire clk , // Top level system clock input. 12 | input wire resetn , // Asynchronous active low reset. 13 | output wire uart_txd , // UART transmit pin. 14 | output wire uart_tx_busy, // Module busy sending previous item. 15 | input wire uart_tx_en , // Send the data on uart_tx_data 16 | input wire [PAYLOAD_BITS-1:0] uart_tx_data // The data to be sent 17 | ); 18 | 19 | // --------------------------------------------------------------------------- 20 | // External parameters. 21 | // 22 | 23 | // 24 | // Input bit rate of the UART line. 25 | parameter BIT_RATE = 9600; // bits / sec 26 | localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds 27 | 28 | // 29 | // Clock frequency in hertz. 30 | parameter CLK_HZ = 50_000_000; 31 | localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds 32 | 33 | // 34 | // Number of data bits recieved per UART packet. 35 | parameter PAYLOAD_BITS = 8; 36 | 37 | // 38 | // Number of stop bits indicating the end of a packet. 39 | parameter STOP_BITS = 1; 40 | 41 | // --------------------------------------------------------------------------- 42 | // Internal parameters. 43 | // 44 | 45 | // 46 | // Number of clock cycles per uart bit. 47 | localparam CYCLES_PER_BIT = BIT_P / CLK_P; 48 | 49 | // 50 | // Size of the registers which store sample counts and bit durations. 51 | localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT); 52 | 53 | // --------------------------------------------------------------------------- 54 | // Internal registers. 55 | // 56 | 57 | // 58 | // Internally latched value of the uart_txd line. Helps break long timing 59 | // paths from the logic to the output pins. 60 | reg txd_reg; 61 | 62 | // 63 | // Storage for the serial data to be sent. 64 | reg [PAYLOAD_BITS-1:0] data_to_send; 65 | 66 | // 67 | // Counter for the number of cycles over a packet bit. 68 | reg [COUNT_REG_LEN-1:0] cycle_counter; 69 | 70 | // 71 | // Counter for the number of sent bits of the packet. 72 | reg [3:0] bit_counter; 73 | 74 | // 75 | // Current and next states of the internal FSM. 76 | reg [2:0] fsm_state; 77 | reg [2:0] n_fsm_state; 78 | 79 | localparam FSM_IDLE = 0; 80 | localparam FSM_START= 1; 81 | localparam FSM_SEND = 2; 82 | localparam FSM_STOP = 3; 83 | 84 | 85 | // --------------------------------------------------------------------------- 86 | // FSM next state selection. 87 | // 88 | 89 | assign uart_tx_busy = fsm_state != FSM_IDLE; 90 | assign uart_txd = txd_reg; 91 | 92 | wire next_bit = cycle_counter == CYCLES_PER_BIT; 93 | wire payload_done = bit_counter == PAYLOAD_BITS ; 94 | wire stop_done = bit_counter == STOP_BITS && fsm_state == FSM_STOP; 95 | 96 | // 97 | // Handle picking the next state. 98 | always @(*) begin : p_n_fsm_state 99 | case(fsm_state) 100 | FSM_IDLE : n_fsm_state = uart_tx_en ? FSM_START: FSM_IDLE ; 101 | FSM_START: n_fsm_state = next_bit ? FSM_SEND : FSM_START; 102 | FSM_SEND : n_fsm_state = payload_done ? FSM_STOP : FSM_SEND ; 103 | FSM_STOP : n_fsm_state = stop_done ? FSM_IDLE : FSM_STOP ; 104 | default : n_fsm_state = FSM_IDLE; 105 | endcase 106 | end 107 | 108 | // --------------------------------------------------------------------------- 109 | // Internal register setting and re-setting. 110 | // 111 | 112 | // 113 | // Handle updates to the sent data register. 114 | integer i = 0; 115 | always @(posedge clk) begin : p_data_to_send 116 | if(!resetn) begin 117 | data_to_send <= {PAYLOAD_BITS{1'b0}}; 118 | end else if(fsm_state == FSM_IDLE && uart_tx_en) begin 119 | data_to_send <= uart_tx_data; 120 | end else if(fsm_state == FSM_SEND && next_bit ) begin 121 | for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin 122 | data_to_send[i] <= data_to_send[i+1]; 123 | end 124 | end 125 | end 126 | 127 | 128 | // 129 | // Increments the bit counter each time a new bit frame is sent. 130 | always @(posedge clk) begin : p_bit_counter 131 | if(!resetn) begin 132 | bit_counter <= 4'b0; 133 | end else if(fsm_state != FSM_SEND && fsm_state != FSM_STOP) begin 134 | bit_counter <= {COUNT_REG_LEN{1'b0}}; 135 | end else if(fsm_state == FSM_SEND && n_fsm_state == FSM_STOP) begin 136 | bit_counter <= {COUNT_REG_LEN{1'b0}}; 137 | end else if(fsm_state == FSM_STOP&& next_bit) begin 138 | bit_counter <= bit_counter + 1'b1; 139 | end else if(fsm_state == FSM_SEND && next_bit) begin 140 | bit_counter <= bit_counter + 1'b1; 141 | end 142 | end 143 | 144 | 145 | // 146 | // Increments the cycle counter when sending. 147 | always @(posedge clk) begin : p_cycle_counter 148 | if(!resetn) begin 149 | cycle_counter <= {COUNT_REG_LEN{1'b0}}; 150 | end else if(next_bit) begin 151 | cycle_counter <= {COUNT_REG_LEN{1'b0}}; 152 | end else if(fsm_state == FSM_START || 153 | fsm_state == FSM_SEND || 154 | fsm_state == FSM_STOP ) begin 155 | cycle_counter <= cycle_counter + 1'b1; 156 | end 157 | end 158 | 159 | 160 | // 161 | // Progresses the next FSM state. 162 | always @(posedge clk) begin : p_fsm_state 163 | if(!resetn) begin 164 | fsm_state <= FSM_IDLE; 165 | end else begin 166 | fsm_state <= n_fsm_state; 167 | end 168 | end 169 | 170 | 171 | // 172 | // Responsible for updating the internal value of the txd_reg. 173 | always @(posedge clk) begin : p_txd_reg 174 | if(!resetn) begin 175 | txd_reg <= 1'b1; 176 | end else if(fsm_state == FSM_IDLE) begin 177 | txd_reg <= 1'b1; 178 | end else if(fsm_state == FSM_START) begin 179 | txd_reg <= 1'b0; 180 | end else if(fsm_state == FSM_SEND) begin 181 | txd_reg <= data_to_send[0]; 182 | end else if(fsm_state == FSM_STOP) begin 183 | txd_reg <= 1'b1; 184 | end 185 | end 186 | 187 | endmodule 188 | -------------------------------------------------------------------------------- /example_demo/qmtech_wukong/wukong_ddr3_openxc7.bit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AngeloJacobo/UberDDR3/a3efc861dafeec665d0885d6bc2e0c380260fe6b/example_demo/qmtech_wukong/wukong_ddr3_openxc7.bit -------------------------------------------------------------------------------- /example_demo/run_make_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Create a logs directory to store all log files 4 | rm -rf build_logs 5 | mkdir -p build_logs 6 | 7 | # Loop through each item in the current directory 8 | for dir in */; do 9 | # Check if it's a directory and contains a Makefile 10 | if [ -d "$dir" ] && [ -f "$dir/Makefile" ]; then 11 | log_file="build_logs/${dir%/}.log" 12 | echo "Building $dir... Logging to $log_file" 13 | { 14 | echo "===== $(date) - Building $dir =====" 15 | cd "$dir" 16 | make clean 17 | make 18 | echo "" 19 | echo "DONE OPENXC7" 20 | echo "" 21 | echo "" 22 | make vivado 23 | echo "" 24 | echo "DONE VIVADO" 25 | echo "" 26 | echo "" 27 | cd .. 28 | echo "===== Finished $dir =====" 29 | } &> "$log_file" 30 | else 31 | echo "Skipping $dir (no Makefile found)" 32 | fi 33 | done 34 | -------------------------------------------------------------------------------- /example_demo/sechzig_mx2/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT = sechzig_mx2_ddr3 2 | FAMILY = artix7 3 | PART = xc7a35tftg256-2 4 | CHIPDB = ${ARTIX7_CHIPDB} 5 | ADDITIONAL_SOURCES = ../../rtl/ddr3_controller.v ../../rtl/ddr3_phy.v ../../rtl/ddr3_top.v uart_rx.v uart_tx.v clk_wiz.v 6 | 7 | 8 | ############################################################################################# 9 | NEXTPNR_XILINX_DIR ?= /snap/openxc7/current/opt/nextpnr-xilinx 10 | NEXTPNR_XILINX_PYTHON_DIR ?= ${NEXTPNR_XILINX_DIR}/python 11 | PRJXRAY_DB_DIR ?= ${NEXTPNR_XILINX_DIR}/external/prjxray-db 12 | 13 | DBPART = $(shell echo ${PART} | sed -e 's/-[0-9]//g') 14 | SPEEDGRADE = $(shell echo ${PART} | sed -e 's/.*\-\([0-9]\)/\1/g') 15 | 16 | CHIPDB ?= ./ 17 | ifeq ($(CHIPDB),) 18 | CHIPDB = ./ 19 | endif 20 | 21 | PYPY3 ?= pypy3 22 | 23 | TOP ?= ${PROJECT} 24 | TOP_MODULE ?= ${TOP} 25 | TOP_VERILOG ?= ${TOP}.v 26 | 27 | PNR_DEBUG ?= # --verbose --debug 28 | 29 | JTAG_LINK ?= -c digilent_hs2 30 | 31 | XDC ?= ${PROJECT}.xdc 32 | 33 | .PHONY: openxc7 34 | openxc7: ${PROJECT}_openxc7.bit 35 | 36 | .PHONY: program 37 | program: ${PROJECT}_openxc7.bit 38 | openFPGALoader ${JTAG_LINK} --bitstream $< 39 | 40 | ${PROJECT}.json: ${TOP_VERILOG} ${ADDITIONAL_SOURCES} 41 | yosys -p "synth_xilinx -flatten -abc9 ${SYNTH_OPTS} -arch xc7 -top ${TOP_MODULE}; write_json ${PROJECT}.json" $< ${ADDITIONAL_SOURCES} 42 | 43 | # The chip database only needs to be generated once 44 | # that is why we don't clean it with make clean 45 | ${CHIPDB}/${DBPART}.bin: 46 | ${PYPY3} ${NEXTPNR_XILINX_PYTHON_DIR}/bbaexport.py --device ${PART} --bba ${DBPART}.bba 47 | bbasm -l ${DBPART}.bba ${CHIPDB}/${DBPART}.bin 48 | rm -f ${DBPART}.bba 49 | 50 | ${PROJECT}.fasm: ${PROJECT}.json ${CHIPDB}/${DBPART}.bin ${XDC} 51 | nextpnr-xilinx --chipdb ${CHIPDB}/${DBPART}.bin --xdc ${XDC} --json ${PROJECT}.json --fasm $@ ${PNR_ARGS} ${PNR_DEBUG} 52 | 53 | ${PROJECT}.frames: ${PROJECT}.fasm 54 | fasm2frames --part ${PART} --db-root ${PRJXRAY_DB_DIR}/${FAMILY} $< > $@ 55 | 56 | ${PROJECT}_openxc7.bit: ${PROJECT}.frames 57 | xc7frames2bit --part_file ${PRJXRAY_DB_DIR}/${FAMILY}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@ 58 | 59 | 60 | ############################################################################################# 61 | # SPDX-License-Identifier: MIT 62 | # Generated from https://github.com/FPGAOL-CE/caas-wizard 63 | # 64 | BUILDDIR := ${CURDIR}/build 65 | 66 | LOGFILE := ${BUILDDIR}/top.log 67 | 68 | # Build design 69 | .PHONY: vivado 70 | vivado: ${BUILDDIR}/${PROJECT}_vivado.bit 71 | 72 | ${BUILDDIR}: 73 | mkdir -m 777 -p ${BUILDDIR} && chown -R nobody ${BUILDDIR} | true 74 | 75 | .ONESHELL: 76 | ${BUILDDIR}/vivado.tcl: ${BUILDDIR} 77 | cat << EOF > $@ 78 | # vivado.tcl generated for FPGAOL-CE/caas-wizard 79 | # can be launched from any directory 80 | cd ${BUILDDIR} 81 | create_project -part ${PART} -force v_proj 82 | set_property target_language Verilog [current_project] 83 | cd .. 84 | read_verilog [glob ${PROJECT}.v ${ADDITIONAL_SOURCES}] 85 | read_xdc [glob $(wildcard ${PROJECT}.xdc) ] 86 | cd build 87 | synth_design -top ${PROJECT} 88 | opt_design 89 | place_design 90 | phys_opt_design 91 | route_design 92 | write_bitstream -verbose -force ${PROJECT}_vivado.bit 93 | # report_utilization -file util.rpt 94 | # report_timing_summary -file timing.rpt 95 | EOF 96 | 97 | ${BUILDDIR}/${PROJECT}_vivado.bit: ${BUILDDIR}/vivado.tcl 98 | cd ${BUILDDIR} && vivado -mode batch -source $< > ${LOGFILE} 2>&1 99 | 100 | .PHONY: program_vivado 101 | program_vivado: 102 | openFPGALoader ${JTAG_LINK} --bitstream ${BUILDDIR}/${PROJECT}_vivado.bit 103 | 104 | ############################################################################################# 105 | 106 | .PHONY: clean 107 | clean: 108 | rm -f *.bit 109 | rm -f *.frames 110 | rm -f *.fasm 111 | rm -f *.json 112 | rm -f *.bin 113 | rm -f *.bba 114 | rm -rf ${BUILDDIR} 115 | -------------------------------------------------------------------------------- /example_demo/sechzig_mx2/clk_wiz.v: -------------------------------------------------------------------------------- 1 | `timescale 1ps/1ps 2 | 3 | module clk_wiz 4 | ( 5 | input wire clk_in1, 6 | output wire clk_out1, 7 | output wire clk_out2, 8 | output wire clk_out3, 9 | output wire clk_out4, 10 | input wire reset, 11 | output wire locked 12 | ); 13 | wire clk_out1_clk_wiz_0; 14 | wire clk_out2_clk_wiz_0; 15 | wire clk_out3_clk_wiz_0; 16 | wire clk_out4_clk_wiz_0; 17 | 18 | wire clkfbout; 19 | 20 | PLLE2_ADV 21 | #(.BANDWIDTH ("OPTIMIZED"), 22 | .COMPENSATION ("INTERNAL"), 23 | .STARTUP_WAIT ("FALSE"), 24 | .DIVCLK_DIVIDE (1), 25 | .CLKFBOUT_MULT (20), // 50 MHz * 20 = 1000 MHz 26 | .CLKFBOUT_PHASE (0.000), 27 | .CLKOUT0_DIVIDE (12), // 1000 MHz / 12 = 83.333 MHz 28 | .CLKOUT0_PHASE (0.000), 29 | .CLKOUT0_DUTY_CYCLE (0.500), 30 | .CLKOUT1_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz 31 | .CLKOUT1_PHASE (0.000), 32 | .CLKOUT1_DUTY_CYCLE (0.500), 33 | .CLKOUT2_DIVIDE (5), // 1000 MHz / 5 = 200 MHz 34 | .CLKOUT2_PHASE (0.000), 35 | .CLKOUT2_DUTY_CYCLE (0.500), 36 | .CLKOUT3_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz, 90 phase 37 | .CLKOUT3_PHASE (90.000), 38 | .CLKOUT3_DUTY_CYCLE (0.500), 39 | .CLKIN1_PERIOD (20.000) // 50 MHz input 40 | ) 41 | plle2_adv_inst 42 | ( 43 | .CLKFBOUT (clkfbout), 44 | .CLKOUT0 (clk_out1_clk_wiz_0), 45 | .CLKOUT1 (clk_out2_clk_wiz_0), 46 | .CLKOUT2 (clk_out3_clk_wiz_0), 47 | .CLKOUT3 (clk_out4_clk_wiz_0), 48 | .CLKFBIN (clkfbout), 49 | .CLKIN1 (clk_in1), 50 | .LOCKED (locked), 51 | .RST (reset) 52 | ); 53 | BUFG clkout1_buf 54 | (.O (clk_out1), 55 | .I (clk_out1_clk_wiz_0)); 56 | BUFG clkout2_buf 57 | (.O (clk_out2), 58 | .I (clk_out2_clk_wiz_0)); 59 | BUFG clkout3_buf 60 | (.O (clk_out3), 61 | .I (clk_out3_clk_wiz_0)); 62 | BUFG clkout4_buf 63 | (.O (clk_out4), 64 | .I (clk_out4_clk_wiz_0)); 65 | 66 | endmodule 67 | -------------------------------------------------------------------------------- /example_demo/sechzig_mx2/sechzig_mx2_ddr3_openxc7.bit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AngeloJacobo/UberDDR3/a3efc861dafeec665d0885d6bc2e0c380260fe6b/example_demo/sechzig_mx2/sechzig_mx2_ddr3_openxc7.bit -------------------------------------------------------------------------------- /example_demo/sechzig_mx2/uart_tx.v: -------------------------------------------------------------------------------- 1 | 2 | 3 | // 4 | // Module: uart_tx 5 | // 6 | // Notes: 7 | // - UART transmitter module. 8 | // 9 | 10 | module uart_tx( 11 | input wire clk , // Top level system clock input. 12 | input wire resetn , // Asynchronous active low reset. 13 | output wire uart_txd , // UART transmit pin. 14 | output wire uart_tx_busy, // Module busy sending previous item. 15 | input wire uart_tx_en , // Send the data on uart_tx_data 16 | input wire [PAYLOAD_BITS-1:0] uart_tx_data // The data to be sent 17 | ); 18 | 19 | // --------------------------------------------------------------------------- 20 | // External parameters. 21 | // 22 | 23 | // 24 | // Input bit rate of the UART line. 25 | parameter BIT_RATE = 9600; // bits / sec 26 | localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds 27 | 28 | // 29 | // Clock frequency in hertz. 30 | parameter CLK_HZ = 50_000_000; 31 | localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds 32 | 33 | // 34 | // Number of data bits recieved per UART packet. 35 | parameter PAYLOAD_BITS = 8; 36 | 37 | // 38 | // Number of stop bits indicating the end of a packet. 39 | parameter STOP_BITS = 1; 40 | 41 | // --------------------------------------------------------------------------- 42 | // Internal parameters. 43 | // 44 | 45 | // 46 | // Number of clock cycles per uart bit. 47 | localparam CYCLES_PER_BIT = BIT_P / CLK_P; 48 | 49 | // 50 | // Size of the registers which store sample counts and bit durations. 51 | localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT); 52 | 53 | // --------------------------------------------------------------------------- 54 | // Internal registers. 55 | // 56 | 57 | // 58 | // Internally latched value of the uart_txd line. Helps break long timing 59 | // paths from the logic to the output pins. 60 | reg txd_reg; 61 | 62 | // 63 | // Storage for the serial data to be sent. 64 | reg [PAYLOAD_BITS-1:0] data_to_send; 65 | 66 | // 67 | // Counter for the number of cycles over a packet bit. 68 | reg [COUNT_REG_LEN-1:0] cycle_counter; 69 | 70 | // 71 | // Counter for the number of sent bits of the packet. 72 | reg [3:0] bit_counter; 73 | 74 | // 75 | // Current and next states of the internal FSM. 76 | reg [2:0] fsm_state; 77 | reg [2:0] n_fsm_state; 78 | 79 | localparam FSM_IDLE = 0; 80 | localparam FSM_START= 1; 81 | localparam FSM_SEND = 2; 82 | localparam FSM_STOP = 3; 83 | 84 | 85 | // --------------------------------------------------------------------------- 86 | // FSM next state selection. 87 | // 88 | 89 | assign uart_tx_busy = fsm_state != FSM_IDLE; 90 | assign uart_txd = txd_reg; 91 | 92 | wire next_bit = cycle_counter == CYCLES_PER_BIT; 93 | wire payload_done = bit_counter == PAYLOAD_BITS ; 94 | wire stop_done = bit_counter == STOP_BITS && fsm_state == FSM_STOP; 95 | 96 | // 97 | // Handle picking the next state. 98 | always @(*) begin : p_n_fsm_state 99 | case(fsm_state) 100 | FSM_IDLE : n_fsm_state = uart_tx_en ? FSM_START: FSM_IDLE ; 101 | FSM_START: n_fsm_state = next_bit ? FSM_SEND : FSM_START; 102 | FSM_SEND : n_fsm_state = payload_done ? FSM_STOP : FSM_SEND ; 103 | FSM_STOP : n_fsm_state = stop_done ? FSM_IDLE : FSM_STOP ; 104 | default : n_fsm_state = FSM_IDLE; 105 | endcase 106 | end 107 | 108 | // --------------------------------------------------------------------------- 109 | // Internal register setting and re-setting. 110 | // 111 | 112 | // 113 | // Handle updates to the sent data register. 114 | integer i = 0; 115 | always @(posedge clk) begin : p_data_to_send 116 | if(!resetn) begin 117 | data_to_send <= {PAYLOAD_BITS{1'b0}}; 118 | end else if(fsm_state == FSM_IDLE && uart_tx_en) begin 119 | data_to_send <= uart_tx_data; 120 | end else if(fsm_state == FSM_SEND && next_bit ) begin 121 | for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin 122 | data_to_send[i] <= data_to_send[i+1]; 123 | end 124 | end 125 | end 126 | 127 | 128 | // 129 | // Increments the bit counter each time a new bit frame is sent. 130 | always @(posedge clk) begin : p_bit_counter 131 | if(!resetn) begin 132 | bit_counter <= 4'b0; 133 | end else if(fsm_state != FSM_SEND && fsm_state != FSM_STOP) begin 134 | bit_counter <= {COUNT_REG_LEN{1'b0}}; 135 | end else if(fsm_state == FSM_SEND && n_fsm_state == FSM_STOP) begin 136 | bit_counter <= {COUNT_REG_LEN{1'b0}}; 137 | end else if(fsm_state == FSM_STOP&& next_bit) begin 138 | bit_counter <= bit_counter + 1'b1; 139 | end else if(fsm_state == FSM_SEND && next_bit) begin 140 | bit_counter <= bit_counter + 1'b1; 141 | end 142 | end 143 | 144 | 145 | // 146 | // Increments the cycle counter when sending. 147 | always @(posedge clk) begin : p_cycle_counter 148 | if(!resetn) begin 149 | cycle_counter <= {COUNT_REG_LEN{1'b0}}; 150 | end else if(next_bit) begin 151 | cycle_counter <= {COUNT_REG_LEN{1'b0}}; 152 | end else if(fsm_state == FSM_START || 153 | fsm_state == FSM_SEND || 154 | fsm_state == FSM_STOP ) begin 155 | cycle_counter <= cycle_counter + 1'b1; 156 | end 157 | end 158 | 159 | 160 | // 161 | // Progresses the next FSM state. 162 | always @(posedge clk) begin : p_fsm_state 163 | if(!resetn) begin 164 | fsm_state <= FSM_IDLE; 165 | end else begin 166 | fsm_state <= n_fsm_state; 167 | end 168 | end 169 | 170 | 171 | // 172 | // Responsible for updating the internal value of the txd_reg. 173 | always @(posedge clk) begin : p_txd_reg 174 | if(!resetn) begin 175 | txd_reg <= 1'b1; 176 | end else if(fsm_state == FSM_IDLE) begin 177 | txd_reg <= 1'b1; 178 | end else if(fsm_state == FSM_START) begin 179 | txd_reg <= 1'b0; 180 | end else if(fsm_state == FSM_SEND) begin 181 | txd_reg <= data_to_send[0]; 182 | end else if(fsm_state == FSM_STOP) begin 183 | txd_reg <= 1'b1; 184 | end 185 | end 186 | 187 | endmodule 188 | -------------------------------------------------------------------------------- /formal/ddr3_multiconfig_default.sby: -------------------------------------------------------------------------------- 1 | [tasks] 2 | prf2lanes_83MHz prf opt_2lanes opt_83MHz opt_with_ODELAY 3 | prf4lanes_83MHz prf opt_4lanes opt_83MHz opt_with_ODELAY 4 | prf8lanes_83MHz prf opt_8lanes opt_83MHz opt_with_ODELAY opt_WB_ERR 5 | prf2lanes_100MHz prf opt_2lanes opt_100MHz opt_with_ODELAY opt_WB_ERR 6 | prf4lanes_100MHz prf opt_4lanes opt_100MHz opt_with_ODELAY 7 | prf8lanes_100MHz prf opt_8lanes opt_100MHz opt_with_ODELAY 8 | prf_no_ODELAY prf opt_8lanes opt_100MHz 9 | 10 | [options] 11 | prf: mode prove 12 | prf: depth 7 13 | 14 | [engines] 15 | prf: smtbmc 16 | 17 | [script] 18 | read -formal ddr3_controller.v 19 | read -formal fwb_slave.v 20 | 21 | --pycode-begin-- 22 | 23 | # Number of Lanes 24 | if "opt_2lanes" in tags: 25 | cmd = "chparam -set LANES 2 ddr3_controller\n" 26 | elif "opt_4lanes" in tags: 27 | cmd = "chparam -set LANES 4 ddr3_controller\n" 28 | elif "opt_8lanes" in tags: 29 | cmd = "chparam -set LANES 8 ddr3_controller\n" 30 | else: 31 | cmd = "chparam -set LANES 8 ddr3_controller\n" 32 | 33 | # Clock period 34 | if "opt_83MHz" in tags: 35 | cmd += "chparam -set CONTROLLER_CLK_PERIOD 12000 ddr3_controller\n" 36 | cmd += "chparam -set DDR3_CLK_PERIOD 3000 ddr3_controller\n" 37 | elif "opt_100MHz" in tags: 38 | cmd += "chparam -set CONTROLLER_CLK_PERIOD 10000 ddr3_controller\n" 39 | cmd += "chparam -set DDR3_CLK_PERIOD 2500 ddr3_controller\n" 40 | else: 41 | cmd += "chparam -set CONTROLLER_CLK_PERIOD 10000 ddr3_controller\n" 42 | cmd += "chparam -set DDR3_CLK_PERIOD 2500 ddr3_controller\n" 43 | 44 | # ODELAY support 45 | if "opt_with_ODELAY" in tags: 46 | cmd += "chparam -set ODELAY_SUPPORTED 1 ddr3_controller\n" 47 | else: 48 | cmd += "chparam -set ODELAY_SUPPORTED 0 ddr3_controller\n" 49 | 50 | # Wishbone Error 51 | if "opt_WB_ERR" in tags: 52 | cmd += "chparam -set WB_ERROR 1 ddr3_controller\n" 53 | else: 54 | cmd += "chparam -set WB_ERROR 0 ddr3_controller\n" 55 | 56 | output(cmd) 57 | --pycode-end-- 58 | 59 | prep -top ddr3_controller 60 | 61 | [files] 62 | ./rtl/ddr3_controller.v 63 | ./formal/fwb_slave.v 64 | 65 | -------------------------------------------------------------------------------- /formal/ddr3_multiconfig_ecc.sby: -------------------------------------------------------------------------------- 1 | [tasks] 2 | prf2lanes_83MHz_ECC_1 prf opt_2lanes opt_83MHz opt_with_ODELAY opt_ECC_1 3 | prf8lanes_100MHz_ECC_1 prf opt_8lanes opt_100MHz opt_ECC_1 4 | prf8lanes_100MHz_ECC_1_err prf opt_8lanes opt_100MHz opt_with_ODELAY opt_ECC_1 opt_WB_ERR 5 | 6 | prf2lanes_83MHz_ECC_2_err prf opt_2lanes opt_83MHz opt_with_ODELAY opt_ECC_2 opt_WB_ERR 7 | 8 | prf2lanes_83MHz_ECC_3 prf_ECC3 opt_2lanes opt_100MHz opt_with_ODELAY opt_ECC_3 9 | prf8lanes_100MHz_ECC_3 prf_ECC3 opt_8lanes opt_83MHz opt_ECC_3 10 | prf8lanes_100MHz_ECC_3_err prf_ECC3 opt_8lanes opt_100MHz opt_ECC_3 opt_WB_ERR 11 | 12 | [options] 13 | prf: mode prove 14 | prf: depth 7 15 | prf_ECC3: mode prove 16 | prf_ECC3: depth 7 17 | 18 | [engines] 19 | prf: smtbmc 20 | prf_ECC3: smtbmc 21 | 22 | [script] 23 | read -formal ddr3_controller.v 24 | read -formal fwb_slave.v 25 | read -formal ecc_dec.sv 26 | read -formal ecc_enc.sv 27 | 28 | --pycode-begin-- 29 | 30 | # Number of Lanes 31 | if "opt_2lanes" in tags: 32 | cmd = "chparam -set LANES 2 ddr3_controller\n" 33 | elif "opt_4lanes" in tags: 34 | cmd = "chparam -set LANES 4 ddr3_controller\n" 35 | elif "opt_8lanes" in tags: 36 | cmd = "chparam -set LANES 8 ddr3_controller\n" 37 | else: 38 | cmd = "chparam -set LANES 8 ddr3_controller\n" 39 | 40 | # Clock period 41 | if "opt_83MHz" in tags: 42 | cmd += "chparam -set CONTROLLER_CLK_PERIOD 12000 ddr3_controller\n" 43 | cmd += "chparam -set DDR3_CLK_PERIOD 3000 ddr3_controller\n" 44 | elif "opt_100MHz" in tags: 45 | cmd += "chparam -set CONTROLLER_CLK_PERIOD 10000 ddr3_controller\n" 46 | cmd += "chparam -set DDR3_CLK_PERIOD 2500 ddr3_controller\n" 47 | else: 48 | cmd += "chparam -set CONTROLLER_CLK_PERIOD 10000 ddr3_controller\n" 49 | cmd += "chparam -set DDR3_CLK_PERIOD 2500 ddr3_controller\n" 50 | 51 | # ODELAY support 52 | if "opt_with_ODELAY" in tags: 53 | cmd += "chparam -set ODELAY_SUPPORTED 1 ddr3_controller\n" 54 | else: 55 | cmd += "chparam -set ODELAY_SUPPORTED 0 ddr3_controller\n" 56 | 57 | # ECC 58 | if "opt_ECC_3" in tags: 59 | cmd += "chparam -set ECC_ENABLE 3 ddr3_controller\n" 60 | elif "opt_ECC_2" in tags: 61 | cmd += "chparam -set ECC_ENABLE 2 ddr3_controller\n" 62 | elif "opt_ECC_1" in tags: 63 | cmd += "chparam -set ECC_ENABLE 1 ddr3_controller\n" 64 | else: 65 | cmd += "chparam -set ECC_ENABLE 0 ddr3_controller\n" 66 | 67 | # Wishbone Error 68 | if "opt_WB_ERR" in tags: 69 | cmd += "chparam -set WB_ERROR 1 ddr3_controller\n" 70 | else: 71 | cmd += "chparam -set WB_ERROR 0 ddr3_controller\n" 72 | 73 | output(cmd) 74 | --pycode-end-- 75 | 76 | prep -top ddr3_controller 77 | 78 | [files] 79 | ./rtl/ddr3_controller.v 80 | ./formal/fwb_slave.v 81 | ./rtl/ecc/ecc_dec.sv 82 | ./rtl/ecc/ecc_enc.sv 83 | 84 | -------------------------------------------------------------------------------- /formal/ddr3_singleconfig.sby: -------------------------------------------------------------------------------- 1 | [options] 2 | mode prove 3 | depth 7 # minimum for 100MHz controller clk 4 | #mode cover 5 | #depth 50 6 | 7 | [engines] 8 | smtbmc 9 | 10 | [script] 11 | read -formal ddr3_controller.v 12 | read -formal fwb_slave.v 13 | read -formal ecc_dec.sv 14 | read -formal ecc_enc.sv 15 | prep -top ddr3_controller 16 | 17 | 18 | [files] 19 | ./rtl/ddr3_controller.v 20 | ./formal/fwb_slave.v 21 | ./rtl/ecc/ecc_dec.sv 22 | ./rtl/ecc/ecc_enc.sv 23 | -------------------------------------------------------------------------------- /formal/ecc.sby: -------------------------------------------------------------------------------- 1 | [options] 2 | mode prove 3 | depth 1 4 | #mode cover 5 | #depth 50 6 | 7 | [engines] 8 | smtbmc 9 | 10 | [script] 11 | read -formal ecc_formal.v 12 | read -formal ecc_dec.sv 13 | read -formal ecc_enc.sv 14 | prep -top ecc_formal 15 | 16 | 17 | [files] 18 | ./formal/ecc_formal.v 19 | ./rtl/ecc/ecc_dec.sv 20 | ./rtl/ecc/ecc_enc.sv 21 | -------------------------------------------------------------------------------- /formal/ecc_formal.v: -------------------------------------------------------------------------------- 1 | module ecc_formal; 2 | parameter K = 8, 3 | P0_LSB = 0; 4 | 5 | // function to find number of check bits 6 | function integer calculate_m; 7 | input integer k; 8 | integer m; 9 | begin 10 | m=1; 11 | while (2**m < m+k+1) m=m+1; 12 | calculate_m = m; 13 | end 14 | endfunction 15 | 16 | // anyseq indicates nets that are controllable by engine 17 | (*anyseq*)wire[K-1:0] d_i; // information input 18 | (*anyseq*) wire[1:0] corrupted; // 0 or 3 = not corrupted bit, 1 = 1 corrupted bit, 2 = 2 corrupted bits 19 | (*anyseq*) wire[$clog2(K+calculate_m(K))-1:0] corrupted_bit1, corrupted_bit2; // which bit will be corrupted 20 | 21 | wire[K-1:0] q_o_dec; 22 | wire[K+calculate_m(K):0] q_o_enc; 23 | reg[K+calculate_m(K):0] q_o_enc_corrupted; 24 | wire sb_err_o; 25 | wire db_err_o; 26 | 27 | ecc_enc #( 28 | .K(K), //Information bit vector size 29 | .P0_LSB(P0_LSB) //0: p0 is located at MSB 30 | //1: p0 is located at LSB 31 | ) ecc_enc_inst ( 32 | .d_i(d_i), //information bit vector input 33 | .q_o(q_o_enc), //encoded data word output 34 | .p_o(), //parity vector output 35 | .p0_o() //extended parity bit 36 | ); 37 | 38 | ecc_dec #( 39 | .K(K), //Information bit vector size 40 | .LATENCY(0), //0: no latency (combinatorial design) 41 | //1: registered outputs 42 | //2: registered inputs+outputs 43 | .P0_LSB(P0_LSB) //0: p0 is located at MSB 44 | //1: p0 is located at LSB 45 | ) ecc_dec_inst ( 46 | //clock/reset ports (if LATENCY > 0) 47 | .rst_ni(1'b1), //asynchronous reset 48 | .clk_i(1'b0), //clock input 49 | .clkena_i(1'b0), //clock enable input 50 | //data ports 51 | .d_i(q_o_enc_corrupted), //encoded code word input 52 | .q_o(q_o_dec), //information bit vector output 53 | .syndrome_o(), //syndrome vector output 54 | //flags 55 | .sb_err_o(sb_err_o), //single bit error detected 56 | .db_err_o(db_err_o), //double bit error detected 57 | .sb_fix_o() //repaired error in the information bits 58 | ); 59 | 60 | `ifdef FORMAL 61 | (*gclk*) reg f_clk = 0; // reference: https://symbiyosys.readthedocs.io/en/latest/verilog.html#global-clock 62 | reg[9:0] f_counter = 0; 63 | 64 | // corrupt the information based on the value of "corrupted" which is controllable by formal engine: 65 | // 0 = no corrupted bits , 1 = 1 corrupted bit, 2 = 2 corrupted bits, 3 = no corrupted bits 66 | always @* begin 67 | q_o_enc_corrupted = q_o_enc; 68 | if(corrupted == 1) begin 69 | q_o_enc_corrupted[corrupted_bit1] = !q_o_enc_corrupted[corrupted_bit1]; //corrupt 1 random bit 70 | assume(corrupted_bit1 != (K+calculate_m(K))); // 71 | end 72 | else if (corrupted == 2) begin // flip 2 bits 73 | q_o_enc_corrupted[corrupted_bit1] = !q_o_enc_corrupted[corrupted_bit1]; //corrupt 2 random bits 74 | q_o_enc_corrupted[corrupted_bit2] = !q_o_enc_corrupted[corrupted_bit2]; 75 | end 76 | assume(corrupted_bit1 != corrupted_bit2); // corrupted bit should be different (in case of 2 corrupted bits) 77 | assume(corrupted_bit1 <= (K+calculate_m(K))); // corrupted bit should be within the index of q_o_enc_corrupted 78 | assume(corrupted_bit2 <= (K+calculate_m(K))); // corrupted bit should be within the index of q_o_enc_corrupted 79 | end 80 | 81 | // main contract of this design 82 | always @* begin 83 | // if no corrupted bits, then decoded info must be equal to original info, and error flags should be low 84 | // OR there is 1 corrupted bit but its the MSB p0 that is corrupted 85 | if( (corrupted == 0 || corrupted == 3) || ( (corrupted == 1) && (corrupted_bit1 == (K+calculate_m(K))) ) ) begin 86 | assert(d_i == q_o_dec); 87 | assert(!sb_err_o); 88 | assert(!db_err_o); 89 | end 90 | // if 1 corrupted bit, then decoded info must still be equal to original info, single-bit error flag must be high, double-bit error flag must be low 91 | else if(corrupted == 1) begin 92 | assert(d_i == q_o_dec); 93 | assert(sb_err_o); 94 | assert(!db_err_o); 95 | end 96 | // if 2 corrupted bits, then single-bit error flag must be low, double-bit error flag must be high 97 | else if(corrupted == 2) begin 98 | assert(!sb_err_o); 99 | assert(db_err_o); 100 | end 101 | end 102 | 103 | // cover 10 cycles 104 | always @(posedge f_clk) begin 105 | f_counter <= f_counter + 1; 106 | assume(corrupted == f_counter[1:0]); // number of corrupted bits change per clock cycle 107 | cover((f_counter == 10)); 108 | end 109 | 110 | // simulate random information 111 | always @(posedge f_clk) begin 112 | assume(d_i != $past(d_i,1)); 113 | assume(d_i != $past(d_i,2)); 114 | assume(d_i != $past(d_i,3)); 115 | assume(d_i != $past(d_i,4)); 116 | assume(d_i != $past(d_i,5)); 117 | assume(d_i != $past(d_i,6)); 118 | assume(d_i != $past(d_i,7)); 119 | assume(d_i != $past(d_i,8)); 120 | assume(d_i != $past(d_i,9)); 121 | assume(d_i != $past(d_i,10)); 122 | end 123 | 124 | `endif 125 | endmodule -------------------------------------------------------------------------------- /rtl/ecp5_phy/oserdes_soft.v: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | `timescale 1ps / 1ps 3 | 4 | module oserdes_soft #(parameter LATTICE_ECP5 = 1) ( 5 | input wire CLK, // High-speed clock (data sampling clock) 6 | input wire CLKDIV, // Divided clock (must be synchronous to CLK, typically CLK/4 for DDR) 7 | input wire RST, // Active high reset 8 | input wire D1, // First data bit 9 | input wire D2, // Second data bit 10 | input wire D3, // Third data bit 11 | input wire D4, // Fourth data bit 12 | input wire D5, // Fifth data bit 13 | input wire D6, // Sixth data bit 14 | input wire D7, // Seventh data bit 15 | input wire D8, // Eighth data bit 16 | output wire OQ // Serialized output data 17 | ); 18 | 19 | // Reset signal synchronized to CLKDIV domain 20 | reg reset_clk_div = 1'b1; 21 | reg[1:0] counter_clk = 2'd0; // 2-bit counter to track which data pair to output 22 | reg[1:0] oq_pair = 2'd0; // 2-bit register to hold serialized data output 23 | 24 | // Synchronize reset signal to CLKDIV domain 25 | always @(posedge CLKDIV) begin 26 | if (RST) begin 27 | reset_clk_div <= 1'b1; 28 | end else begin 29 | reset_clk_div <= 1'b0; 30 | end 31 | end 32 | 33 | // 2-bit counter increments on each CLK cycle to select the correct data pair 34 | always @(posedge CLK) begin 35 | if (reset_clk_div) begin 36 | counter_clk <= 2'd0; // Reset counter when reset is active 37 | end else begin 38 | counter_clk <= counter_clk + 2'd1; // Increment counter every clock cycle 39 | end 40 | end 41 | 42 | // Multiplexer logic: Selects two bits at a time from the 8-bit input data 43 | always @(posedge CLK) begin 44 | case (counter_clk) 45 | 2'd0: oq_pair <= {D2, D1}; // First 2 bits 46 | 2'd1: oq_pair <= {D4, D3}; // Second 2 bits 47 | 2'd2: oq_pair <= {D6, D5}; // Third 2 bits 48 | 2'd3: oq_pair <= {D8, D7}; // Fourth 2 bits 49 | endcase 50 | end 51 | 52 | generate 53 | if(LATTICE_ECP5) begin 54 | // Instantiating ODDRX1F primitive for DDR output data serialization 55 | ODDRX1F ODDRX1F_inst ( 56 | .SCLK(CLK), // High-speed clock 57 | .RST(reset_clk_div), // Reset signal synchronized to CLKDIV 58 | .D0(oq_pair[0]), // First bit of selected pair 59 | .D1(oq_pair[1]), // Second bit of selected pair 60 | .Q(OQ) // Serialized DDR output 61 | ); 62 | end 63 | else begin // XILINX 64 | ODDR 65 | #(.DDR_CLK_EDGE("SAME_EDGE")) ODDR_inst 66 | ( 67 | .C(CLK), // High-speed clock 68 | .R(reset_clk_div), // Reset signal synchronized to CLKDIV 69 | .S(1'b0), // Set 70 | .CE(1'b1), 71 | .D1(oq_pair[0]), // First bit of selected pair 72 | .D2(oq_pair[1]), // Second bit of selected pair 73 | .Q(OQ) // Serialized DDR output 74 | ); 75 | end 76 | endgenerate 77 | 78 | endmodule 79 | -------------------------------------------------------------------------------- /rtl/spd/spd_clk_wiz.v: -------------------------------------------------------------------------------- 1 | `timescale 1ps/1ps 2 | 3 | module clk_wiz 4 | ( 5 | input clk_in1, 6 | output clk_out1, 7 | input reset, 8 | output locked 9 | ); 10 | wire clk_out1_clk_wiz_0; 11 | 12 | 13 | wire clkfbout; 14 | 15 | PLLE2_ADV 16 | #(.BANDWIDTH ("OPTIMIZED"), 17 | .COMPENSATION ("INTERNAL"), 18 | .STARTUP_WAIT ("FALSE"), 19 | .DIVCLK_DIVIDE (1), 20 | .CLKFBOUT_MULT (5), // 200 MHz * 5 = 1000 MHz 21 | .CLKFBOUT_PHASE (0.000), 22 | .CLKOUT0_DIVIDE (10), // 1000 MHz / 10 = 100 MHz 23 | .CLKOUT0_PHASE (0.000), 24 | .CLKOUT0_DUTY_CYCLE (0.500), 25 | .CLKIN1_PERIOD (5.000) // 200 MHz input 26 | ) 27 | plle2_adv_inst 28 | ( 29 | .CLKFBOUT (clkfbout), 30 | .CLKOUT0 (clk_out1_clk_wiz_0), 31 | .CLKFBIN (clkfbout), 32 | .CLKIN1 (clk_in1), 33 | .LOCKED (locked), 34 | .RST (reset) 35 | ); 36 | BUFG clkout1_buf 37 | (.O (clk_out1), 38 | .I (clk_out1_clk_wiz_0)); 39 | endmodule 40 | -------------------------------------------------------------------------------- /rtl/spd/spd_reader_top.v: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Filename: spd_reader_top.v 4 | // Project: Top-level file for SPD reader (intended for AX7325B FPGA board) 5 | // 6 | // Engineer: Angelo C. Jacobo 7 | // 8 | //////////////////////////////////////////////////////////////////////////////// 9 | // 10 | // Copyright (C) 2023-2025 Angelo Jacobo 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //////////////////////////////////////////////////////////////////////////////// 26 | 27 | `default_nettype none 28 | `timescale 1ns / 1ps 29 | 30 | module spd_reader_top ( 31 | // clock and reset 32 | input wire sys_clk_p, 33 | input wire sys_clk_n, 34 | input wire i_rst_n, 35 | // i2c interface 36 | inout wire i2c_scl, 37 | inout wire i2c_sda, 38 | // uart tx interface 39 | output wire uart_tx, 40 | // fan 41 | output wire fan_pwm, 42 | //Debug LEDs 43 | output wire[3:0] led 44 | ); 45 | 46 | wire clk_locked; 47 | wire main_clk_100; 48 | wire find_i2c_address_done, read_spd_done; 49 | 50 | assign fan_pwm = 1'b0; // turn on fan from the start 51 | assign led[0] = find_i2c_address_done; // lights up once done 52 | assign led[1] = find_i2c_address_done; 53 | assign led[2] = read_spd_done; 54 | assign led[3] = read_spd_done; 55 | 56 | //=========================================================================== 57 | //Differentia system clock to single end clock 58 | //=========================================================================== 59 | wire sys_clk; // 200MHz 60 | IBUFGDS u_ibufg_sys_clk 61 | ( 62 | .I (sys_clk_p), 63 | .IB (sys_clk_n), 64 | .O (sys_clk) 65 | ); 66 | 67 | //=========================================================================== 68 | // Generate 100MHz 69 | //=========================================================================== 70 | clk_wiz clk_wiz_inst 71 | ( 72 | // Clock out ports 73 | .clk_out1(main_clk_100), 74 | // Status and control signals 75 | .reset(!i_rst_n), 76 | .locked(clk_locked), 77 | // Clock in ports 78 | .clk_in1(sys_clk) 79 | ); 80 | 81 | //=========================================================================== 82 | // Instantiate SPD reader 83 | //=========================================================================== 84 | spd_reader spd_reader_inst ( 85 | .i_clk(main_clk_100), 86 | .i_rst_n(i_rst_n && clk_locked), 87 | .i2c_scl(i2c_scl), 88 | .i2c_sda(i2c_sda), 89 | .uart_tx(uart_tx), 90 | .find_i2c_address_done(find_i2c_address_done), 91 | .read_spd_done(read_spd_done) 92 | ); 93 | 94 | 95 | endmodule 96 | 97 | 98 | -------------------------------------------------------------------------------- /rtl/spd/uart_tx.v: -------------------------------------------------------------------------------- 1 | 2 | 3 | // 4 | // Module: uart_tx 5 | // 6 | // Notes: 7 | // - UART transmitter module. 8 | // 9 | 10 | module uart_tx( 11 | input wire clk , // Top level system clock input. 12 | input wire resetn , // Asynchronous active low reset. 13 | output wire uart_txd , // UART transmit pin. 14 | output wire uart_tx_busy, // Module busy sending previous item. 15 | input wire uart_tx_en , // Send the data on uart_tx_data 16 | input wire [PAYLOAD_BITS-1:0] uart_tx_data // The data to be sent 17 | ); 18 | 19 | // --------------------------------------------------------------------------- 20 | // External parameters. 21 | // 22 | 23 | // 24 | // Input bit rate of the UART line. 25 | parameter BIT_RATE = 9600; // bits / sec 26 | localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds 27 | 28 | // 29 | // Clock frequency in hertz. 30 | parameter CLK_HZ = 50_000_000; 31 | localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds 32 | 33 | // 34 | // Number of data bits recieved per UART packet. 35 | parameter PAYLOAD_BITS = 8; 36 | 37 | // 38 | // Number of stop bits indicating the end of a packet. 39 | parameter STOP_BITS = 1; 40 | 41 | // --------------------------------------------------------------------------- 42 | // Internal parameters. 43 | // 44 | 45 | // 46 | // Number of clock cycles per uart bit. 47 | localparam CYCLES_PER_BIT = BIT_P / CLK_P; 48 | 49 | // 50 | // Size of the registers which store sample counts and bit durations. 51 | localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT); 52 | 53 | // --------------------------------------------------------------------------- 54 | // Internal registers. 55 | // 56 | 57 | // 58 | // Internally latched value of the uart_txd line. Helps break long timing 59 | // paths from the logic to the output pins. 60 | reg txd_reg; 61 | 62 | // 63 | // Storage for the serial data to be sent. 64 | reg [PAYLOAD_BITS-1:0] data_to_send; 65 | 66 | // 67 | // Counter for the number of cycles over a packet bit. 68 | reg [COUNT_REG_LEN-1:0] cycle_counter; 69 | 70 | // 71 | // Counter for the number of sent bits of the packet. 72 | reg [3:0] bit_counter; 73 | 74 | // 75 | // Current and next states of the internal FSM. 76 | reg [2:0] fsm_state; 77 | reg [2:0] n_fsm_state; 78 | 79 | localparam FSM_IDLE = 0; 80 | localparam FSM_START= 1; 81 | localparam FSM_SEND = 2; 82 | localparam FSM_STOP = 3; 83 | 84 | 85 | // --------------------------------------------------------------------------- 86 | // FSM next state selection. 87 | // 88 | 89 | assign uart_tx_busy = fsm_state != FSM_IDLE; 90 | assign uart_txd = txd_reg; 91 | 92 | wire next_bit = cycle_counter == CYCLES_PER_BIT; 93 | wire payload_done = bit_counter == PAYLOAD_BITS ; 94 | wire stop_done = bit_counter == STOP_BITS && fsm_state == FSM_STOP; 95 | 96 | // 97 | // Handle picking the next state. 98 | always @(*) begin : p_n_fsm_state 99 | case(fsm_state) 100 | FSM_IDLE : n_fsm_state = uart_tx_en ? FSM_START: FSM_IDLE ; 101 | FSM_START: n_fsm_state = next_bit ? FSM_SEND : FSM_START; 102 | FSM_SEND : n_fsm_state = payload_done ? FSM_STOP : FSM_SEND ; 103 | FSM_STOP : n_fsm_state = stop_done ? FSM_IDLE : FSM_STOP ; 104 | default : n_fsm_state = FSM_IDLE; 105 | endcase 106 | end 107 | 108 | // --------------------------------------------------------------------------- 109 | // Internal register setting and re-setting. 110 | // 111 | 112 | // 113 | // Handle updates to the sent data register. 114 | integer i = 0; 115 | always @(posedge clk) begin : p_data_to_send 116 | if(!resetn) begin 117 | data_to_send <= {PAYLOAD_BITS{1'b0}}; 118 | end else if(fsm_state == FSM_IDLE && uart_tx_en) begin 119 | data_to_send <= uart_tx_data; 120 | end else if(fsm_state == FSM_SEND && next_bit ) begin 121 | for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin 122 | data_to_send[i] <= data_to_send[i+1]; 123 | end 124 | end 125 | end 126 | 127 | 128 | // 129 | // Increments the bit counter each time a new bit frame is sent. 130 | always @(posedge clk) begin : p_bit_counter 131 | if(!resetn) begin 132 | bit_counter <= 4'b0; 133 | end else if(fsm_state != FSM_SEND && fsm_state != FSM_STOP) begin 134 | bit_counter <= {COUNT_REG_LEN{1'b0}}; 135 | end else if(fsm_state == FSM_SEND && n_fsm_state == FSM_STOP) begin 136 | bit_counter <= {COUNT_REG_LEN{1'b0}}; 137 | end else if(fsm_state == FSM_STOP&& next_bit) begin 138 | bit_counter <= bit_counter + 1'b1; 139 | end else if(fsm_state == FSM_SEND && next_bit) begin 140 | bit_counter <= bit_counter + 1'b1; 141 | end 142 | end 143 | 144 | 145 | // 146 | // Increments the cycle counter when sending. 147 | always @(posedge clk) begin : p_cycle_counter 148 | if(!resetn) begin 149 | cycle_counter <= {COUNT_REG_LEN{1'b0}}; 150 | end else if(next_bit) begin 151 | cycle_counter <= {COUNT_REG_LEN{1'b0}}; 152 | end else if(fsm_state == FSM_START || 153 | fsm_state == FSM_SEND || 154 | fsm_state == FSM_STOP ) begin 155 | cycle_counter <= cycle_counter + 1'b1; 156 | end 157 | end 158 | 159 | 160 | // 161 | // Progresses the next FSM state. 162 | always @(posedge clk) begin : p_fsm_state 163 | if(!resetn) begin 164 | fsm_state <= FSM_IDLE; 165 | end else begin 166 | fsm_state <= n_fsm_state; 167 | end 168 | end 169 | 170 | 171 | // 172 | // Responsible for updating the internal value of the txd_reg. 173 | always @(posedge clk) begin : p_txd_reg 174 | if(!resetn) begin 175 | txd_reg <= 1'b1; 176 | end else if(fsm_state == FSM_IDLE) begin 177 | txd_reg <= 1'b1; 178 | end else if(fsm_state == FSM_START) begin 179 | txd_reg <= 1'b0; 180 | end else if(fsm_state == FSM_SEND) begin 181 | txd_reg <= data_to_send[0]; 182 | end else if(fsm_state == FSM_STOP) begin 183 | txd_reg <= 1'b1; 184 | end 185 | end 186 | 187 | endmodule 188 | -------------------------------------------------------------------------------- /run_compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Function to run Verilator lint 4 | run_lint() { 5 | echo -e "\e[32mRun Verilator Lint:\e[0m" 6 | verilator --lint-only rtl/ddr3_controller.v rtl/ecc/ecc_dec.sv rtl/ecc/ecc_enc.sv -Irtl/ -Wall 7 | echo "DONE!" 8 | } 9 | 10 | # If the script is called with "lint", run only linting and exit 11 | if [[ "$1" == "lint" ]]; then 12 | run_lint 13 | exit 0 14 | fi 15 | 16 | # Clean files 17 | rm -rf formal/ddr3*prf* 18 | rm -rf formal/ddr3_singleconfig 19 | 20 | # Run Verilator lint 21 | run_lint 22 | 23 | # run yosys compile 24 | echo "" 25 | echo "" 26 | echo -e "\e[32mRun Yosys Compile:\e[0m" 27 | yosys -q -p " 28 | read_verilog -sv ./rtl/ddr3_controller.v rtl/ecc/ecc_dec.sv rtl/ecc/ecc_enc.sv; 29 | synth -top ddr3_controller" 30 | 31 | # run iverilog compile 32 | echo "" 33 | echo "" 34 | echo -e "\e[32mRun IVerilog Compile:\e[0m" 35 | iverilog rtl/ddr3_controller.v -o out 36 | vvp out 37 | rm out 38 | echo 39 | 40 | # run symbiyosys 41 | echo "" 42 | echo -e "\e[32mRun Symbiyosys Formal Verification: ECC\e[0m" 43 | echo "---------------------------------------" 44 | sby -f formal/ecc.sby 45 | 46 | echo "" 47 | echo -e "\e[32mRun Symbiyosys Formal Verification: Single Configuration\e[0m" 48 | echo "---------------------------------------" 49 | sby -f formal/ddr3_singleconfig.sby 50 | 51 | echo "" 52 | echo -e "\e[32mRun Symbiyosys Formal Verification: Multiple Configurations (DEFAULT)\e[0m" 53 | echo "---------------------------------------" 54 | sby -f formal/ddr3_multiconfig_default.sby 55 | 56 | echo "" 57 | echo -e "\e[32mRun Symbiyosys Formal Verification: Multiple Configurations (ECC)\e[0m" 58 | echo "---------------------------------------" 59 | sby -f formal/ddr3_multiconfig_ecc.sby 60 | 61 | 62 | # ANSI color codes 63 | RED='\033[0;31m' 64 | GREEN='\033[0;32m' 65 | NC='\033[0m' # No Color 66 | 67 | echo "" 68 | echo "" 69 | echo "Summary:" 70 | 71 | # Excluded folders 72 | excluded_folders=("formal/ddr3_multiconfig_default/" "formal/ddr3_multiconfig_ecc/") 73 | 74 | # Iterate over folders starting with 'ddr3*' 75 | for folder in formal/ddr3*/ ; do 76 | # Skip excluded folders 77 | [[ " ${excluded_folders[*]} " =~ " ${folder} " ]] && continue 78 | 79 | # Check for 'PASS' file 80 | if [[ -e "${folder}PASS" ]]; then 81 | echo -e "${folder}: ${GREEN}PASS${NC}" 82 | else 83 | echo -e "${folder}: ${RED}FAIL${NC}" 84 | fi 85 | done 86 | 87 | # Iterate over folders inside 'ecc/' 88 | for folder in formal/ecc/ ; do 89 | [[ " ${excluded_folders[*]} " =~ " ${folder} " ]] && continue 90 | 91 | if [[ -e "${folder}PASS" ]]; then 92 | echo -e "${folder}: ${GREEN}PASS${NC}" 93 | else 94 | echo -e "${folder}: ${RED}FAIL${NC}" 95 | fi 96 | done 97 | -------------------------------------------------------------------------------- /testbench/README.txt: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Vivado (TM) v2022.1 (64-bit) 3 | # 4 | # README.txt: Please read the sections below to understand the steps required 5 | # to simulate the design for a simulator, the directory structure 6 | # and the generated exported files. 7 | # 8 | ################################################################################ 9 | 10 | 1. Simulate Design 11 | 12 | To simulate design, cd to the simulator directory and execute the script. 13 | 14 | For example:- 15 | 16 | % cd questa 17 | % ./top.sh 18 | 19 | The export simulation flow requires the Xilinx pre-compiled simulation library 20 | components for the target simulator. These components are referred using the 21 | '-lib_map_path' switch. If this switch is specified, then the export simulation 22 | will automatically set this library path in the generated script and update, 23 | copy the simulator setup file(s) in the exported directory. 24 | 25 | If '-lib_map_path' is not specified, then the pre-compiled simulation library 26 | information will not be included in the exported scripts and that may cause 27 | simulation errors when running this script. Alternatively, you can provide the 28 | library information using this switch while executing the generated script. 29 | 30 | For example:- 31 | 32 | % ./top.sh -lib_map_path /design/questa/clibs 33 | 34 | Please refer to the generated script header 'Prerequisite' section for more details. 35 | 36 | 2. Directory Structure 37 | 38 | By default, if the -directory switch is not specified, export_simulation will 39 | create the following directory structure:- 40 | 41 | /export_sim/ 42 | 43 | For example, if the current working directory is /tmp/test, export_simulation 44 | will create the following directory path:- 45 | 46 | /tmp/test/export_sim/questa 47 | 48 | If -directory switch is specified, export_simulation will create a simulator 49 | sub-directory under the specified directory path. 50 | 51 | For example, 'export_simulation -directory /tmp/test/my_test_area/func_sim' 52 | command will create the following directory:- 53 | 54 | /tmp/test/my_test_area/func_sim/questa 55 | 56 | By default, if -simulator is not specified, export_simulation will create a 57 | simulator sub-directory for each simulator and export the files for each simulator 58 | in this sub-directory respectively. 59 | 60 | IMPORTANT: Please note that the simulation library path must be specified manually 61 | in the generated script for the respective simulator. Please refer to the generated 62 | script header 'Prerequisite' section for more details. 63 | 64 | 3. Exported script and files 65 | 66 | Export simulation will create the driver shell script, setup files and copy the 67 | design sources in the output directory path. 68 | 69 | By default, when the -script_name switch is not specified, export_simulation will 70 | create the following script name:- 71 | 72 | .sh (Unix) 73 | When exporting the files for an IP using the -of_objects switch, export_simulation 74 | will create the following script name:- 75 | 76 | .sh (Unix) 77 | Export simulation will create the setup files for the target simulator specified 78 | with the -simulator switch. 79 | 80 | For example, if the target simulator is "xcelium", export_simulation will create the 81 | 'cds.lib', 'hdl.var' and design library diectories and mappings in the 'cds.lib' 82 | file. 83 | 84 | -------------------------------------------------------------------------------- /testbench/axi_tb/addr.coe: -------------------------------------------------------------------------------- 1 | memory_initialization_radix = 16; 2 | memory_initialization_vector = 3 | 00000000 4 | 00000000 5 | 00000010 6 | 00000010 7 | 00000020 8 | 00000020 9 | 00000030 10 | 00000030 11 | 00000040 12 | 00000040 13 | 00000050 14 | 00000050 15 | 00000060 16 | 00000060 17 | 00000070 18 | 00000070 19 | 00000000 20 | 00000000 21 | 00000000 22 | 00000000 23 | 00000000 24 | 00000000 25 | 00000000 26 | 00000000 27 | 00000000 28 | 00000000 29 | 00000000 30 | 00000000 31 | 00000000 32 | 00000000 33 | 00000000 34 | 00000000 35 | 00000000 36 | 00000000 37 | 00000000 38 | 00000000 39 | 00000000 40 | 00000000 41 | 00000000 42 | 00000000 43 | 00000000 44 | 00000000 45 | 00000000 46 | 00000000 47 | 00000000 48 | 00000000 49 | 00000000 50 | 00000000 51 | 00000000 52 | 00000000 53 | 00000000 54 | 00000000 55 | 00000000 56 | 00000000 57 | 00000000 58 | 00000000 59 | 00000000 60 | 00000000 61 | 00000000 62 | 00000000 63 | 00000000 64 | 00000000 65 | 00000000 66 | 00000000 67 | 00000000 68 | 00000000 69 | 00000000 70 | 00000000 71 | 00000000 72 | 00000000 73 | 00000000 74 | 00000000 75 | 00000000 76 | 00000000 77 | 00000000 78 | 00000000 79 | 00000000 80 | 00000000 81 | 00000000 82 | 00000000 83 | 00000000 84 | 00000000 85 | 00000000 86 | 00000000 87 | 00000000 88 | 00000000 89 | 00000000 90 | 00000000 91 | 00000000 92 | 00000000 93 | 00000000 94 | 00000000 95 | 00000000 96 | 00000000 97 | 00000000 98 | 00000000 99 | 00000000 100 | 00000000 101 | 00000000 102 | 00000000 103 | 00000000 104 | 00000000 105 | 00000000 106 | 00000000 107 | 00000000 108 | 00000000 109 | 00000000 110 | 00000000 111 | 00000000 112 | 00000000 113 | 00000000 114 | 00000000 115 | 00000000 116 | 00000000 117 | 00000000 118 | 00000000 119 | 00000000 120 | 00000000 121 | 00000000 122 | 00000000 123 | 00000000 124 | 00000000 125 | 00000000 126 | 00000000 127 | 00000000 128 | 00000000 129 | 00000000 130 | 00000000 131 | 00000000 132 | 00000000 133 | 00000000 134 | 00000000 135 | 00000000 136 | 00000000 137 | 00000000 138 | 00000000 139 | 00000000 140 | 00000000 141 | 00000000 142 | 00000000 143 | 00000000 144 | 00000000 145 | 00000000 146 | 00000000 147 | 00000000 148 | 00000000 149 | 00000000 150 | 00000000 151 | 00000000 152 | 00000000 153 | 00000000 154 | 00000000 155 | 00000000 156 | 00000000 157 | 00000000 158 | 00000000 159 | 00000000 160 | 00000000 161 | 00000000 162 | 00000000 163 | 00000000 164 | 00000000 165 | 00000000 166 | 00000000 167 | 00000000 168 | 00000000 169 | 00000000 170 | 00000000 171 | 00000000 172 | 00000000 173 | 00000000 174 | 00000000 175 | 00000000 176 | 00000000 177 | 00000000 178 | 00000000 179 | 00000000 180 | 00000000 181 | 00000000 182 | 00000000 183 | 00000000 184 | 00000000 185 | 00000000 186 | 00000000 187 | 00000000 188 | 00000000 189 | 00000000 190 | 00000000 191 | 00000000 192 | 00000000 193 | 00000000 194 | 00000000 195 | 00000000 196 | 00000000 197 | 00000000 198 | 00000000 199 | 00000000 200 | 00000000 201 | 00000000 202 | 00000000 203 | 00000000 204 | 00000000 205 | 00000000 206 | 00000000 207 | 00000000 208 | 00000000 209 | 00000000 210 | 00000000 211 | 00000000 212 | 00000000 213 | 00000000 214 | 00000000 215 | 00000000 216 | 00000000 217 | 00000000 218 | 00000000 219 | 00000000 220 | 00000000 221 | 00000000 222 | 00000000 223 | 00000000 224 | 00000000 225 | 00000000 226 | 00000000 227 | 00000000 228 | 00000000 229 | 00000000 230 | 00000000 231 | 00000000 232 | 00000000 233 | 00000000 234 | 00000000 235 | 00000000 236 | 00000000 237 | 00000000 238 | 00000000 239 | 00000000 240 | 00000000 241 | 00000000 242 | 00000000 243 | 00000000 244 | 00000000 245 | 00000000 246 | 00000000 247 | 00000000 248 | 00000000 249 | 00000000 250 | 00000000 251 | 00000000 252 | 00000000 253 | 00000000 254 | 00000000 255 | 00000000 256 | 00000000 257 | ffffffff 258 | ; 259 | -------------------------------------------------------------------------------- /testbench/axi_tb/ctrl.coe: -------------------------------------------------------------------------------- 1 | memory_initialization_radix = 16; 2 | memory_initialization_vector = 3 | 00030100 4 | 00020201 5 | 00030302 6 | 00020403 7 | 00030504 8 | 00020605 9 | 00030706 10 | 00020807 11 | 00030908 12 | 00020a09 13 | 00030b0a 14 | 00020c0b 15 | 00030d0c 16 | 00020e0d 17 | 00030f0e 18 | 0002100f 19 | 00031110 20 | 00031211 21 | 00031312 22 | 00031413 23 | 00031514 24 | 00031615 25 | 00031716 26 | 00031817 27 | 00031918 28 | 00031a19 29 | 00031b1a 30 | 00031c1b 31 | 00031d1c 32 | 00031e1d 33 | 00031f1e 34 | 0003201f 35 | 00032120 36 | 00032221 37 | 00032322 38 | 00032423 39 | 00032524 40 | 00032625 41 | 00032726 42 | 00032827 43 | 00032928 44 | 00032a29 45 | 00032b2a 46 | 00032c2b 47 | 00032d2c 48 | 00032e2d 49 | 00032f2e 50 | 0003302f 51 | 00033130 52 | 00033231 53 | 00033332 54 | 00033433 55 | 00033534 56 | 00033635 57 | 00033736 58 | 00033837 59 | 00033938 60 | 00033a39 61 | 00033b3a 62 | 00033c3b 63 | 00033d3c 64 | 00033e3d 65 | 00033f3e 66 | 0003403f 67 | 00034140 68 | 00034241 69 | 00034342 70 | 00034443 71 | 00034544 72 | 00034645 73 | 00034746 74 | 00034847 75 | 00034948 76 | 00034a49 77 | 00034b4a 78 | 00034c4b 79 | 00034d4c 80 | 00034e4d 81 | 00034f4e 82 | 0003504f 83 | 00035150 84 | 00035251 85 | 00035352 86 | 00035453 87 | 00035554 88 | 00035655 89 | 00035756 90 | 00035857 91 | 00035958 92 | 00035a59 93 | 00035b5a 94 | 00035c5b 95 | 00035d5c 96 | 00035e5d 97 | 00035f5e 98 | 0003605f 99 | 00036160 100 | 00036261 101 | 00036362 102 | 00036463 103 | 00036564 104 | 00036665 105 | 00036766 106 | 00036867 107 | 00036968 108 | 00036a69 109 | 00036b6a 110 | 00036c6b 111 | 00036d6c 112 | 00036e6d 113 | 00036f6e 114 | 0003706f 115 | 00037170 116 | 00037271 117 | 00037372 118 | 00037473 119 | 00037574 120 | 00037675 121 | 00037776 122 | 00037877 123 | 00037978 124 | 00037a79 125 | 00037b7a 126 | 00037c7b 127 | 00037d7c 128 | 00037e7d 129 | 00037f7e 130 | 0003807f 131 | 00038180 132 | 00038281 133 | 00038382 134 | 00038483 135 | 00038584 136 | 00038685 137 | 00038786 138 | 00038887 139 | 00038988 140 | 00038a89 141 | 00038b8a 142 | 00038c8b 143 | 00038d8c 144 | 00038e8d 145 | 00038f8e 146 | 0003908f 147 | 00039190 148 | 00039291 149 | 00039392 150 | 00039493 151 | 00039594 152 | 00039695 153 | 00039796 154 | 00039897 155 | 00039998 156 | 00039a99 157 | 00039b9a 158 | 00039c9b 159 | 00039d9c 160 | 00039e9d 161 | 00039f9e 162 | 0003a09f 163 | 0003a1a0 164 | 0003a2a1 165 | 0003a3a2 166 | 0003a4a3 167 | 0003a5a4 168 | 0003a6a5 169 | 0003a7a6 170 | 0003a8a7 171 | 0003a9a8 172 | 0003aaa9 173 | 0003abaa 174 | 0003acab 175 | 0003adac 176 | 0003aead 177 | 0003afae 178 | 0003b0af 179 | 0003b1b0 180 | 0003b2b1 181 | 0003b3b2 182 | 0003b4b3 183 | 0003b5b4 184 | 0003b6b5 185 | 0003b7b6 186 | 0003b8b7 187 | 0003b9b8 188 | 0003bab9 189 | 0003bbba 190 | 0003bcbb 191 | 0003bdbc 192 | 0003bebd 193 | 0003bfbe 194 | 0003c0bf 195 | 0003c1c0 196 | 0003c2c1 197 | 0003c3c2 198 | 0003c4c3 199 | 0003c5c4 200 | 0003c6c5 201 | 0003c7c6 202 | 0003c8c7 203 | 0003c9c8 204 | 0003cac9 205 | 0003cbca 206 | 0003cccb 207 | 0003cdcc 208 | 0003cecd 209 | 0003cfce 210 | 0003d0cf 211 | 0003d1d0 212 | 0003d2d1 213 | 0003d3d2 214 | 0003d4d3 215 | 0003d5d4 216 | 0003d6d5 217 | 0003d7d6 218 | 0003d8d7 219 | 0003d9d8 220 | 0003dad9 221 | 0003dbda 222 | 0003dcdb 223 | 0003dddc 224 | 0003dedd 225 | 0003dfde 226 | 0003e0df 227 | 0003e1e0 228 | 0003e2e1 229 | 0003e3e2 230 | 0003e4e3 231 | 0003e5e4 232 | 0003e6e5 233 | 0003e7e6 234 | 0003e8e7 235 | 0003e9e8 236 | 0003eae9 237 | 0003ebea 238 | 0003eceb 239 | 0003edec 240 | 0003eeed 241 | 0003efee 242 | 0003f0ef 243 | 0003f1f0 244 | 0003f2f1 245 | 0003f3f2 246 | 0003f4f3 247 | 0003f5f4 248 | 0003f6f5 249 | 0003f7f6 250 | 0003f8f7 251 | 0003f9f8 252 | 0003faf9 253 | 0003fbfa 254 | 0003fcfb 255 | 0003fdfc 256 | 0003fefd 257 | 0003fffe 258 | ; 259 | -------------------------------------------------------------------------------- /testbench/axi_tb/data.atg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AngeloJacobo/UberDDR3/a3efc861dafeec665d0885d6bc2e0c380260fe6b/testbench/axi_tb/data.atg -------------------------------------------------------------------------------- /testbench/axi_tb/data.coe: -------------------------------------------------------------------------------- 1 | memory_initialization_radix = 16; 2 | memory_initialization_vector = 3 | 01234567 4 | 00000000 5 | 89abcdef 6 | 00000000 7 | 19283746 8 | 00000000 9 | afdec70a 10 | 00000000 11 | 12121212 12 | 00000000 13 | 34343434 14 | 00000000 15 | 00000000 16 | 00000000 17 | ffffffff 18 | 00000000 19 | 00000000 20 | 00000000 21 | 00000000 22 | 00000000 23 | 00000000 24 | 00000000 25 | 00000000 26 | 00000000 27 | 00000000 28 | 00000000 29 | 00000000 30 | 00000000 31 | 00000000 32 | 00000000 33 | 00000000 34 | 00000000 35 | 00000000 36 | 00000000 37 | 00000000 38 | 00000000 39 | 00000000 40 | 00000000 41 | 00000000 42 | 00000000 43 | 00000000 44 | 00000000 45 | 00000000 46 | 00000000 47 | 00000000 48 | 00000000 49 | 00000000 50 | 00000000 51 | 00000000 52 | 00000000 53 | 00000000 54 | 00000000 55 | 00000000 56 | 00000000 57 | 00000000 58 | 00000000 59 | 00000000 60 | 00000000 61 | 00000000 62 | 00000000 63 | 00000000 64 | 00000000 65 | 00000000 66 | 00000000 67 | 00000000 68 | 00000000 69 | 00000000 70 | 00000000 71 | 00000000 72 | 00000000 73 | 00000000 74 | 00000000 75 | 00000000 76 | 00000000 77 | 00000000 78 | 00000000 79 | 00000000 80 | 00000000 81 | 00000000 82 | 00000000 83 | 00000000 84 | 00000000 85 | 00000000 86 | 00000000 87 | 00000000 88 | 00000000 89 | 00000000 90 | 00000000 91 | 00000000 92 | 00000000 93 | 00000000 94 | 00000000 95 | 00000000 96 | 00000000 97 | 00000000 98 | 00000000 99 | 00000000 100 | 00000000 101 | 00000000 102 | 00000000 103 | 00000000 104 | 00000000 105 | 00000000 106 | 00000000 107 | 00000000 108 | 00000000 109 | 00000000 110 | 00000000 111 | 00000000 112 | 00000000 113 | 00000000 114 | 00000000 115 | 00000000 116 | 00000000 117 | 00000000 118 | 00000000 119 | 00000000 120 | 00000000 121 | 00000000 122 | 00000000 123 | 00000000 124 | 00000000 125 | 00000000 126 | 00000000 127 | 00000000 128 | 00000000 129 | 00000000 130 | 00000000 131 | 00000000 132 | 00000000 133 | 00000000 134 | 00000000 135 | 00000000 136 | 00000000 137 | 00000000 138 | 00000000 139 | 00000000 140 | 00000000 141 | 00000000 142 | 00000000 143 | 00000000 144 | 00000000 145 | 00000000 146 | 00000000 147 | 00000000 148 | 00000000 149 | 00000000 150 | 00000000 151 | 00000000 152 | 00000000 153 | 00000000 154 | 00000000 155 | 00000000 156 | 00000000 157 | 00000000 158 | 00000000 159 | 00000000 160 | 00000000 161 | 00000000 162 | 00000000 163 | 00000000 164 | 00000000 165 | 00000000 166 | 00000000 167 | 00000000 168 | 00000000 169 | 00000000 170 | 00000000 171 | 00000000 172 | 00000000 173 | 00000000 174 | 00000000 175 | 00000000 176 | 00000000 177 | 00000000 178 | 00000000 179 | 00000000 180 | 00000000 181 | 00000000 182 | 00000000 183 | 00000000 184 | 00000000 185 | 00000000 186 | 00000000 187 | 00000000 188 | 00000000 189 | 00000000 190 | 00000000 191 | 00000000 192 | 00000000 193 | 00000000 194 | 00000000 195 | 00000000 196 | 00000000 197 | 00000000 198 | 00000000 199 | 00000000 200 | 00000000 201 | 00000000 202 | 00000000 203 | 00000000 204 | 00000000 205 | 00000000 206 | 00000000 207 | 00000000 208 | 00000000 209 | 00000000 210 | 00000000 211 | 00000000 212 | 00000000 213 | 00000000 214 | 00000000 215 | 00000000 216 | 00000000 217 | 00000000 218 | 00000000 219 | 00000000 220 | 00000000 221 | 00000000 222 | 00000000 223 | 00000000 224 | 00000000 225 | 00000000 226 | 00000000 227 | 00000000 228 | 00000000 229 | 00000000 230 | 00000000 231 | 00000000 232 | 00000000 233 | 00000000 234 | 00000000 235 | 00000000 236 | 00000000 237 | 00000000 238 | 00000000 239 | 00000000 240 | 00000000 241 | 00000000 242 | 00000000 243 | 00000000 244 | 00000000 245 | 00000000 246 | 00000000 247 | 00000000 248 | 00000000 249 | 00000000 250 | 00000000 251 | 00000000 252 | 00000000 253 | 00000000 254 | 00000000 255 | 00000000 256 | 00000000 257 | 00000000 258 | ; 259 | -------------------------------------------------------------------------------- /testbench/axi_tb/mask.coe: -------------------------------------------------------------------------------- 1 | memory_initialization_radix = 16; 2 | memory_initialization_vector = 3 | ffffffff 4 | 00000000 5 | ffffffff 6 | 00000000 7 | ffffffff 8 | 00000000 9 | ffffffff 10 | 00000000 11 | ffffffff 12 | 00000000 13 | ffffffff 14 | 00000000 15 | ffffffff 16 | 00000000 17 | ffffffff 18 | 00000000 19 | 00000000 20 | 00000000 21 | 00000000 22 | 00000000 23 | 00000000 24 | 00000000 25 | 00000000 26 | 00000000 27 | 00000000 28 | 00000000 29 | 00000000 30 | 00000000 31 | 00000000 32 | 00000000 33 | 00000000 34 | 00000000 35 | 00000000 36 | 00000000 37 | 00000000 38 | 00000000 39 | 00000000 40 | 00000000 41 | 00000000 42 | 00000000 43 | 00000000 44 | 00000000 45 | 00000000 46 | 00000000 47 | 00000000 48 | 00000000 49 | 00000000 50 | 00000000 51 | 00000000 52 | 00000000 53 | 00000000 54 | 00000000 55 | 00000000 56 | 00000000 57 | 00000000 58 | 00000000 59 | 00000000 60 | 00000000 61 | 00000000 62 | 00000000 63 | 00000000 64 | 00000000 65 | 00000000 66 | 00000000 67 | 00000000 68 | 00000000 69 | 00000000 70 | 00000000 71 | 00000000 72 | 00000000 73 | 00000000 74 | 00000000 75 | 00000000 76 | 00000000 77 | 00000000 78 | 00000000 79 | 00000000 80 | 00000000 81 | 00000000 82 | 00000000 83 | 00000000 84 | 00000000 85 | 00000000 86 | 00000000 87 | 00000000 88 | 00000000 89 | 00000000 90 | 00000000 91 | 00000000 92 | 00000000 93 | 00000000 94 | 00000000 95 | 00000000 96 | 00000000 97 | 00000000 98 | 00000000 99 | 00000000 100 | 00000000 101 | 00000000 102 | 00000000 103 | 00000000 104 | 00000000 105 | 00000000 106 | 00000000 107 | 00000000 108 | 00000000 109 | 00000000 110 | 00000000 111 | 00000000 112 | 00000000 113 | 00000000 114 | 00000000 115 | 00000000 116 | 00000000 117 | 00000000 118 | 00000000 119 | 00000000 120 | 00000000 121 | 00000000 122 | 00000000 123 | 00000000 124 | 00000000 125 | 00000000 126 | 00000000 127 | 00000000 128 | 00000000 129 | 00000000 130 | 00000000 131 | 00000000 132 | 00000000 133 | 00000000 134 | 00000000 135 | 00000000 136 | 00000000 137 | 00000000 138 | 00000000 139 | 00000000 140 | 00000000 141 | 00000000 142 | 00000000 143 | 00000000 144 | 00000000 145 | 00000000 146 | 00000000 147 | 00000000 148 | 00000000 149 | 00000000 150 | 00000000 151 | 00000000 152 | 00000000 153 | 00000000 154 | 00000000 155 | 00000000 156 | 00000000 157 | 00000000 158 | 00000000 159 | 00000000 160 | 00000000 161 | 00000000 162 | 00000000 163 | 00000000 164 | 00000000 165 | 00000000 166 | 00000000 167 | 00000000 168 | 00000000 169 | 00000000 170 | 00000000 171 | 00000000 172 | 00000000 173 | 00000000 174 | 00000000 175 | 00000000 176 | 00000000 177 | 00000000 178 | 00000000 179 | 00000000 180 | 00000000 181 | 00000000 182 | 00000000 183 | 00000000 184 | 00000000 185 | 00000000 186 | 00000000 187 | 00000000 188 | 00000000 189 | 00000000 190 | 00000000 191 | 00000000 192 | 00000000 193 | 00000000 194 | 00000000 195 | 00000000 196 | 00000000 197 | 00000000 198 | 00000000 199 | 00000000 200 | 00000000 201 | 00000000 202 | 00000000 203 | 00000000 204 | 00000000 205 | 00000000 206 | 00000000 207 | 00000000 208 | 00000000 209 | 00000000 210 | 00000000 211 | 00000000 212 | 00000000 213 | 00000000 214 | 00000000 215 | 00000000 216 | 00000000 217 | 00000000 218 | 00000000 219 | 00000000 220 | 00000000 221 | 00000000 222 | 00000000 223 | 00000000 224 | 00000000 225 | 00000000 226 | 00000000 227 | 00000000 228 | 00000000 229 | 00000000 230 | 00000000 231 | 00000000 232 | 00000000 233 | 00000000 234 | 00000000 235 | 00000000 236 | 00000000 237 | 00000000 238 | 00000000 239 | 00000000 240 | 00000000 241 | 00000000 242 | 00000000 243 | 00000000 244 | 00000000 245 | 00000000 246 | 00000000 247 | 00000000 248 | 00000000 249 | 00000000 250 | 00000000 251 | 00000000 252 | 00000000 253 | 00000000 254 | 00000000 255 | 00000000 256 | 00000000 257 | 00000000 258 | ; 259 | -------------------------------------------------------------------------------- /testbench/design.txt: -------------------------------------------------------------------------------- 1 | TIME TEMP 2 | 0 25 3 | 30000 50 4 | 35000 51 5 | 50000 48 6 | 70000 51 7 | 80000 48 8 | 9 | 10 | -------------------------------------------------------------------------------- /testbench/icarus_sim/sim_icarus.sh: -------------------------------------------------------------------------------- 1 | rm -rf ./uberddr3_sim ./sim.log 2 | iverilog -o uberddr3_sim -g2012 \ 3 | -DNO_TEST_MODEL \ 4 | -DSIM_MODEL \ 5 | -s ddr3_dimm_micron_sim \ 6 | -I ../ \ 7 | ../ddr3_dimm_micron_sim.sv \ 8 | ../ddr3.sv \ 9 | ../models/IDELAYCTRL_model.v \ 10 | ../models/IDELAYE2_model.v \ 11 | ../models/IOBUF_DCIEN_model.v \ 12 | ../models/IOBUF_model.v \ 13 | ../models/IOBUFDS_DCIEN_model.v \ 14 | ../models/IOBUFDS_model.v \ 15 | ../models/ISERDESE2_model.v \ 16 | ../models/OBUFDS_model.v \ 17 | ../models/ODELAYE2_model.v \ 18 | ../models/OSERDESE2_model.v \ 19 | ../models/OBUF_model.v \ 20 | ../../rtl/ddr3_top.v \ 21 | ../../rtl/ddr3_controller.v \ 22 | ../../rtl/ddr3_phy.v \ 23 | ../ddr3_module.sv 24 | 25 | vvp -n ./uberddr3_sim 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /testbench/models/IDELAYCTRL_model.v: -------------------------------------------------------------------------------- 1 | `timescale 1 ns/1 ps 2 | 3 | module IDELAYCTRL_model ( 4 | output reg RDY, 5 | input REFCLK, 6 | input RST 7 | ); 8 | initial RDY = 0; 9 | always @(posedge RST) begin 10 | RDY <= 0; 11 | end 12 | always @(negedge RST) begin 13 | # 10; // 10ns delay before RDY assertion 14 | RDY <= 1; 15 | end 16 | 17 | endmodule 18 | 19 | -------------------------------------------------------------------------------- /testbench/models/IDELAYE2_model.v: -------------------------------------------------------------------------------- 1 | `timescale 1 ps / 1 ps 2 | 3 | module IDELAYE2_model ( 4 | output reg DATAOUT, 5 | input wire C, 6 | input wire[4:0] CNTVALUEIN, 7 | input wire LD, 8 | input wire IDATAIN, 9 | 10 | // NOT MODELLED 11 | input wire[4:0] CNTVALUEOUT, 12 | input wire CE, 13 | input wire CINVCTRL, 14 | input wire DATAIN, 15 | input wire INC, 16 | input wire LDPIPEEN, 17 | input wire REGRST 18 | ); 19 | 20 | parameter CINVCTRL_SEL = "FALSE"; 21 | parameter DELAY_SRC = "IDATAIN"; 22 | parameter HIGH_PERFORMANCE_MODE = "FALSE"; 23 | parameter IDELAY_TYPE = "FIXED"; 24 | parameter integer IDELAY_VALUE = 0; 25 | parameter PIPE_SEL = "FALSE"; 26 | parameter real REFCLK_FREQUENCY = 200.0; 27 | parameter SIGNAL_PATTERN = "DATA"; 28 | `ifdef NO_TEST_MODEL 29 | parameter TEST_MODEL = 0; 30 | `else 31 | parameter TEST_MODEL = 1; 32 | `endif 33 | 34 | // stop simulation if this modelfile does not support the settings 35 | initial begin 36 | if(DELAY_SRC != "IDATAIN") begin 37 | $display("DELAY_SRC must be IDATAIN!"); 38 | $stop; 39 | end 40 | if(IDELAY_TYPE != "VAR_LOAD") begin 41 | $display("IDELAY_TYPE must be VAR_LOAD!"); 42 | $stop; 43 | end 44 | if(REFCLK_FREQUENCY != 200) begin 45 | $display("REFCLK_FREQUENCY must be 200!"); 46 | $stop; 47 | end 48 | end 49 | integer delay_value; 50 | initial DATAOUT = 0; 51 | always @(IDATAIN) DATAOUT <= #(delay_value) IDATAIN; 52 | 53 | initial delay_value = 600; 54 | always @(posedge C) begin 55 | if(LD) begin 56 | delay_value <= 600 + 78*CNTVALUEIN; 57 | end 58 | end 59 | generate 60 | if(TEST_MODEL == 1) begin 61 | wire DATAOUT_test; 62 | reg unequal = 0; 63 | 64 | IDELAYE2 #( 65 | .DELAY_SRC("IDATAIN"), // Delay input (IDATAIN, DATAIN) 66 | .HIGH_PERFORMANCE_MODE("TRUE"), //Reduced jitter ("TRUE"), Reduced power ("FALSE") 67 | .IDELAY_TYPE("VAR_LOAD"), //FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE 68 | .IDELAY_VALUE(0), //Input delay tap setting (0-31) 69 | .PIPE_SEL("FALSE"), //Select pipelined mode, FALSE, TRUE 70 | .REFCLK_FREQUENCY(200.0), //IDELAYCTRL clock input frequency in MHz (190.0-210.0). 71 | .SIGNAL_PATTERN("CLOCK") //DATA, CLOCK input signal 72 | ) 73 | IDELAYE2_test_model ( 74 | .CNTVALUEOUT(), // 5-bit output: Counter value output 75 | .DATAOUT(DATAOUT_test), // 1-bit output: Delayed data output 76 | .C(C), // 1-bit input: Clock input 77 | .CE(1'b0), // 1-bit input: Active high enable increment/decrement input 78 | .CINVCTRL(1'b0),// 1-bit input: Dynamic clock inversion input 79 | .CNTVALUEIN(CNTVALUEIN), // 5-bit input: Counter value input 80 | .DATAIN(), //1-bit input: Internal delay data input 81 | .IDATAIN(IDATAIN), // 1-bit input: Data input from the I/O 82 | .INC(1'b0), // 1-bit input: Increment / Decrement tap delay input 83 | .LD(LD), // 1-bit input: Load IDELAY_VALUE input 84 | .LDPIPEEN(1'b0), // 1-bit input: Enable PIPELINE register to load data input 85 | .REGRST(1'b0) // 1-bit input: Active-high reset tap-delay input 86 | ); 87 | 88 | // check if delayed signal matches with the actual IDELAY primitive, if not then stop simulation 89 | always @* begin 90 | #100; 91 | if((DATAOUT_test !== DATAOUT) && ($time > 500_000)) begin 92 | $display("IDELAYE2 MODEL does not match: time = %t", $time); 93 | unequal <= 1; 94 | $stop; 95 | end 96 | end 97 | initial begin 98 | $display("---------------------------------------- TESTING IDELAYE2 Model ----------------------------------------"); 99 | end 100 | end 101 | endgenerate 102 | endmodule 103 | 104 | -------------------------------------------------------------------------------- /testbench/models/IOBUFDS_DCIEN_model.v: -------------------------------------------------------------------------------- 1 | `timescale 1 ps / 1 ps 2 | 3 | module IOBUFDS_DCIEN_model #( 4 | parameter IBUF_LOW_PWR = "TRUE", 5 | parameter SLEW = "SLOW", 6 | parameter USE_IBUFDISABLE = "TRUE" 7 | )( 8 | output O, 9 | inout IO, 10 | inout IOB, 11 | input DCITERMDISABLE, 12 | input I, 13 | input IBUFDISABLE, 14 | input T 15 | ); 16 | // black box 17 | endmodule 18 | -------------------------------------------------------------------------------- /testbench/models/IOBUFDS_model.v: -------------------------------------------------------------------------------- 1 | `timescale 1 ps / 1 ps 2 | 3 | module IOBUFDS_model ( 4 | output O, 5 | inout IO, 6 | inout IOB, 7 | input I, 8 | input T 9 | ); 10 | `ifdef NO_TEST_MODEL 11 | parameter TEST_MODEL = 0; 12 | `else 13 | parameter TEST_MODEL = 1; 14 | `endif 15 | parameter IBUF_LOW_PWR = "FALSE"; 16 | 17 | assign IO = T ? 1'bz : I; 18 | assign IOB = T ? 1'bz : ~I; 19 | reg o_out; 20 | 21 | always @(IO or IOB) begin 22 | if (IO == 1'b1 && IOB == 1'b0) 23 | o_out <= 1'b1; 24 | else if (IO == 1'b0 && IOB == 1'b1) 25 | o_out <= 1'b0; 26 | else if ((IO === 1'bz || IO == 1'b0) && (IOB === 1'bz || IOB == 1'b1)) 27 | o_out <= 1'bx; 28 | else if ((IO === 1'bx) || (IOB == 1'bx)) 29 | o_out <= 1'bx; 30 | end 31 | 32 | assign O = o_out; 33 | 34 | 35 | generate 36 | if(TEST_MODEL == 1) begin 37 | wire O_test, IO_test, IOB_test; 38 | reg unequal = 0; 39 | bufif0 (IO_test, IO, 1'b0); 40 | bufif0 (IOB_test, IOB, 1'b0); 41 | 42 | IOBUFDS IOBUFDS_test_model ( 43 | .O(O_test), // Buffer output 44 | .IO(IO_test), // Diff_p inout (connect directly to top-level port) 45 | .IOB(IOB_test), // Diff_n inout (connect directly to top-level port) 46 | .I(I), // Buffer input 47 | .T(T) // 3-state enable input, high=input, low=output 48 | ); 49 | 50 | always @* begin 51 | #1; 52 | if((O !== O_test) && ($time > 500_000)) begin 53 | $display("IOBUFDS MODEL O does not match: time = %t", $time); 54 | unequal <= 1; 55 | $stop; 56 | end 57 | if(((IO != IO_test) || (IOB != IOB_test)) && ($time > 500_000)) begin 58 | $display("IOBUFDS MODEL IO/IOB does not match: time = %t", $time); 59 | unequal <= 1; 60 | $stop; 61 | end 62 | end 63 | 64 | initial begin 65 | $display("---------------------------------------- TESTING IOBUFDS Model ----------------------------------------"); 66 | end 67 | end 68 | endgenerate 69 | 70 | endmodule 71 | 72 | `endcelldefine 73 | -------------------------------------------------------------------------------- /testbench/models/IOBUF_DCIEN_model.v: -------------------------------------------------------------------------------- 1 | `timescale 1 ps / 1 ps 2 | 3 | module IOBUF_DCIEN_model #( 4 | parameter IBUF_LOW_PWR = "TRUE", 5 | parameter SLEW = "SLOW", 6 | parameter USE_IBUFDISABLE = "TRUE" 7 | )( 8 | output O, 9 | inout IO, 10 | input I, 11 | input T, 12 | input DCITERMDISABLE, 13 | input IBUFDISABLE 14 | ); 15 | // black box 16 | 17 | endmodule 18 | 19 | -------------------------------------------------------------------------------- /testbench/models/IOBUF_model.v: -------------------------------------------------------------------------------- 1 | `timescale 1 ps / 1 ps 2 | 3 | 4 | 5 | module IOBUF_model ( 6 | output O, 7 | inout IO, 8 | input I, 9 | input T 10 | ); 11 | 12 | parameter IBUF_LOW_PWR = "TRUE"; 13 | parameter SLEW = "SLOW"; 14 | `ifdef NO_TEST_MODEL 15 | parameter TEST_MODEL = 0; 16 | `else 17 | parameter TEST_MODEL = 1; 18 | `endif 19 | 20 | 21 | bufif0 T1 (IO, I, T); 22 | buf B1 (O, IO); 23 | 24 | generate 25 | if(TEST_MODEL == 1) begin 26 | reg unequal = 0; 27 | wire O_test, IO_test; 28 | bufif0 (IO_test, IO, 1'b0); 29 | 30 | IOBUF #( 31 | .IBUF_LOW_PWR("FALSE"), // Low Power - "TRUE", High Performance = "FALSE" 32 | .SLEW("FAST") // Specify the output slew rate 33 | ) IOBUF_test_model ( 34 | .O(O_test),// Buffer output 35 | .IO(IO_test), // Buffer inout port (connect directly to top-level port) 36 | .I(I), // Buffer input 37 | .T(T) // 3-state enable input, high=read, low=write 38 | ); 39 | always @* begin 40 | #1; 41 | if((O !== O_test) && ($time > 500_000)) begin 42 | $display("IOBUF MODEL O does not match: time = %t", $time); 43 | unequal <= 1; 44 | $stop; 45 | end 46 | if((IO != IO_test) && ($time > 500_000)) begin 47 | $display("IOBUF MODEL IO does not match: time = %t", $time); 48 | unequal <= 1; 49 | $stop; 50 | end 51 | end 52 | 53 | initial begin 54 | $display("---------------------------------------- TESTING IOBUF Model ----------------------------------------"); 55 | end 56 | end 57 | endgenerate 58 | 59 | endmodule 60 | 61 | 62 | -------------------------------------------------------------------------------- /testbench/models/OBUFDS_model.v: -------------------------------------------------------------------------------- 1 | 2 | `timescale 1 ps/1 ps 3 | 4 | module OBUFDS_model ( 5 | output wire O, 6 | output wire OB, 7 | input wire I 8 | ); 9 | `ifdef NO_TEST_MODEL 10 | parameter TEST_MODEL = 0; 11 | `else 12 | parameter TEST_MODEL = 1; 13 | `endif 14 | 15 | bufif0 (O, I, 1'b0); 16 | notif0 (OB, I, 1'b0); 17 | 18 | generate 19 | if(TEST_MODEL == 1) begin 20 | wire O_test, OB_test; 21 | reg unequal = 0; 22 | 23 | OBUFDS OBUFDS_test_model ( 24 | .O(O_test), // Diff_p output (connect directly to top-level port) 25 | .OB(OB_test), // Diff_n output (connect directly to top-level port) 26 | .I(I) // Buffer input 27 | ); 28 | 29 | always @* begin 30 | #1; 31 | if((O !== O_test) && ($time > 500_000)) begin 32 | $display("OBUFDS MODEL O does not match: time = %t", $time); 33 | unequal <= 1; 34 | $stop; 35 | end 36 | if((OB !== OB_test) && ($time > 500_000)) begin 37 | $display("OBUFDS MODEL OB does not match: time = %t", $time); 38 | unequal <= 1; 39 | $stop; 40 | end 41 | end 42 | 43 | initial begin 44 | $display("---------------------------------------- TESTING OBUFDS Model ----------------------------------------"); 45 | end 46 | end 47 | endgenerate 48 | endmodule 49 | 50 | -------------------------------------------------------------------------------- /testbench/models/OBUF_model.v: -------------------------------------------------------------------------------- 1 | `timescale 1 ps / 1 ps 2 | 3 | 4 | module OBUF_model ( 5 | output O, 6 | input I 7 | ); 8 | parameter SLEW ="FAST"; 9 | `ifdef NO_TEST_MODEL 10 | parameter TEST_MODEL = 0; 11 | `else 12 | parameter TEST_MODEL = 1; 13 | `endif 14 | 15 | bufif0 B1 (O, I, 0); 16 | 17 | generate 18 | if(TEST_MODEL == 1) begin 19 | wire O_test; 20 | reg unequal = 0; 21 | 22 | OBUF #( 23 | .SLEW("FAST") // Specify the output slew rate 24 | ) OBUF_test_model ( 25 | .O(O_test), // Buffer output (connect directly to top-level port) 26 | .I(I) // Buffer input 27 | ); 28 | 29 | always @* begin 30 | #1; 31 | if((O !== O_test) && ($time > 500_000)) begin 32 | $display("OBUF MODEL O does not match: time = %t", $time); 33 | unequal <= 1; 34 | $stop; 35 | end 36 | end 37 | 38 | initial begin 39 | $display("---------------------------------------- TESTING OBUF Model ----------------------------------------"); 40 | end 41 | end 42 | endgenerate 43 | 44 | 45 | endmodule 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /testbench/sim_defines.vh: -------------------------------------------------------------------------------- 1 | // Define either TWO_LANES_x8 or EIGHT_LANES_x8 2 | `define TWO_LANES_x8 3 | //`define EIGHT_LANES_x8 4 | 5 | `ifdef EIGHT_LANES_x8 6 | `ifdef TWO_LANES_x8 7 | ERROR: Display compilation error here 8 | `endif 9 | `define x8 10 | `endif 11 | 12 | `ifdef TWO_LANES_x8 13 | `define x16 14 | `endif 15 | 16 | // Check if neither is defined 17 | `ifndef EIGHT_LANES_x8 18 | `ifndef TWO_LANES_x8 19 | ERROR: Display compilation error here 20 | `endif 21 | `endif 22 | 23 | `define den8192Mb 24 | `define sg125 25 | -------------------------------------------------------------------------------- /testbench/spd_tb/spd_reader_tb.sv: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module spd_reader_tb; 4 | reg clk, rst_n; 5 | wire scl, sda; 6 | 7 | // spd_reader DUT ( 8 | // .i_clk(clk), 9 | // .i_rst_n(rst_n), 10 | // .i2c_scl(scl), 11 | // .i2c_sda(sda) 12 | // ); 13 | spd_reader_top DUT ( 14 | // clock and reset 15 | .sys_clk_p(clk), 16 | .sys_clk_n(!clk), 17 | .i_rst_n(rst_n), 18 | // i2c interface 19 | .i2c_scl(scl), 20 | .i2c_sda(sda) 21 | ); 22 | 23 | initial begin 24 | clk = 0; 25 | rst_n = 0; 26 | #100; 27 | rst_n = 1; 28 | wait(DUT.spd_reader_inst.read_spd_done); 29 | #10_000; 30 | $stop; 31 | end 32 | always #2.5 clk = !clk; // 200MHz 33 | 34 | pullup pullup_scl(scl); // pullup scl line 35 | pullup pullup_sda(sda); // pullup sda line 36 | 37 | i2c_slave i2c_slave( 38 | .scl(scl), 39 | .sda(sda) 40 | ); 41 | endmodule -------------------------------------------------------------------------------- /testbench/xsim/README.txt: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Vivado (TM) v2022.1 (64-bit) 3 | # 4 | # README.txt: Please read the sections below to understand the steps required to 5 | # run the exported script and information about the source files. 6 | # 7 | # Generated by export_simulation on Sun Jan 26 11:59:04 PST 2025 8 | # 9 | ################################################################################ 10 | 11 | 1. How to run the generated simulation script:- 12 | 13 | From the shell prompt in the current directory, issue the following command:- 14 | 15 | ./ddr3_dimm_micron_sim.sh 16 | 17 | This command will launch the 'compile', 'elaborate' and 'simulate' functions 18 | implemented in the script file for the 3-step flow. These functions are called 19 | from the main 'run' function in the script file. 20 | 21 | The 'run' function first executes the 'setup' function, the purpose of which is to 22 | create simulator specific setup files, create design library mappings and library 23 | directories and copy 'glbl.v' from the Vivado software install location into the 24 | current directory. 25 | 26 | The 'setup' function is also used for removing the simulator generated data in 27 | order to reset the current directory to the original state when export_simulation 28 | was launched from Vivado. This generated data can be removed by specifying the 29 | '-reset_run' switch to the './ddr3_dimm_micron_sim.sh' script. 30 | 31 | ./ddr3_dimm_micron_sim.sh -reset_run 32 | 33 | To keep the generated data from the previous run but regenerate the setup files and 34 | library directories, use the '-noclean_files' switch. 35 | 36 | ./ddr3_dimm_micron_sim.sh -noclean_files 37 | 38 | For more information on the script, please type './ddr3_dimm_micron_sim.sh -help'. 39 | 40 | 2. Additional design information files:- 41 | 42 | export_simulation generates following additional file that can be used for fetching 43 | the design files information or for integrating with external custom scripts. 44 | 45 | Name : file_info.txt 46 | Purpose: This file contains detail design file information based on the compile order 47 | when export_simulation was executed from Vivado. The file contains information 48 | about the file type, name, whether it is part of the IP, associated library 49 | and the file path information. 50 | -------------------------------------------------------------------------------- /testbench/xsim/cmd.tcl: -------------------------------------------------------------------------------- 1 | set curr_wave [current_wave_config] 2 | if { [string length $curr_wave] == 0 } { 3 | if { [llength [get_objects]] > 0} { 4 | add_wave / 5 | set_property needs_save false [current_wave_config] 6 | } else { 7 | send_msg_id Add_Wave-1 WARNING "No top level signals found. Simulator will start without a wave window. If you want to open a wave window go to 'File->New Waveform Configuration' or type 'create_wave_config' in the TCL console." 8 | } 9 | } 10 | 11 | run -all 12 | quit 13 | -------------------------------------------------------------------------------- /testbench/xsim/file_info.txt: -------------------------------------------------------------------------------- 1 | IDELAYCTRL_model.v,verilog,xil_defaultlib,../../testbench/models/IDELAYCTRL_model.v,incdir="../../testbench" 2 | IDELAYE2_model.v,verilog,xil_defaultlib,../../testbench/models/IDELAYE2_model.v,incdir="../../testbench" 3 | IOBUF_DCIEN.v,verilog,xil_defaultlib,../../testbench/models/IOBUF_DCIEN.v,incdir="../../testbench" 4 | IOBUF_model.v,verilog,xil_defaultlib,../../testbench/models/IOBUF_model.v,incdir="../../testbench" 5 | IOBUFDS_DCIEN_model.v,verilog,xil_defaultlib,../../testbench/models/IOBUFDS_DCIEN_model.v,incdir="../../testbench" 6 | IOBUFDS_model.v,verilog,xil_defaultlib,../../testbench/models/IOBUFDS_model.v,incdir="../../testbench" 7 | ISERDESE2_model.v,verilog,xil_defaultlib,../../testbench/models/ISERDESE2_model.v,incdir="../../testbench" 8 | OBUFDS_model.v,verilog,xil_defaultlib,../../testbench/models/OBUFDS_model.v,incdir="../../testbench" 9 | ODELAYE2_model.v,verilog,xil_defaultlib,../../testbench/models/ODELAYE2_model.v,incdir="../../testbench" 10 | OSERDESE2_model.v,verilog,xil_defaultlib,../../testbench/models/OSERDESE2_model.v,incdir="../../testbench" 11 | OBUF_model.v,verilog,xil_defaultlib,../../testbench/models/OBUF_model.v,incdir="../../testbench" 12 | 13 | ddr3_controller.v,verilog,xil_defaultlib,../../rtl/ddr3_controller.v,incdir="../../testbench" 14 | ddr3_phy.v,verilog,xil_defaultlib,../../rtl/ddr3_phy.v,incdir="../../testbench" 15 | ddr3_top.v,verilog,xil_defaultlib,../../rtl/ddr3_top.v,incdir="../../testbench" 16 | ddr3.sv,systemverilog,xil_defaultlib,../../testbench/ddr3.sv,incdir="../../testbench" 17 | ddr3_module.sv,systemverilog,xil_defaultlib,../../testbench/ddr3_module.sv,incdir="../../testbench" 18 | ddr3_dimm_micron_sim.sv,systemverilog,xil_defaultlib,../../testbench/ddr3_dimm_micron_sim.sv,incdir="../../testbench" 19 | 20 | glbl.v,Verilog,xil_defaultlib 21 | -------------------------------------------------------------------------------- /testbench/xsim/glbl.v: -------------------------------------------------------------------------------- 1 | // $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/glbl.v,v 1.14 2010/10/28 20:44:00 fphillip Exp $ 2 | `ifndef GLBL 3 | `define GLBL 4 | `timescale 1 ps / 1 ps 5 | 6 | module glbl (); 7 | 8 | parameter ROC_WIDTH = 100000; 9 | parameter TOC_WIDTH = 0; 10 | parameter GRES_WIDTH = 10000; 11 | parameter GRES_START = 10000; 12 | 13 | //-------- STARTUP Globals -------------- 14 | wire GSR; 15 | wire GTS; 16 | wire GWE; 17 | wire PRLD; 18 | wire GRESTORE; 19 | tri1 p_up_tmp; 20 | tri (weak1, strong0) PLL_LOCKG = p_up_tmp; 21 | 22 | wire PROGB_GLBL; 23 | wire CCLKO_GLBL; 24 | wire FCSBO_GLBL; 25 | wire [3:0] DO_GLBL; 26 | wire [3:0] DI_GLBL; 27 | 28 | reg GSR_int; 29 | reg GTS_int; 30 | reg PRLD_int; 31 | reg GRESTORE_int; 32 | 33 | //-------- JTAG Globals -------------- 34 | wire JTAG_TDO_GLBL; 35 | wire JTAG_TCK_GLBL; 36 | wire JTAG_TDI_GLBL; 37 | wire JTAG_TMS_GLBL; 38 | wire JTAG_TRST_GLBL; 39 | 40 | reg JTAG_CAPTURE_GLBL; 41 | reg JTAG_RESET_GLBL; 42 | reg JTAG_SHIFT_GLBL; 43 | reg JTAG_UPDATE_GLBL; 44 | reg JTAG_RUNTEST_GLBL; 45 | 46 | reg JTAG_SEL1_GLBL = 0; 47 | reg JTAG_SEL2_GLBL = 0 ; 48 | reg JTAG_SEL3_GLBL = 0; 49 | reg JTAG_SEL4_GLBL = 0; 50 | 51 | reg JTAG_USER_TDO1_GLBL = 1'bz; 52 | reg JTAG_USER_TDO2_GLBL = 1'bz; 53 | reg JTAG_USER_TDO3_GLBL = 1'bz; 54 | reg JTAG_USER_TDO4_GLBL = 1'bz; 55 | 56 | assign (strong1, weak0) GSR = GSR_int; 57 | assign (strong1, weak0) GTS = GTS_int; 58 | assign (weak1, weak0) PRLD = PRLD_int; 59 | assign (strong1, weak0) GRESTORE = GRESTORE_int; 60 | 61 | initial begin 62 | GSR_int = 1'b1; 63 | PRLD_int = 1'b1; 64 | #(ROC_WIDTH) 65 | GSR_int = 1'b0; 66 | PRLD_int = 1'b0; 67 | end 68 | 69 | initial begin 70 | GTS_int = 1'b1; 71 | #(TOC_WIDTH) 72 | GTS_int = 1'b0; 73 | end 74 | 75 | initial begin 76 | GRESTORE_int = 1'b0; 77 | #(GRES_START); 78 | GRESTORE_int = 1'b1; 79 | #(GRES_WIDTH); 80 | GRESTORE_int = 1'b0; 81 | end 82 | 83 | endmodule 84 | `endif 85 | -------------------------------------------------------------------------------- /testbench/xsim/vlog.prj: -------------------------------------------------------------------------------- 1 | verilog xil_defaultlib --include "../../testbench" \ 2 | "../../testbench/models/IDELAYCTRL_model.v" \ 3 | "../../testbench/models/IDELAYE2_model.v" \ 4 | "../../testbench/models/IOBUF_DCIEN_model.v" \ 5 | "../../testbench/models/IOBUF_model.v" \ 6 | "../../testbench/models/IOBUFDS_DCIEN_model.v" \ 7 | "../../testbench/models/IOBUFDS_model.v" \ 8 | "../../testbench/models/ISERDESE2_model.v" \ 9 | "../../testbench/models/OBUFDS_model.v" \ 10 | "../../testbench/models/ODELAYE2_model.v" \ 11 | "../../testbench/models/OSERDESE2_model.v" \ 12 | "../../testbench/models/OBUF_model.v" \ 13 | "../../rtl/ddr3_controller.v" \ 14 | "../../rtl/ddr3_phy.v" \ 15 | "../../rtl/ddr3_top.v" \ 16 | 17 | sv xil_defaultlib --include "../../testbench" \ 18 | "../../testbench/ddr3.sv" \ 19 | "../../testbench/ddr3_module.sv" \ 20 | "../../testbench/ddr3_dimm_micron_sim.sv" \ 21 | 22 | verilog xil_defaultlib "../../testbench/xsim/glbl.v" 23 | 24 | nosort 25 | -------------------------------------------------------------------------------- /vivado_custom_ip/gui/uberddr3_axi_v1_0.gtcl: -------------------------------------------------------------------------------- 1 | # This file is automatically written. Do not modify. 2 | proc gen_USERPARAMETER_DDR3_CLK_PERIOD_VALUE {CONTROLLER_CLK_PERIOD } {expr $CONTROLLER_CLK_PERIOD / 4} 3 | proc gen_USERPARAMETER_wb_addr_bits_VALUE {ROW_BITS COL_BITS BA_BITS } {expr $ROW_BITS + $COL_BITS + $BA_BITS - 3} 4 | proc gen_USERPARAMETER_wb_data_bits_VALUE {DQ_BITS BYTE_LANES } {expr $DQ_BITS * $BYTE_LANES * 8} 5 | proc gen_USERPARAMETER_wb_sel_bits_VALUE {wb_data_bits } {expr $wb_data_bits / 8} 6 | proc gen_USERPARAMETER_wb2_sel_bits_VALUE {WB2_DATA_BITS } {expr $WB2_DATA_BITS / 8} 7 | proc gen_USERPARAMETER_cmd_len_VALUE {BA_BITS ROW_BITS } {expr 4 + 3 + $BA_BITS + $ROW_BITS} 8 | proc gen_USERPARAMETER_AXI_LSBS_VALUE {wb_data_bits } {expr (log( $wb_data_bits )/log(2)) - 3} 9 | proc gen_USERPARAMETER_AXI_ADDR_WIDTH_VALUE {wb_addr_bits AXI_LSBS } {expr $wb_addr_bits + $AXI_LSBS} 10 | proc gen_USERPARAMETER_AXI_DATA_WIDTH_VALUE {wb_data_bits } {expr $wb_data_bits} 11 | --------------------------------------------------------------------------------