Revert "add self-refresh option, passing Simulation, ongoing formal"
This reverts commit a5e2adf4a4.
This commit is contained in:
parent
a5e2adf4a4
commit
1078e2ffe0
426
README.md
426
README.md
|
|
@ -1,213 +1,213 @@
|
|||
|
||||
# Table of Contents
|
||||
- [Brief Description](https://github.com/AngeloJacobo/DDR3_Controller#brief-description)
|
||||
- [Getting Started](https://github.com/AngeloJacobo/DDR3_Controller#getting-started)
|
||||
- [Instantiate Design](https://github.com/AngeloJacobo/DDR3_Controller#heavy_check_mark-instantiate-design)
|
||||
- [Create Constraint File](https://github.com/AngeloJacobo/DDR3_Controller#heavy_check_mark-create-constraint-file)
|
||||
- [Edit Localparams](https://github.com/AngeloJacobo/DDR3_Controller#heavy_check_mark-edit-localparams)
|
||||
- [Lint and Formal Verification](https://github.com/AngeloJacobo/DDR3_Controller#lint-and-formal-verification)
|
||||
- [Simulation](https://github.com/AngeloJacobo/DDR3_Controller#simulation)
|
||||
- [Demo Projects](https://github.com/AngeloJacobo/UberDDR3/tree/main?tab=readme-ov-file#demo-projects)
|
||||
- [Other Open-Sourced DDR3 Controllers](https://github.com/AngeloJacobo/DDR3_Controller#other-open-sourced-ddr3-controllers)
|
||||
- [Developer Documentation](https://github.com/AngeloJacobo/DDR3_Controller#developer-documentation)
|
||||
|
||||
|
||||
# Brief Description
|
||||
This DDR3 controller was originally designed to be used on the [10-Gigabit Ethernet Project](https://github.com/ZipCPU/eth10g) for an 8-lane x8 DDR3 module running at 800 MHz DDR, but this is now being designed to be a more general DDR3 memory controller with multiple supported FPGA boards. This is a 4:1 memory controller with configurable timing parameters and mode registers so it can be configured to any DDR3 memory device. The user-interface is the basic Wishbone.
|
||||
|
||||
This memory controller is optimized to maintain a high data throughput and continuous sequential burst operations. The controller handles the reset sequence, refresh sequence, mode register configuration, bank status tracking, timing delay tracking, command issuing, and the PHY's calibration. The PHY's calibration handles the bitslip training, read-DQ/DQS alignment via MPR (read calibration), write-DQ/DQS alignment via write leveling (write calibration), and also an optional comprehensive read/write test.
|
||||
|
||||
The optional comprehensive read/write tests made it easier to test the memory controller without needing an external CPU. These tests include a burst access, random access, and alternating read-write access tests. Only if no error is found on these tests will the calibration end and user can start accessing the wishbone interface.
|
||||
|
||||
This design is [formally verified](https://github.com/AngeloJacobo/DDR3_Controller#lint-and-formal-verification) and [simulated using the Micron DDR3 model](https://github.com/AngeloJacobo/DDR3_Controller#simulation).
|
||||
|
||||
# Getting Started
|
||||
The recommended way to instantiate this IP is to use the top module [`rtl/ddr3_top.v`](https://github.com/AngeloJacobo/DDR3_Controller/blob/main/rtl/ddr3_top.v), a template for instantiation is also included in that file. Steps to include this DDR3 memory controller IP is to instantiate design, create the constraint file, then edit the localparams.
|
||||
|
||||
## :heavy_check_mark: Instantiate Design
|
||||
The first thing to edit are the **top-level parameters**:
|
||||
|
||||
| Parameter | Function |
|
||||
| :---: | :--- |
|
||||
| CONTROLLER_CLK_PERIOD | clock period of the controller interface in picoseconds. Tested values range from `12_000` ps (83.33 MHz) to `10_000` ps (100 MHz). |
|
||||
| DDR3_CLK_PERIOD | clock period of the DDR3 RAM device in picoseconds which must be 1/4 of the `CONTROLLER_CLK_PERIOD`. Tested values range from `3_000` ps (333.33 MHz) to `2_500` ps (400 MHz). |
|
||||
| ROW_BITS | width of row address. Use chapter _2.11 DDR3 SDRAM Addressing_ from [JEDEC DDR3 doc (page 15)](https://www.jedec.org/sites/default/files/docs/JESD79-3F.pdf) as a guide. Possible values range from `12` to `16`. |
|
||||
| COL_BITS | width of column address. Use chapter _2.11 DDR3 SDRAM Addressing_ from [JEDEC DDR3 doc (page 15)](https://www.jedec.org/sites/default/files/docs/JESD79-3F.pdf) as a guide. Possible values range from `10` to `12`. |
|
||||
| BA_BITS | width of bank address. Use chapter _2.11 DDR3 SDRAM Addressing_ from [JEDEC DDR3 doc (page 15)](https://www.jedec.org/sites/default/files/docs/JESD79-3F.pdf) as a guide. Usual value is `3`.
|
||||
| BYTE_LANES | number of bytes based on width of DQ. <sup>[[1]](https://github.com/AngeloJacobo/DDR3_Controller#note) </sup> |
|
||||
| AUX_WIDTH | width of auxiliary line. Value must be >= 4. <sup>[[2]](https://github.com/AngeloJacobo/DDR3_Controller#note) </sup> |
|
||||
| WB2_ADDR_BITS | width of 2nd wishbone address bus for debugging (only relevant if SECOND_WISHBONE = 1). |
|
||||
| WB2_DATA_BITS | width of 2nd wishbone data bus for debugging (only relevant if SECOND_WISHBONE = 1). |
|
||||
| MICRON_SIM | set to 1 if used in Micron DDR3 model to shorten power-on sequence, otherwise 0. |
|
||||
| ODELAY_SUPPORTED | set to 1 if ODELAYE2 primitive is supported by the FPGA, otherwise 0. <sup>[[3]](https://github.com/AngeloJacobo/DDR3_Controller#note) </sup> |
|
||||
| SECOND_WISHBONE | set to 1 if 2nd wishbone for debugging is needed , otherwise 0.|
|
||||
|
||||
|
||||
***
|
||||
|
||||
After the parameters, connect the ports of the top module to your design. Below are the **ports for clocks and reset**:
|
||||
| Ports | Function |
|
||||
| :---: | :--- |
|
||||
| i_controller_clk | clock of the controller interface with period of `CONTROLLER_CLK_PERIOD` |
|
||||
| i_ddr3_clk | clock of the DDR3 interface with period of `DDR3_CLK_PERIOD` |
|
||||
| i_ref_clk | reference clock for IDELAYCTRL primitive with frequency of 200 MHz |
|
||||
| i_ddr3_clk_90 | clock required only if ODELAY_SUPPORTED = 0, otherwise can be left unconnected. Has a period of `DDR3_CLK_PERIOD` with 90° phase shift. |
|
||||
| i_rst_n | Active-low synchronous reset for the entire DDR3 controller and PHY |
|
||||
|
||||
It is recommended to generate all these clocks from a single PLL or clock-generator.
|
||||
|
||||
***
|
||||
|
||||
Next are the **main wishbone ports**:
|
||||
|
||||
| Ports | Function |
|
||||
| :---: | :--- |
|
||||
| i_wb_cyc | Indicates if a bus cycle is active. A high value (1) signifies normal operation, while a low value (0) signals the cancellation of all ongoing transactions. |
|
||||
| i_wb_stb | Strobe or transfer request signal. It's asserted (set to 1) to request a data transfer. |
|
||||
| i_wb_we | Write-enable signal. A high value (1) indicates a write operation, and a low value (0) indicates a read operation. |
|
||||
| i_wb_addr | Address bus. Used to specify the address for the current read or write operation. Formatted as {row, bank, column}. |
|
||||
| i_wb_data | Data bus for write operations. In a 4:1 controller, the data width is 8 times the DDR3 pins `8`x`DQ_BITS`x`LANES`. |
|
||||
| i_wb_sel | Byte select for write operations. Indicates which bytes of the data bus are to be overwritten for the write operation. |
|
||||
| o_wb_stall | Indicates if the controller is busy (1)and cannot accept any new requests. |
|
||||
| o_wb_ack | Acknowledgement signal. Indicates that a read or write request has been completed. |
|
||||
| o_wb_data | Data bus for read operations. Similar to `i_wb_data`, the data width for a 4:1 controller is 8 times the DDR3 pins `8`x`DQ_BITS`x`LANES`. |
|
||||
|
||||
***
|
||||
|
||||
Below are the **auxiliary ports** associated with the main wishbone. This is not required for normal operation, but is intended for AXI-interface compatibility *which is not yet available*:
|
||||
| Ports | Function |
|
||||
| :---: | :--- |
|
||||
| i_aux | Request ID line with width of `AUX_WIDTH`. The Request ID is retrieved simultaneously with the strobe request. |
|
||||
| o_aux | Request ID line with width of `AUX_WIDTH`. The Request ID is sent back concurrently with the acknowledgement signal. |
|
||||
|
||||
|
||||
***
|
||||
|
||||
After main wishbone port are the **second-wishbone ports**. This interface is only for debugging-purposes and would normally not be needed thus can be left unconnected by setting `SECOND_WISHBONE` = 0. The ports for the second-wishbone is very much the same as the main wishbone.
|
||||
|
||||
Next are the **DDR3 I/O ports**, these will be connected directly to the top-level pins of your design thus port-names must match what is indicated on your constraint file. You do not need to understand what each DDR3 I/O ports does but if you're curious, details on each DDR3 I/O pins are described on _2.10 Pinout Description_ from [JEDEC DDR3 doc (page 13)](https://www.jedec.org/sites/default/files/docs/JESD79-3F.pdf).
|
||||
|
||||
Finally are the **debug ports**, these are connected to relevant registers containing information on current state of the controller. Trace each `o_debug_*` inside `ddr3_controller.v` to edit the registers to be monitored.
|
||||
|
||||
## :heavy_check_mark: Create Constraint File
|
||||
* One example of constraint file is from the [Kintex-7 Ethernet Switch Project](https://github.com/AngeloJacobo/DDR3_Controller/blob/main/example_demo/klusterlab/kluster.xdc#L227-L389) <sup>[[4]](https://github.com/AngeloJacobo/DDR3_Controller#note) </sup>, highlighted are all the DDR3 pins. This constraint file assumes a dual-rank DDR3 RAM (thus 2 pairs of `o_ddr3_clk`, `o_ddr3_cke`, `o_ddr3_s_n`, and `o_ddr3_odt`) with 8 lanes of x8 DDR3 (thus 8 `o_ddr3_dm`, 8 `io_ddr3_dqs`, and 64 `io_ddr3_dq`). The constraint file also has [set_property](https://github.com/AngeloJacobo/DDR3_Controller/blob/main/example_demo/klusterlab/kluster.xdc#L453-L457) required for proper operation. The property `INTERNAL_VREF` must be set to half of the bank voltage (1.5V thus set to `0.75`). The property `BITSTREAM.STARTUP.MATCH_CYCLE` ([page 240 of UG628: Command Line Guide](https://docs.xilinx.com/v/u/en-US/devref)) is verified to work properly when value is set to `6`. Kintex-7 has HP bank where the DDR3 is connected thus allow the use of DCI (Digitally-Controlled Impedance) for impedance matching by using `SSTL15_T_DCI` type of `IOSTANDARD`.
|
||||
|
||||
* Another example of constraint file is for the [Arty-S7 project]( https://github.com/AngeloJacobo/UberDDR3/blob/main/example_demo/arty_s7/Arty-S7-50-Master.xdc#L24-L244), highlighted are the DDR3 pins. The Arty-S7 has x16 DDR3 and it works like two x8 (thus 2 `ddr3_dm`, 2 `ddr3_dqs`, and 16 `io_ddr3_dq`) <sup>[[1]](https://github.com/AngeloJacobo/DDR3_Controller#note) </sup>. Arty-S7 only has HR bank where the DDR3 is connected, this restricts the design to use on-chip split-termination [(UG471 7-Series Select Guide page 33)](https://docs.xilinx.com/v/u/en-US/ug471_7Series_SelectIO) for impedance matching instead of DCI used in HP banks. `IN_TERM UNTUNED_SPLIT_50` signifies that the input termination is set to an untuned split termination of 50 ohms. The constraint file was easily created by retrieving the pin constraints generated by the Vivado Memory Interface Generator (MIG) together with the [`.prj` file](https://github.com/Digilent/vivado-boards/blob/master/new/board_files/arty-s7-50/B.0/mig.prj#L47-L96) provided by Digilent for Arty-S7. The generated `.xdc` file by the MIG can be located at `[vivado_proj].gen/sources_1/ip/mig_7series_0/mig_7series_0/user_design/constraints/mig_7series_0.xdc`
|
||||
|
||||
## :heavy_check_mark: Edit Localparams
|
||||
The verilog file [`rtl/ddr3_controller`](https://github.com/AngeloJacobo/DDR3_Controller/blob/main/rtl/ddr3_controller.v) contains the timing parameters that needs to be configured by the user to align with the DDR3 device. User should base the timing values on _Chapter 13 Electrical Characteristics and AC Timing_ from [JEDEC DDR3 doc (page 169)](https://www.jedec.org/sites/default/files/docs/JESD79-3F.pdf). _The default values on the verilog file should generally work for DDR3-800_.
|
||||
|
||||
### Note:
|
||||
[1]: For x16 DDR3 like in Arty S7, use `BYTE_LANES` of 2. If the memory configuration is a SO-DIMM with 8 DDR3 RAM modules, each being x8 to form a total of 64 bits of data, then BYTE_LANES would be 8.
|
||||
[2]: The auxiliary line is intended for AXI-interface compatibility but is also utilized in the reset sequence, which is the origin of the minimum required width of 4.
|
||||
[3]: ODELAYE2 is supported if DDR3 device is connected to an HP (High-Powered) bank of FPGA. HR (High-Rank) bank does not support ODELAYE2 as based on [UG471 7-Series Select Guide (page 134)](https://docs.xilinx.com/v/u/en-US/ug471_7Series_SelectIO).
|
||||
[4]: This is the open-sourced [10Gb Ethernet Project](https://github.com/ZipCPU/eth10g).
|
||||
|
||||
|
||||
***
|
||||
|
||||
# Lint and Formal Verification
|
||||
The easiest way to compile, lint, and formally verify the design is to run [`./run_compile.sh`](https://github.com/AngeloJacobo/DDR3_Controller/blob/main/run_compile.sh) on the top-level directory. This will first run [Verilator](https://verilator.org/guide/latest/install.html) lint.
|
||||
|
||||
Next is compilation with [Yosys](https://github.com/YosysHQ/yosys), this will show warnings:
|
||||
> Warning: Replacing memory ... with list of registers.
|
||||
|
||||
Disregards this kind of warning as it just converts small memory elements in the design into a series of register elements.
|
||||
|
||||
After Yosys compilation is [Icarus Verilog](https://github.com/steveicarus/iverilog) compilation, this should not show any warning or errors but will display the `Test Functions` to verify that the verilog-functions return the correct values, and `Controller Parameters` to verify the top-level parameters are set properly. Delay values for some timing parameters are also shown.
|
||||
|
||||
Last is the [Symbiyosys Formal Verification](https://symbiyosys.readthedocs.io/en/latest/install.html), this will run the [single and multiple configuration sby](https://github.com/AngeloJacobo/UberDDR3/tree/main/formal) for formal verification. A summary is shown at the end where all tasks passed:
|
||||
|
||||

|
||||
|
||||
|
||||
# Simulation
|
||||
|
||||
For simulation, the DDR3 SDRAM Verilog [Model from Micron](https://www.micron.com/search-results?searchRequest=%7B%22term%22%3A%22DDR3%20model%22%7D) is used. Import all simulation files under [./testbench](https://github.com/AngeloJacobo/DDR3_Controller/tree/main/testbench) to Vivado. [`ddr3_dimm_micron_sim.sv`](https://github.com/AngeloJacobo/DDR3_Controller/blob/main/testbench/ddr3_dimm_micron_sim.sv) is the top-level module which instantiates both the DDR3 memory controller and the Micron DDR3 model. This module issues read and write requests to the controller via the wishbone bus, then the returned data from read requests are verified if it matches the data written. Both sequential and random accesses are tested.
|
||||
|
||||
Currently, there are 2 general options for running the simulation and is defined by a `define` directive on the `ddr3_dimm_micron_sim.sv` file: `TWO_LANES_x8` and `EIGHT_LANES_x8`. `TWO_LANES_x8` simulates an Arty-S7 FPGA board which has an x16 DDR3, meanwhile `EIGHT_LANES_x8` simulates 8-lanes of x8 DDR3 module. **Make sure to change the organization via a `define` directive under [ddr3.sv](https://github.com/AngeloJacobo/DDR3_Controller/blob/main/testbench/ddr3.sv)** (`TWO_LANES_x8` must use `define x8` while `EIGHT_LANES_x8` must use `define x16`).
|
||||
|
||||
|
||||
After configuring, run simulation. The `ddr3_dimm_micron_sim_behav.wcfg` contains the waveform. Shown below are the clocks:
|
||||

|
||||
|
||||
|
||||
As shown below, `command_used` shows the command issued at a specific time. During reads the `dqs` should toggle and `dq` should have a valid value, else they must be in high-impedance `Z`. Precharge and activate also happens between reads when row addresses are different.
|
||||

|
||||
|
||||
|
||||
A part of internal test is to do alternate write then read consecutively as shown below. The data written must match the data read. `dqs` should also toggle along with the data written and read.
|
||||

|
||||
|
||||
|
||||
There are counters for the number of correct and wrong read data during the internal read/write test: `correct_read_data` and `wrong_read_data`. As shown below, the `wrong_read_data` must remain zero while `correct_read_data` must increment until it reaches the maximum (3499 on this example).
|
||||

|
||||
|
||||
The simulation also reports the status of the simulation. For example, the report below:
|
||||
> [10000 ps] RD @ (0, 840) -> [10000 ps] RD @ (0, 848) -> [10000 ps] RD @ (0, 856) -> [10000 ps] RD @ (0, 864) -> [10000 ps] RD @ (0, 872) ->
|
||||
|
||||
The format is [`time_delay`] `command` @ (`bank`, `address`), so `[10000 ps] RD @ (0, 840)` means 10000 ps delay before a read command with bank 0 and address 840. Notice how each read command has a delay of 10000 ps or 10 ns from each other, since this has a controller clock of 100 MHz (10 ns clock period) this shows that there are no interruptions between sequential read commands resulting in a very high throughput.
|
||||
|
||||
A short report is also shown in each test section:
|
||||
> DONE TEST 1: LAST ROW
|
||||
Number of Operations: 2304
|
||||
Time Started: 363390 ns
|
||||
Time Done: 387980 ns
|
||||
Average Rate: 10 ns/request
|
||||
|
||||
|
||||
This report is after a burst write then burst read. This report means there were 2304 write and read operation, and the average time per request is 10 ns (1 controller clock period of 100 MHz). The average rate is optimal since this is a burst write and read. But for random writes and reads:
|
||||
> DONE TEST 2: RANDOM
|
||||
Number of Operations: 2304
|
||||
Time Started: 387980 ns
|
||||
Time Done: 497660 ns
|
||||
Average Rate: 47 ns/request
|
||||
|
||||
|
||||
Notice how the average rate increased to 47 ns/request. Random access requires occasional precharge and activate which takes time and thus prolong the time for every read or write access. At the very end of the report shows a summary:
|
||||
|
||||
> TEST CALIBRATION
|
||||
[-]: write_test_address_counter = 5000
|
||||
[-]: read_test_address_counter = 2000
|
||||
[-]: correct_read_data = 3499
|
||||
[-]: wrong_read_data = 0
|
||||
|
||||
> ------- SUMMARY -------
|
||||
Number of Writes = 4608
|
||||
Number of Reads = 4608
|
||||
Number of Success = 4604
|
||||
Number of Fails = 4
|
||||
Number of Injected Errors = 4
|
||||
|
||||
The summary under `TEST CALIBRATION` are the results from the **internal** read/write test as part of the internal calibration. These are the same counters on the waveform shown before where the `wrong_read_data` should be zero. Under `SUMMARY` is the report from the **external** read/write test where the top-level simulation file `ddr3_dimm_micron_sim.sv` sends read/write request to the DDR3 controller via the wishbone bus. Notice that the number of fails (4) matches the number of injected errors (4) which is only proper.
|
||||
|
||||
# Demo Projects
|
||||
- The [Arty-S7 demo project](./example_demo/arty_s7) is a basic project for testing the DDR3 controller. The gist is that the 4 LEDS should light-up which means reset sequence is done and all internal read/write test passed during calibration. This project also uses a UART line, sending small letters via UART will write those corresponding small letters to memory, meanwhile sending capital letters will read those small letters back from memory.
|
||||
- To run this project on your Arty-S7 board, import all verilog files and xdc file under `example_demo/arty_s7/` and `rtl/`. Run synthesis-to-bitstream generation then upload the bitfile. After around 2 seconds, the 4 LEDS should light up then you can start interacting with the UART line. BTN0 button is for reset.
|
||||
- Or just upload the [bitfile already given in the repo](./example_demo/arty_s7).
|
||||
|
||||
- The [Nexys Video demo project](./example_demo/nexys_video) utilizes the DDR3 chip on the Digilent Nexys Video board with xc7a200t. Only one lane is used for simplicity. Supports OpenXC7 toolchain. Makefiles have been included for quick start, just run the following command in the root directory of repo:
|
||||
|
||||
- Vivado compilation: `source /opt/Xilinx/Vivado/2019.1/settings64.sh` then `make -C example_demo/nexys_video -f Makefile.vivado`
|
||||
- OpenXC7 compilation (using toolchain in Docker): `docker run --rm -v .:/mnt -v /chipdb:/chipdb regymm/openxc7 make -C /mnt/nexys_video -f Makefile.openxc7`
|
||||
|
||||
The bitstream will be compiled as `nexys_video/build/top.bit`.
|
||||
|
||||
- Board test: after programming bitstream, the 8 LEDs will show some pattern, then become all lit up after calibration. When pressing BTND(D22), LD7/LD6 will show a blinky, and LD5-LD0 will show 101110 after successful calibration. BTNC(B22) resets the controller, and calibration will be redone. 9600 baud UART will be the same as the Arty-S7 case: type small `abcd` to write to memory, and type capital `ABCD` to read back. For example, type `abcd` then `ABCDEFGH` will show `abcd<63><64><EFBFBD><EFBFBD>` (because EFGH memory locations are not written yet).
|
||||
- The [QMTech Wukong demo project](./example_demo/qmtech_wukong) is just the same as the arty-s7 demo mentioned above.
|
||||
- To run this project on your [QMTech Wukong board](https://github.com/ChinaQMTECH/QM_XC7A100T_WUKONG_BOARD/tree/master/V3), import all verilog files and xdc file under `example_demo/qmtech_wukong/` and `rtl/`. Run synthesis-to-bitstream generation then upload the bitfile. After around 2 seconds, the 2 LEDS should light up then you can start interacting with the UART line. SW2 button is for reset.
|
||||
- Or just upload the [bitfile already given in the repo](./example_demo/qmtech_wukong).
|
||||
-
|
||||
- The [10Gb Ethernet Switch](https://github.com/ZipCPU/eth10g) project utilizes this DDR3 controller for accessing a single-rank DDR3 module (8 lanes of x8 DDR3) at DDR3-800 (100 MHz controller and 400 MHz PHY).
|
||||
|
||||
# Other Open-Sourced DDR3 Controllers
|
||||
(soon...)
|
||||
|
||||
# Developer Documentation
|
||||
There is no developer documentation yet. But may I include here the [notes I compiled](https://github.com/AngeloJacobo/DDR3-Notes) when I did an intensive study on DDR3 before I started this project.
|
||||
|
||||
# Acknowledgement
|
||||
This project is funded through [NGI0 Entrust](https://nlnet.nl/entrust), a fund established by [NLnet](https://nlnet.nl) with financial support from the European Commission's [Next Generation Internet](https://ngi.eu) program. Learn more at the [NLnet project page](https://nlnet.nl/project/UberDDR3).
|
||||
|
||||
[<img src="https://nlnet.nl/logo/banner.png" alt="NLnet foundation logo" width="20%" />](https://nlnet.nl)
|
||||
[<img src="https://nlnet.nl/image/logos/NGI0_tag.svg" alt="NGI Zero Logo" width="20%" />](https://nlnet.nl/entrust)
|
||||
|
||||
# Table of Contents
|
||||
- [Brief Description](https://github.com/AngeloJacobo/DDR3_Controller#brief-description)
|
||||
- [Getting Started](https://github.com/AngeloJacobo/DDR3_Controller#getting-started)
|
||||
- [Instantiate Design](https://github.com/AngeloJacobo/DDR3_Controller#heavy_check_mark-instantiate-design)
|
||||
- [Create Constraint File](https://github.com/AngeloJacobo/DDR3_Controller#heavy_check_mark-create-constraint-file)
|
||||
- [Edit Localparams](https://github.com/AngeloJacobo/DDR3_Controller#heavy_check_mark-edit-localparams)
|
||||
- [Lint and Formal Verification](https://github.com/AngeloJacobo/DDR3_Controller#lint-and-formal-verification)
|
||||
- [Simulation](https://github.com/AngeloJacobo/DDR3_Controller#simulation)
|
||||
- [Demo Projects](https://github.com/AngeloJacobo/UberDDR3/tree/main?tab=readme-ov-file#demo-projects)
|
||||
- [Other Open-Sourced DDR3 Controllers](https://github.com/AngeloJacobo/DDR3_Controller#other-open-sourced-ddr3-controllers)
|
||||
- [Developer Documentation](https://github.com/AngeloJacobo/DDR3_Controller#developer-documentation)
|
||||
|
||||
|
||||
# Brief Description
|
||||
This DDR3 controller was originally designed to be used on the [10-Gigabit Ethernet Project](https://github.com/ZipCPU/eth10g) for an 8-lane x8 DDR3 module running at 800 MHz DDR, but this is now being designed to be a more general DDR3 memory controller with multiple supported FPGA boards. This is a 4:1 memory controller with configurable timing parameters and mode registers so it can be configured to any DDR3 memory device. The user-interface is the basic Wishbone.
|
||||
|
||||
This memory controller is optimized to maintain a high data throughput and continuous sequential burst operations. The controller handles the reset sequence, refresh sequence, mode register configuration, bank status tracking, timing delay tracking, command issuing, and the PHY's calibration. The PHY's calibration handles the bitslip training, read-DQ/DQS alignment via MPR (read calibration), write-DQ/DQS alignment via write leveling (write calibration), and also an optional comprehensive read/write test.
|
||||
|
||||
The optional comprehensive read/write tests made it easier to test the memory controller without needing an external CPU. These tests include a burst access, random access, and alternating read-write access tests. Only if no error is found on these tests will the calibration end and user can start accessing the wishbone interface.
|
||||
|
||||
This design is [formally verified](https://github.com/AngeloJacobo/DDR3_Controller#lint-and-formal-verification) and [simulated using the Micron DDR3 model](https://github.com/AngeloJacobo/DDR3_Controller#simulation).
|
||||
|
||||
# Getting Started
|
||||
The recommended way to instantiate this IP is to use the top module [`rtl/ddr3_top.v`](https://github.com/AngeloJacobo/DDR3_Controller/blob/main/rtl/ddr3_top.v), a template for instantiation is also included in that file. Steps to include this DDR3 memory controller IP is to instantiate design, create the constraint file, then edit the localparams.
|
||||
|
||||
## :heavy_check_mark: Instantiate Design
|
||||
The first thing to edit are the **top-level parameters**:
|
||||
|
||||
| Parameter | Function |
|
||||
| :---: | :--- |
|
||||
| CONTROLLER_CLK_PERIOD | clock period of the controller interface in picoseconds. Tested values range from `12_000` ps (83.33 MHz) to `10_000` ps (100 MHz). |
|
||||
| DDR3_CLK_PERIOD | clock period of the DDR3 RAM device in picoseconds which must be 1/4 of the `CONTROLLER_CLK_PERIOD`. Tested values range from `3_000` ps (333.33 MHz) to `2_500` ps (400 MHz). |
|
||||
| ROW_BITS | width of row address. Use chapter _2.11 DDR3 SDRAM Addressing_ from [JEDEC DDR3 doc (page 15)](https://www.jedec.org/sites/default/files/docs/JESD79-3F.pdf) as a guide. Possible values range from `12` to `16`. |
|
||||
| COL_BITS | width of column address. Use chapter _2.11 DDR3 SDRAM Addressing_ from [JEDEC DDR3 doc (page 15)](https://www.jedec.org/sites/default/files/docs/JESD79-3F.pdf) as a guide. Possible values range from `10` to `12`. |
|
||||
| BA_BITS | width of bank address. Use chapter _2.11 DDR3 SDRAM Addressing_ from [JEDEC DDR3 doc (page 15)](https://www.jedec.org/sites/default/files/docs/JESD79-3F.pdf) as a guide. Usual value is `3`.
|
||||
| BYTE_LANES | number of bytes based on width of DQ. <sup>[[1]](https://github.com/AngeloJacobo/DDR3_Controller#note) </sup> |
|
||||
| AUX_WIDTH | width of auxiliary line. Value must be >= 4. <sup>[[2]](https://github.com/AngeloJacobo/DDR3_Controller#note) </sup> |
|
||||
| WB2_ADDR_BITS | width of 2nd wishbone address bus for debugging (only relevant if SECOND_WISHBONE = 1). |
|
||||
| WB2_DATA_BITS | width of 2nd wishbone data bus for debugging (only relevant if SECOND_WISHBONE = 1). |
|
||||
| MICRON_SIM | set to 1 if used in Micron DDR3 model to shorten power-on sequence, otherwise 0. |
|
||||
| ODELAY_SUPPORTED | set to 1 if ODELAYE2 primitive is supported by the FPGA, otherwise 0. <sup>[[3]](https://github.com/AngeloJacobo/DDR3_Controller#note) </sup> |
|
||||
| SECOND_WISHBONE | set to 1 if 2nd wishbone for debugging is needed , otherwise 0.|
|
||||
|
||||
|
||||
***
|
||||
|
||||
After the parameters, connect the ports of the top module to your design. Below are the **ports for clocks and reset**:
|
||||
| Ports | Function |
|
||||
| :---: | :--- |
|
||||
| i_controller_clk | clock of the controller interface with period of `CONTROLLER_CLK_PERIOD` |
|
||||
| i_ddr3_clk | clock of the DDR3 interface with period of `DDR3_CLK_PERIOD` |
|
||||
| i_ref_clk | reference clock for IDELAYCTRL primitive with frequency of 200 MHz |
|
||||
| i_ddr3_clk_90 | clock required only if ODELAY_SUPPORTED = 0, otherwise can be left unconnected. Has a period of `DDR3_CLK_PERIOD` with 90° phase shift. |
|
||||
| i_rst_n | Active-low synchronous reset for the entire DDR3 controller and PHY |
|
||||
|
||||
It is recommended to generate all these clocks from a single PLL or clock-generator.
|
||||
|
||||
***
|
||||
|
||||
Next are the **main wishbone ports**:
|
||||
|
||||
| Ports | Function |
|
||||
| :---: | :--- |
|
||||
| i_wb_cyc | Indicates if a bus cycle is active. A high value (1) signifies normal operation, while a low value (0) signals the cancellation of all ongoing transactions. |
|
||||
| i_wb_stb | Strobe or transfer request signal. It's asserted (set to 1) to request a data transfer. |
|
||||
| i_wb_we | Write-enable signal. A high value (1) indicates a write operation, and a low value (0) indicates a read operation. |
|
||||
| i_wb_addr | Address bus. Used to specify the address for the current read or write operation. Formatted as {row, bank, column}. |
|
||||
| i_wb_data | Data bus for write operations. In a 4:1 controller, the data width is 8 times the DDR3 pins `8`x`DQ_BITS`x`LANES`. |
|
||||
| i_wb_sel | Byte select for write operations. Indicates which bytes of the data bus are to be overwritten for the write operation. |
|
||||
| o_wb_stall | Indicates if the controller is busy (1)and cannot accept any new requests. |
|
||||
| o_wb_ack | Acknowledgement signal. Indicates that a read or write request has been completed. |
|
||||
| o_wb_data | Data bus for read operations. Similar to `i_wb_data`, the data width for a 4:1 controller is 8 times the DDR3 pins `8`x`DQ_BITS`x`LANES`. |
|
||||
|
||||
***
|
||||
|
||||
Below are the **auxiliary ports** associated with the main wishbone. This is not required for normal operation, but is intended for AXI-interface compatibility *which is not yet available*:
|
||||
| Ports | Function |
|
||||
| :---: | :--- |
|
||||
| i_aux | Request ID line with width of `AUX_WIDTH`. The Request ID is retrieved simultaneously with the strobe request. |
|
||||
| o_aux | Request ID line with width of `AUX_WIDTH`. The Request ID is sent back concurrently with the acknowledgement signal. |
|
||||
|
||||
|
||||
***
|
||||
|
||||
After main wishbone port are the **second-wishbone ports**. This interface is only for debugging-purposes and would normally not be needed thus can be left unconnected by setting `SECOND_WISHBONE` = 0. The ports for the second-wishbone is very much the same as the main wishbone.
|
||||
|
||||
Next are the **DDR3 I/O ports**, these will be connected directly to the top-level pins of your design thus port-names must match what is indicated on your constraint file. You do not need to understand what each DDR3 I/O ports does but if you're curious, details on each DDR3 I/O pins are described on _2.10 Pinout Description_ from [JEDEC DDR3 doc (page 13)](https://www.jedec.org/sites/default/files/docs/JESD79-3F.pdf).
|
||||
|
||||
Finally are the **debug ports**, these are connected to relevant registers containing information on current state of the controller. Trace each `o_debug_*` inside `ddr3_controller.v` to edit the registers to be monitored.
|
||||
|
||||
## :heavy_check_mark: Create Constraint File
|
||||
* One example of constraint file is from the [Kintex-7 Ethernet Switch Project](https://github.com/AngeloJacobo/DDR3_Controller/blob/main/example_demo/klusterlab/kluster.xdc#L227-L389) <sup>[[4]](https://github.com/AngeloJacobo/DDR3_Controller#note) </sup>, highlighted are all the DDR3 pins. This constraint file assumes a dual-rank DDR3 RAM (thus 2 pairs of `o_ddr3_clk`, `o_ddr3_cke`, `o_ddr3_s_n`, and `o_ddr3_odt`) with 8 lanes of x8 DDR3 (thus 8 `o_ddr3_dm`, 8 `io_ddr3_dqs`, and 64 `io_ddr3_dq`). The constraint file also has [set_property](https://github.com/AngeloJacobo/DDR3_Controller/blob/main/example_demo/klusterlab/kluster.xdc#L453-L457) required for proper operation. The property `INTERNAL_VREF` must be set to half of the bank voltage (1.5V thus set to `0.75`). The property `BITSTREAM.STARTUP.MATCH_CYCLE` ([page 240 of UG628: Command Line Guide](https://docs.xilinx.com/v/u/en-US/devref)) is verified to work properly when value is set to `6`. Kintex-7 has HP bank where the DDR3 is connected thus allow the use of DCI (Digitally-Controlled Impedance) for impedance matching by using `SSTL15_T_DCI` type of `IOSTANDARD`.
|
||||
|
||||
* Another example of constraint file is for the [Arty-S7 project]( https://github.com/AngeloJacobo/UberDDR3/blob/main/example_demo/arty_s7/Arty-S7-50-Master.xdc#L24-L244), highlighted are the DDR3 pins. The Arty-S7 has x16 DDR3 and it works like two x8 (thus 2 `ddr3_dm`, 2 `ddr3_dqs`, and 16 `io_ddr3_dq`) <sup>[[1]](https://github.com/AngeloJacobo/DDR3_Controller#note) </sup>. Arty-S7 only has HR bank where the DDR3 is connected, this restricts the design to use on-chip split-termination [(UG471 7-Series Select Guide page 33)](https://docs.xilinx.com/v/u/en-US/ug471_7Series_SelectIO) for impedance matching instead of DCI used in HP banks. `IN_TERM UNTUNED_SPLIT_50` signifies that the input termination is set to an untuned split termination of 50 ohms. The constraint file was easily created by retrieving the pin constraints generated by the Vivado Memory Interface Generator (MIG) together with the [`.prj` file](https://github.com/Digilent/vivado-boards/blob/master/new/board_files/arty-s7-50/B.0/mig.prj#L47-L96) provided by Digilent for Arty-S7. The generated `.xdc` file by the MIG can be located at `[vivado_proj].gen/sources_1/ip/mig_7series_0/mig_7series_0/user_design/constraints/mig_7series_0.xdc`
|
||||
|
||||
## :heavy_check_mark: Edit Localparams
|
||||
The verilog file [`rtl/ddr3_controller`](https://github.com/AngeloJacobo/DDR3_Controller/blob/main/rtl/ddr3_controller.v) contains the timing parameters that needs to be configured by the user to align with the DDR3 device. User should base the timing values on _Chapter 13 Electrical Characteristics and AC Timing_ from [JEDEC DDR3 doc (page 169)](https://www.jedec.org/sites/default/files/docs/JESD79-3F.pdf). _The default values on the verilog file should generally work for DDR3-800_.
|
||||
|
||||
### Note:
|
||||
[1]: For x16 DDR3 like in Arty S7, use `BYTE_LANES` of 2. If the memory configuration is a SO-DIMM with 8 DDR3 RAM modules, each being x8 to form a total of 64 bits of data, then BYTE_LANES would be 8.
|
||||
[2]: The auxiliary line is intended for AXI-interface compatibility but is also utilized in the reset sequence, which is the origin of the minimum required width of 4.
|
||||
[3]: ODELAYE2 is supported if DDR3 device is connected to an HP (High-Powered) bank of FPGA. HR (High-Rank) bank does not support ODELAYE2 as based on [UG471 7-Series Select Guide (page 134)](https://docs.xilinx.com/v/u/en-US/ug471_7Series_SelectIO).
|
||||
[4]: This is the open-sourced [10Gb Ethernet Project](https://github.com/ZipCPU/eth10g).
|
||||
|
||||
|
||||
***
|
||||
|
||||
# Lint and Formal Verification
|
||||
The easiest way to compile, lint, and formally verify the design is to run [`./run_compile.sh`](https://github.com/AngeloJacobo/DDR3_Controller/blob/main/run_compile.sh) on the top-level directory. This will first run [Verilator](https://verilator.org/guide/latest/install.html) lint.
|
||||
|
||||
Next is compilation with [Yosys](https://github.com/YosysHQ/yosys), this will show warnings:
|
||||
> Warning: Replacing memory ... with list of registers.
|
||||
|
||||
Disregards this kind of warning as it just converts small memory elements in the design into a series of register elements.
|
||||
|
||||
After Yosys compilation is [Icarus Verilog](https://github.com/steveicarus/iverilog) compilation, this should not show any warning or errors but will display the `Test Functions` to verify that the verilog-functions return the correct values, and `Controller Parameters` to verify the top-level parameters are set properly. Delay values for some timing parameters are also shown.
|
||||
|
||||
Last is the [Symbiyosys Formal Verification](https://symbiyosys.readthedocs.io/en/latest/install.html), this will run the [single and multiple configuration sby](https://github.com/AngeloJacobo/UberDDR3/tree/main/formal) for formal verification. A summary is shown at the end where all tasks passed:
|
||||
|
||||

|
||||
|
||||
|
||||
# Simulation
|
||||
|
||||
For simulation, the DDR3 SDRAM Verilog [Model from Micron](https://www.micron.com/search-results?searchRequest=%7B%22term%22%3A%22DDR3%20model%22%7D) is used. Import all simulation files under [./testbench](https://github.com/AngeloJacobo/DDR3_Controller/tree/main/testbench) to Vivado. [`ddr3_dimm_micron_sim.sv`](https://github.com/AngeloJacobo/DDR3_Controller/blob/main/testbench/ddr3_dimm_micron_sim.sv) is the top-level module which instantiates both the DDR3 memory controller and the Micron DDR3 model. This module issues read and write requests to the controller via the wishbone bus, then the returned data from read requests are verified if it matches the data written. Both sequential and random accesses are tested.
|
||||
|
||||
Currently, there are 2 general options for running the simulation and is defined by a `define` directive on the `ddr3_dimm_micron_sim.sv` file: `TWO_LANES_x8` and `EIGHT_LANES_x8`. `TWO_LANES_x8` simulates an Arty-S7 FPGA board which has an x16 DDR3, meanwhile `EIGHT_LANES_x8` simulates 8-lanes of x8 DDR3 module. **Make sure to change the organization via a `define` directive under [ddr3.sv](https://github.com/AngeloJacobo/DDR3_Controller/blob/main/testbench/ddr3.sv)** (`TWO_LANES_x8` must use `define x8` while `EIGHT_LANES_x8` must use `define x16`).
|
||||
|
||||
|
||||
After configuring, run simulation. The `ddr3_dimm_micron_sim_behav.wcfg` contains the waveform. Shown below are the clocks:
|
||||

|
||||
|
||||
|
||||
As shown below, `command_used` shows the command issued at a specific time. During reads the `dqs` should toggle and `dq` should have a valid value, else they must be in high-impedance `Z`. Precharge and activate also happens between reads when row addresses are different.
|
||||

|
||||
|
||||
|
||||
A part of internal test is to do alternate write then read consecutively as shown below. The data written must match the data read. `dqs` should also toggle along with the data written and read.
|
||||

|
||||
|
||||
|
||||
There are counters for the number of correct and wrong read data during the internal read/write test: `correct_read_data` and `wrong_read_data`. As shown below, the `wrong_read_data` must remain zero while `correct_read_data` must increment until it reaches the maximum (3499 on this example).
|
||||

|
||||
|
||||
The simulation also reports the status of the simulation. For example, the report below:
|
||||
> [10000 ps] RD @ (0, 840) -> [10000 ps] RD @ (0, 848) -> [10000 ps] RD @ (0, 856) -> [10000 ps] RD @ (0, 864) -> [10000 ps] RD @ (0, 872) ->
|
||||
|
||||
The format is [`time_delay`] `command` @ (`bank`, `address`), so `[10000 ps] RD @ (0, 840)` means 10000 ps delay before a read command with bank 0 and address 840. Notice how each read command has a delay of 10000 ps or 10 ns from each other, since this has a controller clock of 100 MHz (10 ns clock period) this shows that there are no interruptions between sequential read commands resulting in a very high throughput.
|
||||
|
||||
A short report is also shown in each test section:
|
||||
> DONE TEST 1: LAST ROW
|
||||
Number of Operations: 2304
|
||||
Time Started: 363390 ns
|
||||
Time Done: 387980 ns
|
||||
Average Rate: 10 ns/request
|
||||
|
||||
|
||||
This report is after a burst write then burst read. This report means there were 2304 write and read operation, and the average time per request is 10 ns (1 controller clock period of 100 MHz). The average rate is optimal since this is a burst write and read. But for random writes and reads:
|
||||
> DONE TEST 2: RANDOM
|
||||
Number of Operations: 2304
|
||||
Time Started: 387980 ns
|
||||
Time Done: 497660 ns
|
||||
Average Rate: 47 ns/request
|
||||
|
||||
|
||||
Notice how the average rate increased to 47 ns/request. Random access requires occasional precharge and activate which takes time and thus prolong the time for every read or write access. At the very end of the report shows a summary:
|
||||
|
||||
> TEST CALIBRATION
|
||||
[-]: write_test_address_counter = 5000
|
||||
[-]: read_test_address_counter = 2000
|
||||
[-]: correct_read_data = 3499
|
||||
[-]: wrong_read_data = 0
|
||||
|
||||
> ------- SUMMARY -------
|
||||
Number of Writes = 4608
|
||||
Number of Reads = 4608
|
||||
Number of Success = 4604
|
||||
Number of Fails = 4
|
||||
Number of Injected Errors = 4
|
||||
|
||||
The summary under `TEST CALIBRATION` are the results from the **internal** read/write test as part of the internal calibration. These are the same counters on the waveform shown before where the `wrong_read_data` should be zero. Under `SUMMARY` is the report from the **external** read/write test where the top-level simulation file `ddr3_dimm_micron_sim.sv` sends read/write request to the DDR3 controller via the wishbone bus. Notice that the number of fails (4) matches the number of injected errors (4) which is only proper.
|
||||
|
||||
# Demo Projects
|
||||
- The [Arty-S7 demo project](./example_demo/arty_s7) is a basic project for testing the DDR3 controller. The gist is that the 4 LEDS should light-up which means reset sequence is done and all internal read/write test passed during calibration. This project also uses a UART line, sending small letters via UART will write those corresponding small letters to memory, meanwhile sending capital letters will read those small letters back from memory.
|
||||
- To run this project on your Arty-S7 board, import all verilog files and xdc file under `example_demo/arty_s7/` and `rtl/`. Run synthesis-to-bitstream generation then upload the bitfile. After around 2 seconds, the 4 LEDS should light up then you can start interacting with the UART line. BTN0 button is for reset.
|
||||
- Or just upload the [bitfile already given in the repo](./example_demo/arty_s7).
|
||||
|
||||
- The [Nexys Video demo project](./example_demo/nexys_video) utilizes the DDR3 chip on the Digilent Nexys Video board with xc7a200t. Only one lane is used for simplicity. Supports OpenXC7 toolchain. Makefiles have been included for quick start, just run the following command in the root directory of repo:
|
||||
|
||||
- Vivado compilation: `source /opt/Xilinx/Vivado/2019.1/settings64.sh` then `make -C example_demo/nexys_video -f Makefile.vivado`
|
||||
- OpenXC7 compilation (using toolchain in Docker): `docker run --rm -v .:/mnt -v /chipdb:/chipdb regymm/openxc7 make -C /mnt/nexys_video -f Makefile.openxc7`
|
||||
|
||||
The bitstream will be compiled as `nexys_video/build/top.bit`.
|
||||
|
||||
- Board test: after programming bitstream, the 8 LEDs will show some pattern, then become all lit up after calibration. When pressing BTND(D22), LD7/LD6 will show a blinky, and LD5-LD0 will show 101110 after successful calibration. BTNC(B22) resets the controller, and calibration will be redone. 9600 baud UART will be the same as the Arty-S7 case: type small `abcd` to write to memory, and type capital `ABCD` to read back. For example, type `abcd` then `ABCDEFGH` will show `abcd<63><64><EFBFBD><EFBFBD>` (because EFGH memory locations are not written yet).
|
||||
- The [QMTech Wukong demo project](./example_demo/qmtech_wukong) is just the same as the arty-s7 demo mentioned above.
|
||||
- To run this project on your [QMTech Wukong board](https://github.com/ChinaQMTECH/QM_XC7A100T_WUKONG_BOARD/tree/master/V3), import all verilog files and xdc file under `example_demo/qmtech_wukong/` and `rtl/`. Run synthesis-to-bitstream generation then upload the bitfile. After around 2 seconds, the 2 LEDS should light up then you can start interacting with the UART line. SW2 button is for reset.
|
||||
- Or just upload the [bitfile already given in the repo](./example_demo/qmtech_wukong).
|
||||
-
|
||||
- The [10Gb Ethernet Switch](https://github.com/ZipCPU/eth10g) project utilizes this DDR3 controller for accessing a single-rank DDR3 module (8 lanes of x8 DDR3) at DDR3-800 (100 MHz controller and 400 MHz PHY).
|
||||
|
||||
# Other Open-Sourced DDR3 Controllers
|
||||
(soon...)
|
||||
|
||||
# Developer Documentation
|
||||
There is no developer documentation yet. But may I include here the [notes I compiled](https://github.com/AngeloJacobo/DDR3-Notes) when I did an intensive study on DDR3 before I started this project.
|
||||
|
||||
# Acknowledgement
|
||||
This project is funded through [NGI0 Entrust](https://nlnet.nl/entrust), a fund established by [NLnet](https://nlnet.nl) with financial support from the European Commission's [Next Generation Internet](https://ngi.eu) program. Learn more at the [NLnet project page](https://nlnet.nl/project/UberDDR3).
|
||||
|
||||
[<img src="https://nlnet.nl/logo/banner.png" alt="NLnet foundation logo" width="20%" />](https://nlnet.nl)
|
||||
[<img src="https://nlnet.nl/image/logos/NGI0_tag.svg" alt="NGI Zero Logo" width="20%" />](https://nlnet.nl/entrust)
|
||||
|
|
|
|||
|
|
@ -1,70 +1,70 @@
|
|||
PROJECT = ax7103_ddr3
|
||||
FAMILY = artix7
|
||||
PART = xc7a100tfgg484-2
|
||||
CHIPDB = ${ARTIX7_CHIPDB}
|
||||
ADDITIONAL_SOURCES = ../../rtl/ddr3_controller.v ../../rtl/ddr3_phy.v ../../rtl/ddr3_top.v uart_rx.v uart_tx.v clk_wiz.v
|
||||
|
||||
#############################################################################################
|
||||
NEXTPNR_XILINX_DIR ?= /snap/openxc7/current/opt/nextpnr-xilinx
|
||||
NEXTPNR_XILINX_PYTHON_DIR ?= ${NEXTPNR_XILINX_DIR}/python
|
||||
PRJXRAY_DB_DIR ?= ${NEXTPNR_XILINX_DIR}/external/prjxray-db
|
||||
|
||||
DBPART = $(shell echo ${PART} | sed -e 's/-[0-9]//g')
|
||||
SPEEDGRADE = $(shell echo ${PART} | sed -e 's/.*\-\([0-9]\)/\1/g')
|
||||
|
||||
CHIPDB ?= ./
|
||||
ifeq ($(CHIPDB),)
|
||||
CHIPDB = ./
|
||||
endif
|
||||
|
||||
PYPY3 ?= pypy3
|
||||
|
||||
TOP ?= ${PROJECT}
|
||||
TOP_MODULE ?= ${TOP}
|
||||
TOP_VERILOG ?= ${TOP}.v
|
||||
|
||||
PNR_DEBUG ?= # --verbose --debug
|
||||
|
||||
BOARD ?= UNKNOWN
|
||||
JTAG_LINK ?= --board ${BOARD}
|
||||
|
||||
XDC ?= ${PROJECT}.xdc
|
||||
|
||||
.PHONY: all
|
||||
all: ${PROJECT}.bit
|
||||
|
||||
.PHONY: program
|
||||
program: ${PROJECT}.bit
|
||||
openFPGALoader ${JTAG_LINK} --bitstream $<
|
||||
|
||||
${PROJECT}.json: ${TOP_VERILOG} ${ADDITIONAL_SOURCES}
|
||||
yosys -p "synth_xilinx -flatten -abc9 ${SYNTH_OPTS} -arch xc7 -top ${TOP_MODULE}; write_json ${PROJECT}.json" $< ${ADDITIONAL_SOURCES}
|
||||
|
||||
# The chip database only needs to be generated once
|
||||
# that is why we don't clean it with make clean
|
||||
${CHIPDB}/${DBPART}.bin:
|
||||
${PYPY3} ${NEXTPNR_XILINX_PYTHON_DIR}/bbaexport.py --device ${PART} --bba ${DBPART}.bba
|
||||
bbasm -l ${DBPART}.bba ${CHIPDB}/${DBPART}.bin
|
||||
rm -f ${DBPART}.bba
|
||||
|
||||
${PROJECT}.fasm: ${PROJECT}.json ${CHIPDB}/${DBPART}.bin ${XDC}
|
||||
nextpnr-xilinx --chipdb ${CHIPDB}/${DBPART}.bin --xdc ${XDC} --json ${PROJECT}.json --fasm $@ ${PNR_ARGS} ${PNR_DEBUG}
|
||||
|
||||
${PROJECT}.frames: ${PROJECT}.fasm
|
||||
fasm2frames --part ${PART} --db-root ${PRJXRAY_DB_DIR}/${FAMILY} $< > $@
|
||||
|
||||
${PROJECT}.bit: ${PROJECT}.frames
|
||||
xc7frames2bit --part_file ${PRJXRAY_DB_DIR}/${FAMILY}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -f *.bit
|
||||
@rm -f *.frames
|
||||
@rm -f *.fasm
|
||||
@rm -f *.json
|
||||
@rm -f *.bin
|
||||
@rm -f *.bba
|
||||
|
||||
.PHONY: pnrclean
|
||||
pnrclean:
|
||||
PROJECT = ax7103_ddr3
|
||||
FAMILY = artix7
|
||||
PART = xc7a100tfgg484-2
|
||||
CHIPDB = ${ARTIX7_CHIPDB}
|
||||
ADDITIONAL_SOURCES = ../../rtl/ddr3_controller.v ../../rtl/ddr3_phy.v ../../rtl/ddr3_top.v uart_rx.v uart_tx.v clk_wiz.v
|
||||
|
||||
#############################################################################################
|
||||
NEXTPNR_XILINX_DIR ?= /snap/openxc7/current/opt/nextpnr-xilinx
|
||||
NEXTPNR_XILINX_PYTHON_DIR ?= ${NEXTPNR_XILINX_DIR}/python
|
||||
PRJXRAY_DB_DIR ?= ${NEXTPNR_XILINX_DIR}/external/prjxray-db
|
||||
|
||||
DBPART = $(shell echo ${PART} | sed -e 's/-[0-9]//g')
|
||||
SPEEDGRADE = $(shell echo ${PART} | sed -e 's/.*\-\([0-9]\)/\1/g')
|
||||
|
||||
CHIPDB ?= ./
|
||||
ifeq ($(CHIPDB),)
|
||||
CHIPDB = ./
|
||||
endif
|
||||
|
||||
PYPY3 ?= pypy3
|
||||
|
||||
TOP ?= ${PROJECT}
|
||||
TOP_MODULE ?= ${TOP}
|
||||
TOP_VERILOG ?= ${TOP}.v
|
||||
|
||||
PNR_DEBUG ?= # --verbose --debug
|
||||
|
||||
BOARD ?= UNKNOWN
|
||||
JTAG_LINK ?= --board ${BOARD}
|
||||
|
||||
XDC ?= ${PROJECT}.xdc
|
||||
|
||||
.PHONY: all
|
||||
all: ${PROJECT}.bit
|
||||
|
||||
.PHONY: program
|
||||
program: ${PROJECT}.bit
|
||||
openFPGALoader ${JTAG_LINK} --bitstream $<
|
||||
|
||||
${PROJECT}.json: ${TOP_VERILOG} ${ADDITIONAL_SOURCES}
|
||||
yosys -p "synth_xilinx -flatten -abc9 ${SYNTH_OPTS} -arch xc7 -top ${TOP_MODULE}; write_json ${PROJECT}.json" $< ${ADDITIONAL_SOURCES}
|
||||
|
||||
# The chip database only needs to be generated once
|
||||
# that is why we don't clean it with make clean
|
||||
${CHIPDB}/${DBPART}.bin:
|
||||
${PYPY3} ${NEXTPNR_XILINX_PYTHON_DIR}/bbaexport.py --device ${PART} --bba ${DBPART}.bba
|
||||
bbasm -l ${DBPART}.bba ${CHIPDB}/${DBPART}.bin
|
||||
rm -f ${DBPART}.bba
|
||||
|
||||
${PROJECT}.fasm: ${PROJECT}.json ${CHIPDB}/${DBPART}.bin ${XDC}
|
||||
nextpnr-xilinx --chipdb ${CHIPDB}/${DBPART}.bin --xdc ${XDC} --json ${PROJECT}.json --fasm $@ ${PNR_ARGS} ${PNR_DEBUG}
|
||||
|
||||
${PROJECT}.frames: ${PROJECT}.fasm
|
||||
fasm2frames --part ${PART} --db-root ${PRJXRAY_DB_DIR}/${FAMILY} $< > $@
|
||||
|
||||
${PROJECT}.bit: ${PROJECT}.frames
|
||||
xc7frames2bit --part_file ${PRJXRAY_DB_DIR}/${FAMILY}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -f *.bit
|
||||
@rm -f *.frames
|
||||
@rm -f *.fasm
|
||||
@rm -f *.json
|
||||
@rm -f *.bin
|
||||
@rm -f *.bba
|
||||
|
||||
.PHONY: pnrclean
|
||||
pnrclean:
|
||||
rm *.fasm *.frames *.bit
|
||||
|
|
@ -1,207 +1,207 @@
|
|||
|
||||
//
|
||||
// Module: uart_rx
|
||||
//
|
||||
// Notes:
|
||||
// - UART reciever module.
|
||||
//
|
||||
|
||||
module uart_rx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
input wire uart_rxd , // UART Recieve pin.
|
||||
input wire uart_rx_en , // Recieve enable
|
||||
output wire uart_rx_break, // Did we get a BREAK message?
|
||||
output wire uart_rx_valid, // Valid data recieved and available.
|
||||
output reg [PAYLOAD_BITS-1:0] uart_rx_data // The recieved data.
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_rxd line. Helps break long timing
|
||||
// paths from input pins into the logic.
|
||||
reg rxd_reg;
|
||||
reg rxd_reg_0;
|
||||
|
||||
//
|
||||
// Storage for the recieved serial data.
|
||||
reg [PAYLOAD_BITS-1:0] recieved_data;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of recieved bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Sample of the UART input line whenever we are in the middle of a bit frame.
|
||||
reg bit_sample;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_RECV = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Output assignment
|
||||
//
|
||||
|
||||
assign uart_rx_break = uart_rx_valid && ~|recieved_data;
|
||||
assign uart_rx_valid = fsm_state == FSM_STOP && n_fsm_state == FSM_IDLE;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(!resetn) begin
|
||||
uart_rx_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if (fsm_state == FSM_STOP) begin
|
||||
uart_rx_data <= recieved_data;
|
||||
end
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT ||
|
||||
fsm_state == FSM_STOP &&
|
||||
cycle_counter == CYCLES_PER_BIT/2;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = rxd_reg ? FSM_IDLE : FSM_START;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_RECV : FSM_START;
|
||||
FSM_RECV : n_fsm_state = payload_done ? FSM_STOP : FSM_RECV ;
|
||||
FSM_STOP : n_fsm_state = next_bit ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the recieved data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_recieved_data
|
||||
if(!resetn) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE ) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit ) begin
|
||||
recieved_data[PAYLOAD_BITS-1] <= bit_sample;
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
recieved_data[i] <= recieved_data[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Increments the bit counter when recieving.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_RECV) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Sample the recieved bit when in the middle of a bit frame.
|
||||
always @(posedge clk) begin : p_bit_sample
|
||||
if(!resetn) begin
|
||||
bit_sample <= 1'b0;
|
||||
end else if (cycle_counter == CYCLES_PER_BIT/2) begin
|
||||
bit_sample <= rxd_reg;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when recieving.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_RECV ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the rxd_reg.
|
||||
always @(posedge clk) begin : p_rxd_reg
|
||||
if(!resetn) begin
|
||||
rxd_reg <= 1'b1;
|
||||
rxd_reg_0 <= 1'b1;
|
||||
end else if(uart_rx_en) begin
|
||||
rxd_reg <= rxd_reg_0;
|
||||
rxd_reg_0 <= uart_rxd;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
//
|
||||
// Module: uart_rx
|
||||
//
|
||||
// Notes:
|
||||
// - UART reciever module.
|
||||
//
|
||||
|
||||
module uart_rx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
input wire uart_rxd , // UART Recieve pin.
|
||||
input wire uart_rx_en , // Recieve enable
|
||||
output wire uart_rx_break, // Did we get a BREAK message?
|
||||
output wire uart_rx_valid, // Valid data recieved and available.
|
||||
output reg [PAYLOAD_BITS-1:0] uart_rx_data // The recieved data.
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_rxd line. Helps break long timing
|
||||
// paths from input pins into the logic.
|
||||
reg rxd_reg;
|
||||
reg rxd_reg_0;
|
||||
|
||||
//
|
||||
// Storage for the recieved serial data.
|
||||
reg [PAYLOAD_BITS-1:0] recieved_data;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of recieved bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Sample of the UART input line whenever we are in the middle of a bit frame.
|
||||
reg bit_sample;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_RECV = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Output assignment
|
||||
//
|
||||
|
||||
assign uart_rx_break = uart_rx_valid && ~|recieved_data;
|
||||
assign uart_rx_valid = fsm_state == FSM_STOP && n_fsm_state == FSM_IDLE;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(!resetn) begin
|
||||
uart_rx_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if (fsm_state == FSM_STOP) begin
|
||||
uart_rx_data <= recieved_data;
|
||||
end
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT ||
|
||||
fsm_state == FSM_STOP &&
|
||||
cycle_counter == CYCLES_PER_BIT/2;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = rxd_reg ? FSM_IDLE : FSM_START;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_RECV : FSM_START;
|
||||
FSM_RECV : n_fsm_state = payload_done ? FSM_STOP : FSM_RECV ;
|
||||
FSM_STOP : n_fsm_state = next_bit ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the recieved data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_recieved_data
|
||||
if(!resetn) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE ) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit ) begin
|
||||
recieved_data[PAYLOAD_BITS-1] <= bit_sample;
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
recieved_data[i] <= recieved_data[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Increments the bit counter when recieving.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_RECV) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Sample the recieved bit when in the middle of a bit frame.
|
||||
always @(posedge clk) begin : p_bit_sample
|
||||
if(!resetn) begin
|
||||
bit_sample <= 1'b0;
|
||||
end else if (cycle_counter == CYCLES_PER_BIT/2) begin
|
||||
bit_sample <= rxd_reg;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when recieving.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_RECV ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the rxd_reg.
|
||||
always @(posedge clk) begin : p_rxd_reg
|
||||
if(!resetn) begin
|
||||
rxd_reg <= 1'b1;
|
||||
rxd_reg_0 <= 1'b1;
|
||||
end else if(uart_rx_en) begin
|
||||
rxd_reg <= rxd_reg_0;
|
||||
rxd_reg_0 <= uart_rxd;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,187 +1,187 @@
|
|||
|
||||
|
||||
//
|
||||
// Module: uart_tx
|
||||
//
|
||||
// Notes:
|
||||
// - UART transmitter module.
|
||||
//
|
||||
|
||||
module uart_tx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
output wire uart_txd , // UART transmit pin.
|
||||
output wire uart_tx_busy, // Module busy sending previous item.
|
||||
input wire uart_tx_en , // Send the data on uart_tx_data
|
||||
input wire [PAYLOAD_BITS-1:0] uart_tx_data // The data to be sent
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_txd line. Helps break long timing
|
||||
// paths from the logic to the output pins.
|
||||
reg txd_reg;
|
||||
|
||||
//
|
||||
// Storage for the serial data to be sent.
|
||||
reg [PAYLOAD_BITS-1:0] data_to_send;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of sent bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_SEND = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
assign uart_tx_busy = fsm_state != FSM_IDLE;
|
||||
assign uart_txd = txd_reg;
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
wire stop_done = bit_counter == STOP_BITS && fsm_state == FSM_STOP;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = uart_tx_en ? FSM_START: FSM_IDLE ;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_SEND : FSM_START;
|
||||
FSM_SEND : n_fsm_state = payload_done ? FSM_STOP : FSM_SEND ;
|
||||
FSM_STOP : n_fsm_state = stop_done ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the sent data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_data_to_send
|
||||
if(!resetn) begin
|
||||
data_to_send <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE && uart_tx_en) begin
|
||||
data_to_send <= uart_tx_data;
|
||||
end else if(fsm_state == FSM_SEND && next_bit ) begin
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
data_to_send[i] <= data_to_send[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the bit counter each time a new bit frame is sent.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_SEND && fsm_state != FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_SEND && n_fsm_state == FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_STOP&& next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end else if(fsm_state == FSM_SEND && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when sending.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_SEND ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the txd_reg.
|
||||
always @(posedge clk) begin : p_txd_reg
|
||||
if(!resetn) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_IDLE) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_START) begin
|
||||
txd_reg <= 1'b0;
|
||||
end else if(fsm_state == FSM_SEND) begin
|
||||
txd_reg <= data_to_send[0];
|
||||
end else if(fsm_state == FSM_STOP) begin
|
||||
txd_reg <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
//
|
||||
// Module: uart_tx
|
||||
//
|
||||
// Notes:
|
||||
// - UART transmitter module.
|
||||
//
|
||||
|
||||
module uart_tx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
output wire uart_txd , // UART transmit pin.
|
||||
output wire uart_tx_busy, // Module busy sending previous item.
|
||||
input wire uart_tx_en , // Send the data on uart_tx_data
|
||||
input wire [PAYLOAD_BITS-1:0] uart_tx_data // The data to be sent
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_txd line. Helps break long timing
|
||||
// paths from the logic to the output pins.
|
||||
reg txd_reg;
|
||||
|
||||
//
|
||||
// Storage for the serial data to be sent.
|
||||
reg [PAYLOAD_BITS-1:0] data_to_send;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of sent bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_SEND = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
assign uart_tx_busy = fsm_state != FSM_IDLE;
|
||||
assign uart_txd = txd_reg;
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
wire stop_done = bit_counter == STOP_BITS && fsm_state == FSM_STOP;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = uart_tx_en ? FSM_START: FSM_IDLE ;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_SEND : FSM_START;
|
||||
FSM_SEND : n_fsm_state = payload_done ? FSM_STOP : FSM_SEND ;
|
||||
FSM_STOP : n_fsm_state = stop_done ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the sent data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_data_to_send
|
||||
if(!resetn) begin
|
||||
data_to_send <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE && uart_tx_en) begin
|
||||
data_to_send <= uart_tx_data;
|
||||
end else if(fsm_state == FSM_SEND && next_bit ) begin
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
data_to_send[i] <= data_to_send[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the bit counter each time a new bit frame is sent.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_SEND && fsm_state != FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_SEND && n_fsm_state == FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_STOP&& next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end else if(fsm_state == FSM_SEND && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when sending.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_SEND ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the txd_reg.
|
||||
always @(posedge clk) begin : p_txd_reg
|
||||
if(!resetn) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_IDLE) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_START) begin
|
||||
txd_reg <= 1'b0;
|
||||
end else if(fsm_state == FSM_SEND) begin
|
||||
txd_reg <= data_to_send[0];
|
||||
end else if(fsm_state == FSM_STOP) begin
|
||||
txd_reg <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,70 +1,70 @@
|
|||
PROJECT = ax7325b_ddr3
|
||||
FAMILY = kintex7
|
||||
PART = xc7k325tffg900-2
|
||||
CHIPDB = ${KINTEX7_CHIPDB}
|
||||
ADDITIONAL_SOURCES = ../../rtl/ddr3_controller.v ../../rtl/ddr3_phy.v ../../rtl/ddr3_top.v uart_rx.v uart_tx.v clk_wiz.v
|
||||
|
||||
#############################################################################################
|
||||
NEXTPNR_XILINX_DIR ?= /snap/openxc7/current/opt/nextpnr-xilinx
|
||||
NEXTPNR_XILINX_PYTHON_DIR ?= ${NEXTPNR_XILINX_DIR}/python
|
||||
PRJXRAY_DB_DIR ?= ${NEXTPNR_XILINX_DIR}/external/prjxray-db
|
||||
|
||||
DBPART = $(shell echo ${PART} | sed -e 's/-[0-9]//g')
|
||||
SPEEDGRADE = $(shell echo ${PART} | sed -e 's/.*\-\([0-9]\)/\1/g')
|
||||
|
||||
CHIPDB ?= ./
|
||||
ifeq ($(CHIPDB),)
|
||||
CHIPDB = ./
|
||||
endif
|
||||
|
||||
PYPY3 ?= pypy3
|
||||
|
||||
TOP ?= ${PROJECT}
|
||||
TOP_MODULE ?= ${TOP}
|
||||
TOP_VERILOG ?= ${TOP}.v
|
||||
|
||||
PNR_DEBUG ?= # --verbose --debug
|
||||
|
||||
BOARD ?= UNKNOWN
|
||||
JTAG_LINK ?= --board ${BOARD}
|
||||
|
||||
XDC ?= ${PROJECT}.xdc
|
||||
|
||||
.PHONY: all
|
||||
all: ${PROJECT}.bit
|
||||
|
||||
.PHONY: program
|
||||
program: ${PROJECT}.bit
|
||||
openFPGALoader ${JTAG_LINK} --bitstream $<
|
||||
|
||||
${PROJECT}.json: ${TOP_VERILOG} ${ADDITIONAL_SOURCES}
|
||||
yosys -p "synth_xilinx -flatten -abc9 ${SYNTH_OPTS} -arch xc7 -top ${TOP_MODULE}; write_json ${PROJECT}.json" $< ${ADDITIONAL_SOURCES}
|
||||
|
||||
# The chip database only needs to be generated once
|
||||
# that is why we don't clean it with make clean
|
||||
${CHIPDB}/${DBPART}.bin:
|
||||
${PYPY3} ${NEXTPNR_XILINX_PYTHON_DIR}/bbaexport.py --device ${PART} --bba ${DBPART}.bba
|
||||
bbasm -l ${DBPART}.bba ${CHIPDB}/${DBPART}.bin
|
||||
rm -f ${DBPART}.bba
|
||||
|
||||
${PROJECT}.fasm: ${PROJECT}.json ${CHIPDB}/${DBPART}.bin ${XDC}
|
||||
nextpnr-xilinx --chipdb ${CHIPDB}/${DBPART}.bin --xdc ${XDC} --json ${PROJECT}.json --fasm $@ ${PNR_ARGS} ${PNR_DEBUG}
|
||||
|
||||
${PROJECT}.frames: ${PROJECT}.fasm
|
||||
fasm2frames --part ${PART} --db-root ${PRJXRAY_DB_DIR}/${FAMILY} $< > $@
|
||||
|
||||
${PROJECT}.bit: ${PROJECT}.frames
|
||||
xc7frames2bit --part_file ${PRJXRAY_DB_DIR}/${FAMILY}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -f *.bit
|
||||
@rm -f *.frames
|
||||
@rm -f *.fasm
|
||||
@rm -f *.json
|
||||
@rm -f *.bin
|
||||
@rm -f *.bba
|
||||
|
||||
.PHONY: pnrclean
|
||||
pnrclean:
|
||||
PROJECT = ax7325b_ddr3
|
||||
FAMILY = kintex7
|
||||
PART = xc7k325tffg900-2
|
||||
CHIPDB = ${KINTEX7_CHIPDB}
|
||||
ADDITIONAL_SOURCES = ../../rtl/ddr3_controller.v ../../rtl/ddr3_phy.v ../../rtl/ddr3_top.v uart_rx.v uart_tx.v clk_wiz.v
|
||||
|
||||
#############################################################################################
|
||||
NEXTPNR_XILINX_DIR ?= /snap/openxc7/current/opt/nextpnr-xilinx
|
||||
NEXTPNR_XILINX_PYTHON_DIR ?= ${NEXTPNR_XILINX_DIR}/python
|
||||
PRJXRAY_DB_DIR ?= ${NEXTPNR_XILINX_DIR}/external/prjxray-db
|
||||
|
||||
DBPART = $(shell echo ${PART} | sed -e 's/-[0-9]//g')
|
||||
SPEEDGRADE = $(shell echo ${PART} | sed -e 's/.*\-\([0-9]\)/\1/g')
|
||||
|
||||
CHIPDB ?= ./
|
||||
ifeq ($(CHIPDB),)
|
||||
CHIPDB = ./
|
||||
endif
|
||||
|
||||
PYPY3 ?= pypy3
|
||||
|
||||
TOP ?= ${PROJECT}
|
||||
TOP_MODULE ?= ${TOP}
|
||||
TOP_VERILOG ?= ${TOP}.v
|
||||
|
||||
PNR_DEBUG ?= # --verbose --debug
|
||||
|
||||
BOARD ?= UNKNOWN
|
||||
JTAG_LINK ?= --board ${BOARD}
|
||||
|
||||
XDC ?= ${PROJECT}.xdc
|
||||
|
||||
.PHONY: all
|
||||
all: ${PROJECT}.bit
|
||||
|
||||
.PHONY: program
|
||||
program: ${PROJECT}.bit
|
||||
openFPGALoader ${JTAG_LINK} --bitstream $<
|
||||
|
||||
${PROJECT}.json: ${TOP_VERILOG} ${ADDITIONAL_SOURCES}
|
||||
yosys -p "synth_xilinx -flatten -abc9 ${SYNTH_OPTS} -arch xc7 -top ${TOP_MODULE}; write_json ${PROJECT}.json" $< ${ADDITIONAL_SOURCES}
|
||||
|
||||
# The chip database only needs to be generated once
|
||||
# that is why we don't clean it with make clean
|
||||
${CHIPDB}/${DBPART}.bin:
|
||||
${PYPY3} ${NEXTPNR_XILINX_PYTHON_DIR}/bbaexport.py --device ${PART} --bba ${DBPART}.bba
|
||||
bbasm -l ${DBPART}.bba ${CHIPDB}/${DBPART}.bin
|
||||
rm -f ${DBPART}.bba
|
||||
|
||||
${PROJECT}.fasm: ${PROJECT}.json ${CHIPDB}/${DBPART}.bin ${XDC}
|
||||
nextpnr-xilinx --chipdb ${CHIPDB}/${DBPART}.bin --xdc ${XDC} --json ${PROJECT}.json --fasm $@ ${PNR_ARGS} ${PNR_DEBUG}
|
||||
|
||||
${PROJECT}.frames: ${PROJECT}.fasm
|
||||
fasm2frames --part ${PART} --db-root ${PRJXRAY_DB_DIR}/${FAMILY} $< > $@
|
||||
|
||||
${PROJECT}.bit: ${PROJECT}.frames
|
||||
xc7frames2bit --part_file ${PRJXRAY_DB_DIR}/${FAMILY}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -f *.bit
|
||||
@rm -f *.frames
|
||||
@rm -f *.fasm
|
||||
@rm -f *.json
|
||||
@rm -f *.bin
|
||||
@rm -f *.bba
|
||||
|
||||
.PHONY: pnrclean
|
||||
pnrclean:
|
||||
rm *.fasm *.frames *.bit
|
||||
|
|
@ -1,207 +1,207 @@
|
|||
|
||||
//
|
||||
// Module: uart_rx
|
||||
//
|
||||
// Notes:
|
||||
// - UART reciever module.
|
||||
//
|
||||
|
||||
module uart_rx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
input wire uart_rxd , // UART Recieve pin.
|
||||
input wire uart_rx_en , // Recieve enable
|
||||
output wire uart_rx_break, // Did we get a BREAK message?
|
||||
output wire uart_rx_valid, // Valid data recieved and available.
|
||||
output reg [PAYLOAD_BITS-1:0] uart_rx_data // The recieved data.
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_rxd line. Helps break long timing
|
||||
// paths from input pins into the logic.
|
||||
reg rxd_reg;
|
||||
reg rxd_reg_0;
|
||||
|
||||
//
|
||||
// Storage for the recieved serial data.
|
||||
reg [PAYLOAD_BITS-1:0] recieved_data;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of recieved bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Sample of the UART input line whenever we are in the middle of a bit frame.
|
||||
reg bit_sample;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_RECV = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Output assignment
|
||||
//
|
||||
|
||||
assign uart_rx_break = uart_rx_valid && ~|recieved_data;
|
||||
assign uart_rx_valid = fsm_state == FSM_STOP && n_fsm_state == FSM_IDLE;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(!resetn) begin
|
||||
uart_rx_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if (fsm_state == FSM_STOP) begin
|
||||
uart_rx_data <= recieved_data;
|
||||
end
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT ||
|
||||
fsm_state == FSM_STOP &&
|
||||
cycle_counter == CYCLES_PER_BIT/2;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = rxd_reg ? FSM_IDLE : FSM_START;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_RECV : FSM_START;
|
||||
FSM_RECV : n_fsm_state = payload_done ? FSM_STOP : FSM_RECV ;
|
||||
FSM_STOP : n_fsm_state = next_bit ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the recieved data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_recieved_data
|
||||
if(!resetn) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE ) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit ) begin
|
||||
recieved_data[PAYLOAD_BITS-1] <= bit_sample;
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
recieved_data[i] <= recieved_data[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Increments the bit counter when recieving.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_RECV) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Sample the recieved bit when in the middle of a bit frame.
|
||||
always @(posedge clk) begin : p_bit_sample
|
||||
if(!resetn) begin
|
||||
bit_sample <= 1'b0;
|
||||
end else if (cycle_counter == CYCLES_PER_BIT/2) begin
|
||||
bit_sample <= rxd_reg;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when recieving.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_RECV ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the rxd_reg.
|
||||
always @(posedge clk) begin : p_rxd_reg
|
||||
if(!resetn) begin
|
||||
rxd_reg <= 1'b1;
|
||||
rxd_reg_0 <= 1'b1;
|
||||
end else if(uart_rx_en) begin
|
||||
rxd_reg <= rxd_reg_0;
|
||||
rxd_reg_0 <= uart_rxd;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
//
|
||||
// Module: uart_rx
|
||||
//
|
||||
// Notes:
|
||||
// - UART reciever module.
|
||||
//
|
||||
|
||||
module uart_rx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
input wire uart_rxd , // UART Recieve pin.
|
||||
input wire uart_rx_en , // Recieve enable
|
||||
output wire uart_rx_break, // Did we get a BREAK message?
|
||||
output wire uart_rx_valid, // Valid data recieved and available.
|
||||
output reg [PAYLOAD_BITS-1:0] uart_rx_data // The recieved data.
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_rxd line. Helps break long timing
|
||||
// paths from input pins into the logic.
|
||||
reg rxd_reg;
|
||||
reg rxd_reg_0;
|
||||
|
||||
//
|
||||
// Storage for the recieved serial data.
|
||||
reg [PAYLOAD_BITS-1:0] recieved_data;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of recieved bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Sample of the UART input line whenever we are in the middle of a bit frame.
|
||||
reg bit_sample;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_RECV = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Output assignment
|
||||
//
|
||||
|
||||
assign uart_rx_break = uart_rx_valid && ~|recieved_data;
|
||||
assign uart_rx_valid = fsm_state == FSM_STOP && n_fsm_state == FSM_IDLE;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(!resetn) begin
|
||||
uart_rx_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if (fsm_state == FSM_STOP) begin
|
||||
uart_rx_data <= recieved_data;
|
||||
end
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT ||
|
||||
fsm_state == FSM_STOP &&
|
||||
cycle_counter == CYCLES_PER_BIT/2;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = rxd_reg ? FSM_IDLE : FSM_START;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_RECV : FSM_START;
|
||||
FSM_RECV : n_fsm_state = payload_done ? FSM_STOP : FSM_RECV ;
|
||||
FSM_STOP : n_fsm_state = next_bit ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the recieved data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_recieved_data
|
||||
if(!resetn) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE ) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit ) begin
|
||||
recieved_data[PAYLOAD_BITS-1] <= bit_sample;
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
recieved_data[i] <= recieved_data[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Increments the bit counter when recieving.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_RECV) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Sample the recieved bit when in the middle of a bit frame.
|
||||
always @(posedge clk) begin : p_bit_sample
|
||||
if(!resetn) begin
|
||||
bit_sample <= 1'b0;
|
||||
end else if (cycle_counter == CYCLES_PER_BIT/2) begin
|
||||
bit_sample <= rxd_reg;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when recieving.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_RECV ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the rxd_reg.
|
||||
always @(posedge clk) begin : p_rxd_reg
|
||||
if(!resetn) begin
|
||||
rxd_reg <= 1'b1;
|
||||
rxd_reg_0 <= 1'b1;
|
||||
end else if(uart_rx_en) begin
|
||||
rxd_reg <= rxd_reg_0;
|
||||
rxd_reg_0 <= uart_rxd;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,187 +1,187 @@
|
|||
|
||||
|
||||
//
|
||||
// Module: uart_tx
|
||||
//
|
||||
// Notes:
|
||||
// - UART transmitter module.
|
||||
//
|
||||
|
||||
module uart_tx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
output wire uart_txd , // UART transmit pin.
|
||||
output wire uart_tx_busy, // Module busy sending previous item.
|
||||
input wire uart_tx_en , // Send the data on uart_tx_data
|
||||
input wire [PAYLOAD_BITS-1:0] uart_tx_data // The data to be sent
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_txd line. Helps break long timing
|
||||
// paths from the logic to the output pins.
|
||||
reg txd_reg;
|
||||
|
||||
//
|
||||
// Storage for the serial data to be sent.
|
||||
reg [PAYLOAD_BITS-1:0] data_to_send;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of sent bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_SEND = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
assign uart_tx_busy = fsm_state != FSM_IDLE;
|
||||
assign uart_txd = txd_reg;
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
wire stop_done = bit_counter == STOP_BITS && fsm_state == FSM_STOP;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = uart_tx_en ? FSM_START: FSM_IDLE ;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_SEND : FSM_START;
|
||||
FSM_SEND : n_fsm_state = payload_done ? FSM_STOP : FSM_SEND ;
|
||||
FSM_STOP : n_fsm_state = stop_done ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the sent data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_data_to_send
|
||||
if(!resetn) begin
|
||||
data_to_send <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE && uart_tx_en) begin
|
||||
data_to_send <= uart_tx_data;
|
||||
end else if(fsm_state == FSM_SEND && next_bit ) begin
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
data_to_send[i] <= data_to_send[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the bit counter each time a new bit frame is sent.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_SEND && fsm_state != FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_SEND && n_fsm_state == FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_STOP&& next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end else if(fsm_state == FSM_SEND && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when sending.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_SEND ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the txd_reg.
|
||||
always @(posedge clk) begin : p_txd_reg
|
||||
if(!resetn) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_IDLE) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_START) begin
|
||||
txd_reg <= 1'b0;
|
||||
end else if(fsm_state == FSM_SEND) begin
|
||||
txd_reg <= data_to_send[0];
|
||||
end else if(fsm_state == FSM_STOP) begin
|
||||
txd_reg <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
//
|
||||
// Module: uart_tx
|
||||
//
|
||||
// Notes:
|
||||
// - UART transmitter module.
|
||||
//
|
||||
|
||||
module uart_tx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
output wire uart_txd , // UART transmit pin.
|
||||
output wire uart_tx_busy, // Module busy sending previous item.
|
||||
input wire uart_tx_en , // Send the data on uart_tx_data
|
||||
input wire [PAYLOAD_BITS-1:0] uart_tx_data // The data to be sent
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_txd line. Helps break long timing
|
||||
// paths from the logic to the output pins.
|
||||
reg txd_reg;
|
||||
|
||||
//
|
||||
// Storage for the serial data to be sent.
|
||||
reg [PAYLOAD_BITS-1:0] data_to_send;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of sent bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_SEND = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
assign uart_tx_busy = fsm_state != FSM_IDLE;
|
||||
assign uart_txd = txd_reg;
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
wire stop_done = bit_counter == STOP_BITS && fsm_state == FSM_STOP;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = uart_tx_en ? FSM_START: FSM_IDLE ;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_SEND : FSM_START;
|
||||
FSM_SEND : n_fsm_state = payload_done ? FSM_STOP : FSM_SEND ;
|
||||
FSM_STOP : n_fsm_state = stop_done ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the sent data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_data_to_send
|
||||
if(!resetn) begin
|
||||
data_to_send <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE && uart_tx_en) begin
|
||||
data_to_send <= uart_tx_data;
|
||||
end else if(fsm_state == FSM_SEND && next_bit ) begin
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
data_to_send[i] <= data_to_send[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the bit counter each time a new bit frame is sent.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_SEND && fsm_state != FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_SEND && n_fsm_state == FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_STOP&& next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end else if(fsm_state == FSM_SEND && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when sending.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_SEND ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the txd_reg.
|
||||
always @(posedge clk) begin : p_txd_reg
|
||||
if(!resetn) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_IDLE) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_START) begin
|
||||
txd_reg <= 1'b0;
|
||||
end else if(fsm_state == FSM_SEND) begin
|
||||
txd_reg <= data_to_send[0];
|
||||
end else if(fsm_state == FSM_STOP) begin
|
||||
txd_reg <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,71 +1,71 @@
|
|||
PROJECT = arty_ddr3
|
||||
BOARD = arty_s7_50
|
||||
FAMILY = spartan7
|
||||
PART = xc7s50csga324-1
|
||||
CHIPDB = ${SPARTAN7_CHIPDB}
|
||||
ADDITIONAL_SOURCES = ../../rtl/ddr3_controller.v ../../rtl/ddr3_phy.v ../../rtl/ddr3_top.v uart_rx.v uart_tx.v clk_wiz.v
|
||||
|
||||
#############################################################################################
|
||||
NEXTPNR_XILINX_DIR ?= /snap/openxc7/current/opt/nextpnr-xilinx
|
||||
NEXTPNR_XILINX_PYTHON_DIR ?= ${NEXTPNR_XILINX_DIR}/python
|
||||
PRJXRAY_DB_DIR ?= ${NEXTPNR_XILINX_DIR}/external/prjxray-db
|
||||
|
||||
DBPART = $(shell echo ${PART} | sed -e 's/-[0-9]//g')
|
||||
SPEEDGRADE = $(shell echo ${PART} | sed -e 's/.*\-\([0-9]\)/\1/g')
|
||||
|
||||
CHIPDB ?= ./
|
||||
ifeq ($(CHIPDB),)
|
||||
CHIPDB = ./
|
||||
endif
|
||||
|
||||
PYPY3 ?= pypy3
|
||||
|
||||
TOP ?= ${PROJECT}
|
||||
TOP_MODULE ?= ${TOP}
|
||||
TOP_VERILOG ?= ${TOP}.v
|
||||
|
||||
PNR_DEBUG ?= # --verbose --debug
|
||||
|
||||
BOARD ?= UNKNOWN
|
||||
JTAG_LINK ?= --board ${BOARD}
|
||||
|
||||
XDC ?= ${PROJECT}.xdc
|
||||
|
||||
.PHONY: all
|
||||
all: ${PROJECT}.bit
|
||||
|
||||
.PHONY: program
|
||||
program: ${PROJECT}.bit
|
||||
openFPGALoader ${JTAG_LINK} --bitstream $<
|
||||
|
||||
${PROJECT}.json: ${TOP_VERILOG} ${ADDITIONAL_SOURCES}
|
||||
yosys -p "synth_xilinx -flatten -abc9 ${SYNTH_OPTS} -arch xc7 -top ${TOP_MODULE}; write_json ${PROJECT}.json" $< ${ADDITIONAL_SOURCES}
|
||||
|
||||
# The chip database only needs to be generated once
|
||||
# that is why we don't clean it with make clean
|
||||
${CHIPDB}/${DBPART}.bin:
|
||||
${PYPY3} ${NEXTPNR_XILINX_PYTHON_DIR}/bbaexport.py --device ${PART} --bba ${DBPART}.bba
|
||||
bbasm -l ${DBPART}.bba ${CHIPDB}/${DBPART}.bin
|
||||
rm -f ${DBPART}.bba
|
||||
|
||||
${PROJECT}.fasm: ${PROJECT}.json ${CHIPDB}/${DBPART}.bin ${XDC}
|
||||
nextpnr-xilinx --chipdb ${CHIPDB}/${DBPART}.bin --xdc ${XDC} --json ${PROJECT}.json --fasm $@ ${PNR_ARGS} ${PNR_DEBUG}
|
||||
|
||||
${PROJECT}.frames: ${PROJECT}.fasm
|
||||
fasm2frames --part ${PART} --db-root ${PRJXRAY_DB_DIR}/${FAMILY} $< > $@
|
||||
|
||||
${PROJECT}.bit: ${PROJECT}.frames
|
||||
xc7frames2bit --part_file ${PRJXRAY_DB_DIR}/${FAMILY}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -f *.bit
|
||||
@rm -f *.frames
|
||||
@rm -f *.fasm
|
||||
@rm -f *.json
|
||||
@rm -f *.bin
|
||||
@rm -f *.bba
|
||||
|
||||
.PHONY: pnrclean
|
||||
pnrclean:
|
||||
PROJECT = arty_ddr3
|
||||
BOARD = arty_s7_50
|
||||
FAMILY = spartan7
|
||||
PART = xc7s50csga324-1
|
||||
CHIPDB = ${SPARTAN7_CHIPDB}
|
||||
ADDITIONAL_SOURCES = ../../rtl/ddr3_controller.v ../../rtl/ddr3_phy.v ../../rtl/ddr3_top.v uart_rx.v uart_tx.v clk_wiz.v
|
||||
|
||||
#############################################################################################
|
||||
NEXTPNR_XILINX_DIR ?= /snap/openxc7/current/opt/nextpnr-xilinx
|
||||
NEXTPNR_XILINX_PYTHON_DIR ?= ${NEXTPNR_XILINX_DIR}/python
|
||||
PRJXRAY_DB_DIR ?= ${NEXTPNR_XILINX_DIR}/external/prjxray-db
|
||||
|
||||
DBPART = $(shell echo ${PART} | sed -e 's/-[0-9]//g')
|
||||
SPEEDGRADE = $(shell echo ${PART} | sed -e 's/.*\-\([0-9]\)/\1/g')
|
||||
|
||||
CHIPDB ?= ./
|
||||
ifeq ($(CHIPDB),)
|
||||
CHIPDB = ./
|
||||
endif
|
||||
|
||||
PYPY3 ?= pypy3
|
||||
|
||||
TOP ?= ${PROJECT}
|
||||
TOP_MODULE ?= ${TOP}
|
||||
TOP_VERILOG ?= ${TOP}.v
|
||||
|
||||
PNR_DEBUG ?= # --verbose --debug
|
||||
|
||||
BOARD ?= UNKNOWN
|
||||
JTAG_LINK ?= --board ${BOARD}
|
||||
|
||||
XDC ?= ${PROJECT}.xdc
|
||||
|
||||
.PHONY: all
|
||||
all: ${PROJECT}.bit
|
||||
|
||||
.PHONY: program
|
||||
program: ${PROJECT}.bit
|
||||
openFPGALoader ${JTAG_LINK} --bitstream $<
|
||||
|
||||
${PROJECT}.json: ${TOP_VERILOG} ${ADDITIONAL_SOURCES}
|
||||
yosys -p "synth_xilinx -flatten -abc9 ${SYNTH_OPTS} -arch xc7 -top ${TOP_MODULE}; write_json ${PROJECT}.json" $< ${ADDITIONAL_SOURCES}
|
||||
|
||||
# The chip database only needs to be generated once
|
||||
# that is why we don't clean it with make clean
|
||||
${CHIPDB}/${DBPART}.bin:
|
||||
${PYPY3} ${NEXTPNR_XILINX_PYTHON_DIR}/bbaexport.py --device ${PART} --bba ${DBPART}.bba
|
||||
bbasm -l ${DBPART}.bba ${CHIPDB}/${DBPART}.bin
|
||||
rm -f ${DBPART}.bba
|
||||
|
||||
${PROJECT}.fasm: ${PROJECT}.json ${CHIPDB}/${DBPART}.bin ${XDC}
|
||||
nextpnr-xilinx --chipdb ${CHIPDB}/${DBPART}.bin --xdc ${XDC} --json ${PROJECT}.json --fasm $@ ${PNR_ARGS} ${PNR_DEBUG}
|
||||
|
||||
${PROJECT}.frames: ${PROJECT}.fasm
|
||||
fasm2frames --part ${PART} --db-root ${PRJXRAY_DB_DIR}/${FAMILY} $< > $@
|
||||
|
||||
${PROJECT}.bit: ${PROJECT}.frames
|
||||
xc7frames2bit --part_file ${PRJXRAY_DB_DIR}/${FAMILY}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -f *.bit
|
||||
@rm -f *.frames
|
||||
@rm -f *.fasm
|
||||
@rm -f *.json
|
||||
@rm -f *.bin
|
||||
@rm -f *.bba
|
||||
|
||||
.PHONY: pnrclean
|
||||
pnrclean:
|
||||
rm *.fasm *.frames *.bit
|
||||
|
|
@ -1,265 +1,265 @@
|
|||
## This file is a general .xdc for the Arty S7-50 Rev. E
|
||||
## To use it in a project:
|
||||
## - uncomment the lines corresponding to used pins
|
||||
## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project
|
||||
|
||||
## Clock Signals
|
||||
set_property -dict {PACKAGE_PIN R2 IOSTANDARD SSTL135} [get_ports i_clk]
|
||||
create_clock -period 10.000 -name sys_clk_pin -waveform {0.000 5.000} -add [get_ports i_clk]
|
||||
|
||||
## LEDs
|
||||
set_property -dict {PACKAGE_PIN E18 IOSTANDARD LVCMOS33} [get_ports {led[0]}]
|
||||
set_property -dict {PACKAGE_PIN F13 IOSTANDARD LVCMOS33} [get_ports {led[1]}]
|
||||
set_property -dict {PACKAGE_PIN E13 IOSTANDARD LVCMOS33} [get_ports {led[2]}]
|
||||
set_property -dict {PACKAGE_PIN H15 IOSTANDARD LVCMOS33} [get_ports {led[3]}]
|
||||
|
||||
## Buttons
|
||||
set_property -dict {PACKAGE_PIN G15 IOSTANDARD LVCMOS33} [get_ports i_rst]
|
||||
|
||||
## USB-UART Interface
|
||||
set_property -dict {PACKAGE_PIN R12 IOSTANDARD LVCMOS33} [get_ports tx]
|
||||
set_property -dict {PACKAGE_PIN V12 IOSTANDARD LVCMOS33} [get_ports rx]
|
||||
|
||||
|
||||
############## DDR3 ##################
|
||||
# DQ PINS
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[0]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[0]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[0]}]
|
||||
set_property PACKAGE_PIN K2 [get_ports {ddr3_dq[0]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[1]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[1]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[1]}]
|
||||
set_property PACKAGE_PIN K3 [get_ports {ddr3_dq[1]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[2]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[2]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[2]}]
|
||||
set_property PACKAGE_PIN L4 [get_ports {ddr3_dq[2]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[3]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[3]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[3]}]
|
||||
set_property PACKAGE_PIN M6 [get_ports {ddr3_dq[3]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[4]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[4]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[4]}]
|
||||
set_property PACKAGE_PIN K6 [get_ports {ddr3_dq[4]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[5]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[5]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[5]}]
|
||||
set_property PACKAGE_PIN M4 [get_ports {ddr3_dq[5]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[6]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[6]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[6]}]
|
||||
set_property PACKAGE_PIN L5 [get_ports {ddr3_dq[6]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[7]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[7]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[7]}]
|
||||
set_property PACKAGE_PIN L6 [get_ports {ddr3_dq[7]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[8]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[8]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[8]}]
|
||||
set_property PACKAGE_PIN N4 [get_ports {ddr3_dq[8]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[9]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[9]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[9]}]
|
||||
set_property PACKAGE_PIN R1 [get_ports {ddr3_dq[9]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[10]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[10]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[10]}]
|
||||
set_property PACKAGE_PIN N1 [get_ports {ddr3_dq[10]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[11]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[11]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[11]}]
|
||||
set_property PACKAGE_PIN N5 [get_ports {ddr3_dq[11]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[12]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[12]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[12]}]
|
||||
set_property PACKAGE_PIN M2 [get_ports {ddr3_dq[12]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[13]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[13]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[13]}]
|
||||
set_property PACKAGE_PIN P1 [get_ports {ddr3_dq[13]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[14]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[14]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[14]}]
|
||||
set_property PACKAGE_PIN M1 [get_ports {ddr3_dq[14]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[15]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[15]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[15]}]
|
||||
set_property PACKAGE_PIN P2 [get_ports {ddr3_dq[15]}]
|
||||
|
||||
# Address Pins
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[13]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[13]}]
|
||||
set_property PACKAGE_PIN U6 [get_ports {ddr3_addr[13]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[12]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[12]}]
|
||||
set_property PACKAGE_PIN R6 [get_ports {ddr3_addr[12]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[11]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[11]}]
|
||||
set_property PACKAGE_PIN T5 [get_ports {ddr3_addr[11]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[10]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[10]}]
|
||||
set_property PACKAGE_PIN P6 [get_ports {ddr3_addr[10]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[9]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[9]}]
|
||||
set_property PACKAGE_PIN V7 [get_ports {ddr3_addr[9]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[8]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[8]}]
|
||||
set_property PACKAGE_PIN U7 [get_ports {ddr3_addr[8]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[7]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[7]}]
|
||||
set_property PACKAGE_PIN T6 [get_ports {ddr3_addr[7]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[6]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[6]}]
|
||||
set_property PACKAGE_PIN V6 [get_ports {ddr3_addr[6]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[5]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[5]}]
|
||||
set_property PACKAGE_PIN R7 [get_ports {ddr3_addr[5]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[4]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[4]}]
|
||||
set_property PACKAGE_PIN T3 [get_ports {ddr3_addr[4]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[3]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[3]}]
|
||||
set_property PACKAGE_PIN V4 [get_ports {ddr3_addr[3]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[2]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[2]}]
|
||||
set_property PACKAGE_PIN V2 [get_ports {ddr3_addr[2]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[1]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[1]}]
|
||||
set_property PACKAGE_PIN R4 [get_ports {ddr3_addr[1]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[0]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[0]}]
|
||||
set_property PACKAGE_PIN U2 [get_ports {ddr3_addr[0]}]
|
||||
|
||||
# Bank Pins
|
||||
set_property SLEW FAST [get_ports {ddr3_ba[2]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_ba[2]}]
|
||||
set_property PACKAGE_PIN U3 [get_ports {ddr3_ba[2]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_ba[1]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_ba[1]}]
|
||||
set_property PACKAGE_PIN T1 [get_ports {ddr3_ba[1]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_ba[0]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_ba[0]}]
|
||||
set_property PACKAGE_PIN V5 [get_ports {ddr3_ba[0]}]
|
||||
|
||||
# Command Pins
|
||||
set_property SLEW FAST [get_ports ddr3_ras_n]
|
||||
set_property IOSTANDARD SSTL135 [get_ports ddr3_ras_n]
|
||||
set_property PACKAGE_PIN U1 [get_ports ddr3_ras_n]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_cas_n]
|
||||
set_property IOSTANDARD SSTL135 [get_ports ddr3_cas_n]
|
||||
set_property PACKAGE_PIN V3 [get_ports ddr3_cas_n]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_we_n]
|
||||
set_property IOSTANDARD SSTL135 [get_ports ddr3_we_n]
|
||||
set_property PACKAGE_PIN P7 [get_ports ddr3_we_n]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_reset_n]
|
||||
set_property IOSTANDARD SSTL135 [get_ports ddr3_reset_n]
|
||||
set_property PACKAGE_PIN J6 [get_ports ddr3_reset_n]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_cke]
|
||||
set_property IOSTANDARD SSTL135 [get_ports ddr3_cke]
|
||||
set_property PACKAGE_PIN T2 [get_ports ddr3_cke]
|
||||
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_odt]
|
||||
set_property IOSTANDARD SSTL135 [get_ports ddr3_odt]
|
||||
set_property PACKAGE_PIN P5 [get_ports ddr3_odt]
|
||||
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_cs_n]
|
||||
set_property IOSTANDARD SSTL135 [get_ports ddr3_cs_n]
|
||||
set_property PACKAGE_PIN R3 [get_ports ddr3_cs_n]
|
||||
|
||||
# Data Mask Pins
|
||||
set_property SLEW FAST [get_ports {ddr3_dm[0]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dm[0]}]
|
||||
set_property PACKAGE_PIN K4 [get_ports {ddr3_dm[0]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dm[1]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dm[1]}]
|
||||
set_property PACKAGE_PIN M3 [get_ports {ddr3_dm[1]}]
|
||||
|
||||
# DQS Pins
|
||||
set_property SLEW FAST [get_ports {ddr3_dqs_p[0]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dqs_p[0]}]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddr3_dqs_p[0]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dqs_n[0]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dqs_n[0]}]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddr3_dqs_n[0]}]
|
||||
set_property PACKAGE_PIN K1 [get_ports {ddr3_dqs_p[0]}]
|
||||
set_property PACKAGE_PIN L1 [get_ports {ddr3_dqs_n[0]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dqs_p[1]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dqs_p[1]}]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddr3_dqs_p[1]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dqs_n[1]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dqs_n[1]}]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddr3_dqs_n[1]}]
|
||||
set_property PACKAGE_PIN N3 [get_ports {ddr3_dqs_p[1]}]
|
||||
set_property PACKAGE_PIN N2 [get_ports {ddr3_dqs_n[1]}]
|
||||
|
||||
# Clock Pins
|
||||
set_property SLEW FAST [get_ports ddr3_clk_p]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports ddr3_clk_p]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_clk_n]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports ddr3_clk_n]
|
||||
set_property PACKAGE_PIN R5 [get_ports ddr3_clk_p]
|
||||
set_property PACKAGE_PIN T4 [get_ports ddr3_clk_n]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Configuration options, can be used for all designs
|
||||
set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design]
|
||||
set_property CONFIG_VOLTAGE 3.3 [current_design]
|
||||
set_property CFGBVS VCCO [current_design]
|
||||
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
|
||||
set_property CONFIG_MODE SPIx4 [current_design]
|
||||
|
||||
## SW3 is assigned to a pin M5 in the 1.35v bank. This pin can also be used as
|
||||
## the VREF for BANK 34. To ensure that SW3 does not define the reference voltage
|
||||
## and to be able to use this pin as an ordinary I/O the following property must
|
||||
## be set to enable an internal VREF for BANK 34. Since a 1.35v supply is being
|
||||
## used the internal reference is set to half that value (i.e. 0.675v). Note that
|
||||
## this property must be set even if SW3 is not used in the design.
|
||||
# set_property INTERNAL_VREF 0.675 [get_iobanks 34]
|
||||
|
||||
|
||||
## This file is a general .xdc for the Arty S7-50 Rev. E
|
||||
## To use it in a project:
|
||||
## - uncomment the lines corresponding to used pins
|
||||
## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project
|
||||
|
||||
## Clock Signals
|
||||
set_property -dict {PACKAGE_PIN R2 IOSTANDARD SSTL135} [get_ports i_clk]
|
||||
create_clock -period 10.000 -name sys_clk_pin -waveform {0.000 5.000} -add [get_ports i_clk]
|
||||
|
||||
## LEDs
|
||||
set_property -dict {PACKAGE_PIN E18 IOSTANDARD LVCMOS33} [get_ports {led[0]}]
|
||||
set_property -dict {PACKAGE_PIN F13 IOSTANDARD LVCMOS33} [get_ports {led[1]}]
|
||||
set_property -dict {PACKAGE_PIN E13 IOSTANDARD LVCMOS33} [get_ports {led[2]}]
|
||||
set_property -dict {PACKAGE_PIN H15 IOSTANDARD LVCMOS33} [get_ports {led[3]}]
|
||||
|
||||
## Buttons
|
||||
set_property -dict {PACKAGE_PIN G15 IOSTANDARD LVCMOS33} [get_ports i_rst]
|
||||
|
||||
## USB-UART Interface
|
||||
set_property -dict {PACKAGE_PIN R12 IOSTANDARD LVCMOS33} [get_ports tx]
|
||||
set_property -dict {PACKAGE_PIN V12 IOSTANDARD LVCMOS33} [get_ports rx]
|
||||
|
||||
|
||||
############## DDR3 ##################
|
||||
# DQ PINS
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[0]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[0]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[0]}]
|
||||
set_property PACKAGE_PIN K2 [get_ports {ddr3_dq[0]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[1]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[1]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[1]}]
|
||||
set_property PACKAGE_PIN K3 [get_ports {ddr3_dq[1]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[2]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[2]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[2]}]
|
||||
set_property PACKAGE_PIN L4 [get_ports {ddr3_dq[2]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[3]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[3]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[3]}]
|
||||
set_property PACKAGE_PIN M6 [get_ports {ddr3_dq[3]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[4]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[4]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[4]}]
|
||||
set_property PACKAGE_PIN K6 [get_ports {ddr3_dq[4]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[5]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[5]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[5]}]
|
||||
set_property PACKAGE_PIN M4 [get_ports {ddr3_dq[5]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[6]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[6]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[6]}]
|
||||
set_property PACKAGE_PIN L5 [get_ports {ddr3_dq[6]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[7]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[7]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[7]}]
|
||||
set_property PACKAGE_PIN L6 [get_ports {ddr3_dq[7]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[8]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[8]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[8]}]
|
||||
set_property PACKAGE_PIN N4 [get_ports {ddr3_dq[8]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[9]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[9]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[9]}]
|
||||
set_property PACKAGE_PIN R1 [get_ports {ddr3_dq[9]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[10]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[10]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[10]}]
|
||||
set_property PACKAGE_PIN N1 [get_ports {ddr3_dq[10]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[11]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[11]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[11]}]
|
||||
set_property PACKAGE_PIN N5 [get_ports {ddr3_dq[11]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[12]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[12]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[12]}]
|
||||
set_property PACKAGE_PIN M2 [get_ports {ddr3_dq[12]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[13]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[13]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[13]}]
|
||||
set_property PACKAGE_PIN P1 [get_ports {ddr3_dq[13]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[14]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[14]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[14]}]
|
||||
set_property PACKAGE_PIN M1 [get_ports {ddr3_dq[14]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[15]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[15]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[15]}]
|
||||
set_property PACKAGE_PIN P2 [get_ports {ddr3_dq[15]}]
|
||||
|
||||
# Address Pins
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[13]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[13]}]
|
||||
set_property PACKAGE_PIN U6 [get_ports {ddr3_addr[13]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[12]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[12]}]
|
||||
set_property PACKAGE_PIN R6 [get_ports {ddr3_addr[12]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[11]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[11]}]
|
||||
set_property PACKAGE_PIN T5 [get_ports {ddr3_addr[11]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[10]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[10]}]
|
||||
set_property PACKAGE_PIN P6 [get_ports {ddr3_addr[10]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[9]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[9]}]
|
||||
set_property PACKAGE_PIN V7 [get_ports {ddr3_addr[9]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[8]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[8]}]
|
||||
set_property PACKAGE_PIN U7 [get_ports {ddr3_addr[8]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[7]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[7]}]
|
||||
set_property PACKAGE_PIN T6 [get_ports {ddr3_addr[7]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[6]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[6]}]
|
||||
set_property PACKAGE_PIN V6 [get_ports {ddr3_addr[6]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[5]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[5]}]
|
||||
set_property PACKAGE_PIN R7 [get_ports {ddr3_addr[5]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[4]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[4]}]
|
||||
set_property PACKAGE_PIN T3 [get_ports {ddr3_addr[4]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[3]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[3]}]
|
||||
set_property PACKAGE_PIN V4 [get_ports {ddr3_addr[3]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[2]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[2]}]
|
||||
set_property PACKAGE_PIN V2 [get_ports {ddr3_addr[2]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[1]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[1]}]
|
||||
set_property PACKAGE_PIN R4 [get_ports {ddr3_addr[1]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[0]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[0]}]
|
||||
set_property PACKAGE_PIN U2 [get_ports {ddr3_addr[0]}]
|
||||
|
||||
# Bank Pins
|
||||
set_property SLEW FAST [get_ports {ddr3_ba[2]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_ba[2]}]
|
||||
set_property PACKAGE_PIN U3 [get_ports {ddr3_ba[2]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_ba[1]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_ba[1]}]
|
||||
set_property PACKAGE_PIN T1 [get_ports {ddr3_ba[1]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_ba[0]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_ba[0]}]
|
||||
set_property PACKAGE_PIN V5 [get_ports {ddr3_ba[0]}]
|
||||
|
||||
# Command Pins
|
||||
set_property SLEW FAST [get_ports ddr3_ras_n]
|
||||
set_property IOSTANDARD SSTL135 [get_ports ddr3_ras_n]
|
||||
set_property PACKAGE_PIN U1 [get_ports ddr3_ras_n]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_cas_n]
|
||||
set_property IOSTANDARD SSTL135 [get_ports ddr3_cas_n]
|
||||
set_property PACKAGE_PIN V3 [get_ports ddr3_cas_n]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_we_n]
|
||||
set_property IOSTANDARD SSTL135 [get_ports ddr3_we_n]
|
||||
set_property PACKAGE_PIN P7 [get_ports ddr3_we_n]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_reset_n]
|
||||
set_property IOSTANDARD SSTL135 [get_ports ddr3_reset_n]
|
||||
set_property PACKAGE_PIN J6 [get_ports ddr3_reset_n]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_cke]
|
||||
set_property IOSTANDARD SSTL135 [get_ports ddr3_cke]
|
||||
set_property PACKAGE_PIN T2 [get_ports ddr3_cke]
|
||||
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_odt]
|
||||
set_property IOSTANDARD SSTL135 [get_ports ddr3_odt]
|
||||
set_property PACKAGE_PIN P5 [get_ports ddr3_odt]
|
||||
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_cs_n]
|
||||
set_property IOSTANDARD SSTL135 [get_ports ddr3_cs_n]
|
||||
set_property PACKAGE_PIN R3 [get_ports ddr3_cs_n]
|
||||
|
||||
# Data Mask Pins
|
||||
set_property SLEW FAST [get_ports {ddr3_dm[0]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dm[0]}]
|
||||
set_property PACKAGE_PIN K4 [get_ports {ddr3_dm[0]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dm[1]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dm[1]}]
|
||||
set_property PACKAGE_PIN M3 [get_ports {ddr3_dm[1]}]
|
||||
|
||||
# DQS Pins
|
||||
set_property SLEW FAST [get_ports {ddr3_dqs_p[0]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dqs_p[0]}]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddr3_dqs_p[0]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dqs_n[0]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dqs_n[0]}]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddr3_dqs_n[0]}]
|
||||
set_property PACKAGE_PIN K1 [get_ports {ddr3_dqs_p[0]}]
|
||||
set_property PACKAGE_PIN L1 [get_ports {ddr3_dqs_n[0]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dqs_p[1]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dqs_p[1]}]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddr3_dqs_p[1]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dqs_n[1]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dqs_n[1]}]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddr3_dqs_n[1]}]
|
||||
set_property PACKAGE_PIN N3 [get_ports {ddr3_dqs_p[1]}]
|
||||
set_property PACKAGE_PIN N2 [get_ports {ddr3_dqs_n[1]}]
|
||||
|
||||
# Clock Pins
|
||||
set_property SLEW FAST [get_ports ddr3_clk_p]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports ddr3_clk_p]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_clk_n]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports ddr3_clk_n]
|
||||
set_property PACKAGE_PIN R5 [get_ports ddr3_clk_p]
|
||||
set_property PACKAGE_PIN T4 [get_ports ddr3_clk_n]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Configuration options, can be used for all designs
|
||||
set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design]
|
||||
set_property CONFIG_VOLTAGE 3.3 [current_design]
|
||||
set_property CFGBVS VCCO [current_design]
|
||||
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
|
||||
set_property CONFIG_MODE SPIx4 [current_design]
|
||||
|
||||
## SW3 is assigned to a pin M5 in the 1.35v bank. This pin can also be used as
|
||||
## the VREF for BANK 34. To ensure that SW3 does not define the reference voltage
|
||||
## and to be able to use this pin as an ordinary I/O the following property must
|
||||
## be set to enable an internal VREF for BANK 34. Since a 1.35v supply is being
|
||||
## used the internal reference is set to half that value (i.e. 0.675v). Note that
|
||||
## this property must be set even if SW3 is not used in the design.
|
||||
# set_property INTERNAL_VREF 0.675 [get_iobanks 34]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,66 +1,66 @@
|
|||
`timescale 1ps/1ps
|
||||
|
||||
module clk_wiz
|
||||
(
|
||||
input clk_in1,
|
||||
output clk_out1,
|
||||
output clk_out2,
|
||||
output clk_out3,
|
||||
output clk_out4,
|
||||
input reset,
|
||||
output locked
|
||||
);
|
||||
wire clk_out1_clk_wiz_0;
|
||||
wire clk_out2_clk_wiz_0;
|
||||
wire clk_out3_clk_wiz_0;
|
||||
wire clk_out4_clk_wiz_0;
|
||||
|
||||
wire clkfbout;
|
||||
|
||||
PLLE2_ADV
|
||||
#(.BANDWIDTH ("OPTIMIZED"),
|
||||
.COMPENSATION ("INTERNAL"),
|
||||
.STARTUP_WAIT ("FALSE"),
|
||||
.DIVCLK_DIVIDE (1),
|
||||
.CLKFBOUT_MULT (10), // 100 MHz * 10 = 1000 MHz
|
||||
.CLKFBOUT_PHASE (0.000),
|
||||
.CLKOUT0_DIVIDE (12), // 1000 MHz / 12 = 83.333 MHz
|
||||
.CLKOUT0_PHASE (0.000),
|
||||
.CLKOUT0_DUTY_CYCLE (0.500),
|
||||
.CLKOUT1_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz
|
||||
.CLKOUT1_PHASE (0.000),
|
||||
.CLKOUT1_DUTY_CYCLE (0.500),
|
||||
.CLKOUT2_DIVIDE (5), // 1000 MHz / 5 = 200 MHz
|
||||
.CLKOUT2_PHASE (0.000),
|
||||
.CLKOUT2_DUTY_CYCLE (0.500),
|
||||
.CLKOUT3_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz, 90 phase
|
||||
.CLKOUT3_PHASE (90.000),
|
||||
.CLKOUT3_DUTY_CYCLE (0.500),
|
||||
.CLKIN1_PERIOD (10.000) // 100 MHz input
|
||||
)
|
||||
plle2_adv_inst
|
||||
(
|
||||
.CLKFBOUT (clkfbout),
|
||||
.CLKOUT0 (clk_out1_clk_wiz_0),
|
||||
.CLKOUT1 (clk_out2_clk_wiz_0),
|
||||
.CLKOUT2 (clk_out3_clk_wiz_0),
|
||||
.CLKOUT3 (clk_out4_clk_wiz_0),
|
||||
.CLKFBIN (clkfbout),
|
||||
.CLKIN1 (clk_in1),
|
||||
.LOCKED (locked),
|
||||
.RST (reset)
|
||||
);
|
||||
BUFG clkout1_buf
|
||||
(.O (clk_out1),
|
||||
.I (clk_out1_clk_wiz_0));
|
||||
BUFG clkout2_buf
|
||||
(.O (clk_out2),
|
||||
.I (clk_out2_clk_wiz_0));
|
||||
BUFG clkout3_buf
|
||||
(.O (clk_out3),
|
||||
.I (clk_out3_clk_wiz_0));
|
||||
BUFG clkout4_buf
|
||||
(.O (clk_out4),
|
||||
.I (clk_out4_clk_wiz_0));
|
||||
|
||||
endmodule
|
||||
`timescale 1ps/1ps
|
||||
|
||||
module clk_wiz
|
||||
(
|
||||
input clk_in1,
|
||||
output clk_out1,
|
||||
output clk_out2,
|
||||
output clk_out3,
|
||||
output clk_out4,
|
||||
input reset,
|
||||
output locked
|
||||
);
|
||||
wire clk_out1_clk_wiz_0;
|
||||
wire clk_out2_clk_wiz_0;
|
||||
wire clk_out3_clk_wiz_0;
|
||||
wire clk_out4_clk_wiz_0;
|
||||
|
||||
wire clkfbout;
|
||||
|
||||
PLLE2_ADV
|
||||
#(.BANDWIDTH ("OPTIMIZED"),
|
||||
.COMPENSATION ("INTERNAL"),
|
||||
.STARTUP_WAIT ("FALSE"),
|
||||
.DIVCLK_DIVIDE (1),
|
||||
.CLKFBOUT_MULT (10), // 100 MHz * 10 = 1000 MHz
|
||||
.CLKFBOUT_PHASE (0.000),
|
||||
.CLKOUT0_DIVIDE (12), // 1000 MHz / 12 = 83.333 MHz
|
||||
.CLKOUT0_PHASE (0.000),
|
||||
.CLKOUT0_DUTY_CYCLE (0.500),
|
||||
.CLKOUT1_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz
|
||||
.CLKOUT1_PHASE (0.000),
|
||||
.CLKOUT1_DUTY_CYCLE (0.500),
|
||||
.CLKOUT2_DIVIDE (5), // 1000 MHz / 5 = 200 MHz
|
||||
.CLKOUT2_PHASE (0.000),
|
||||
.CLKOUT2_DUTY_CYCLE (0.500),
|
||||
.CLKOUT3_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz, 90 phase
|
||||
.CLKOUT3_PHASE (90.000),
|
||||
.CLKOUT3_DUTY_CYCLE (0.500),
|
||||
.CLKIN1_PERIOD (10.000) // 100 MHz input
|
||||
)
|
||||
plle2_adv_inst
|
||||
(
|
||||
.CLKFBOUT (clkfbout),
|
||||
.CLKOUT0 (clk_out1_clk_wiz_0),
|
||||
.CLKOUT1 (clk_out2_clk_wiz_0),
|
||||
.CLKOUT2 (clk_out3_clk_wiz_0),
|
||||
.CLKOUT3 (clk_out4_clk_wiz_0),
|
||||
.CLKFBIN (clkfbout),
|
||||
.CLKIN1 (clk_in1),
|
||||
.LOCKED (locked),
|
||||
.RST (reset)
|
||||
);
|
||||
BUFG clkout1_buf
|
||||
(.O (clk_out1),
|
||||
.I (clk_out1_clk_wiz_0));
|
||||
BUFG clkout2_buf
|
||||
(.O (clk_out2),
|
||||
.I (clk_out2_clk_wiz_0));
|
||||
BUFG clkout3_buf
|
||||
(.O (clk_out3),
|
||||
.I (clk_out3_clk_wiz_0));
|
||||
BUFG clkout4_buf
|
||||
(.O (clk_out4),
|
||||
.I (clk_out4_clk_wiz_0));
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,207 +1,207 @@
|
|||
|
||||
//
|
||||
// Module: uart_rx
|
||||
//
|
||||
// Notes:
|
||||
// - UART reciever module.
|
||||
//
|
||||
|
||||
module uart_rx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
input wire uart_rxd , // UART Recieve pin.
|
||||
input wire uart_rx_en , // Recieve enable
|
||||
output wire uart_rx_break, // Did we get a BREAK message?
|
||||
output wire uart_rx_valid, // Valid data recieved and available.
|
||||
output reg [PAYLOAD_BITS-1:0] uart_rx_data // The recieved data.
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_rxd line. Helps break long timing
|
||||
// paths from input pins into the logic.
|
||||
reg rxd_reg;
|
||||
reg rxd_reg_0;
|
||||
|
||||
//
|
||||
// Storage for the recieved serial data.
|
||||
reg [PAYLOAD_BITS-1:0] recieved_data;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of recieved bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Sample of the UART input line whenever we are in the middle of a bit frame.
|
||||
reg bit_sample;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_RECV = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Output assignment
|
||||
//
|
||||
|
||||
assign uart_rx_break = uart_rx_valid && ~|recieved_data;
|
||||
assign uart_rx_valid = fsm_state == FSM_STOP && n_fsm_state == FSM_IDLE;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(!resetn) begin
|
||||
uart_rx_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if (fsm_state == FSM_STOP) begin
|
||||
uart_rx_data <= recieved_data;
|
||||
end
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT ||
|
||||
fsm_state == FSM_STOP &&
|
||||
cycle_counter == CYCLES_PER_BIT/2;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = rxd_reg ? FSM_IDLE : FSM_START;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_RECV : FSM_START;
|
||||
FSM_RECV : n_fsm_state = payload_done ? FSM_STOP : FSM_RECV ;
|
||||
FSM_STOP : n_fsm_state = next_bit ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the recieved data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_recieved_data
|
||||
if(!resetn) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE ) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit ) begin
|
||||
recieved_data[PAYLOAD_BITS-1] <= bit_sample;
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
recieved_data[i] <= recieved_data[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Increments the bit counter when recieving.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_RECV) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Sample the recieved bit when in the middle of a bit frame.
|
||||
always @(posedge clk) begin : p_bit_sample
|
||||
if(!resetn) begin
|
||||
bit_sample <= 1'b0;
|
||||
end else if (cycle_counter == CYCLES_PER_BIT/2) begin
|
||||
bit_sample <= rxd_reg;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when recieving.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_RECV ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the rxd_reg.
|
||||
always @(posedge clk) begin : p_rxd_reg
|
||||
if(!resetn) begin
|
||||
rxd_reg <= 1'b1;
|
||||
rxd_reg_0 <= 1'b1;
|
||||
end else if(uart_rx_en) begin
|
||||
rxd_reg <= rxd_reg_0;
|
||||
rxd_reg_0 <= uart_rxd;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
//
|
||||
// Module: uart_rx
|
||||
//
|
||||
// Notes:
|
||||
// - UART reciever module.
|
||||
//
|
||||
|
||||
module uart_rx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
input wire uart_rxd , // UART Recieve pin.
|
||||
input wire uart_rx_en , // Recieve enable
|
||||
output wire uart_rx_break, // Did we get a BREAK message?
|
||||
output wire uart_rx_valid, // Valid data recieved and available.
|
||||
output reg [PAYLOAD_BITS-1:0] uart_rx_data // The recieved data.
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_rxd line. Helps break long timing
|
||||
// paths from input pins into the logic.
|
||||
reg rxd_reg;
|
||||
reg rxd_reg_0;
|
||||
|
||||
//
|
||||
// Storage for the recieved serial data.
|
||||
reg [PAYLOAD_BITS-1:0] recieved_data;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of recieved bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Sample of the UART input line whenever we are in the middle of a bit frame.
|
||||
reg bit_sample;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_RECV = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Output assignment
|
||||
//
|
||||
|
||||
assign uart_rx_break = uart_rx_valid && ~|recieved_data;
|
||||
assign uart_rx_valid = fsm_state == FSM_STOP && n_fsm_state == FSM_IDLE;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(!resetn) begin
|
||||
uart_rx_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if (fsm_state == FSM_STOP) begin
|
||||
uart_rx_data <= recieved_data;
|
||||
end
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT ||
|
||||
fsm_state == FSM_STOP &&
|
||||
cycle_counter == CYCLES_PER_BIT/2;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = rxd_reg ? FSM_IDLE : FSM_START;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_RECV : FSM_START;
|
||||
FSM_RECV : n_fsm_state = payload_done ? FSM_STOP : FSM_RECV ;
|
||||
FSM_STOP : n_fsm_state = next_bit ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the recieved data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_recieved_data
|
||||
if(!resetn) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE ) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit ) begin
|
||||
recieved_data[PAYLOAD_BITS-1] <= bit_sample;
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
recieved_data[i] <= recieved_data[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Increments the bit counter when recieving.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_RECV) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Sample the recieved bit when in the middle of a bit frame.
|
||||
always @(posedge clk) begin : p_bit_sample
|
||||
if(!resetn) begin
|
||||
bit_sample <= 1'b0;
|
||||
end else if (cycle_counter == CYCLES_PER_BIT/2) begin
|
||||
bit_sample <= rxd_reg;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when recieving.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_RECV ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the rxd_reg.
|
||||
always @(posedge clk) begin : p_rxd_reg
|
||||
if(!resetn) begin
|
||||
rxd_reg <= 1'b1;
|
||||
rxd_reg_0 <= 1'b1;
|
||||
end else if(uart_rx_en) begin
|
||||
rxd_reg <= rxd_reg_0;
|
||||
rxd_reg_0 <= uart_rxd;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,187 +1,187 @@
|
|||
|
||||
|
||||
//
|
||||
// Module: uart_tx
|
||||
//
|
||||
// Notes:
|
||||
// - UART transmitter module.
|
||||
//
|
||||
|
||||
module uart_tx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
output wire uart_txd , // UART transmit pin.
|
||||
output wire uart_tx_busy, // Module busy sending previous item.
|
||||
input wire uart_tx_en , // Send the data on uart_tx_data
|
||||
input wire [PAYLOAD_BITS-1:0] uart_tx_data // The data to be sent
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_txd line. Helps break long timing
|
||||
// paths from the logic to the output pins.
|
||||
reg txd_reg;
|
||||
|
||||
//
|
||||
// Storage for the serial data to be sent.
|
||||
reg [PAYLOAD_BITS-1:0] data_to_send;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of sent bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_SEND = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
assign uart_tx_busy = fsm_state != FSM_IDLE;
|
||||
assign uart_txd = txd_reg;
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
wire stop_done = bit_counter == STOP_BITS && fsm_state == FSM_STOP;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = uart_tx_en ? FSM_START: FSM_IDLE ;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_SEND : FSM_START;
|
||||
FSM_SEND : n_fsm_state = payload_done ? FSM_STOP : FSM_SEND ;
|
||||
FSM_STOP : n_fsm_state = stop_done ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the sent data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_data_to_send
|
||||
if(!resetn) begin
|
||||
data_to_send <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE && uart_tx_en) begin
|
||||
data_to_send <= uart_tx_data;
|
||||
end else if(fsm_state == FSM_SEND && next_bit ) begin
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
data_to_send[i] <= data_to_send[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the bit counter each time a new bit frame is sent.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_SEND && fsm_state != FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_SEND && n_fsm_state == FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_STOP&& next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end else if(fsm_state == FSM_SEND && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when sending.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_SEND ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the txd_reg.
|
||||
always @(posedge clk) begin : p_txd_reg
|
||||
if(!resetn) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_IDLE) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_START) begin
|
||||
txd_reg <= 1'b0;
|
||||
end else if(fsm_state == FSM_SEND) begin
|
||||
txd_reg <= data_to_send[0];
|
||||
end else if(fsm_state == FSM_STOP) begin
|
||||
txd_reg <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
//
|
||||
// Module: uart_tx
|
||||
//
|
||||
// Notes:
|
||||
// - UART transmitter module.
|
||||
//
|
||||
|
||||
module uart_tx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
output wire uart_txd , // UART transmit pin.
|
||||
output wire uart_tx_busy, // Module busy sending previous item.
|
||||
input wire uart_tx_en , // Send the data on uart_tx_data
|
||||
input wire [PAYLOAD_BITS-1:0] uart_tx_data // The data to be sent
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_txd line. Helps break long timing
|
||||
// paths from the logic to the output pins.
|
||||
reg txd_reg;
|
||||
|
||||
//
|
||||
// Storage for the serial data to be sent.
|
||||
reg [PAYLOAD_BITS-1:0] data_to_send;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of sent bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_SEND = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
assign uart_tx_busy = fsm_state != FSM_IDLE;
|
||||
assign uart_txd = txd_reg;
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
wire stop_done = bit_counter == STOP_BITS && fsm_state == FSM_STOP;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = uart_tx_en ? FSM_START: FSM_IDLE ;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_SEND : FSM_START;
|
||||
FSM_SEND : n_fsm_state = payload_done ? FSM_STOP : FSM_SEND ;
|
||||
FSM_STOP : n_fsm_state = stop_done ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the sent data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_data_to_send
|
||||
if(!resetn) begin
|
||||
data_to_send <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE && uart_tx_en) begin
|
||||
data_to_send <= uart_tx_data;
|
||||
end else if(fsm_state == FSM_SEND && next_bit ) begin
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
data_to_send[i] <= data_to_send[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the bit counter each time a new bit frame is sent.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_SEND && fsm_state != FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_SEND && n_fsm_state == FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_STOP&& next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end else if(fsm_state == FSM_SEND && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when sending.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_SEND ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the txd_reg.
|
||||
always @(posedge clk) begin : p_txd_reg
|
||||
if(!resetn) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_IDLE) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_START) begin
|
||||
txd_reg <= 1'b0;
|
||||
end else if(fsm_state == FSM_SEND) begin
|
||||
txd_reg <= data_to_send[0];
|
||||
end else if(fsm_state == FSM_STOP) begin
|
||||
txd_reg <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,71 +1,71 @@
|
|||
FAMILY = kintex7
|
||||
PART = xc7k160tffg676-2
|
||||
BOARD = qmtechKintex7
|
||||
PROJECT = enclustra_ddr3
|
||||
CHIPDB = ${KINTEX7_CHIPDB}
|
||||
ADDITIONAL_SOURCES = ../../rtl/ddr3_controller.v ../../rtl/ddr3_phy.v ../../rtl/ddr3_top.v uart_rx.v uart_tx.v clk_wiz.v
|
||||
|
||||
#############################################################################################
|
||||
NEXTPNR_XILINX_DIR ?= /snap/openxc7/current/opt/nextpnr-xilinx
|
||||
NEXTPNR_XILINX_PYTHON_DIR ?= ${NEXTPNR_XILINX_DIR}/python
|
||||
PRJXRAY_DB_DIR ?= ${NEXTPNR_XILINX_DIR}/external/prjxray-db
|
||||
|
||||
DBPART = $(shell echo ${PART} | sed -e 's/-[0-9]//g')
|
||||
SPEEDGRADE = $(shell echo ${PART} | sed -e 's/.*\-\([0-9]\)/\1/g')
|
||||
|
||||
CHIPDB ?= ./
|
||||
ifeq ($(CHIPDB),)
|
||||
CHIPDB = ./
|
||||
endif
|
||||
|
||||
PYPY3 ?= pypy3
|
||||
|
||||
TOP ?= ${PROJECT}
|
||||
TOP_MODULE ?= ${TOP}
|
||||
TOP_VERILOG ?= ${TOP}.v
|
||||
|
||||
PNR_DEBUG ?= # --verbose --debug
|
||||
|
||||
BOARD ?= UNKNOWN
|
||||
JTAG_LINK ?= --board ${BOARD}
|
||||
|
||||
XDC ?= ${PROJECT}.xdc
|
||||
|
||||
.PHONY: all
|
||||
all: ${PROJECT}.bit
|
||||
|
||||
.PHONY: program
|
||||
program: ${PROJECT}.bit
|
||||
openFPGALoader ${JTAG_LINK} --bitstream $<
|
||||
|
||||
${PROJECT}.json: ${TOP_VERILOG} ${ADDITIONAL_SOURCES}
|
||||
yosys -p "synth_xilinx -flatten -abc9 ${SYNTH_OPTS} -arch xc7 -top ${TOP_MODULE}; write_json ${PROJECT}.json" $< ${ADDITIONAL_SOURCES}
|
||||
|
||||
# The chip database only needs to be generated once
|
||||
# that is why we don't clean it with make clean
|
||||
${CHIPDB}/${DBPART}.bin:
|
||||
${PYPY3} ${NEXTPNR_XILINX_PYTHON_DIR}/bbaexport.py --device ${PART} --bba ${DBPART}.bba
|
||||
bbasm -l ${DBPART}.bba ${CHIPDB}/${DBPART}.bin
|
||||
rm -f ${DBPART}.bba
|
||||
|
||||
${PROJECT}.fasm: ${PROJECT}.json ${CHIPDB}/${DBPART}.bin ${XDC}
|
||||
nextpnr-xilinx --chipdb ${CHIPDB}/${DBPART}.bin --xdc ${XDC} --json ${PROJECT}.json --fasm $@ ${PNR_ARGS} ${PNR_DEBUG}
|
||||
|
||||
${PROJECT}.frames: ${PROJECT}.fasm
|
||||
fasm2frames --part ${PART} --db-root ${PRJXRAY_DB_DIR}/${FAMILY} $< > $@
|
||||
|
||||
${PROJECT}.bit: ${PROJECT}.frames
|
||||
xc7frames2bit --part_file ${PRJXRAY_DB_DIR}/${FAMILY}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -f *.bit
|
||||
@rm -f *.frames
|
||||
@rm -f *.fasm
|
||||
@rm -f *.json
|
||||
@rm -f *.bin
|
||||
@rm -f *.bba
|
||||
|
||||
.PHONY: pnrclean
|
||||
pnrclean:
|
||||
FAMILY = kintex7
|
||||
PART = xc7k160tffg676-2
|
||||
BOARD = qmtechKintex7
|
||||
PROJECT = enclustra_ddr3
|
||||
CHIPDB = ${KINTEX7_CHIPDB}
|
||||
ADDITIONAL_SOURCES = ../../rtl/ddr3_controller.v ../../rtl/ddr3_phy.v ../../rtl/ddr3_top.v uart_rx.v uart_tx.v clk_wiz.v
|
||||
|
||||
#############################################################################################
|
||||
NEXTPNR_XILINX_DIR ?= /snap/openxc7/current/opt/nextpnr-xilinx
|
||||
NEXTPNR_XILINX_PYTHON_DIR ?= ${NEXTPNR_XILINX_DIR}/python
|
||||
PRJXRAY_DB_DIR ?= ${NEXTPNR_XILINX_DIR}/external/prjxray-db
|
||||
|
||||
DBPART = $(shell echo ${PART} | sed -e 's/-[0-9]//g')
|
||||
SPEEDGRADE = $(shell echo ${PART} | sed -e 's/.*\-\([0-9]\)/\1/g')
|
||||
|
||||
CHIPDB ?= ./
|
||||
ifeq ($(CHIPDB),)
|
||||
CHIPDB = ./
|
||||
endif
|
||||
|
||||
PYPY3 ?= pypy3
|
||||
|
||||
TOP ?= ${PROJECT}
|
||||
TOP_MODULE ?= ${TOP}
|
||||
TOP_VERILOG ?= ${TOP}.v
|
||||
|
||||
PNR_DEBUG ?= # --verbose --debug
|
||||
|
||||
BOARD ?= UNKNOWN
|
||||
JTAG_LINK ?= --board ${BOARD}
|
||||
|
||||
XDC ?= ${PROJECT}.xdc
|
||||
|
||||
.PHONY: all
|
||||
all: ${PROJECT}.bit
|
||||
|
||||
.PHONY: program
|
||||
program: ${PROJECT}.bit
|
||||
openFPGALoader ${JTAG_LINK} --bitstream $<
|
||||
|
||||
${PROJECT}.json: ${TOP_VERILOG} ${ADDITIONAL_SOURCES}
|
||||
yosys -p "synth_xilinx -flatten -abc9 ${SYNTH_OPTS} -arch xc7 -top ${TOP_MODULE}; write_json ${PROJECT}.json" $< ${ADDITIONAL_SOURCES}
|
||||
|
||||
# The chip database only needs to be generated once
|
||||
# that is why we don't clean it with make clean
|
||||
${CHIPDB}/${DBPART}.bin:
|
||||
${PYPY3} ${NEXTPNR_XILINX_PYTHON_DIR}/bbaexport.py --device ${PART} --bba ${DBPART}.bba
|
||||
bbasm -l ${DBPART}.bba ${CHIPDB}/${DBPART}.bin
|
||||
rm -f ${DBPART}.bba
|
||||
|
||||
${PROJECT}.fasm: ${PROJECT}.json ${CHIPDB}/${DBPART}.bin ${XDC}
|
||||
nextpnr-xilinx --chipdb ${CHIPDB}/${DBPART}.bin --xdc ${XDC} --json ${PROJECT}.json --fasm $@ ${PNR_ARGS} ${PNR_DEBUG}
|
||||
|
||||
${PROJECT}.frames: ${PROJECT}.fasm
|
||||
fasm2frames --part ${PART} --db-root ${PRJXRAY_DB_DIR}/${FAMILY} $< > $@
|
||||
|
||||
${PROJECT}.bit: ${PROJECT}.frames
|
||||
xc7frames2bit --part_file ${PRJXRAY_DB_DIR}/${FAMILY}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -f *.bit
|
||||
@rm -f *.frames
|
||||
@rm -f *.fasm
|
||||
@rm -f *.json
|
||||
@rm -f *.bin
|
||||
@rm -f *.bba
|
||||
|
||||
.PHONY: pnrclean
|
||||
pnrclean:
|
||||
rm *.fasm *.frames *.bit
|
||||
|
|
@ -1,66 +1,66 @@
|
|||
`timescale 1ps/1ps
|
||||
|
||||
module clk_wiz
|
||||
(
|
||||
input clk_in1,
|
||||
output clk_out1,
|
||||
output clk_out2,
|
||||
output clk_out3,
|
||||
output clk_out4,
|
||||
input reset,
|
||||
output locked
|
||||
);
|
||||
wire clk_out1_clk_wiz_0;
|
||||
wire clk_out2_clk_wiz_0;
|
||||
wire clk_out3_clk_wiz_0;
|
||||
wire clk_out4_clk_wiz_0;
|
||||
|
||||
wire clkfbout;
|
||||
|
||||
PLLE2_ADV
|
||||
#(.BANDWIDTH ("OPTIMIZED"),
|
||||
.COMPENSATION ("INTERNAL"),
|
||||
.STARTUP_WAIT ("FALSE"),
|
||||
.DIVCLK_DIVIDE (1),
|
||||
.CLKFBOUT_MULT (5), // 200 MHz * 5 = 1000 MHz
|
||||
.CLKFBOUT_PHASE (0.000),
|
||||
.CLKOUT0_DIVIDE (12), // 1000 MHz / 12 = 83.333 MHz
|
||||
.CLKOUT0_PHASE (0.000),
|
||||
.CLKOUT0_DUTY_CYCLE (0.500),
|
||||
.CLKOUT1_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz
|
||||
.CLKOUT1_PHASE (0.000),
|
||||
.CLKOUT1_DUTY_CYCLE (0.500),
|
||||
.CLKOUT2_DIVIDE (5), // 1000 MHz / 5 = 200 MHz
|
||||
.CLKOUT2_PHASE (0.000),
|
||||
.CLKOUT2_DUTY_CYCLE (0.500),
|
||||
.CLKOUT3_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz, 90 phase
|
||||
.CLKOUT3_PHASE (90.000),
|
||||
.CLKOUT3_DUTY_CYCLE (0.500),
|
||||
.CLKIN1_PERIOD (5) // 200 MHz input
|
||||
)
|
||||
plle2_adv_inst
|
||||
(
|
||||
.CLKFBOUT (clkfbout),
|
||||
.CLKOUT0 (clk_out1_clk_wiz_0),
|
||||
.CLKOUT1 (clk_out2_clk_wiz_0),
|
||||
.CLKOUT2 (clk_out3_clk_wiz_0),
|
||||
.CLKOUT3 (clk_out4_clk_wiz_0),
|
||||
.CLKFBIN (clkfbout),
|
||||
.CLKIN1 (clk_in1),
|
||||
.LOCKED (locked),
|
||||
.RST (reset)
|
||||
);
|
||||
BUFG clkout1_buf
|
||||
(.O (clk_out1),
|
||||
.I (clk_out1_clk_wiz_0));
|
||||
BUFG clkout2_buf
|
||||
(.O (clk_out2),
|
||||
.I (clk_out2_clk_wiz_0));
|
||||
BUFG clkout3_buf
|
||||
(.O (clk_out3),
|
||||
.I (clk_out3_clk_wiz_0));
|
||||
BUFG clkout4_buf
|
||||
(.O (clk_out4),
|
||||
.I (clk_out4_clk_wiz_0));
|
||||
|
||||
endmodule
|
||||
`timescale 1ps/1ps
|
||||
|
||||
module clk_wiz
|
||||
(
|
||||
input clk_in1,
|
||||
output clk_out1,
|
||||
output clk_out2,
|
||||
output clk_out3,
|
||||
output clk_out4,
|
||||
input reset,
|
||||
output locked
|
||||
);
|
||||
wire clk_out1_clk_wiz_0;
|
||||
wire clk_out2_clk_wiz_0;
|
||||
wire clk_out3_clk_wiz_0;
|
||||
wire clk_out4_clk_wiz_0;
|
||||
|
||||
wire clkfbout;
|
||||
|
||||
PLLE2_ADV
|
||||
#(.BANDWIDTH ("OPTIMIZED"),
|
||||
.COMPENSATION ("INTERNAL"),
|
||||
.STARTUP_WAIT ("FALSE"),
|
||||
.DIVCLK_DIVIDE (1),
|
||||
.CLKFBOUT_MULT (5), // 200 MHz * 5 = 1000 MHz
|
||||
.CLKFBOUT_PHASE (0.000),
|
||||
.CLKOUT0_DIVIDE (12), // 1000 MHz / 12 = 83.333 MHz
|
||||
.CLKOUT0_PHASE (0.000),
|
||||
.CLKOUT0_DUTY_CYCLE (0.500),
|
||||
.CLKOUT1_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz
|
||||
.CLKOUT1_PHASE (0.000),
|
||||
.CLKOUT1_DUTY_CYCLE (0.500),
|
||||
.CLKOUT2_DIVIDE (5), // 1000 MHz / 5 = 200 MHz
|
||||
.CLKOUT2_PHASE (0.000),
|
||||
.CLKOUT2_DUTY_CYCLE (0.500),
|
||||
.CLKOUT3_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz, 90 phase
|
||||
.CLKOUT3_PHASE (90.000),
|
||||
.CLKOUT3_DUTY_CYCLE (0.500),
|
||||
.CLKIN1_PERIOD (5) // 200 MHz input
|
||||
)
|
||||
plle2_adv_inst
|
||||
(
|
||||
.CLKFBOUT (clkfbout),
|
||||
.CLKOUT0 (clk_out1_clk_wiz_0),
|
||||
.CLKOUT1 (clk_out2_clk_wiz_0),
|
||||
.CLKOUT2 (clk_out3_clk_wiz_0),
|
||||
.CLKOUT3 (clk_out4_clk_wiz_0),
|
||||
.CLKFBIN (clkfbout),
|
||||
.CLKIN1 (clk_in1),
|
||||
.LOCKED (locked),
|
||||
.RST (reset)
|
||||
);
|
||||
BUFG clkout1_buf
|
||||
(.O (clk_out1),
|
||||
.I (clk_out1_clk_wiz_0));
|
||||
BUFG clkout2_buf
|
||||
(.O (clk_out2),
|
||||
.I (clk_out2_clk_wiz_0));
|
||||
BUFG clkout3_buf
|
||||
(.O (clk_out3),
|
||||
.I (clk_out3_clk_wiz_0));
|
||||
BUFG clkout4_buf
|
||||
(.O (clk_out4),
|
||||
.I (clk_out4_clk_wiz_0));
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,210 +1,210 @@
|
|||
################################################################################
|
||||
################################################################################
|
||||
set_property CFGBVS GND [current_design]
|
||||
set_property CONFIG_VOLTAGE 1.8 [current_design]
|
||||
set_property BITSTREAM.CONFIG.CONFIGRATE 22 [current_design]
|
||||
set_property BITSTREAM.CONFIG.OVERTEMPPOWERDOWN ENABLE [current_design]
|
||||
set_property BITSTREAM.CONFIG.UNUSEDPIN PULLNONE [current_design]
|
||||
|
||||
# set_property -dict {PACKAGE_PIN AD24 IOSTANDARD LVCMOS18 } [get_ports {CLK_100_CAL}]
|
||||
# set_property DCI_CASCADE {32 33} [get_iobanks 34]
|
||||
## For a 1.5V memory, the appropriate VREF voltage is half of 1.5, or 0.75 Volts
|
||||
## Of the DDR3 bank(s), only bank 33 needs the INTERNAL_VREF. The other DDR3
|
||||
## banks are explicitly connected to an external VREF signal. However, bank
|
||||
## 33s IOs are overloaded--there was no room for the VREF. Hence, to spare
|
||||
## two pins, bank 33 uses an internal voltage reference. Sadly, the same
|
||||
## problem plays out in banks 12-16 as well.
|
||||
# set_property INTERNAL_VREF 0.750 [get_iobanks 33]
|
||||
# ## Other IO banks have internal VREFs as well, those these aren't as critical
|
||||
# set_property INTERNAL_VREF 0.90 [get_iobanks 12]
|
||||
# set_property INTERNAL_VREF 0.60 [get_iobanks 13]
|
||||
# set_property INTERNAL_VREF 0.90 [get_iobanks 14]
|
||||
# set_property INTERNAL_VREF 0.90 [get_iobanks 15]
|
||||
# set_property INTERNAL_VREF 0.90 [get_iobanks 16]
|
||||
|
||||
## Clocks
|
||||
# 100MHz single ended input clock
|
||||
set_property -dict {PACKAGE_PIN AA4 IOSTANDARD SSTL15} [get_ports i_clk]
|
||||
create_clock -period 10.000 -name sys_clk_pin -waveform {0.000 5.000} -add [get_ports i_clk]
|
||||
|
||||
# Baseboard LEDs
|
||||
# set_property -dict {SLEW SLOW PACKAGE_PIN F22 IOSTANDARD LVCMOS18 } [get_ports { o_led_status[4] }] # GPIO0_LED0_N
|
||||
set_property -dict {PACKAGE_PIN E23 IOSTANDARD LVCMOS18} [get_ports {led[0]}]
|
||||
set_property -dict {PACKAGE_PIN K25 IOSTANDARD LVCMOS12} [get_ports {led[1]}]
|
||||
set_property -dict {PACKAGE_PIN K26 IOSTANDARD LVCMOS12} [get_ports {led[2]}]
|
||||
|
||||
## UART
|
||||
## {{{
|
||||
set_property -dict {PACKAGE_PIN B20 IOSTANDARD LVCMOS18 } [get_ports {rx}]
|
||||
set_property -dict {PACKAGE_PIN A20 IOSTANDARD LVCMOS18 } [get_ports {tx}]
|
||||
## }}}
|
||||
|
||||
## Buttons
|
||||
## {{{
|
||||
set_property -dict {PACKAGE_PIN C22 IOSTANDARD LVCMOS18 } [get_ports {i_rst_n}]
|
||||
|
||||
## DDR3 MEMORY
|
||||
set_property -dict {PACKAGE_PIN AB7 IOSTANDARD LVCMOS15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_reset_n}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AB12 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_clk_p}]
|
||||
set_property -dict {PACKAGE_PIN AC12 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_clk_n}]
|
||||
set_property -dict {PACKAGE_PIN AA13 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_cke}]
|
||||
## set_property -dict {SLEW SLOW PACKAGE_PIN AA3 IOSTANDARD LVCMOS15 } [get_ports {o_ddr3_vsel}]
|
||||
set_property -dict {PACKAGE_PIN Y12 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_cs_n}]
|
||||
set_property -dict {PACKAGE_PIN AE13 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_ras_n}]
|
||||
set_property -dict {PACKAGE_PIN AE12 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_cas_n}]
|
||||
set_property -dict {PACKAGE_PIN AA12 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_we_n}]
|
||||
set_property -dict {PACKAGE_PIN AD13 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_odt}]
|
||||
|
||||
|
||||
## Address lines
|
||||
set_property -dict {PACKAGE_PIN AE11 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[0]}]
|
||||
set_property -dict {PACKAGE_PIN AF9 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[1]}]
|
||||
set_property -dict {PACKAGE_PIN AD10 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[2]}]
|
||||
set_property -dict {PACKAGE_PIN AB10 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[3]}]
|
||||
set_property -dict {PACKAGE_PIN AA9 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[4]}]
|
||||
set_property -dict {PACKAGE_PIN AB9 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[5]}]
|
||||
set_property -dict {PACKAGE_PIN AA8 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[6]}]
|
||||
set_property -dict {PACKAGE_PIN AC8 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[7]}]
|
||||
set_property -dict {PACKAGE_PIN AA7 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[8]}]
|
||||
set_property -dict {PACKAGE_PIN AE8 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[9]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AF10 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[10]}]
|
||||
set_property -dict {PACKAGE_PIN AD8 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[11]}]
|
||||
set_property -dict {PACKAGE_PIN AE10 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[12]}]
|
||||
set_property -dict {PACKAGE_PIN AF8 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[13]}]
|
||||
set_property -dict {PACKAGE_PIN AC7 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[14]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AD11 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_ba[0]}]
|
||||
set_property -dict {PACKAGE_PIN AA10 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_ba[1]}]
|
||||
set_property -dict {PACKAGE_PIN AF12 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_ba[2]}]
|
||||
|
||||
|
||||
## Byte lane #0
|
||||
set_property -dict {PACKAGE_PIN AA2 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[0]}]
|
||||
set_property -dict {PACKAGE_PIN Y2 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[1]}]
|
||||
set_property -dict {PACKAGE_PIN AB2 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[2]}]
|
||||
set_property -dict {PACKAGE_PIN V1 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[3]}]
|
||||
set_property -dict {PACKAGE_PIN Y1 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[4]}]
|
||||
set_property -dict {PACKAGE_PIN W1 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[5]}]
|
||||
set_property -dict {PACKAGE_PIN AC2 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[6]}]
|
||||
set_property -dict {PACKAGE_PIN V2 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[7]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN Y3 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_dm[0]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AB1 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_p[0]}]
|
||||
set_property -dict {PACKAGE_PIN AC1 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_n[0]}]
|
||||
|
||||
|
||||
## Byte lane #1
|
||||
set_property -dict {PACKAGE_PIN W3 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[8]}]
|
||||
set_property -dict {PACKAGE_PIN V3 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[9]}]
|
||||
set_property -dict {PACKAGE_PIN U1 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[10]}]
|
||||
set_property -dict {PACKAGE_PIN U7 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[11]}]
|
||||
set_property -dict {PACKAGE_PIN U6 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[12]}]
|
||||
set_property -dict {PACKAGE_PIN V4 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[13]}]
|
||||
set_property -dict {PACKAGE_PIN V6 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[14]}]
|
||||
set_property -dict {PACKAGE_PIN U2 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[15]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN U5 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_dm[1]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN W6 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_p[1]}]
|
||||
set_property -dict {PACKAGE_PIN W5 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_n[1]}]
|
||||
|
||||
|
||||
## Byte lane #2
|
||||
set_property -dict {PACKAGE_PIN AE3 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[16]}]
|
||||
set_property -dict {PACKAGE_PIN AE6 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[17]}]
|
||||
set_property -dict {PACKAGE_PIN AF3 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[18]}]
|
||||
set_property -dict {PACKAGE_PIN AD1 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[19]}]
|
||||
set_property -dict {PACKAGE_PIN AE1 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[20]}]
|
||||
set_property -dict {PACKAGE_PIN AE2 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[21]}]
|
||||
set_property -dict {PACKAGE_PIN AF2 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[22]}]
|
||||
set_property -dict {PACKAGE_PIN AE5 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[23]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AD4 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_dm[2]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AF5 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_p[2]}]
|
||||
set_property -dict {PACKAGE_PIN AF4 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_n[2]}]
|
||||
|
||||
|
||||
## Byte lane #3
|
||||
set_property -dict {PACKAGE_PIN AD5 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[24]}]
|
||||
set_property -dict {PACKAGE_PIN Y5 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[25]}]
|
||||
set_property -dict {PACKAGE_PIN AC6 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[26]}]
|
||||
set_property -dict {PACKAGE_PIN Y6 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[27]}]
|
||||
set_property -dict {PACKAGE_PIN AB4 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[28]}]
|
||||
set_property -dict {PACKAGE_PIN AD6 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[29]}]
|
||||
set_property -dict {PACKAGE_PIN AB6 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[30]}]
|
||||
set_property -dict {PACKAGE_PIN AC3 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[31]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AC4 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_dm[3]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AA5 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_p[3]}]
|
||||
set_property -dict {PACKAGE_PIN AB5 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_n[3]}]
|
||||
|
||||
|
||||
## Byte lane #4
|
||||
set_property -dict {PACKAGE_PIN AD16 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[32]}]
|
||||
set_property -dict {PACKAGE_PIN AE17 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[33]}]
|
||||
set_property -dict {PACKAGE_PIN AF15 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[34]}]
|
||||
set_property -dict {PACKAGE_PIN AF20 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[35]}]
|
||||
set_property -dict {PACKAGE_PIN AD15 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[36]}]
|
||||
set_property -dict {PACKAGE_PIN AF14 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[37]}]
|
||||
set_property -dict {PACKAGE_PIN AE15 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[38]}]
|
||||
set_property -dict {PACKAGE_PIN AF17 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[39]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AF19 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_dm[4]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AE18 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_p[4]}]
|
||||
set_property -dict {PACKAGE_PIN AF18 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_n[4]}]
|
||||
|
||||
|
||||
## Byte lane #5
|
||||
set_property -dict {PACKAGE_PIN AA14 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[40]}]
|
||||
set_property -dict {PACKAGE_PIN AA15 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[41]}]
|
||||
set_property -dict {PACKAGE_PIN AC14 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[42]}]
|
||||
set_property -dict {PACKAGE_PIN AD14 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[43]}]
|
||||
set_property -dict {PACKAGE_PIN AB14 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[44]}]
|
||||
set_property -dict {PACKAGE_PIN AB15 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[45]}]
|
||||
set_property -dict {PACKAGE_PIN AA17 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[46]}]
|
||||
set_property -dict {PACKAGE_PIN AA18 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[47]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AC16 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_dm[5]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN Y15 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_p[5]}]
|
||||
set_property -dict {PACKAGE_PIN Y16 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_n[5]}]
|
||||
|
||||
|
||||
## Byte lane #6
|
||||
set_property -dict {PACKAGE_PIN AB20 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[48]}]
|
||||
set_property -dict {PACKAGE_PIN AD19 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[49]}]
|
||||
set_property -dict {PACKAGE_PIN AC19 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[50]}]
|
||||
set_property -dict {PACKAGE_PIN AA20 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[51]}]
|
||||
set_property -dict {PACKAGE_PIN AA19 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[52]}]
|
||||
set_property -dict {PACKAGE_PIN AC17 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[53]}]
|
||||
set_property -dict {PACKAGE_PIN AD18 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[54]}]
|
||||
set_property -dict {PACKAGE_PIN AB17 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[55]}]
|
||||
set_property -dict {PACKAGE_PIN AB19 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_dm[6]}]
|
||||
set_property -dict {PACKAGE_PIN AD20 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_p[6]}]
|
||||
set_property -dict {PACKAGE_PIN AE20 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_n[6]}]
|
||||
|
||||
|
||||
## Byte lane #7
|
||||
set_property -dict {PACKAGE_PIN W15 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[56]}]
|
||||
set_property -dict {PACKAGE_PIN W16 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[57]}]
|
||||
set_property -dict {PACKAGE_PIN W14 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[58]}]
|
||||
set_property -dict {PACKAGE_PIN V16 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[59]}]
|
||||
set_property -dict {PACKAGE_PIN V19 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[60]}]
|
||||
set_property -dict {PACKAGE_PIN V17 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[61]}]
|
||||
set_property -dict {PACKAGE_PIN V18 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[62]}]
|
||||
set_property -dict {PACKAGE_PIN Y17 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[63]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN V14 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_dm[7]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN W18 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_p[7]}]
|
||||
set_property -dict {PACKAGE_PIN W19 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_n[7]}]
|
||||
|
||||
|
||||
|
||||
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
|
||||
################################################################################
|
||||
################################################################################
|
||||
set_property CFGBVS GND [current_design]
|
||||
set_property CONFIG_VOLTAGE 1.8 [current_design]
|
||||
set_property BITSTREAM.CONFIG.CONFIGRATE 22 [current_design]
|
||||
set_property BITSTREAM.CONFIG.OVERTEMPPOWERDOWN ENABLE [current_design]
|
||||
set_property BITSTREAM.CONFIG.UNUSEDPIN PULLNONE [current_design]
|
||||
|
||||
# set_property -dict {PACKAGE_PIN AD24 IOSTANDARD LVCMOS18 } [get_ports {CLK_100_CAL}]
|
||||
# set_property DCI_CASCADE {32 33} [get_iobanks 34]
|
||||
## For a 1.5V memory, the appropriate VREF voltage is half of 1.5, or 0.75 Volts
|
||||
## Of the DDR3 bank(s), only bank 33 needs the INTERNAL_VREF. The other DDR3
|
||||
## banks are explicitly connected to an external VREF signal. However, bank
|
||||
## 33s IOs are overloaded--there was no room for the VREF. Hence, to spare
|
||||
## two pins, bank 33 uses an internal voltage reference. Sadly, the same
|
||||
## problem plays out in banks 12-16 as well.
|
||||
# set_property INTERNAL_VREF 0.750 [get_iobanks 33]
|
||||
# ## Other IO banks have internal VREFs as well, those these aren't as critical
|
||||
# set_property INTERNAL_VREF 0.90 [get_iobanks 12]
|
||||
# set_property INTERNAL_VREF 0.60 [get_iobanks 13]
|
||||
# set_property INTERNAL_VREF 0.90 [get_iobanks 14]
|
||||
# set_property INTERNAL_VREF 0.90 [get_iobanks 15]
|
||||
# set_property INTERNAL_VREF 0.90 [get_iobanks 16]
|
||||
|
||||
## Clocks
|
||||
# 100MHz single ended input clock
|
||||
set_property -dict {PACKAGE_PIN AA4 IOSTANDARD SSTL15} [get_ports i_clk]
|
||||
create_clock -period 10.000 -name sys_clk_pin -waveform {0.000 5.000} -add [get_ports i_clk]
|
||||
|
||||
# Baseboard LEDs
|
||||
# set_property -dict {SLEW SLOW PACKAGE_PIN F22 IOSTANDARD LVCMOS18 } [get_ports { o_led_status[4] }] # GPIO0_LED0_N
|
||||
set_property -dict {PACKAGE_PIN E23 IOSTANDARD LVCMOS18} [get_ports {led[0]}]
|
||||
set_property -dict {PACKAGE_PIN K25 IOSTANDARD LVCMOS12} [get_ports {led[1]}]
|
||||
set_property -dict {PACKAGE_PIN K26 IOSTANDARD LVCMOS12} [get_ports {led[2]}]
|
||||
|
||||
## UART
|
||||
## {{{
|
||||
set_property -dict {PACKAGE_PIN B20 IOSTANDARD LVCMOS18 } [get_ports {rx}]
|
||||
set_property -dict {PACKAGE_PIN A20 IOSTANDARD LVCMOS18 } [get_ports {tx}]
|
||||
## }}}
|
||||
|
||||
## Buttons
|
||||
## {{{
|
||||
set_property -dict {PACKAGE_PIN C22 IOSTANDARD LVCMOS18 } [get_ports {i_rst_n}]
|
||||
|
||||
## DDR3 MEMORY
|
||||
set_property -dict {PACKAGE_PIN AB7 IOSTANDARD LVCMOS15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_reset_n}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AB12 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_clk_p}]
|
||||
set_property -dict {PACKAGE_PIN AC12 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_clk_n}]
|
||||
set_property -dict {PACKAGE_PIN AA13 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_cke}]
|
||||
## set_property -dict {SLEW SLOW PACKAGE_PIN AA3 IOSTANDARD LVCMOS15 } [get_ports {o_ddr3_vsel}]
|
||||
set_property -dict {PACKAGE_PIN Y12 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_cs_n}]
|
||||
set_property -dict {PACKAGE_PIN AE13 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_ras_n}]
|
||||
set_property -dict {PACKAGE_PIN AE12 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_cas_n}]
|
||||
set_property -dict {PACKAGE_PIN AA12 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_we_n}]
|
||||
set_property -dict {PACKAGE_PIN AD13 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_odt}]
|
||||
|
||||
|
||||
## Address lines
|
||||
set_property -dict {PACKAGE_PIN AE11 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[0]}]
|
||||
set_property -dict {PACKAGE_PIN AF9 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[1]}]
|
||||
set_property -dict {PACKAGE_PIN AD10 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[2]}]
|
||||
set_property -dict {PACKAGE_PIN AB10 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[3]}]
|
||||
set_property -dict {PACKAGE_PIN AA9 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[4]}]
|
||||
set_property -dict {PACKAGE_PIN AB9 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[5]}]
|
||||
set_property -dict {PACKAGE_PIN AA8 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[6]}]
|
||||
set_property -dict {PACKAGE_PIN AC8 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[7]}]
|
||||
set_property -dict {PACKAGE_PIN AA7 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[8]}]
|
||||
set_property -dict {PACKAGE_PIN AE8 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[9]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AF10 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[10]}]
|
||||
set_property -dict {PACKAGE_PIN AD8 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[11]}]
|
||||
set_property -dict {PACKAGE_PIN AE10 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[12]}]
|
||||
set_property -dict {PACKAGE_PIN AF8 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[13]}]
|
||||
set_property -dict {PACKAGE_PIN AC7 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_addr[14]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AD11 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_ba[0]}]
|
||||
set_property -dict {PACKAGE_PIN AA10 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_ba[1]}]
|
||||
set_property -dict {PACKAGE_PIN AF12 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_ba[2]}]
|
||||
|
||||
|
||||
## Byte lane #0
|
||||
set_property -dict {PACKAGE_PIN AA2 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[0]}]
|
||||
set_property -dict {PACKAGE_PIN Y2 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[1]}]
|
||||
set_property -dict {PACKAGE_PIN AB2 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[2]}]
|
||||
set_property -dict {PACKAGE_PIN V1 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[3]}]
|
||||
set_property -dict {PACKAGE_PIN Y1 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[4]}]
|
||||
set_property -dict {PACKAGE_PIN W1 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[5]}]
|
||||
set_property -dict {PACKAGE_PIN AC2 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[6]}]
|
||||
set_property -dict {PACKAGE_PIN V2 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[7]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN Y3 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_dm[0]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AB1 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_p[0]}]
|
||||
set_property -dict {PACKAGE_PIN AC1 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_n[0]}]
|
||||
|
||||
|
||||
## Byte lane #1
|
||||
set_property -dict {PACKAGE_PIN W3 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[8]}]
|
||||
set_property -dict {PACKAGE_PIN V3 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[9]}]
|
||||
set_property -dict {PACKAGE_PIN U1 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[10]}]
|
||||
set_property -dict {PACKAGE_PIN U7 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[11]}]
|
||||
set_property -dict {PACKAGE_PIN U6 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[12]}]
|
||||
set_property -dict {PACKAGE_PIN V4 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[13]}]
|
||||
set_property -dict {PACKAGE_PIN V6 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[14]}]
|
||||
set_property -dict {PACKAGE_PIN U2 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[15]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN U5 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_dm[1]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN W6 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_p[1]}]
|
||||
set_property -dict {PACKAGE_PIN W5 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_n[1]}]
|
||||
|
||||
|
||||
## Byte lane #2
|
||||
set_property -dict {PACKAGE_PIN AE3 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[16]}]
|
||||
set_property -dict {PACKAGE_PIN AE6 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[17]}]
|
||||
set_property -dict {PACKAGE_PIN AF3 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[18]}]
|
||||
set_property -dict {PACKAGE_PIN AD1 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[19]}]
|
||||
set_property -dict {PACKAGE_PIN AE1 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[20]}]
|
||||
set_property -dict {PACKAGE_PIN AE2 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[21]}]
|
||||
set_property -dict {PACKAGE_PIN AF2 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[22]}]
|
||||
set_property -dict {PACKAGE_PIN AE5 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[23]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AD4 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_dm[2]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AF5 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_p[2]}]
|
||||
set_property -dict {PACKAGE_PIN AF4 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_n[2]}]
|
||||
|
||||
|
||||
## Byte lane #3
|
||||
set_property -dict {PACKAGE_PIN AD5 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[24]}]
|
||||
set_property -dict {PACKAGE_PIN Y5 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[25]}]
|
||||
set_property -dict {PACKAGE_PIN AC6 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[26]}]
|
||||
set_property -dict {PACKAGE_PIN Y6 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[27]}]
|
||||
set_property -dict {PACKAGE_PIN AB4 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[28]}]
|
||||
set_property -dict {PACKAGE_PIN AD6 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[29]}]
|
||||
set_property -dict {PACKAGE_PIN AB6 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[30]}]
|
||||
set_property -dict {PACKAGE_PIN AC3 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[31]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AC4 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_dm[3]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AA5 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_p[3]}]
|
||||
set_property -dict {PACKAGE_PIN AB5 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_n[3]}]
|
||||
|
||||
|
||||
## Byte lane #4
|
||||
set_property -dict {PACKAGE_PIN AD16 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[32]}]
|
||||
set_property -dict {PACKAGE_PIN AE17 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[33]}]
|
||||
set_property -dict {PACKAGE_PIN AF15 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[34]}]
|
||||
set_property -dict {PACKAGE_PIN AF20 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[35]}]
|
||||
set_property -dict {PACKAGE_PIN AD15 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[36]}]
|
||||
set_property -dict {PACKAGE_PIN AF14 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[37]}]
|
||||
set_property -dict {PACKAGE_PIN AE15 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[38]}]
|
||||
set_property -dict {PACKAGE_PIN AF17 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[39]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AF19 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_dm[4]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AE18 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_p[4]}]
|
||||
set_property -dict {PACKAGE_PIN AF18 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_n[4]}]
|
||||
|
||||
|
||||
## Byte lane #5
|
||||
set_property -dict {PACKAGE_PIN AA14 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[40]}]
|
||||
set_property -dict {PACKAGE_PIN AA15 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[41]}]
|
||||
set_property -dict {PACKAGE_PIN AC14 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[42]}]
|
||||
set_property -dict {PACKAGE_PIN AD14 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[43]}]
|
||||
set_property -dict {PACKAGE_PIN AB14 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[44]}]
|
||||
set_property -dict {PACKAGE_PIN AB15 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[45]}]
|
||||
set_property -dict {PACKAGE_PIN AA17 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[46]}]
|
||||
set_property -dict {PACKAGE_PIN AA18 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[47]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AC16 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_dm[5]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN Y15 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_p[5]}]
|
||||
set_property -dict {PACKAGE_PIN Y16 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_n[5]}]
|
||||
|
||||
|
||||
## Byte lane #6
|
||||
set_property -dict {PACKAGE_PIN AB20 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[48]}]
|
||||
set_property -dict {PACKAGE_PIN AD19 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[49]}]
|
||||
set_property -dict {PACKAGE_PIN AC19 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[50]}]
|
||||
set_property -dict {PACKAGE_PIN AA20 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[51]}]
|
||||
set_property -dict {PACKAGE_PIN AA19 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[52]}]
|
||||
set_property -dict {PACKAGE_PIN AC17 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[53]}]
|
||||
set_property -dict {PACKAGE_PIN AD18 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[54]}]
|
||||
set_property -dict {PACKAGE_PIN AB17 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[55]}]
|
||||
set_property -dict {PACKAGE_PIN AB19 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_dm[6]}]
|
||||
set_property -dict {PACKAGE_PIN AD20 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_p[6]}]
|
||||
set_property -dict {PACKAGE_PIN AE20 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_n[6]}]
|
||||
|
||||
|
||||
## Byte lane #7
|
||||
set_property -dict {PACKAGE_PIN W15 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[56]}]
|
||||
set_property -dict {PACKAGE_PIN W16 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[57]}]
|
||||
set_property -dict {PACKAGE_PIN W14 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[58]}]
|
||||
set_property -dict {PACKAGE_PIN V16 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[59]}]
|
||||
set_property -dict {PACKAGE_PIN V19 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[60]}]
|
||||
set_property -dict {PACKAGE_PIN V17 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[61]}]
|
||||
set_property -dict {PACKAGE_PIN V18 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[62]}]
|
||||
set_property -dict {PACKAGE_PIN Y17 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dq[63]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN V14 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH } [get_ports {ddr3_dm[7]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN W18 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_p[7]}]
|
||||
set_property -dict {PACKAGE_PIN W19 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports {ddr3_dqs_n[7]}]
|
||||
|
||||
|
||||
|
||||
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,207 +1,207 @@
|
|||
|
||||
//
|
||||
// Module: uart_rx
|
||||
//
|
||||
// Notes:
|
||||
// - UART reciever module.
|
||||
//
|
||||
|
||||
module uart_rx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
input wire uart_rxd , // UART Recieve pin.
|
||||
input wire uart_rx_en , // Recieve enable
|
||||
output wire uart_rx_break, // Did we get a BREAK message?
|
||||
output wire uart_rx_valid, // Valid data recieved and available.
|
||||
output reg [PAYLOAD_BITS-1:0] uart_rx_data // The recieved data.
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_rxd line. Helps break long timing
|
||||
// paths from input pins into the logic.
|
||||
reg rxd_reg;
|
||||
reg rxd_reg_0;
|
||||
|
||||
//
|
||||
// Storage for the recieved serial data.
|
||||
reg [PAYLOAD_BITS-1:0] recieved_data;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of recieved bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Sample of the UART input line whenever we are in the middle of a bit frame.
|
||||
reg bit_sample;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_RECV = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Output assignment
|
||||
//
|
||||
|
||||
assign uart_rx_break = uart_rx_valid && ~|recieved_data;
|
||||
assign uart_rx_valid = fsm_state == FSM_STOP && n_fsm_state == FSM_IDLE;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(!resetn) begin
|
||||
uart_rx_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if (fsm_state == FSM_STOP) begin
|
||||
uart_rx_data <= recieved_data;
|
||||
end
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT ||
|
||||
fsm_state == FSM_STOP &&
|
||||
cycle_counter == CYCLES_PER_BIT/2;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = rxd_reg ? FSM_IDLE : FSM_START;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_RECV : FSM_START;
|
||||
FSM_RECV : n_fsm_state = payload_done ? FSM_STOP : FSM_RECV ;
|
||||
FSM_STOP : n_fsm_state = next_bit ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the recieved data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_recieved_data
|
||||
if(!resetn) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE ) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit ) begin
|
||||
recieved_data[PAYLOAD_BITS-1] <= bit_sample;
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
recieved_data[i] <= recieved_data[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Increments the bit counter when recieving.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_RECV) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Sample the recieved bit when in the middle of a bit frame.
|
||||
always @(posedge clk) begin : p_bit_sample
|
||||
if(!resetn) begin
|
||||
bit_sample <= 1'b0;
|
||||
end else if (cycle_counter == CYCLES_PER_BIT/2) begin
|
||||
bit_sample <= rxd_reg;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when recieving.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_RECV ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the rxd_reg.
|
||||
always @(posedge clk) begin : p_rxd_reg
|
||||
if(!resetn) begin
|
||||
rxd_reg <= 1'b1;
|
||||
rxd_reg_0 <= 1'b1;
|
||||
end else if(uart_rx_en) begin
|
||||
rxd_reg <= rxd_reg_0;
|
||||
rxd_reg_0 <= uart_rxd;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
//
|
||||
// Module: uart_rx
|
||||
//
|
||||
// Notes:
|
||||
// - UART reciever module.
|
||||
//
|
||||
|
||||
module uart_rx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
input wire uart_rxd , // UART Recieve pin.
|
||||
input wire uart_rx_en , // Recieve enable
|
||||
output wire uart_rx_break, // Did we get a BREAK message?
|
||||
output wire uart_rx_valid, // Valid data recieved and available.
|
||||
output reg [PAYLOAD_BITS-1:0] uart_rx_data // The recieved data.
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_rxd line. Helps break long timing
|
||||
// paths from input pins into the logic.
|
||||
reg rxd_reg;
|
||||
reg rxd_reg_0;
|
||||
|
||||
//
|
||||
// Storage for the recieved serial data.
|
||||
reg [PAYLOAD_BITS-1:0] recieved_data;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of recieved bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Sample of the UART input line whenever we are in the middle of a bit frame.
|
||||
reg bit_sample;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_RECV = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Output assignment
|
||||
//
|
||||
|
||||
assign uart_rx_break = uart_rx_valid && ~|recieved_data;
|
||||
assign uart_rx_valid = fsm_state == FSM_STOP && n_fsm_state == FSM_IDLE;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(!resetn) begin
|
||||
uart_rx_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if (fsm_state == FSM_STOP) begin
|
||||
uart_rx_data <= recieved_data;
|
||||
end
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT ||
|
||||
fsm_state == FSM_STOP &&
|
||||
cycle_counter == CYCLES_PER_BIT/2;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = rxd_reg ? FSM_IDLE : FSM_START;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_RECV : FSM_START;
|
||||
FSM_RECV : n_fsm_state = payload_done ? FSM_STOP : FSM_RECV ;
|
||||
FSM_STOP : n_fsm_state = next_bit ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the recieved data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_recieved_data
|
||||
if(!resetn) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE ) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit ) begin
|
||||
recieved_data[PAYLOAD_BITS-1] <= bit_sample;
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
recieved_data[i] <= recieved_data[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Increments the bit counter when recieving.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_RECV) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Sample the recieved bit when in the middle of a bit frame.
|
||||
always @(posedge clk) begin : p_bit_sample
|
||||
if(!resetn) begin
|
||||
bit_sample <= 1'b0;
|
||||
end else if (cycle_counter == CYCLES_PER_BIT/2) begin
|
||||
bit_sample <= rxd_reg;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when recieving.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_RECV ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the rxd_reg.
|
||||
always @(posedge clk) begin : p_rxd_reg
|
||||
if(!resetn) begin
|
||||
rxd_reg <= 1'b1;
|
||||
rxd_reg_0 <= 1'b1;
|
||||
end else if(uart_rx_en) begin
|
||||
rxd_reg <= rxd_reg_0;
|
||||
rxd_reg_0 <= uart_rxd;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,187 +1,187 @@
|
|||
|
||||
|
||||
//
|
||||
// Module: uart_tx
|
||||
//
|
||||
// Notes:
|
||||
// - UART transmitter module.
|
||||
//
|
||||
|
||||
module uart_tx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
output wire uart_txd , // UART transmit pin.
|
||||
output wire uart_tx_busy, // Module busy sending previous item.
|
||||
input wire uart_tx_en , // Send the data on uart_tx_data
|
||||
input wire [PAYLOAD_BITS-1:0] uart_tx_data // The data to be sent
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_txd line. Helps break long timing
|
||||
// paths from the logic to the output pins.
|
||||
reg txd_reg;
|
||||
|
||||
//
|
||||
// Storage for the serial data to be sent.
|
||||
reg [PAYLOAD_BITS-1:0] data_to_send;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of sent bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_SEND = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
assign uart_tx_busy = fsm_state != FSM_IDLE;
|
||||
assign uart_txd = txd_reg;
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
wire stop_done = bit_counter == STOP_BITS && fsm_state == FSM_STOP;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = uart_tx_en ? FSM_START: FSM_IDLE ;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_SEND : FSM_START;
|
||||
FSM_SEND : n_fsm_state = payload_done ? FSM_STOP : FSM_SEND ;
|
||||
FSM_STOP : n_fsm_state = stop_done ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the sent data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_data_to_send
|
||||
if(!resetn) begin
|
||||
data_to_send <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE && uart_tx_en) begin
|
||||
data_to_send <= uart_tx_data;
|
||||
end else if(fsm_state == FSM_SEND && next_bit ) begin
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
data_to_send[i] <= data_to_send[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the bit counter each time a new bit frame is sent.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_SEND && fsm_state != FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_SEND && n_fsm_state == FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_STOP&& next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end else if(fsm_state == FSM_SEND && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when sending.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_SEND ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the txd_reg.
|
||||
always @(posedge clk) begin : p_txd_reg
|
||||
if(!resetn) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_IDLE) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_START) begin
|
||||
txd_reg <= 1'b0;
|
||||
end else if(fsm_state == FSM_SEND) begin
|
||||
txd_reg <= data_to_send[0];
|
||||
end else if(fsm_state == FSM_STOP) begin
|
||||
txd_reg <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
//
|
||||
// Module: uart_tx
|
||||
//
|
||||
// Notes:
|
||||
// - UART transmitter module.
|
||||
//
|
||||
|
||||
module uart_tx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
output wire uart_txd , // UART transmit pin.
|
||||
output wire uart_tx_busy, // Module busy sending previous item.
|
||||
input wire uart_tx_en , // Send the data on uart_tx_data
|
||||
input wire [PAYLOAD_BITS-1:0] uart_tx_data // The data to be sent
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_txd line. Helps break long timing
|
||||
// paths from the logic to the output pins.
|
||||
reg txd_reg;
|
||||
|
||||
//
|
||||
// Storage for the serial data to be sent.
|
||||
reg [PAYLOAD_BITS-1:0] data_to_send;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of sent bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_SEND = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
assign uart_tx_busy = fsm_state != FSM_IDLE;
|
||||
assign uart_txd = txd_reg;
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
wire stop_done = bit_counter == STOP_BITS && fsm_state == FSM_STOP;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = uart_tx_en ? FSM_START: FSM_IDLE ;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_SEND : FSM_START;
|
||||
FSM_SEND : n_fsm_state = payload_done ? FSM_STOP : FSM_SEND ;
|
||||
FSM_STOP : n_fsm_state = stop_done ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the sent data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_data_to_send
|
||||
if(!resetn) begin
|
||||
data_to_send <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE && uart_tx_en) begin
|
||||
data_to_send <= uart_tx_data;
|
||||
end else if(fsm_state == FSM_SEND && next_bit ) begin
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
data_to_send[i] <= data_to_send[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the bit counter each time a new bit frame is sent.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_SEND && fsm_state != FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_SEND && n_fsm_state == FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_STOP&& next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end else if(fsm_state == FSM_SEND && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when sending.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_SEND ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the txd_reg.
|
||||
always @(posedge clk) begin : p_txd_reg
|
||||
if(!resetn) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_IDLE) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_START) begin
|
||||
txd_reg <= 1'b0;
|
||||
end else if(fsm_state == FSM_SEND) begin
|
||||
txd_reg <= data_to_send[0];
|
||||
end else if(fsm_state == FSM_STOP) begin
|
||||
txd_reg <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,363 +1,363 @@
|
|||
################################################################################
|
||||
##
|
||||
## Filename: ddr3.txt
|
||||
## {{{
|
||||
## Project: 10Gb Ethernet switch
|
||||
##
|
||||
## Purpose: To describe how to provide access to an SDRAM controller
|
||||
## from the Wishbone bus, where such SDRAM controller uses a
|
||||
## different clock from the Wishbone bus itself.
|
||||
##
|
||||
## Creator: Dan Gisselquist, Ph.D.
|
||||
## Gisselquist Technology, LLC
|
||||
##
|
||||
################################################################################
|
||||
## }}}
|
||||
## Copyright (C) 2023, Gisselquist Technology, LLC
|
||||
## {{{
|
||||
## This file is part of the ETH10G project.
|
||||
##
|
||||
## The ETH10G project contains free software and gateware, licensed under the
|
||||
## Apache License, Version 2.0 (the "License"). You may not use this project,
|
||||
## or this file, except in compliance with the License. You may obtain a copy
|
||||
## of the License at
|
||||
## }}}
|
||||
## http://www.apache.org/licenses/LICENSE-2.0
|
||||
## {{{
|
||||
## Unless required by applicable law or agreed to in writing, files
|
||||
## distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
## WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
## License for the specific language governing permissions and limitations
|
||||
## under the License.
|
||||
##
|
||||
################################################################################
|
||||
##
|
||||
## }}}
|
||||
# Wishbone 1
|
||||
@PREFIX=ddr3_controller
|
||||
@DEVID=DDR3_CONTROLLER
|
||||
@ACCESS=@$(DEVID)_ACCESS
|
||||
## LGMEMSZ is the size of the SDRAM in bytes. For a 1GB DDR3 RAM: 30 => 1GB
|
||||
@$LGMEMSZ=30
|
||||
@LGMEMSZ.FORMAT=%d
|
||||
@$NADDR=(1<< @$(LGMEMSZ))/(@$(SLAVE.BUS.WIDTH)/8)
|
||||
@$NBYTES=(1<<(@$LGMEMSZ))
|
||||
@NBYTES.FORMAT=0x%08x
|
||||
@$MADDR= @$(REGBASE)
|
||||
@MADDR.FORMAT=0x%08x
|
||||
@$NLANES=@$(SLAVE.BUS.WIDTH)/64
|
||||
@SLAVE.TYPE=MEMORY
|
||||
@SLAVE.BUS=wbwide
|
||||
@BUS=wbwide
|
||||
@LD.PERM=wx
|
||||
#
|
||||
@REGS.N=1
|
||||
@REGS.0= 0 R_@$(DEVID) @$(DEVID)
|
||||
@REGDEFS.H.DEFNS=
|
||||
#define @$(DEVID)BASE @$[0x%08x](REGBASE)
|
||||
#define @$(DEVID)LEN @$(NBYTES)
|
||||
@BDEF.OSDEF=_BOARD_HAS_@$(DEVID)
|
||||
@BDEF.OSVAL=extern char _@$(PREFIX)[@$NBYTES];
|
||||
|
||||
@TOP.PORTLIST=
|
||||
// DDR3 I/O port wires
|
||||
o_ddr3_reset_n, o_ddr3_cke, o_ddr3_clk_p, o_ddr3_clk_n,
|
||||
o_ddr3_s_n, o_ddr3_ras_n, o_ddr3_cas_n, o_ddr3_we_n,
|
||||
o_ddr3_ba, o_ddr3_a,
|
||||
o_ddr3_odt, o_ddr3_dm,
|
||||
io_ddr3_dqs_p, io_ddr3_dqs_n, io_ddr3_dq
|
||||
|
||||
|
||||
@TOP.PARAM=
|
||||
localparam real @$(DEVID)CONTROLLER_CLK_PERIOD = 10, //ns, period of clock input to this DDR3 controller module
|
||||
DDR3_CLK_PERIOD = 2.5; //ns, period of clock input to DDR3 RAM device
|
||||
localparam @$(DEVID)ROW_BITS = 14, // width of row address
|
||||
@$(DEVID)COL_BITS = 10, // width of column address
|
||||
@$(DEVID)BA_BITS = 3, // width of bank address
|
||||
@$(DEVID)DQ_BITS = 8, // Size of one octet
|
||||
@$(DEVID)LANES = 8, //@$(NLANES), //8 lanes of DQ
|
||||
@$(DEVID)AUX_WIDTH = 8, //must be 8 bits or more (also used in internal test and calibration)
|
||||
@$(DEVID)SERDES_RATIO = $rtoi(@$(DEVID)CONTROLLER_CLK_PERIOD/DDR3_CLK_PERIOD),
|
||||
//4 is the width of a single ddr3 command {cs_n, ras_n, cas_n, we_n} plus 3 (ck_en, odt, reset_n) plus bank bits plus row bits
|
||||
@$(DEVID)CMD_LEN = 4 + 3 + @$(DEVID)BA_BITS + @$(DEVID)ROW_BITS;
|
||||
|
||||
|
||||
@TOP.IODECL=
|
||||
// I/O declarations for the DDR3 SDRAM
|
||||
// {{{
|
||||
output wire o_ddr3_reset_n;
|
||||
output wire [1:0] o_ddr3_cke;
|
||||
output wire [0:0] o_ddr3_clk_p, o_ddr3_clk_n;
|
||||
output wire [1:0] o_ddr3_s_n; // o_ddr3_s_n[1] is set to 0 since controller only support single rank
|
||||
output wire [0:0] o_ddr3_ras_n, o_ddr3_cas_n, o_ddr3_we_n;
|
||||
output wire [@$(DEVID)BA_BITS-1:0] o_ddr3_ba;
|
||||
output wire [15:0] o_ddr3_a; //set to max of 16 bits, but only ROW_BITS bits are relevant
|
||||
output wire [1:0] o_ddr3_odt;
|
||||
output wire [@$(DEVID)LANES-1:0] o_ddr3_dm;
|
||||
inout wire [(@$(DEVID)DQ_BITS*@$(DEVID)LANES)/8-1:0] io_ddr3_dqs_p, io_ddr3_dqs_n;
|
||||
inout wire [(@$(DEVID)DQ_BITS*@$(DEVID)LANES)-1:0] io_ddr3_dq;
|
||||
// }}}
|
||||
|
||||
|
||||
@TOP.DEFNS=
|
||||
// Wires connected to PHY interface of DDR3 controller
|
||||
// {{{
|
||||
genvar @$(PREFIX)gen_index;
|
||||
|
||||
wire [@$(DEVID)DQ_BITS*@$(DEVID)LANES*8-1:0] @$(PREFIX)_iserdes_data;
|
||||
wire [@$(DEVID)LANES*8-1:0] @$(PREFIX)_iserdes_dqs;
|
||||
wire [@$(DEVID)LANES*8-1:0] @$(PREFIX)_iserdes_bitslip_reference;
|
||||
wire @$(PREFIX)_idelayctrl_rdy;
|
||||
wire [@$(DEVID)CMD_LEN*@$(DEVID)SERDES_RATIO-1:0] @$(PREFIX)_cmd;
|
||||
wire @$(PREFIX)_dqs_tri_control, @$(PREFIX)_dq_tri_control;
|
||||
wire @$(PREFIX)_toggle_dqs;
|
||||
wire [@$(DEVID)DQ_BITS*@$(DEVID)LANES*8-1:0] @$(PREFIX)_data;
|
||||
wire [(@$(DEVID)DQ_BITS*@$(DEVID)LANES*8)/8-1:0] @$(PREFIX)_dm;
|
||||
wire [4:0] @$(PREFIX)_odelay_data_cntvaluein, @$(PREFIX)_odelay_dqs_cntvaluein;
|
||||
wire [4:0] @$(PREFIX)_idelay_data_cntvaluein, @$(PREFIX)_idelay_dqs_cntvaluein;
|
||||
wire [@$(DEVID)LANES-1:0] @$(PREFIX)_odelay_data_ld, @$(PREFIX)_odelay_dqs_ld;
|
||||
wire [@$(DEVID)LANES-1:0] @$(PREFIX)_idelay_data_ld, @$(PREFIX)_idelay_dqs_ld;
|
||||
wire [@$(DEVID)LANES-1:0] @$(PREFIX)_bitslip;
|
||||
wire @$(PREFIX)_write_leveling_calib;
|
||||
wire @$(PREFIX)_reset;
|
||||
wire [@$(DEVID)LANES-1:0] @$(PREFIX)_debug_read_dqs_p, @$(PREFIX)_debug_read_dqs_n;
|
||||
wire @$(PREFIX)_debug_clk_p, @$(PREFIX)_debug_clk_n;
|
||||
// }}}
|
||||
@TOP.MAIN=
|
||||
// DDR3 Controller-PHY Interface
|
||||
@$(PREFIX)_iserdes_data, @$(PREFIX)_iserdes_dqs,
|
||||
@$(PREFIX)_iserdes_bitslip_reference,
|
||||
@$(PREFIX)_idelayctrl_rdy,
|
||||
@$(PREFIX)_cmd,
|
||||
@$(PREFIX)_dqs_tri_control, @$(PREFIX)_dq_tri_control,
|
||||
@$(PREFIX)_toggle_dqs, @$(PREFIX)_data, @$(PREFIX)_dm,
|
||||
@$(PREFIX)_odelay_data_cntvaluein, @$(PREFIX)_odelay_dqs_cntvaluein,
|
||||
@$(PREFIX)_idelay_data_cntvaluein, @$(PREFIX)_idelay_dqs_cntvaluein,
|
||||
@$(PREFIX)_odelay_data_ld, @$(PREFIX)_odelay_dqs_ld,
|
||||
@$(PREFIX)_idelay_data_ld, @$(PREFIX)_idelay_dqs_ld,
|
||||
@$(PREFIX)_bitslip,
|
||||
@$(PREFIX)_write_leveling_calib,
|
||||
@$(PREFIX)_reset
|
||||
@TOP.INSERT=
|
||||
/*
|
||||
wire clk_locked;
|
||||
wire controller_clk, ddr3_clk, ref_ddr3_clk, ddr3_clk_90;
|
||||
clk_wiz_0 clk_ddr3
|
||||
(
|
||||
// Clock out ports
|
||||
.clk_out1(controller_clk),
|
||||
.clk_out2(ddr3_clk),
|
||||
.clk_out3(ref_ddr3_clk),
|
||||
.clk_out4(ddr3_clk_90),
|
||||
// Status and control signals
|
||||
.reset(s_reset),
|
||||
.locked(clk_locked),
|
||||
// Clock in ports
|
||||
.clk_in1(s_clk200)
|
||||
);
|
||||
*/
|
||||
// DDR3 PHY Instantiation
|
||||
ddr3_phy #(
|
||||
.ROW_BITS(@$(DEVID)ROW_BITS), //width of row address
|
||||
.BA_BITS(@$(DEVID)BA_BITS), //width of bank address
|
||||
.DQ_BITS(@$(DEVID)DQ_BITS), //width of DQ
|
||||
.LANES(@$(DEVID)LANES), //8 lanes of DQ
|
||||
.CONTROLLER_CLK_PERIOD(@$(DEVID)CONTROLLER_CLK_PERIOD), //ns, period of clock input to this DDR3 controller module
|
||||
.DDR3_CLK_PERIOD(DDR3_CLK_PERIOD), //ns, period of clock input to DDR3 RAM device
|
||||
.ODELAY_SUPPORTED(1)
|
||||
) ddr3_phy_inst (
|
||||
// clock and reset
|
||||
.i_controller_clk(s_clk),
|
||||
.i_ddr3_clk(s_clk4x),
|
||||
.i_ref_clk(s_clk200),
|
||||
.i_ddr3_clk_90(0), //required only when ODELAY_SUPPORTED is zero
|
||||
.i_rst_n(!s_reset),
|
||||
// Controller Interface
|
||||
.i_controller_reset(@$(PREFIX)_reset),
|
||||
.i_controller_cmd(@$(PREFIX)_cmd),
|
||||
.i_controller_dqs_tri_control(@$(PREFIX)_dqs_tri_control),
|
||||
.i_controller_dq_tri_control(@$(PREFIX)_dq_tri_control),
|
||||
.i_controller_toggle_dqs(@$(PREFIX)_toggle_dqs),
|
||||
.i_controller_data(@$(PREFIX)_data),
|
||||
.i_controller_dm(@$(PREFIX)_dm),
|
||||
.i_controller_odelay_data_cntvaluein(@$(PREFIX)_odelay_data_cntvaluein),
|
||||
.i_controller_odelay_dqs_cntvaluein(@$(PREFIX)_odelay_dqs_cntvaluein),
|
||||
.i_controller_idelay_data_cntvaluein(@$(PREFIX)_idelay_data_cntvaluein),
|
||||
.i_controller_idelay_dqs_cntvaluein(@$(PREFIX)_idelay_dqs_cntvaluein),
|
||||
.i_controller_odelay_data_ld(@$(PREFIX)_odelay_data_ld),
|
||||
.i_controller_odelay_dqs_ld(@$(PREFIX)_odelay_dqs_ld),
|
||||
.i_controller_idelay_data_ld(@$(PREFIX)_idelay_data_ld),
|
||||
.i_controller_idelay_dqs_ld(@$(PREFIX)_idelay_dqs_ld),
|
||||
.i_controller_bitslip(@$(PREFIX)_bitslip),
|
||||
.i_controller_write_leveling_calib(@$(PREFIX)_write_leveling_calib),
|
||||
.o_controller_iserdes_data(@$(PREFIX)_iserdes_data),
|
||||
.o_controller_iserdes_dqs(@$(PREFIX)_iserdes_dqs),
|
||||
.o_controller_iserdes_bitslip_reference(@$(PREFIX)_iserdes_bitslip_reference),
|
||||
.o_controller_idelayctrl_rdy(@$(PREFIX)_idelayctrl_rdy),
|
||||
// DDR3 I/O Interface
|
||||
.o_ddr3_clk_p(o_ddr3_clk_p),
|
||||
.o_ddr3_clk_n(o_ddr3_clk_n),
|
||||
.o_ddr3_reset_n(o_ddr3_reset_n),
|
||||
.o_ddr3_cke(o_ddr3_cke[0]), // CKE
|
||||
.o_ddr3_cs_n(o_ddr3_s_n[0]), // chip select signal (controls rank 1 only)
|
||||
.o_ddr3_ras_n(o_ddr3_ras_n), // RAS#
|
||||
.o_ddr3_cas_n(o_ddr3_cas_n), // CAS#
|
||||
.o_ddr3_we_n(o_ddr3_we_n), // WE#
|
||||
.o_ddr3_addr(o_ddr3_a[@$(DEVID)ROW_BITS-1:0]),
|
||||
.o_ddr3_ba_addr(o_ddr3_ba),
|
||||
.io_ddr3_dq(io_ddr3_dq),
|
||||
.io_ddr3_dqs(io_ddr3_dqs_p),
|
||||
.io_ddr3_dqs_n(io_ddr3_dqs_n),
|
||||
.o_ddr3_dm(o_ddr3_dm),
|
||||
.o_ddr3_odt(o_ddr3_odt[0]), // on-die termination
|
||||
// DEBUG PHY
|
||||
.o_ddr3_debug_read_dqs_p(@$(PREFIX)_debug_read_dqs_p),
|
||||
.o_ddr3_debug_read_dqs_n(@$(PREFIX)_debug_read_dqs_n)
|
||||
);
|
||||
//assign o_tp = {@$(PREFIX)_debug_read_dqs_n[1:0],@$(PREFIX)_debug_read_dqs_p[1:0]};
|
||||
assign o_ddr3_s_n[1] = 1; // set to 1 (disabled) since controller only supports single rank
|
||||
assign o_ddr3_cke[1] = 0; // set to 0 (disabled) since controller only supports single rank
|
||||
assign o_ddr3_odt[1] = 0; // set to 0 (disabled) since controller only supports single rank
|
||||
generate for(@$(PREFIX)gen_index = @$(DEVID)ROW_BITS;
|
||||
@$(PREFIX)gen_index < 16;
|
||||
@$(PREFIX)gen_index = @$(PREFIX)gen_index + 1)
|
||||
begin : GEN_UNUSED_@$(DEVID)_ASSIGN
|
||||
assign o_ddr3_a[@$(PREFIX)gen_index] = 0;
|
||||
end endgenerate
|
||||
/*
|
||||
// OBUFDS: Differential Output Buffer
|
||||
// 7 Series
|
||||
// Xilinx HDL Libraries Guide, version 13.4
|
||||
OBUFDS OBUFDS_inst (
|
||||
.O(o_ddr3_clk_p[1]), // Diff_p output (connect directly to top-level port)
|
||||
.OB(o_ddr3_clk_n[1]), // Diff_n output (connect directly to top-level port)
|
||||
.I(s_clk4x) // Buffer input
|
||||
);
|
||||
// End of OBUFDS_inst instantiation
|
||||
*/
|
||||
@MAIN.PORTLIST=
|
||||
// DDR3 Controller Interface
|
||||
i_@$(PREFIX)_iserdes_data, i_@$(PREFIX)_iserdes_dqs,
|
||||
i_@$(PREFIX)_iserdes_bitslip_reference,
|
||||
i_@$(PREFIX)_idelayctrl_rdy,
|
||||
o_@$(PREFIX)_cmd,
|
||||
o_@$(PREFIX)_dqs_tri_control, o_@$(PREFIX)_dq_tri_control,
|
||||
o_@$(PREFIX)_toggle_dqs, o_@$(PREFIX)_data, o_@$(PREFIX)_dm,
|
||||
o_@$(PREFIX)_odelay_data_cntvaluein, o_@$(PREFIX)_odelay_dqs_cntvaluein,
|
||||
o_@$(PREFIX)_idelay_data_cntvaluein, o_@$(PREFIX)_idelay_dqs_cntvaluein,
|
||||
o_@$(PREFIX)_odelay_data_ld, o_@$(PREFIX)_odelay_dqs_ld,
|
||||
o_@$(PREFIX)_idelay_data_ld, o_@$(PREFIX)_idelay_dqs_ld,
|
||||
o_@$(PREFIX)_bitslip,
|
||||
o_@$(PREFIX)_leveling_calib,
|
||||
o_@$(PREFIX)_reset
|
||||
@MAIN.PARAM=@$(TOP.PARAM)
|
||||
@MAIN.IODECL=
|
||||
// DDR3 Controller I/O declarations
|
||||
// {{{
|
||||
input wire [@$(DEVID)DQ_BITS*@$(DEVID)LANES*8-1:0] i_@$(PREFIX)_iserdes_data;
|
||||
input wire [@$(DEVID)LANES*8-1:0] i_@$(PREFIX)_iserdes_dqs;
|
||||
input wire [@$(DEVID)LANES*8-1:0] i_@$(PREFIX)_iserdes_bitslip_reference;
|
||||
input wire i_@$(PREFIX)_idelayctrl_rdy;
|
||||
output wire [@$(DEVID)CMD_LEN*@$(DEVID)SERDES_RATIO-1:0] o_@$(PREFIX)_cmd;
|
||||
output wire o_@$(PREFIX)_dqs_tri_control, o_@$(PREFIX)_dq_tri_control;
|
||||
output wire o_@$(PREFIX)_toggle_dqs;
|
||||
output wire [@$(DEVID)DQ_BITS*@$(DEVID)LANES*8-1:0] o_@$(PREFIX)_data;
|
||||
output wire [(@$(DEVID)DQ_BITS*@$(DEVID)LANES*8)/8-1:0] o_@$(PREFIX)_dm;
|
||||
output wire [4:0] o_@$(PREFIX)_odelay_data_cntvaluein, o_@$(PREFIX)_odelay_dqs_cntvaluein;
|
||||
output wire [4:0] o_@$(PREFIX)_idelay_data_cntvaluein, o_@$(PREFIX)_idelay_dqs_cntvaluein;
|
||||
output wire [@$(DEVID)LANES-1:0] o_@$(PREFIX)_odelay_data_ld, o_@$(PREFIX)_odelay_dqs_ld;
|
||||
output wire [@$(DEVID)LANES-1:0] o_@$(PREFIX)_idelay_data_ld, o_@$(PREFIX)_idelay_dqs_ld;
|
||||
output wire [@$(DEVID)LANES-1:0] o_@$(PREFIX)_bitslip;
|
||||
output wire o_@$(PREFIX)_leveling_calib;
|
||||
output wire o_@$(PREFIX)_reset;
|
||||
// }}}
|
||||
@MAIN.DEFNS=
|
||||
// Verilator lint_off UNUSED
|
||||
wire [@$(DEVID)AUX_WIDTH-1:0] @$(PREFIX)_aux_out;
|
||||
wire [31:0] @$(PREFIX)_debug1, @$(PREFIX)_debug2, @$(PREFIX)_debug3;
|
||||
// Verilator lint_on UNUSED
|
||||
@MAIN.INSERT=
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DDR3 Controller instantiation
|
||||
// {{{
|
||||
ddr3_controller #(
|
||||
.CONTROLLER_CLK_PERIOD(@$(DEVID)CONTROLLER_CLK_PERIOD), //ns, period of clock input to this DDR3 controller module
|
||||
.DDR3_CLK_PERIOD(DDR3_CLK_PERIOD), //ns, period of clock input to DDR3 RAM device
|
||||
.ROW_BITS(@$(DEVID)ROW_BITS), //width of row address
|
||||
.COL_BITS(@$(DEVID)COL_BITS), //width of column address
|
||||
.BA_BITS(@$(DEVID)BA_BITS), //width of bank address
|
||||
.DQ_BITS(@$(DEVID)DQ_BITS), //width of DQ
|
||||
.LANES(@$(DEVID)LANES), //8 lanes of DQ
|
||||
.AUX_WIDTH(@$(DEVID)AUX_WIDTH), //
|
||||
.MICRON_SIM(0), //simulation for micron ddr3 model (shorten POWER_ON_RESET_HIGH and INITIAL_CKE_LOW)
|
||||
.ODELAY_SUPPORTED(1), //set to 1 when ODELAYE2 is supported
|
||||
.OPT_LOWPOWER(1), //1 = low power, 0 = low logic
|
||||
.OPT_BUS_ABORT(1) //1 = can abort bus, 0 = no abort (i_wb_cyc will be ignored, ideal for an AXI implementation which cannot abort transaction)
|
||||
) ddr3_controller_inst (
|
||||
.i_controller_clk(i_clk), //i_controller_clk has period of CONTROLLER_CLK_PERIOD
|
||||
.i_rst_n(!i_reset), //200MHz input clock
|
||||
// Wishbone 1 (Controller)
|
||||
@$(SLAVE.ANSIPORTLIST),
|
||||
.i_aux(0),
|
||||
.o_aux(@$(PREFIX)_aux_out), // Leaving this empty would've caused a Verilator warning
|
||||
// Wishbone 2 (PHY)
|
||||
@$(ddr3_phy.SLAVE.ANSIPORTLIST),
|
||||
//
|
||||
// PHY interface
|
||||
.i_phy_iserdes_data(i_@$(PREFIX)_iserdes_data),
|
||||
.i_phy_iserdes_dqs(i_@$(PREFIX)_iserdes_dqs),
|
||||
.i_phy_iserdes_bitslip_reference(i_@$(PREFIX)_iserdes_bitslip_reference),
|
||||
.i_phy_idelayctrl_rdy(i_@$(PREFIX)_idelayctrl_rdy),
|
||||
.o_phy_cmd(o_@$(PREFIX)_cmd),
|
||||
.o_phy_dqs_tri_control(o_@$(PREFIX)_dqs_tri_control),
|
||||
.o_phy_dq_tri_control(o_@$(PREFIX)_dq_tri_control),
|
||||
.o_phy_toggle_dqs(o_@$(PREFIX)_toggle_dqs),
|
||||
.o_phy_data(o_@$(PREFIX)_data),
|
||||
.o_phy_dm(o_@$(PREFIX)_dm),
|
||||
.o_phy_odelay_data_cntvaluein(o_@$(PREFIX)_odelay_data_cntvaluein),
|
||||
.o_phy_odelay_dqs_cntvaluein(o_@$(PREFIX)_odelay_dqs_cntvaluein),
|
||||
.o_phy_idelay_data_cntvaluein(o_@$(PREFIX)_idelay_data_cntvaluein),
|
||||
.o_phy_idelay_dqs_cntvaluein(o_@$(PREFIX)_idelay_dqs_cntvaluein),
|
||||
.o_phy_odelay_data_ld(o_@$(PREFIX)_odelay_data_ld),
|
||||
.o_phy_odelay_dqs_ld(o_@$(PREFIX)_odelay_dqs_ld),
|
||||
.o_phy_idelay_data_ld(o_@$(PREFIX)_idelay_data_ld),
|
||||
.o_phy_idelay_dqs_ld(o_@$(PREFIX)_idelay_dqs_ld),
|
||||
.o_phy_bitslip(o_@$(PREFIX)_bitslip),
|
||||
.o_phy_write_leveling_calib(o_@$(PREFIX)_leveling_calib),
|
||||
.o_phy_reset(o_@$(PREFIX)_reset),
|
||||
// Debug port
|
||||
.o_debug1(@$(PREFIX)_debug1),
|
||||
.o_debug2(@$(PREFIX)_debug2),
|
||||
.o_debug3(@$(PREFIX)_debug3)
|
||||
);
|
||||
// }}}
|
||||
##
|
||||
##
|
||||
@PREFIX=ddr3_phy
|
||||
@DEVID=DDR3_PHY
|
||||
@ACCESS=@$(DEVID)_ACCESS
|
||||
@$NADDR=128
|
||||
@SLAVE.TYPE=OTHER
|
||||
@SLAVE.BUS=wb32
|
||||
@SLAVE.ANSPREFIX=wb2_
|
||||
#
|
||||
@REGS.N=1
|
||||
@REGS.0= 0 R_@$(DEVID) @$(DEVID)
|
||||
@BDEF.DEFN=
|
||||
|
||||
## Define the structure of your PHY controller here. How are the bits all
|
||||
## layout out? What register names do you have? That should all go here.
|
||||
|
||||
typedef struct @$(DEVID)_S {
|
||||
unsigned ph_something;
|
||||
} @$(DEVID);
|
||||
|
||||
@BDEF.IONAME=_@$(PREFIX)
|
||||
@BDEF.IOTYPE=@$(DEVID)
|
||||
@BDEF.OSDEF=_BOARD_HAS_@$(DEVID)
|
||||
@BDEF.OSVAL=static volatile @$(BDEF.IOTYPE) *const @$(BDEF.IONAME) = ((@$(BDEF.IOTYPE) *)@$[0x%08x](REGBASE));
|
||||
|
||||
@RTL.MAKE.GROUP= DDR3
|
||||
@RTL.MAKE.SUBD=ddr3
|
||||
@RTL.MAKE.FILES= ddr3_controller.v ddr3_phy.v
|
||||
################################################################################
|
||||
##
|
||||
## Filename: ddr3.txt
|
||||
## {{{
|
||||
## Project: 10Gb Ethernet switch
|
||||
##
|
||||
## Purpose: To describe how to provide access to an SDRAM controller
|
||||
## from the Wishbone bus, where such SDRAM controller uses a
|
||||
## different clock from the Wishbone bus itself.
|
||||
##
|
||||
## Creator: Dan Gisselquist, Ph.D.
|
||||
## Gisselquist Technology, LLC
|
||||
##
|
||||
################################################################################
|
||||
## }}}
|
||||
## Copyright (C) 2023, Gisselquist Technology, LLC
|
||||
## {{{
|
||||
## This file is part of the ETH10G project.
|
||||
##
|
||||
## The ETH10G project contains free software and gateware, licensed under the
|
||||
## Apache License, Version 2.0 (the "License"). You may not use this project,
|
||||
## or this file, except in compliance with the License. You may obtain a copy
|
||||
## of the License at
|
||||
## }}}
|
||||
## http://www.apache.org/licenses/LICENSE-2.0
|
||||
## {{{
|
||||
## Unless required by applicable law or agreed to in writing, files
|
||||
## distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
## WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
## License for the specific language governing permissions and limitations
|
||||
## under the License.
|
||||
##
|
||||
################################################################################
|
||||
##
|
||||
## }}}
|
||||
# Wishbone 1
|
||||
@PREFIX=ddr3_controller
|
||||
@DEVID=DDR3_CONTROLLER
|
||||
@ACCESS=@$(DEVID)_ACCESS
|
||||
## LGMEMSZ is the size of the SDRAM in bytes. For a 1GB DDR3 RAM: 30 => 1GB
|
||||
@$LGMEMSZ=30
|
||||
@LGMEMSZ.FORMAT=%d
|
||||
@$NADDR=(1<< @$(LGMEMSZ))/(@$(SLAVE.BUS.WIDTH)/8)
|
||||
@$NBYTES=(1<<(@$LGMEMSZ))
|
||||
@NBYTES.FORMAT=0x%08x
|
||||
@$MADDR= @$(REGBASE)
|
||||
@MADDR.FORMAT=0x%08x
|
||||
@$NLANES=@$(SLAVE.BUS.WIDTH)/64
|
||||
@SLAVE.TYPE=MEMORY
|
||||
@SLAVE.BUS=wbwide
|
||||
@BUS=wbwide
|
||||
@LD.PERM=wx
|
||||
#
|
||||
@REGS.N=1
|
||||
@REGS.0= 0 R_@$(DEVID) @$(DEVID)
|
||||
@REGDEFS.H.DEFNS=
|
||||
#define @$(DEVID)BASE @$[0x%08x](REGBASE)
|
||||
#define @$(DEVID)LEN @$(NBYTES)
|
||||
@BDEF.OSDEF=_BOARD_HAS_@$(DEVID)
|
||||
@BDEF.OSVAL=extern char _@$(PREFIX)[@$NBYTES];
|
||||
|
||||
@TOP.PORTLIST=
|
||||
// DDR3 I/O port wires
|
||||
o_ddr3_reset_n, o_ddr3_cke, o_ddr3_clk_p, o_ddr3_clk_n,
|
||||
o_ddr3_s_n, o_ddr3_ras_n, o_ddr3_cas_n, o_ddr3_we_n,
|
||||
o_ddr3_ba, o_ddr3_a,
|
||||
o_ddr3_odt, o_ddr3_dm,
|
||||
io_ddr3_dqs_p, io_ddr3_dqs_n, io_ddr3_dq
|
||||
|
||||
|
||||
@TOP.PARAM=
|
||||
localparam real @$(DEVID)CONTROLLER_CLK_PERIOD = 10, //ns, period of clock input to this DDR3 controller module
|
||||
DDR3_CLK_PERIOD = 2.5; //ns, period of clock input to DDR3 RAM device
|
||||
localparam @$(DEVID)ROW_BITS = 14, // width of row address
|
||||
@$(DEVID)COL_BITS = 10, // width of column address
|
||||
@$(DEVID)BA_BITS = 3, // width of bank address
|
||||
@$(DEVID)DQ_BITS = 8, // Size of one octet
|
||||
@$(DEVID)LANES = 8, //@$(NLANES), //8 lanes of DQ
|
||||
@$(DEVID)AUX_WIDTH = 8, //must be 8 bits or more (also used in internal test and calibration)
|
||||
@$(DEVID)SERDES_RATIO = $rtoi(@$(DEVID)CONTROLLER_CLK_PERIOD/DDR3_CLK_PERIOD),
|
||||
//4 is the width of a single ddr3 command {cs_n, ras_n, cas_n, we_n} plus 3 (ck_en, odt, reset_n) plus bank bits plus row bits
|
||||
@$(DEVID)CMD_LEN = 4 + 3 + @$(DEVID)BA_BITS + @$(DEVID)ROW_BITS;
|
||||
|
||||
|
||||
@TOP.IODECL=
|
||||
// I/O declarations for the DDR3 SDRAM
|
||||
// {{{
|
||||
output wire o_ddr3_reset_n;
|
||||
output wire [1:0] o_ddr3_cke;
|
||||
output wire [0:0] o_ddr3_clk_p, o_ddr3_clk_n;
|
||||
output wire [1:0] o_ddr3_s_n; // o_ddr3_s_n[1] is set to 0 since controller only support single rank
|
||||
output wire [0:0] o_ddr3_ras_n, o_ddr3_cas_n, o_ddr3_we_n;
|
||||
output wire [@$(DEVID)BA_BITS-1:0] o_ddr3_ba;
|
||||
output wire [15:0] o_ddr3_a; //set to max of 16 bits, but only ROW_BITS bits are relevant
|
||||
output wire [1:0] o_ddr3_odt;
|
||||
output wire [@$(DEVID)LANES-1:0] o_ddr3_dm;
|
||||
inout wire [(@$(DEVID)DQ_BITS*@$(DEVID)LANES)/8-1:0] io_ddr3_dqs_p, io_ddr3_dqs_n;
|
||||
inout wire [(@$(DEVID)DQ_BITS*@$(DEVID)LANES)-1:0] io_ddr3_dq;
|
||||
// }}}
|
||||
|
||||
|
||||
@TOP.DEFNS=
|
||||
// Wires connected to PHY interface of DDR3 controller
|
||||
// {{{
|
||||
genvar @$(PREFIX)gen_index;
|
||||
|
||||
wire [@$(DEVID)DQ_BITS*@$(DEVID)LANES*8-1:0] @$(PREFIX)_iserdes_data;
|
||||
wire [@$(DEVID)LANES*8-1:0] @$(PREFIX)_iserdes_dqs;
|
||||
wire [@$(DEVID)LANES*8-1:0] @$(PREFIX)_iserdes_bitslip_reference;
|
||||
wire @$(PREFIX)_idelayctrl_rdy;
|
||||
wire [@$(DEVID)CMD_LEN*@$(DEVID)SERDES_RATIO-1:0] @$(PREFIX)_cmd;
|
||||
wire @$(PREFIX)_dqs_tri_control, @$(PREFIX)_dq_tri_control;
|
||||
wire @$(PREFIX)_toggle_dqs;
|
||||
wire [@$(DEVID)DQ_BITS*@$(DEVID)LANES*8-1:0] @$(PREFIX)_data;
|
||||
wire [(@$(DEVID)DQ_BITS*@$(DEVID)LANES*8)/8-1:0] @$(PREFIX)_dm;
|
||||
wire [4:0] @$(PREFIX)_odelay_data_cntvaluein, @$(PREFIX)_odelay_dqs_cntvaluein;
|
||||
wire [4:0] @$(PREFIX)_idelay_data_cntvaluein, @$(PREFIX)_idelay_dqs_cntvaluein;
|
||||
wire [@$(DEVID)LANES-1:0] @$(PREFIX)_odelay_data_ld, @$(PREFIX)_odelay_dqs_ld;
|
||||
wire [@$(DEVID)LANES-1:0] @$(PREFIX)_idelay_data_ld, @$(PREFIX)_idelay_dqs_ld;
|
||||
wire [@$(DEVID)LANES-1:0] @$(PREFIX)_bitslip;
|
||||
wire @$(PREFIX)_write_leveling_calib;
|
||||
wire @$(PREFIX)_reset;
|
||||
wire [@$(DEVID)LANES-1:0] @$(PREFIX)_debug_read_dqs_p, @$(PREFIX)_debug_read_dqs_n;
|
||||
wire @$(PREFIX)_debug_clk_p, @$(PREFIX)_debug_clk_n;
|
||||
// }}}
|
||||
@TOP.MAIN=
|
||||
// DDR3 Controller-PHY Interface
|
||||
@$(PREFIX)_iserdes_data, @$(PREFIX)_iserdes_dqs,
|
||||
@$(PREFIX)_iserdes_bitslip_reference,
|
||||
@$(PREFIX)_idelayctrl_rdy,
|
||||
@$(PREFIX)_cmd,
|
||||
@$(PREFIX)_dqs_tri_control, @$(PREFIX)_dq_tri_control,
|
||||
@$(PREFIX)_toggle_dqs, @$(PREFIX)_data, @$(PREFIX)_dm,
|
||||
@$(PREFIX)_odelay_data_cntvaluein, @$(PREFIX)_odelay_dqs_cntvaluein,
|
||||
@$(PREFIX)_idelay_data_cntvaluein, @$(PREFIX)_idelay_dqs_cntvaluein,
|
||||
@$(PREFIX)_odelay_data_ld, @$(PREFIX)_odelay_dqs_ld,
|
||||
@$(PREFIX)_idelay_data_ld, @$(PREFIX)_idelay_dqs_ld,
|
||||
@$(PREFIX)_bitslip,
|
||||
@$(PREFIX)_write_leveling_calib,
|
||||
@$(PREFIX)_reset
|
||||
@TOP.INSERT=
|
||||
/*
|
||||
wire clk_locked;
|
||||
wire controller_clk, ddr3_clk, ref_ddr3_clk, ddr3_clk_90;
|
||||
clk_wiz_0 clk_ddr3
|
||||
(
|
||||
// Clock out ports
|
||||
.clk_out1(controller_clk),
|
||||
.clk_out2(ddr3_clk),
|
||||
.clk_out3(ref_ddr3_clk),
|
||||
.clk_out4(ddr3_clk_90),
|
||||
// Status and control signals
|
||||
.reset(s_reset),
|
||||
.locked(clk_locked),
|
||||
// Clock in ports
|
||||
.clk_in1(s_clk200)
|
||||
);
|
||||
*/
|
||||
// DDR3 PHY Instantiation
|
||||
ddr3_phy #(
|
||||
.ROW_BITS(@$(DEVID)ROW_BITS), //width of row address
|
||||
.BA_BITS(@$(DEVID)BA_BITS), //width of bank address
|
||||
.DQ_BITS(@$(DEVID)DQ_BITS), //width of DQ
|
||||
.LANES(@$(DEVID)LANES), //8 lanes of DQ
|
||||
.CONTROLLER_CLK_PERIOD(@$(DEVID)CONTROLLER_CLK_PERIOD), //ns, period of clock input to this DDR3 controller module
|
||||
.DDR3_CLK_PERIOD(DDR3_CLK_PERIOD), //ns, period of clock input to DDR3 RAM device
|
||||
.ODELAY_SUPPORTED(1)
|
||||
) ddr3_phy_inst (
|
||||
// clock and reset
|
||||
.i_controller_clk(s_clk),
|
||||
.i_ddr3_clk(s_clk4x),
|
||||
.i_ref_clk(s_clk200),
|
||||
.i_ddr3_clk_90(0), //required only when ODELAY_SUPPORTED is zero
|
||||
.i_rst_n(!s_reset),
|
||||
// Controller Interface
|
||||
.i_controller_reset(@$(PREFIX)_reset),
|
||||
.i_controller_cmd(@$(PREFIX)_cmd),
|
||||
.i_controller_dqs_tri_control(@$(PREFIX)_dqs_tri_control),
|
||||
.i_controller_dq_tri_control(@$(PREFIX)_dq_tri_control),
|
||||
.i_controller_toggle_dqs(@$(PREFIX)_toggle_dqs),
|
||||
.i_controller_data(@$(PREFIX)_data),
|
||||
.i_controller_dm(@$(PREFIX)_dm),
|
||||
.i_controller_odelay_data_cntvaluein(@$(PREFIX)_odelay_data_cntvaluein),
|
||||
.i_controller_odelay_dqs_cntvaluein(@$(PREFIX)_odelay_dqs_cntvaluein),
|
||||
.i_controller_idelay_data_cntvaluein(@$(PREFIX)_idelay_data_cntvaluein),
|
||||
.i_controller_idelay_dqs_cntvaluein(@$(PREFIX)_idelay_dqs_cntvaluein),
|
||||
.i_controller_odelay_data_ld(@$(PREFIX)_odelay_data_ld),
|
||||
.i_controller_odelay_dqs_ld(@$(PREFIX)_odelay_dqs_ld),
|
||||
.i_controller_idelay_data_ld(@$(PREFIX)_idelay_data_ld),
|
||||
.i_controller_idelay_dqs_ld(@$(PREFIX)_idelay_dqs_ld),
|
||||
.i_controller_bitslip(@$(PREFIX)_bitslip),
|
||||
.i_controller_write_leveling_calib(@$(PREFIX)_write_leveling_calib),
|
||||
.o_controller_iserdes_data(@$(PREFIX)_iserdes_data),
|
||||
.o_controller_iserdes_dqs(@$(PREFIX)_iserdes_dqs),
|
||||
.o_controller_iserdes_bitslip_reference(@$(PREFIX)_iserdes_bitslip_reference),
|
||||
.o_controller_idelayctrl_rdy(@$(PREFIX)_idelayctrl_rdy),
|
||||
// DDR3 I/O Interface
|
||||
.o_ddr3_clk_p(o_ddr3_clk_p),
|
||||
.o_ddr3_clk_n(o_ddr3_clk_n),
|
||||
.o_ddr3_reset_n(o_ddr3_reset_n),
|
||||
.o_ddr3_cke(o_ddr3_cke[0]), // CKE
|
||||
.o_ddr3_cs_n(o_ddr3_s_n[0]), // chip select signal (controls rank 1 only)
|
||||
.o_ddr3_ras_n(o_ddr3_ras_n), // RAS#
|
||||
.o_ddr3_cas_n(o_ddr3_cas_n), // CAS#
|
||||
.o_ddr3_we_n(o_ddr3_we_n), // WE#
|
||||
.o_ddr3_addr(o_ddr3_a[@$(DEVID)ROW_BITS-1:0]),
|
||||
.o_ddr3_ba_addr(o_ddr3_ba),
|
||||
.io_ddr3_dq(io_ddr3_dq),
|
||||
.io_ddr3_dqs(io_ddr3_dqs_p),
|
||||
.io_ddr3_dqs_n(io_ddr3_dqs_n),
|
||||
.o_ddr3_dm(o_ddr3_dm),
|
||||
.o_ddr3_odt(o_ddr3_odt[0]), // on-die termination
|
||||
// DEBUG PHY
|
||||
.o_ddr3_debug_read_dqs_p(@$(PREFIX)_debug_read_dqs_p),
|
||||
.o_ddr3_debug_read_dqs_n(@$(PREFIX)_debug_read_dqs_n)
|
||||
);
|
||||
//assign o_tp = {@$(PREFIX)_debug_read_dqs_n[1:0],@$(PREFIX)_debug_read_dqs_p[1:0]};
|
||||
assign o_ddr3_s_n[1] = 1; // set to 1 (disabled) since controller only supports single rank
|
||||
assign o_ddr3_cke[1] = 0; // set to 0 (disabled) since controller only supports single rank
|
||||
assign o_ddr3_odt[1] = 0; // set to 0 (disabled) since controller only supports single rank
|
||||
generate for(@$(PREFIX)gen_index = @$(DEVID)ROW_BITS;
|
||||
@$(PREFIX)gen_index < 16;
|
||||
@$(PREFIX)gen_index = @$(PREFIX)gen_index + 1)
|
||||
begin : GEN_UNUSED_@$(DEVID)_ASSIGN
|
||||
assign o_ddr3_a[@$(PREFIX)gen_index] = 0;
|
||||
end endgenerate
|
||||
/*
|
||||
// OBUFDS: Differential Output Buffer
|
||||
// 7 Series
|
||||
// Xilinx HDL Libraries Guide, version 13.4
|
||||
OBUFDS OBUFDS_inst (
|
||||
.O(o_ddr3_clk_p[1]), // Diff_p output (connect directly to top-level port)
|
||||
.OB(o_ddr3_clk_n[1]), // Diff_n output (connect directly to top-level port)
|
||||
.I(s_clk4x) // Buffer input
|
||||
);
|
||||
// End of OBUFDS_inst instantiation
|
||||
*/
|
||||
@MAIN.PORTLIST=
|
||||
// DDR3 Controller Interface
|
||||
i_@$(PREFIX)_iserdes_data, i_@$(PREFIX)_iserdes_dqs,
|
||||
i_@$(PREFIX)_iserdes_bitslip_reference,
|
||||
i_@$(PREFIX)_idelayctrl_rdy,
|
||||
o_@$(PREFIX)_cmd,
|
||||
o_@$(PREFIX)_dqs_tri_control, o_@$(PREFIX)_dq_tri_control,
|
||||
o_@$(PREFIX)_toggle_dqs, o_@$(PREFIX)_data, o_@$(PREFIX)_dm,
|
||||
o_@$(PREFIX)_odelay_data_cntvaluein, o_@$(PREFIX)_odelay_dqs_cntvaluein,
|
||||
o_@$(PREFIX)_idelay_data_cntvaluein, o_@$(PREFIX)_idelay_dqs_cntvaluein,
|
||||
o_@$(PREFIX)_odelay_data_ld, o_@$(PREFIX)_odelay_dqs_ld,
|
||||
o_@$(PREFIX)_idelay_data_ld, o_@$(PREFIX)_idelay_dqs_ld,
|
||||
o_@$(PREFIX)_bitslip,
|
||||
o_@$(PREFIX)_leveling_calib,
|
||||
o_@$(PREFIX)_reset
|
||||
@MAIN.PARAM=@$(TOP.PARAM)
|
||||
@MAIN.IODECL=
|
||||
// DDR3 Controller I/O declarations
|
||||
// {{{
|
||||
input wire [@$(DEVID)DQ_BITS*@$(DEVID)LANES*8-1:0] i_@$(PREFIX)_iserdes_data;
|
||||
input wire [@$(DEVID)LANES*8-1:0] i_@$(PREFIX)_iserdes_dqs;
|
||||
input wire [@$(DEVID)LANES*8-1:0] i_@$(PREFIX)_iserdes_bitslip_reference;
|
||||
input wire i_@$(PREFIX)_idelayctrl_rdy;
|
||||
output wire [@$(DEVID)CMD_LEN*@$(DEVID)SERDES_RATIO-1:0] o_@$(PREFIX)_cmd;
|
||||
output wire o_@$(PREFIX)_dqs_tri_control, o_@$(PREFIX)_dq_tri_control;
|
||||
output wire o_@$(PREFIX)_toggle_dqs;
|
||||
output wire [@$(DEVID)DQ_BITS*@$(DEVID)LANES*8-1:0] o_@$(PREFIX)_data;
|
||||
output wire [(@$(DEVID)DQ_BITS*@$(DEVID)LANES*8)/8-1:0] o_@$(PREFIX)_dm;
|
||||
output wire [4:0] o_@$(PREFIX)_odelay_data_cntvaluein, o_@$(PREFIX)_odelay_dqs_cntvaluein;
|
||||
output wire [4:0] o_@$(PREFIX)_idelay_data_cntvaluein, o_@$(PREFIX)_idelay_dqs_cntvaluein;
|
||||
output wire [@$(DEVID)LANES-1:0] o_@$(PREFIX)_odelay_data_ld, o_@$(PREFIX)_odelay_dqs_ld;
|
||||
output wire [@$(DEVID)LANES-1:0] o_@$(PREFIX)_idelay_data_ld, o_@$(PREFIX)_idelay_dqs_ld;
|
||||
output wire [@$(DEVID)LANES-1:0] o_@$(PREFIX)_bitslip;
|
||||
output wire o_@$(PREFIX)_leveling_calib;
|
||||
output wire o_@$(PREFIX)_reset;
|
||||
// }}}
|
||||
@MAIN.DEFNS=
|
||||
// Verilator lint_off UNUSED
|
||||
wire [@$(DEVID)AUX_WIDTH-1:0] @$(PREFIX)_aux_out;
|
||||
wire [31:0] @$(PREFIX)_debug1, @$(PREFIX)_debug2, @$(PREFIX)_debug3;
|
||||
// Verilator lint_on UNUSED
|
||||
@MAIN.INSERT=
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DDR3 Controller instantiation
|
||||
// {{{
|
||||
ddr3_controller #(
|
||||
.CONTROLLER_CLK_PERIOD(@$(DEVID)CONTROLLER_CLK_PERIOD), //ns, period of clock input to this DDR3 controller module
|
||||
.DDR3_CLK_PERIOD(DDR3_CLK_PERIOD), //ns, period of clock input to DDR3 RAM device
|
||||
.ROW_BITS(@$(DEVID)ROW_BITS), //width of row address
|
||||
.COL_BITS(@$(DEVID)COL_BITS), //width of column address
|
||||
.BA_BITS(@$(DEVID)BA_BITS), //width of bank address
|
||||
.DQ_BITS(@$(DEVID)DQ_BITS), //width of DQ
|
||||
.LANES(@$(DEVID)LANES), //8 lanes of DQ
|
||||
.AUX_WIDTH(@$(DEVID)AUX_WIDTH), //
|
||||
.MICRON_SIM(0), //simulation for micron ddr3 model (shorten POWER_ON_RESET_HIGH and INITIAL_CKE_LOW)
|
||||
.ODELAY_SUPPORTED(1), //set to 1 when ODELAYE2 is supported
|
||||
.OPT_LOWPOWER(1), //1 = low power, 0 = low logic
|
||||
.OPT_BUS_ABORT(1) //1 = can abort bus, 0 = no abort (i_wb_cyc will be ignored, ideal for an AXI implementation which cannot abort transaction)
|
||||
) ddr3_controller_inst (
|
||||
.i_controller_clk(i_clk), //i_controller_clk has period of CONTROLLER_CLK_PERIOD
|
||||
.i_rst_n(!i_reset), //200MHz input clock
|
||||
// Wishbone 1 (Controller)
|
||||
@$(SLAVE.ANSIPORTLIST),
|
||||
.i_aux(0),
|
||||
.o_aux(@$(PREFIX)_aux_out), // Leaving this empty would've caused a Verilator warning
|
||||
// Wishbone 2 (PHY)
|
||||
@$(ddr3_phy.SLAVE.ANSIPORTLIST),
|
||||
//
|
||||
// PHY interface
|
||||
.i_phy_iserdes_data(i_@$(PREFIX)_iserdes_data),
|
||||
.i_phy_iserdes_dqs(i_@$(PREFIX)_iserdes_dqs),
|
||||
.i_phy_iserdes_bitslip_reference(i_@$(PREFIX)_iserdes_bitslip_reference),
|
||||
.i_phy_idelayctrl_rdy(i_@$(PREFIX)_idelayctrl_rdy),
|
||||
.o_phy_cmd(o_@$(PREFIX)_cmd),
|
||||
.o_phy_dqs_tri_control(o_@$(PREFIX)_dqs_tri_control),
|
||||
.o_phy_dq_tri_control(o_@$(PREFIX)_dq_tri_control),
|
||||
.o_phy_toggle_dqs(o_@$(PREFIX)_toggle_dqs),
|
||||
.o_phy_data(o_@$(PREFIX)_data),
|
||||
.o_phy_dm(o_@$(PREFIX)_dm),
|
||||
.o_phy_odelay_data_cntvaluein(o_@$(PREFIX)_odelay_data_cntvaluein),
|
||||
.o_phy_odelay_dqs_cntvaluein(o_@$(PREFIX)_odelay_dqs_cntvaluein),
|
||||
.o_phy_idelay_data_cntvaluein(o_@$(PREFIX)_idelay_data_cntvaluein),
|
||||
.o_phy_idelay_dqs_cntvaluein(o_@$(PREFIX)_idelay_dqs_cntvaluein),
|
||||
.o_phy_odelay_data_ld(o_@$(PREFIX)_odelay_data_ld),
|
||||
.o_phy_odelay_dqs_ld(o_@$(PREFIX)_odelay_dqs_ld),
|
||||
.o_phy_idelay_data_ld(o_@$(PREFIX)_idelay_data_ld),
|
||||
.o_phy_idelay_dqs_ld(o_@$(PREFIX)_idelay_dqs_ld),
|
||||
.o_phy_bitslip(o_@$(PREFIX)_bitslip),
|
||||
.o_phy_write_leveling_calib(o_@$(PREFIX)_leveling_calib),
|
||||
.o_phy_reset(o_@$(PREFIX)_reset),
|
||||
// Debug port
|
||||
.o_debug1(@$(PREFIX)_debug1),
|
||||
.o_debug2(@$(PREFIX)_debug2),
|
||||
.o_debug3(@$(PREFIX)_debug3)
|
||||
);
|
||||
// }}}
|
||||
##
|
||||
##
|
||||
@PREFIX=ddr3_phy
|
||||
@DEVID=DDR3_PHY
|
||||
@ACCESS=@$(DEVID)_ACCESS
|
||||
@$NADDR=128
|
||||
@SLAVE.TYPE=OTHER
|
||||
@SLAVE.BUS=wb32
|
||||
@SLAVE.ANSPREFIX=wb2_
|
||||
#
|
||||
@REGS.N=1
|
||||
@REGS.0= 0 R_@$(DEVID) @$(DEVID)
|
||||
@BDEF.DEFN=
|
||||
|
||||
## Define the structure of your PHY controller here. How are the bits all
|
||||
## layout out? What register names do you have? That should all go here.
|
||||
|
||||
typedef struct @$(DEVID)_S {
|
||||
unsigned ph_something;
|
||||
} @$(DEVID);
|
||||
|
||||
@BDEF.IONAME=_@$(PREFIX)
|
||||
@BDEF.IOTYPE=@$(DEVID)
|
||||
@BDEF.OSDEF=_BOARD_HAS_@$(DEVID)
|
||||
@BDEF.OSVAL=static volatile @$(BDEF.IOTYPE) *const @$(BDEF.IONAME) = ((@$(BDEF.IOTYPE) *)@$[0x%08x](REGBASE));
|
||||
|
||||
@RTL.MAKE.GROUP= DDR3
|
||||
@RTL.MAKE.SUBD=ddr3
|
||||
@RTL.MAKE.FILES= ddr3_controller.v ddr3_phy.v
|
||||
|
|
|
|||
|
|
@ -1,68 +1,68 @@
|
|||
################################################################################
|
||||
##
|
||||
## Filename: sdscope.txt
|
||||
## {{{
|
||||
## Project: 10Gb Ethernet switch
|
||||
##
|
||||
## Purpose: Describes how to connect the SMI controller's debugging port to
|
||||
## a wishbone scope, then to be connected to the bus by autofpga.
|
||||
##
|
||||
## Creator: Dan Gisselquist, Ph.D.
|
||||
## Gisselquist Technology, LLC
|
||||
##
|
||||
################################################################################
|
||||
## }}}
|
||||
## Copyright (C) 2023, Gisselquist Technology, LLC
|
||||
## {{{
|
||||
## This file is part of the ETH10G project.
|
||||
##
|
||||
## The ETH10G project contains free software and gateware, licensed under the
|
||||
## Apache License, Version 2.0 (the "License"). You may not use this project,
|
||||
## or this file, except in compliance with the License. You may obtain a copy
|
||||
## of the License at
|
||||
## }}}
|
||||
## http://www.apache.org/licenses/LICENSE-2.0
|
||||
## {{{
|
||||
## Unless required by applicable law or agreed to in writing, files
|
||||
## distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
## WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
## License for the specific language governing permissions and limitations
|
||||
## under the License.
|
||||
##
|
||||
################################################################################
|
||||
##
|
||||
## }}}
|
||||
@PREFIX=scope1_ddr3
|
||||
@DEVID=DDR3SCOPE1
|
||||
@TARGET=ddr3_controller
|
||||
@TRIGGER=ddr3_controller_debug1[31]
|
||||
@DEBUG=@$(TARGET)_debug1[30:0]
|
||||
@$LOG_CAPTURE_SIZE=10
|
||||
@INCLUDEFILE=wbscopc.txt
|
||||
@INT.DDR3SCOPE1.PIC=altpic
|
||||
@INT.DDR3SCOPE1.WIRE=@$(PREFIX)_int
|
||||
@MAIN.DEFNS=
|
||||
#
|
||||
#
|
||||
@PREFIX=scope2_ddr3
|
||||
@DEVID=DDR3SCOPE2
|
||||
@TARGET=ddr3_controller
|
||||
@TRIGGER=ddr3_controller_debug2[31]
|
||||
@DEBUG=@$(TARGET)_debug2[30:0]
|
||||
@$LOG_CAPTURE_SIZE=10
|
||||
@INCLUDEFILE=wbscopc.txt
|
||||
@INT.DDR3SCOPE2.PIC=altpic
|
||||
@INT.DDR3SCOPE2.WIRE=@$(PREFIX)_int
|
||||
@MAIN.DEFNS=
|
||||
#
|
||||
#
|
||||
@PREFIX=scope3_ddr3
|
||||
@DEVID=DDR3SCOPE3
|
||||
@TARGET=ddr3_controller
|
||||
@TRIGGER=ddr3_controller_debug3[31]
|
||||
@DEBUG=@$(TARGET)_debug3[30:0]
|
||||
@$LOG_CAPTURE_SIZE=10
|
||||
@INCLUDEFILE=wbscopc.txt
|
||||
@INT.DDR3SCOPE2.PIC=altpic
|
||||
@INT.DDR3SCOPE2.WIRE=@$(PREFIX)_int
|
||||
@MAIN.DEFNS=
|
||||
################################################################################
|
||||
##
|
||||
## Filename: sdscope.txt
|
||||
## {{{
|
||||
## Project: 10Gb Ethernet switch
|
||||
##
|
||||
## Purpose: Describes how to connect the SMI controller's debugging port to
|
||||
## a wishbone scope, then to be connected to the bus by autofpga.
|
||||
##
|
||||
## Creator: Dan Gisselquist, Ph.D.
|
||||
## Gisselquist Technology, LLC
|
||||
##
|
||||
################################################################################
|
||||
## }}}
|
||||
## Copyright (C) 2023, Gisselquist Technology, LLC
|
||||
## {{{
|
||||
## This file is part of the ETH10G project.
|
||||
##
|
||||
## The ETH10G project contains free software and gateware, licensed under the
|
||||
## Apache License, Version 2.0 (the "License"). You may not use this project,
|
||||
## or this file, except in compliance with the License. You may obtain a copy
|
||||
## of the License at
|
||||
## }}}
|
||||
## http://www.apache.org/licenses/LICENSE-2.0
|
||||
## {{{
|
||||
## Unless required by applicable law or agreed to in writing, files
|
||||
## distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
## WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
## License for the specific language governing permissions and limitations
|
||||
## under the License.
|
||||
##
|
||||
################################################################################
|
||||
##
|
||||
## }}}
|
||||
@PREFIX=scope1_ddr3
|
||||
@DEVID=DDR3SCOPE1
|
||||
@TARGET=ddr3_controller
|
||||
@TRIGGER=ddr3_controller_debug1[31]
|
||||
@DEBUG=@$(TARGET)_debug1[30:0]
|
||||
@$LOG_CAPTURE_SIZE=10
|
||||
@INCLUDEFILE=wbscopc.txt
|
||||
@INT.DDR3SCOPE1.PIC=altpic
|
||||
@INT.DDR3SCOPE1.WIRE=@$(PREFIX)_int
|
||||
@MAIN.DEFNS=
|
||||
#
|
||||
#
|
||||
@PREFIX=scope2_ddr3
|
||||
@DEVID=DDR3SCOPE2
|
||||
@TARGET=ddr3_controller
|
||||
@TRIGGER=ddr3_controller_debug2[31]
|
||||
@DEBUG=@$(TARGET)_debug2[30:0]
|
||||
@$LOG_CAPTURE_SIZE=10
|
||||
@INCLUDEFILE=wbscopc.txt
|
||||
@INT.DDR3SCOPE2.PIC=altpic
|
||||
@INT.DDR3SCOPE2.WIRE=@$(PREFIX)_int
|
||||
@MAIN.DEFNS=
|
||||
#
|
||||
#
|
||||
@PREFIX=scope3_ddr3
|
||||
@DEVID=DDR3SCOPE3
|
||||
@TARGET=ddr3_controller
|
||||
@TRIGGER=ddr3_controller_debug3[31]
|
||||
@DEBUG=@$(TARGET)_debug3[30:0]
|
||||
@$LOG_CAPTURE_SIZE=10
|
||||
@INCLUDEFILE=wbscopc.txt
|
||||
@INT.DDR3SCOPE2.PIC=altpic
|
||||
@INT.DDR3SCOPE2.WIRE=@$(PREFIX)_int
|
||||
@MAIN.DEFNS=
|
||||
|
|
|
|||
|
|
@ -1,136 +1,136 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Filename: ddr3scope.cpp
|
||||
// {{{
|
||||
// Project: 10Gb Ethernet switch
|
||||
//
|
||||
// Purpose: This file decodes the debug bits produced by the SMI IP and
|
||||
// stored in a (compressed) WB scope. It is useful for determining
|
||||
// if the SMI IP is working, or even if/how the RPi is toggling the
|
||||
// associated SMI bits.
|
||||
//
|
||||
// Creator: Dan Gisselquist, Ph.D.
|
||||
// Gisselquist Technology, LLC
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// }}}
|
||||
// Copyright (C) 2023, Gisselquist Technology, LLC
|
||||
// {{{
|
||||
// This file is part of the ETH10G project.
|
||||
//
|
||||
// The ETH10G project contains free software and gateware, licensed under the
|
||||
// Apache License, Version 2.0 (the "License"). You may not use this project,
|
||||
// or this file, except in compliance with the License. You may obtain a copy
|
||||
// of the License at
|
||||
// }}}
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// {{{
|
||||
// Unless required by applicable law or agreed to in writing, files
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// }}}
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <strings.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "regdefs.h"
|
||||
#include "devbus.h"
|
||||
#include "scopecls.h"
|
||||
|
||||
#ifndef R_DDR3SCOPE1
|
||||
int main(int argc, char **argv) {
|
||||
printf("This design was not built with a NET scope within it.\n");
|
||||
}
|
||||
#else
|
||||
|
||||
#define WBSCOPE R_DDR3SCOPE1
|
||||
#define WBSCOPEDATA R_DDR3SCOPE1D
|
||||
|
||||
DEVBUS *m_fpga;
|
||||
void closeup(int v) {
|
||||
m_fpga->kill();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
class DDR3SCOPE1 : public SCOPE {
|
||||
public:
|
||||
DDR3SCOPE1(DEVBUS *fpga, unsigned addr, bool vecread = true)
|
||||
: SCOPE(fpga, addr, true, vecread) {};
|
||||
~DDR3SCOPE1(void) {}
|
||||
|
||||
virtual void decode(DEVBUS::BUSW val) const {
|
||||
int trigger;
|
||||
|
||||
trigger = (val>>31)&1;
|
||||
|
||||
printf("%6s", (trigger) ? "TRIGGERED at state_calibrate == MPR_READ! ":"");
|
||||
}
|
||||
|
||||
virtual void define_traces(void) {
|
||||
/*
|
||||
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],
|
||||
dqs_target_index[4:0], instruction_address[4:0], state_calibrate[4:0], o_wb2_stall};
|
||||
|
||||
register_trace("delay_before_read_data",4,25);
|
||||
register_trace("i_phy_idelayctrl_rdy",1,24);
|
||||
register_trace("lane",3,21);
|
||||
register_trace("dqs_start_index_stored",5,16);
|
||||
register_trace("dqs_target_index",5,11);
|
||||
register_trace("instruction_address",5,6);
|
||||
register_trace("state_calibrate",5,1);
|
||||
register_trace("o_wb2_stall",1,0);
|
||||
*/
|
||||
/*
|
||||
assign o_debug1 = {debug_trigger,stage1_we,stage1_col[5:0],stage1_data[7:0],stage1_dm[15:0]};
|
||||
|
||||
register_trace("stage1_we",1,30);
|
||||
register_trace("stage1_col",6,24);
|
||||
register_trace("stage1_data",8,16);
|
||||
register_trace("stage1_dm",16,0);
|
||||
*/
|
||||
/*
|
||||
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,
|
||||
delay_before_read_data[2:0],delay_before_write_level_feedback[4:0],lane};
|
||||
assign o_debug1 = {debug_trigger,i_phy_iserdes_dqs[7:0],state_calibrate[4:0], instruction_address[4:0],reset_from_wb2,
|
||||
repeat_test, delay_before_read_data[2:0], delay_before_write_level_feedback[4:0],lane[2:0]};
|
||||
*/
|
||||
register_trace("i_phy_iserdes_dqs",8,23);
|
||||
register_trace("state_calibrate",5,18);
|
||||
register_trace("instruction_address",5,13);
|
||||
register_trace("reset_from_wb2",1,12);
|
||||
register_trace("repeat_test",1,11);
|
||||
register_trace("delay_before_read_data",3,8);
|
||||
register_trace("delay_before_write_level_feedback",5,3);
|
||||
register_trace("lane",3,0);
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
m_fpga = connect_devbus(NULL);
|
||||
|
||||
signal(SIGSTOP, closeup);
|
||||
signal(SIGHUP, closeup);
|
||||
|
||||
DDR3SCOPE1 *scope = new DDR3SCOPE1(m_fpga, WBSCOPE);
|
||||
// scope->set_clkfreq_hz(ENETCLKFREQHZ);
|
||||
scope->set_clkfreq_hz(100000000);
|
||||
if (!scope->ready()) {
|
||||
printf("Scope is not yet ready:\n");
|
||||
scope->decode_control();
|
||||
} else {
|
||||
scope->print();
|
||||
scope->writevcd("ddr3scope1.vcd");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Filename: ddr3scope.cpp
|
||||
// {{{
|
||||
// Project: 10Gb Ethernet switch
|
||||
//
|
||||
// Purpose: This file decodes the debug bits produced by the SMI IP and
|
||||
// stored in a (compressed) WB scope. It is useful for determining
|
||||
// if the SMI IP is working, or even if/how the RPi is toggling the
|
||||
// associated SMI bits.
|
||||
//
|
||||
// Creator: Dan Gisselquist, Ph.D.
|
||||
// Gisselquist Technology, LLC
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// }}}
|
||||
// Copyright (C) 2023, Gisselquist Technology, LLC
|
||||
// {{{
|
||||
// This file is part of the ETH10G project.
|
||||
//
|
||||
// The ETH10G project contains free software and gateware, licensed under the
|
||||
// Apache License, Version 2.0 (the "License"). You may not use this project,
|
||||
// or this file, except in compliance with the License. You may obtain a copy
|
||||
// of the License at
|
||||
// }}}
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// {{{
|
||||
// Unless required by applicable law or agreed to in writing, files
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// }}}
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <strings.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "regdefs.h"
|
||||
#include "devbus.h"
|
||||
#include "scopecls.h"
|
||||
|
||||
#ifndef R_DDR3SCOPE1
|
||||
int main(int argc, char **argv) {
|
||||
printf("This design was not built with a NET scope within it.\n");
|
||||
}
|
||||
#else
|
||||
|
||||
#define WBSCOPE R_DDR3SCOPE1
|
||||
#define WBSCOPEDATA R_DDR3SCOPE1D
|
||||
|
||||
DEVBUS *m_fpga;
|
||||
void closeup(int v) {
|
||||
m_fpga->kill();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
class DDR3SCOPE1 : public SCOPE {
|
||||
public:
|
||||
DDR3SCOPE1(DEVBUS *fpga, unsigned addr, bool vecread = true)
|
||||
: SCOPE(fpga, addr, true, vecread) {};
|
||||
~DDR3SCOPE1(void) {}
|
||||
|
||||
virtual void decode(DEVBUS::BUSW val) const {
|
||||
int trigger;
|
||||
|
||||
trigger = (val>>31)&1;
|
||||
|
||||
printf("%6s", (trigger) ? "TRIGGERED at state_calibrate == MPR_READ! ":"");
|
||||
}
|
||||
|
||||
virtual void define_traces(void) {
|
||||
/*
|
||||
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],
|
||||
dqs_target_index[4:0], instruction_address[4:0], state_calibrate[4:0], o_wb2_stall};
|
||||
|
||||
register_trace("delay_before_read_data",4,25);
|
||||
register_trace("i_phy_idelayctrl_rdy",1,24);
|
||||
register_trace("lane",3,21);
|
||||
register_trace("dqs_start_index_stored",5,16);
|
||||
register_trace("dqs_target_index",5,11);
|
||||
register_trace("instruction_address",5,6);
|
||||
register_trace("state_calibrate",5,1);
|
||||
register_trace("o_wb2_stall",1,0);
|
||||
*/
|
||||
/*
|
||||
assign o_debug1 = {debug_trigger,stage1_we,stage1_col[5:0],stage1_data[7:0],stage1_dm[15:0]};
|
||||
|
||||
register_trace("stage1_we",1,30);
|
||||
register_trace("stage1_col",6,24);
|
||||
register_trace("stage1_data",8,16);
|
||||
register_trace("stage1_dm",16,0);
|
||||
*/
|
||||
/*
|
||||
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,
|
||||
delay_before_read_data[2:0],delay_before_write_level_feedback[4:0],lane};
|
||||
assign o_debug1 = {debug_trigger,i_phy_iserdes_dqs[7:0],state_calibrate[4:0], instruction_address[4:0],reset_from_wb2,
|
||||
repeat_test, delay_before_read_data[2:0], delay_before_write_level_feedback[4:0],lane[2:0]};
|
||||
*/
|
||||
register_trace("i_phy_iserdes_dqs",8,23);
|
||||
register_trace("state_calibrate",5,18);
|
||||
register_trace("instruction_address",5,13);
|
||||
register_trace("reset_from_wb2",1,12);
|
||||
register_trace("repeat_test",1,11);
|
||||
register_trace("delay_before_read_data",3,8);
|
||||
register_trace("delay_before_write_level_feedback",5,3);
|
||||
register_trace("lane",3,0);
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
m_fpga = connect_devbus(NULL);
|
||||
|
||||
signal(SIGSTOP, closeup);
|
||||
signal(SIGHUP, closeup);
|
||||
|
||||
DDR3SCOPE1 *scope = new DDR3SCOPE1(m_fpga, WBSCOPE);
|
||||
// scope->set_clkfreq_hz(ENETCLKFREQHZ);
|
||||
scope->set_clkfreq_hz(100000000);
|
||||
if (!scope->ready()) {
|
||||
printf("Scope is not yet ready:\n");
|
||||
scope->decode_control();
|
||||
} else {
|
||||
scope->print();
|
||||
scope->writevcd("ddr3scope1.vcd");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,122 +1,122 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Filename: ddr3scope.cpp
|
||||
// {{{
|
||||
// Project: 10Gb Ethernet switch
|
||||
//
|
||||
// Purpose: This file decodes the debug bits produced by the SMI IP and
|
||||
// stored in a (compressed) WB scope. It is useful for determining
|
||||
// if the SMI IP is working, or even if/how the RPi is toggling the
|
||||
// associated SMI bits.
|
||||
//
|
||||
// Creator: Dan Gisselquist, Ph.D.
|
||||
// Gisselquist Technology, LLC
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// }}}
|
||||
// Copyright (C) 2023, Gisselquist Technology, LLC
|
||||
// {{{
|
||||
// This file is part of the ETH10G project.
|
||||
//
|
||||
// The ETH10G project contains free software and gateware, licensed under the
|
||||
// Apache License, Version 2.0 (the "License"). You may not use this project,
|
||||
// or this file, except in compliance with the License. You may obtain a copy
|
||||
// of the License at
|
||||
// }}}
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// {{{
|
||||
// Unless required by applicable law or agreed to in writing, files
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// }}}
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <strings.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "regdefs.h"
|
||||
#include "devbus.h"
|
||||
#include "scopecls.h"
|
||||
|
||||
#ifndef R_DDR3SCOPE2
|
||||
int main(int argc, char **argv) {
|
||||
printf("This design was not built with a NET scope within it.\n");
|
||||
}
|
||||
#else
|
||||
|
||||
#define WBSCOPE R_DDR3SCOPE2
|
||||
#define WBSCOPEDATA R_DDR3SCOPE2D
|
||||
|
||||
DEVBUS *m_fpga;
|
||||
void closeup(int v) {
|
||||
m_fpga->kill();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
class DDR3SCOPE2 : public SCOPE {
|
||||
public:
|
||||
DDR3SCOPE2(DEVBUS *fpga, unsigned addr, bool vecread = true)
|
||||
: SCOPE(fpga, addr, true, vecread) {};
|
||||
~DDR3SCOPE2(void) {}
|
||||
|
||||
virtual void decode(DEVBUS::BUSW val) const {
|
||||
int trigger;
|
||||
|
||||
trigger = (val>>31)&1;
|
||||
|
||||
printf("%6s", (trigger) ? "TRIGGERED at state_calibrate == MPR_READ! ":"");
|
||||
}
|
||||
|
||||
virtual void define_traces(void) {
|
||||
/*
|
||||
assign o_debug2 = {debug_trigger, idelay_dqs_cntvaluein[lane][4:0], idelay_data_cntvaluein[lane][4:0], i_phy_iserdes_dqs[15:0],
|
||||
o_phy_dqs_tri_control, o_phy_dq_tri_control,
|
||||
(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}} } )
|
||||
};
|
||||
|
||||
|
||||
register_trace("idelay_dqs_cntvaluein",5,26);
|
||||
register_trace("idelay_data_cntvaluein",5,21);
|
||||
register_trace("i_phy_iserdes_dqs_lane1",8,13);
|
||||
register_trace("i_phy_iserdes_dqs_lane0",8,5);
|
||||
register_trace("o_phy_dqs_tri_control",1,4);
|
||||
register_trace("o_phy_dq_tri_control",1,3);
|
||||
register_trace("i_phy_iserdes_data_is_zero",1,2);
|
||||
register_trace("i_phy_iserdes_data_all_1s",1,1);
|
||||
register_trace("i_phy_iserdes_data_less_than_half",1,0);
|
||||
*/
|
||||
/*
|
||||
assign o_debug2 = {debug_trigger,i_phy_iserdes_data[62:32]};
|
||||
*/
|
||||
register_trace("i_phy_iserdes_data_62_32",31,0);
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
m_fpga = connect_devbus(NULL);
|
||||
|
||||
signal(SIGSTOP, closeup);
|
||||
signal(SIGHUP, closeup);
|
||||
|
||||
DDR3SCOPE2 *scope = new DDR3SCOPE2(m_fpga, WBSCOPE);
|
||||
// scope->set_clkfreq_hz(ENETCLKFREQHZ);
|
||||
scope->set_clkfreq_hz(100000000);
|
||||
if (!scope->ready()) {
|
||||
printf("Scope is not yet ready:\n");
|
||||
scope->decode_control();
|
||||
} else {
|
||||
scope->print();
|
||||
scope->writevcd("ddr3scope2.vcd");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Filename: ddr3scope.cpp
|
||||
// {{{
|
||||
// Project: 10Gb Ethernet switch
|
||||
//
|
||||
// Purpose: This file decodes the debug bits produced by the SMI IP and
|
||||
// stored in a (compressed) WB scope. It is useful for determining
|
||||
// if the SMI IP is working, or even if/how the RPi is toggling the
|
||||
// associated SMI bits.
|
||||
//
|
||||
// Creator: Dan Gisselquist, Ph.D.
|
||||
// Gisselquist Technology, LLC
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// }}}
|
||||
// Copyright (C) 2023, Gisselquist Technology, LLC
|
||||
// {{{
|
||||
// This file is part of the ETH10G project.
|
||||
//
|
||||
// The ETH10G project contains free software and gateware, licensed under the
|
||||
// Apache License, Version 2.0 (the "License"). You may not use this project,
|
||||
// or this file, except in compliance with the License. You may obtain a copy
|
||||
// of the License at
|
||||
// }}}
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// {{{
|
||||
// Unless required by applicable law or agreed to in writing, files
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// }}}
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <strings.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "regdefs.h"
|
||||
#include "devbus.h"
|
||||
#include "scopecls.h"
|
||||
|
||||
#ifndef R_DDR3SCOPE2
|
||||
int main(int argc, char **argv) {
|
||||
printf("This design was not built with a NET scope within it.\n");
|
||||
}
|
||||
#else
|
||||
|
||||
#define WBSCOPE R_DDR3SCOPE2
|
||||
#define WBSCOPEDATA R_DDR3SCOPE2D
|
||||
|
||||
DEVBUS *m_fpga;
|
||||
void closeup(int v) {
|
||||
m_fpga->kill();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
class DDR3SCOPE2 : public SCOPE {
|
||||
public:
|
||||
DDR3SCOPE2(DEVBUS *fpga, unsigned addr, bool vecread = true)
|
||||
: SCOPE(fpga, addr, true, vecread) {};
|
||||
~DDR3SCOPE2(void) {}
|
||||
|
||||
virtual void decode(DEVBUS::BUSW val) const {
|
||||
int trigger;
|
||||
|
||||
trigger = (val>>31)&1;
|
||||
|
||||
printf("%6s", (trigger) ? "TRIGGERED at state_calibrate == MPR_READ! ":"");
|
||||
}
|
||||
|
||||
virtual void define_traces(void) {
|
||||
/*
|
||||
assign o_debug2 = {debug_trigger, idelay_dqs_cntvaluein[lane][4:0], idelay_data_cntvaluein[lane][4:0], i_phy_iserdes_dqs[15:0],
|
||||
o_phy_dqs_tri_control, o_phy_dq_tri_control,
|
||||
(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}} } )
|
||||
};
|
||||
|
||||
|
||||
register_trace("idelay_dqs_cntvaluein",5,26);
|
||||
register_trace("idelay_data_cntvaluein",5,21);
|
||||
register_trace("i_phy_iserdes_dqs_lane1",8,13);
|
||||
register_trace("i_phy_iserdes_dqs_lane0",8,5);
|
||||
register_trace("o_phy_dqs_tri_control",1,4);
|
||||
register_trace("o_phy_dq_tri_control",1,3);
|
||||
register_trace("i_phy_iserdes_data_is_zero",1,2);
|
||||
register_trace("i_phy_iserdes_data_all_1s",1,1);
|
||||
register_trace("i_phy_iserdes_data_less_than_half",1,0);
|
||||
*/
|
||||
/*
|
||||
assign o_debug2 = {debug_trigger,i_phy_iserdes_data[62:32]};
|
||||
*/
|
||||
register_trace("i_phy_iserdes_data_62_32",31,0);
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
m_fpga = connect_devbus(NULL);
|
||||
|
||||
signal(SIGSTOP, closeup);
|
||||
signal(SIGHUP, closeup);
|
||||
|
||||
DDR3SCOPE2 *scope = new DDR3SCOPE2(m_fpga, WBSCOPE);
|
||||
// scope->set_clkfreq_hz(ENETCLKFREQHZ);
|
||||
scope->set_clkfreq_hz(100000000);
|
||||
if (!scope->ready()) {
|
||||
printf("Scope is not yet ready:\n");
|
||||
scope->decode_control();
|
||||
} else {
|
||||
scope->print();
|
||||
scope->writevcd("ddr3scope2.vcd");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,150 +1,150 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Filename: ddr3scope.cpp
|
||||
// {{{
|
||||
// Project: 10Gb Ethernet switch
|
||||
//
|
||||
// Purpose: This file decodes the debug bits produced by the SMI IP and
|
||||
// stored in a (compressed) WB scope. It is useful for determining
|
||||
// if the SMI IP is working, or even if/how the RPi is toggling the
|
||||
// associated SMI bits.
|
||||
//
|
||||
// Creator: Dan Gisselquist, Ph.D.
|
||||
// Gisselquist Technology, LLC
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// }}}
|
||||
// Copyright (C) 2023, Gisselquist Technology, LLC
|
||||
// {{{
|
||||
// This file is part of the ETH10G project.
|
||||
//
|
||||
// The ETH10G project contains free software and gateware, licensed under the
|
||||
// Apache License, Version 2.0 (the "License"). You may not use this project,
|
||||
// or this file, except in compliance with the License. You may obtain a copy
|
||||
// of the License at
|
||||
// }}}
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// {{{
|
||||
// Unless required by applicable law or agreed to in writing, files
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// }}}
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <strings.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "regdefs.h"
|
||||
#include "devbus.h"
|
||||
#include "scopecls.h"
|
||||
|
||||
#ifndef R_DDR3SCOPE3
|
||||
int main(int argc, char **argv) {
|
||||
printf("This design was not built with a NET scope within it.\n");
|
||||
}
|
||||
#else
|
||||
|
||||
#define WBSCOPE R_DDR3SCOPE3
|
||||
#define WBSCOPEDATA R_DDR3SCOPE3D
|
||||
|
||||
DEVBUS *m_fpga;
|
||||
void closeup(int v) {
|
||||
m_fpga->kill();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
class DDR3SCOPE3 : public SCOPE {
|
||||
public:
|
||||
DDR3SCOPE3(DEVBUS *fpga, unsigned addr, bool vecread = true)
|
||||
: SCOPE(fpga, addr, true, vecread) {};
|
||||
~DDR3SCOPE3(void) {}
|
||||
|
||||
virtual void decode(DEVBUS::BUSW val) const {
|
||||
int trigger;
|
||||
|
||||
trigger = (val>>31)&1;
|
||||
|
||||
printf("%6s", (trigger) ? "TRIGGERED at state_calibrate == MPR_READ! ":"");
|
||||
}
|
||||
|
||||
virtual void define_traces(void) {
|
||||
/*
|
||||
assign o_debug3 = {debug_trigger, delay_before_write_level_feedback[4:0], odelay_data_cntvaluein[lane][4:0], odelay_dqs_cntvaluein[lane][4:0],
|
||||
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]
|
||||
, i_phy_iserdes_data[16], i_phy_iserdes_data[8], i_phy_iserdes_data[0], lane[2:0] };
|
||||
|
||||
|
||||
register_trace("delay_before_write_level_feedback",5,26);
|
||||
register_trace("odelay_data_cntvaluein",5,21);
|
||||
register_trace("odelay_dqs_cntvaluein",5,16);
|
||||
register_trace("state_calibrate",5,11);
|
||||
register_trace("prev_write_level_feedback",1,10);
|
||||
|
||||
register_trace("i_phy_iserdes_data_lane6",1,9);
|
||||
register_trace("i_phy_iserdes_data_lane5",1,8);
|
||||
register_trace("i_phy_iserdes_data_lane4",1,7);
|
||||
register_trace("i_phy_iserdes_data_lane3",1,6);
|
||||
register_trace("i_phy_iserdes_data_lane2",1,5);
|
||||
register_trace("i_phy_iserdes_data_lane1",1,4);
|
||||
register_trace("i_phy_iserdes_data_lane0",1,3);
|
||||
register_trace("lane",3,0);
|
||||
*/
|
||||
/*
|
||||
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],
|
||||
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]};
|
||||
|
||||
register_trace("lane",3,28);
|
||||
register_trace("delay_before_read_data",4,24);
|
||||
register_trace("i_phy_iserdes_data_burst7",3,21);
|
||||
register_trace("i_phy_iserdes_data_burst6",3,18);
|
||||
register_trace("i_phy_iserdes_data_burst5",3,15);
|
||||
register_trace("i_phy_iserdes_data_burst4",3,12);
|
||||
register_trace("i_phy_iserdes_data_burst3",3,9);
|
||||
register_trace("i_phy_iserdes_data_burst2",3,6);
|
||||
register_trace("i_phy_iserdes_data_burst1",3,3);
|
||||
register_trace("i_phy_iserdes_data_burst0",3,0);
|
||||
*/
|
||||
/*
|
||||
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]};
|
||||
|
||||
|
||||
register_trace("i_phy_iserdes_data_burst3",7,24);
|
||||
register_trace("i_phy_iserdes_data_burst2",8,16);
|
||||
register_trace("i_phy_iserdes_data_burst1",8,8);
|
||||
register_trace("i_phy_iserdes_data_burst0",8,0);
|
||||
*/
|
||||
/*
|
||||
assign o_debug3 = {debug_trigger,i_phy_iserdes_data[30:0]};
|
||||
*/
|
||||
register_trace("i_phy_iserdes_data_30_0",31,0);
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
m_fpga = connect_devbus(NULL);
|
||||
|
||||
signal(SIGSTOP, closeup);
|
||||
signal(SIGHUP, closeup);
|
||||
|
||||
DDR3SCOPE3 *scope = new DDR3SCOPE3(m_fpga, WBSCOPE);
|
||||
// scope->set_clkfreq_hz(ENETCLKFREQHZ);
|
||||
scope->set_clkfreq_hz(100000000);
|
||||
if (!scope->ready()) {
|
||||
printf("Scope is not yet ready:\n");
|
||||
scope->decode_control();
|
||||
} else {
|
||||
scope->print();
|
||||
scope->writevcd("ddr3scope3.vcd");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Filename: ddr3scope.cpp
|
||||
// {{{
|
||||
// Project: 10Gb Ethernet switch
|
||||
//
|
||||
// Purpose: This file decodes the debug bits produced by the SMI IP and
|
||||
// stored in a (compressed) WB scope. It is useful for determining
|
||||
// if the SMI IP is working, or even if/how the RPi is toggling the
|
||||
// associated SMI bits.
|
||||
//
|
||||
// Creator: Dan Gisselquist, Ph.D.
|
||||
// Gisselquist Technology, LLC
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// }}}
|
||||
// Copyright (C) 2023, Gisselquist Technology, LLC
|
||||
// {{{
|
||||
// This file is part of the ETH10G project.
|
||||
//
|
||||
// The ETH10G project contains free software and gateware, licensed under the
|
||||
// Apache License, Version 2.0 (the "License"). You may not use this project,
|
||||
// or this file, except in compliance with the License. You may obtain a copy
|
||||
// of the License at
|
||||
// }}}
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// {{{
|
||||
// Unless required by applicable law or agreed to in writing, files
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// }}}
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <strings.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "regdefs.h"
|
||||
#include "devbus.h"
|
||||
#include "scopecls.h"
|
||||
|
||||
#ifndef R_DDR3SCOPE3
|
||||
int main(int argc, char **argv) {
|
||||
printf("This design was not built with a NET scope within it.\n");
|
||||
}
|
||||
#else
|
||||
|
||||
#define WBSCOPE R_DDR3SCOPE3
|
||||
#define WBSCOPEDATA R_DDR3SCOPE3D
|
||||
|
||||
DEVBUS *m_fpga;
|
||||
void closeup(int v) {
|
||||
m_fpga->kill();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
class DDR3SCOPE3 : public SCOPE {
|
||||
public:
|
||||
DDR3SCOPE3(DEVBUS *fpga, unsigned addr, bool vecread = true)
|
||||
: SCOPE(fpga, addr, true, vecread) {};
|
||||
~DDR3SCOPE3(void) {}
|
||||
|
||||
virtual void decode(DEVBUS::BUSW val) const {
|
||||
int trigger;
|
||||
|
||||
trigger = (val>>31)&1;
|
||||
|
||||
printf("%6s", (trigger) ? "TRIGGERED at state_calibrate == MPR_READ! ":"");
|
||||
}
|
||||
|
||||
virtual void define_traces(void) {
|
||||
/*
|
||||
assign o_debug3 = {debug_trigger, delay_before_write_level_feedback[4:0], odelay_data_cntvaluein[lane][4:0], odelay_dqs_cntvaluein[lane][4:0],
|
||||
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]
|
||||
, i_phy_iserdes_data[16], i_phy_iserdes_data[8], i_phy_iserdes_data[0], lane[2:0] };
|
||||
|
||||
|
||||
register_trace("delay_before_write_level_feedback",5,26);
|
||||
register_trace("odelay_data_cntvaluein",5,21);
|
||||
register_trace("odelay_dqs_cntvaluein",5,16);
|
||||
register_trace("state_calibrate",5,11);
|
||||
register_trace("prev_write_level_feedback",1,10);
|
||||
|
||||
register_trace("i_phy_iserdes_data_lane6",1,9);
|
||||
register_trace("i_phy_iserdes_data_lane5",1,8);
|
||||
register_trace("i_phy_iserdes_data_lane4",1,7);
|
||||
register_trace("i_phy_iserdes_data_lane3",1,6);
|
||||
register_trace("i_phy_iserdes_data_lane2",1,5);
|
||||
register_trace("i_phy_iserdes_data_lane1",1,4);
|
||||
register_trace("i_phy_iserdes_data_lane0",1,3);
|
||||
register_trace("lane",3,0);
|
||||
*/
|
||||
/*
|
||||
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],
|
||||
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]};
|
||||
|
||||
register_trace("lane",3,28);
|
||||
register_trace("delay_before_read_data",4,24);
|
||||
register_trace("i_phy_iserdes_data_burst7",3,21);
|
||||
register_trace("i_phy_iserdes_data_burst6",3,18);
|
||||
register_trace("i_phy_iserdes_data_burst5",3,15);
|
||||
register_trace("i_phy_iserdes_data_burst4",3,12);
|
||||
register_trace("i_phy_iserdes_data_burst3",3,9);
|
||||
register_trace("i_phy_iserdes_data_burst2",3,6);
|
||||
register_trace("i_phy_iserdes_data_burst1",3,3);
|
||||
register_trace("i_phy_iserdes_data_burst0",3,0);
|
||||
*/
|
||||
/*
|
||||
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]};
|
||||
|
||||
|
||||
register_trace("i_phy_iserdes_data_burst3",7,24);
|
||||
register_trace("i_phy_iserdes_data_burst2",8,16);
|
||||
register_trace("i_phy_iserdes_data_burst1",8,8);
|
||||
register_trace("i_phy_iserdes_data_burst0",8,0);
|
||||
*/
|
||||
/*
|
||||
assign o_debug3 = {debug_trigger,i_phy_iserdes_data[30:0]};
|
||||
*/
|
||||
register_trace("i_phy_iserdes_data_30_0",31,0);
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
m_fpga = connect_devbus(NULL);
|
||||
|
||||
signal(SIGSTOP, closeup);
|
||||
signal(SIGHUP, closeup);
|
||||
|
||||
DDR3SCOPE3 *scope = new DDR3SCOPE3(m_fpga, WBSCOPE);
|
||||
// scope->set_clkfreq_hz(ENETCLKFREQHZ);
|
||||
scope->set_clkfreq_hz(100000000);
|
||||
if (!scope->ready()) {
|
||||
printf("Scope is not yet ready:\n");
|
||||
scope->decode_control();
|
||||
} else {
|
||||
scope->print();
|
||||
scope->writevcd("ddr3scope3.vcd");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,462 +1,462 @@
|
|||
## Define our clocks
|
||||
## {{{
|
||||
set_property -dict { PACKAGE_PIN AC9 IOSTANDARD DIFF_SSTL15 } [get_ports i_clk_200mhz_p]
|
||||
set_property -dict { PACKAGE_PIN AD9 IOSTANDARD DIFF_SSTL15 } [get_ports i_clk_200mhz_n]
|
||||
create_clock -period 5.0 -name SYSCLK -waveform { 0.0 2.50 } -add [get_ports i_clk_200mhz_p]
|
||||
|
||||
#set_property -dict { PACKAGE_PIN F6 } [get_ports i_clk_150mhz_p]
|
||||
#set_property -dict { PACKAGE_PIN F5 } [get_ports i_clk_150mhz_n]
|
||||
#create_clock -period 6.6666 -name SATAREF -waveform { 0.0 3.3333 } -add [get_ports i_clk_150mhz_p]
|
||||
|
||||
#set_property -dict { PACKAGE_PIN H6 } [get_ports i_clk_156mhz_p]
|
||||
#set_property -dict { PACKAGE_PIN H5 } [get_ports i_clk_156mhz_n]
|
||||
#create_clock -period 6.4 -name NETREF -waveform { 0.0 3.4 } -add [get_ports i_clk_156mhz_p]
|
||||
|
||||
#set_property -dict { PACKAGE_PIN K6 } [get_ports i_clk_si_p]
|
||||
#set_property -dict { PACKAGE_PIN K5 } [get_ports i_clk_si_n]
|
||||
#create_clock -period 5.2 -name SIREF -waveform { 0.0 2.6 } -add [get_ports i_clk_si_p]
|
||||
|
||||
#set_property -dict { PACKAGE_PIN B26 } [get_ports i_emcclk]
|
||||
#create_clock -period 15.0 -name EMCCLK -waveform { 0.0 7.5 } -add [get_ports i_emcclk]
|
||||
|
||||
#set_property -dict { PACKAGE_PIN B26 IOSTANDARD LVCMOS18 } [get_ports i_clk_66mhz_p]
|
||||
#create_clock -period 15.0 -name INITREF -waveform { 0.0 7.5 } -add [get_ports i_clk_66mhz_p]
|
||||
|
||||
#set_property -dict { PACKAGE_PIN R21 IOSTANDARD TMDS_33 } [get_ports o_siref_clk_p]
|
||||
#set_property -dict { PACKAGE_PIN P21 IOSTANDARD TMDS_33 } [get_ports o_siref_clk_n]
|
||||
|
||||
#set_property -dict { PACKAGE_PIN R21 IOSTANDARD LVCMOS33 } [get_ports io_siref_clk_p]
|
||||
#set_property -dict { PACKAGE_PIN P21 IOSTANDARD LVCMOS33 } [get_ports io_siref_clk_n]
|
||||
|
||||
## }}}
|
||||
|
||||
## UART
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN A17 IOSTANDARD LVCMOS33} [get_ports o_wbu_uart_tx]
|
||||
#set_property -dict {PACKAGE_PIN K15 IOSTANDARD LVCMOS33} [get_ports i_wbu_uart_rx]
|
||||
#set_property -dict {PACKAGE_PIN B17 IOSTANDARD LVCMOS33} [get_ports i_wbu_uart_rts_n]
|
||||
#set_property -dict {PACKAGE_PIN F18 IOSTANDARD LVCMOS33} [get_ports o_wbu_uart_cts_n]
|
||||
## }}}
|
||||
|
||||
## Switches
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN E25 IOSTANDARD LVCMOS18} [get_ports i_sw[0]]
|
||||
#set_property -dict {PACKAGE_PIN E26 IOSTANDARD LVCMOS18} [get_ports i_sw[1]]
|
||||
#set_property -dict {PACKAGE_PIN D25 IOSTANDARD LVCMOS18} [get_ports i_sw[2]]
|
||||
#set_property -dict {PACKAGE_PIN F22 IOSTANDARD LVCMOS18} [get_ports i_sw[3]]
|
||||
#set_property -dict {PACKAGE_PIN D24 IOSTANDARD LVCMOS18} [get_ports i_sw[4]]
|
||||
#set_property -dict {PACKAGE_PIN D23 IOSTANDARD LVCMOS18} [get_ports i_sw[5]]
|
||||
#set_property -dict {PACKAGE_PIN E23 IOSTANDARD LVCMOS18} [get_ports i_sw[6]]
|
||||
#set_property -dict {PACKAGE_PIN E22 IOSTANDARD LVCMOS18} [get_ports i_sw[7]]
|
||||
## #set_property -dict {PACKAGE_PIN J25 IOSTANDARD LVCMOS18} [get_ports i_sw[8]]
|
||||
## }}}
|
||||
|
||||
## Buttons
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN J24 IOSTANDARD LVCMOS18} [get_ports i_nbtn_u]
|
||||
#set_property -dict {PACKAGE_PIN H22 IOSTANDARD LVCMOS18} [get_ports i_nbtn_l]
|
||||
#set_property -dict {PACKAGE_PIN H23 IOSTANDARD LVCMOS18} [get_ports i_nbtn_c]
|
||||
#set_property -dict {PACKAGE_PIN H24 IOSTANDARD LVCMOS18} [get_ports i_nbtn_r]
|
||||
#set_property -dict {PACKAGE_PIN G22 IOSTANDARD LVCMOS18} [get_ports i_nbtn_d]
|
||||
## }}}
|
||||
|
||||
## LEDs
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN F23 IOSTANDARD LVCMOS18} [get_ports o_led[0]]
|
||||
#set_property -dict {PACKAGE_PIN J26 IOSTANDARD LVCMOS18} [get_ports o_led[1]]
|
||||
#set_property -dict {PACKAGE_PIN G26 IOSTANDARD LVCMOS18} [get_ports o_led[2]]
|
||||
#set_property -dict {PACKAGE_PIN H26 IOSTANDARD LVCMOS18} [get_ports o_led[3]]
|
||||
#set_property -dict {PACKAGE_PIN G25 IOSTANDARD LVCMOS18} [get_ports o_led[4]]
|
||||
#set_property -dict {PACKAGE_PIN F24 IOSTANDARD LVCMOS18} [get_ports o_led[5]]
|
||||
#set_property -dict {PACKAGE_PIN F25 IOSTANDARD LVCMOS18} [get_ports o_led[6]]
|
||||
#set_property -dict {PACKAGE_PIN G24 IOSTANDARD LVCMOS18} [get_ports o_led[7]]
|
||||
## }}}
|
||||
|
||||
## FAN control
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN B19 IOSTANDARD LVCMOS33} [get_ports i_fan_tach]
|
||||
#set_property -dict {PACKAGE_PIN C17 IOSTANDARD LVCMOS33} [get_ports o_fan_pwm]
|
||||
#set_property -dict {PACKAGE_PIN C19 IOSTANDARD LVCMOS33} [get_ports o_fan_sys]
|
||||
## }}}
|
||||
|
||||
## External resets
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN A18 IOSTANDARD LVCMOS33} [get_ports i_pi_reset_n]
|
||||
#set_property -dict {PACKAGE_PIN A20 IOSTANDARD LVCMOS18} [get_ports i_soft_reset]
|
||||
## }}}
|
||||
|
||||
## I2C
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN W21 IOSTANDARD LVCMOS18} [get_ports o_i2c_mxrst_n]
|
||||
#set_property -dict {PACKAGE_PIN V21 IOSTANDARD LVCMOS18} [get_ports io_i2c_scl]
|
||||
#set_property -dict {PACKAGE_PIN AE22 IOSTANDARD LVCMOS18} [get_ports io_i2c_sda]
|
||||
#set_property -dict {PACKAGE_PIN AE26 IOSTANDARD LVCMOS18} [get_ports io_temp_scl]
|
||||
#set_property -dict {PACKAGE_PIN AD26 IOSTANDARD LVCMOS18} [get_ports io_temp_sda]
|
||||
#set_property -dict {PACKAGE_PIN V24 IOSTANDARD LVCMOS18} [get_ports i_si5324_int]
|
||||
#set_property -dict {PACKAGE_PIN V22 IOSTANDARD LVCMOS18} [get_ports o_si5324_rst]
|
||||
## }}}
|
||||
|
||||
## ETH10G
|
||||
## {{{
|
||||
## LOS
|
||||
#set_property -dict {PACKAGE_PIN T19 IOSTANDARD LVCMOS33} [get_ports i_gnet_los[0]]
|
||||
#set_property -dict {PACKAGE_PIN M19 IOSTANDARD LVCMOS33} [get_ports i_gnet_los[1]]
|
||||
#set_property -dict {PACKAGE_PIN R17 IOSTANDARD LVCMOS33} [get_ports i_gnet_los[2]]
|
||||
#set_property -dict {PACKAGE_PIN R16 IOSTANDARD LVCMOS33} [get_ports i_gnet_los[3]]
|
||||
|
||||
## TX Disable
|
||||
#set_property -dict {PACKAGE_PIN R18 IOSTANDARD LVCMOS33} [get_ports o_gnettx_disable[0]]
|
||||
#set_property -dict {PACKAGE_PIN N18 IOSTANDARD LVCMOS33} [get_ports o_gnettx_disable[1]]
|
||||
#set_property -dict {PACKAGE_PIN N17 IOSTANDARD LVCMOS33} [get_ports o_gnettx_disable[2]]
|
||||
#set_property -dict {PACKAGE_PIN P16 IOSTANDARD LVCMOS33} [get_ports o_gnettx_disable[3]]
|
||||
|
||||
## LinkUp LEDs
|
||||
#set_property -dict {PACKAGE_PIN T24 IOSTANDARD LVCMOS33} [get_ports o_gnet_linkup[0]]
|
||||
#set_property -dict {PACKAGE_PIN T22 IOSTANDARD LVCMOS33} [get_ports o_gnet_linkup[1]]
|
||||
#set_property -dict {PACKAGE_PIN N22 IOSTANDARD LVCMOS33} [get_ports o_gnet_linkup[2]]
|
||||
#set_property -dict {PACKAGE_PIN R20 IOSTANDARD LVCMOS33} [get_ports o_gnet_linkup[3]]
|
||||
|
||||
## Activity LEDs
|
||||
#set_property -dict {PACKAGE_PIN T25 IOSTANDARD LVCMOS33} [get_ports o_gnet_activity[0]]
|
||||
#set_property -dict {PACKAGE_PIN R23 IOSTANDARD LVCMOS33} [get_ports o_gnet_activity[1]]
|
||||
#set_property -dict {PACKAGE_PIN N21 IOSTANDARD LVCMOS33} [get_ports o_gnet_activity[2]]
|
||||
#set_property -dict {PACKAGE_PIN R22 IOSTANDARD LVCMOS33} [get_ports o_gnet_activity[3]]
|
||||
|
||||
## Network transmit/outputs
|
||||
#set_property -dict {PACKAGE_PIN P2} [get_ports o_gnet_p[0]]
|
||||
#set_property -dict {PACKAGE_PIN P1} [get_ports o_gnet_n[0]]
|
||||
#set_property -dict {PACKAGE_PIN M2} [get_ports o_gnet_p[1]]
|
||||
#set_property -dict {PACKAGE_PIN M1} [get_ports o_gnet_n[1]]
|
||||
#set_property -dict {PACKAGE_PIN K2} [get_ports o_gnet_p[2]]
|
||||
#set_property -dict {PACKAGE_PIN K1} [get_ports o_gnet_n[2]]
|
||||
#set_property -dict {PACKAGE_PIN H2} [get_ports o_gnet_p[3]]
|
||||
#set_property -dict {PACKAGE_PIN H1} [get_ports o_gnet_n[3]]
|
||||
|
||||
## Network receive/input
|
||||
#set_property -dict {PACKAGE_PIN R4} [get_ports i_gnet_p[0]]
|
||||
#set_property -dict {PACKAGE_PIN R3} [get_ports i_gnet_n[0]]
|
||||
#set_property -dict {PACKAGE_PIN N4} [get_ports i_gnet_p[1]]
|
||||
#set_property -dict {PACKAGE_PIN N3} [get_ports i_gnet_n[1]]
|
||||
#set_property -dict {PACKAGE_PIN L4} [get_ports i_gnet_p[2]]
|
||||
#set_property -dict {PACKAGE_PIN L3} [get_ports i_gnet_n[2]]
|
||||
#set_property -dict {PACKAGE_PIN J4} [get_ports i_gnet_p[3]]
|
||||
#set_property -dict {PACKAGE_PIN J3} [get_ports i_gnet_n[3]]
|
||||
|
||||
## }}}
|
||||
|
||||
## SMI
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN AC24 IOSTANDARD LVCMOS18} [get_ports i_smi_oen]
|
||||
#set_property -dict {PACKAGE_PIN W23 IOSTANDARD LVCMOS18} [get_ports i_smi_wen]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN AB26 IOSTANDARD LVCMOS18} [get_ports i_smi_sa[0]]
|
||||
#set_property -dict {PACKAGE_PIN V26 IOSTANDARD LVCMOS18} [get_ports i_smi_sa[1]]
|
||||
#set_property -dict {PACKAGE_PIN U24 IOSTANDARD LVCMOS18} [get_ports i_smi_sa[2]]
|
||||
#set_property -dict {PACKAGE_PIN U26 IOSTANDARD LVCMOS18} [get_ports i_smi_sa[3]]
|
||||
#set_property -dict {PACKAGE_PIN AB25 IOSTANDARD LVCMOS18} [get_ports i_smi_sa[4]]
|
||||
#set_property -dict {PACKAGE_PIN V23 IOSTANDARD LVCMOS18} [get_ports i_smi_sa[5]]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN W24 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[0]]
|
||||
#set_property -dict {PACKAGE_PIN Y26 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[1]]
|
||||
#set_property -dict {PACKAGE_PIN Y25 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[2]]
|
||||
#set_property -dict {PACKAGE_PIN AA25 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[3]]
|
||||
#set_property -dict {PACKAGE_PIN U22 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[4]]
|
||||
#set_property -dict {PACKAGE_PIN AC26 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[5]]
|
||||
#set_property -dict {PACKAGE_PIN U25 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[6]]
|
||||
#set_property -dict {PACKAGE_PIN AB24 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[7]]
|
||||
#set_property -dict {PACKAGE_PIN Y22 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[8]]
|
||||
#set_property -dict {PACKAGE_PIN W25 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[9]]
|
||||
#set_property -dict {PACKAGE_PIN Y23 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[10]]
|
||||
#set_property -dict {PACKAGE_PIN AC23 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[11]]
|
||||
#set_property -dict {PACKAGE_PIN Y21 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[12]]
|
||||
#set_property -dict {PACKAGE_PIN W20 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[13]]
|
||||
#set_property -dict {PACKAGE_PIN W26 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[14]]
|
||||
#set_property -dict {PACKAGE_PIN AA23 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[15]]
|
||||
#set_property -dict {PACKAGE_PIN AA24 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[16]]
|
||||
#set_property -dict {PACKAGE_PIN AA22 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[17]]
|
||||
## }}}
|
||||
|
||||
## uSD
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN AC22 IOSTANDARD LVCMOS18} [get_ports i_sdcard_cd_n]
|
||||
#set_property -dict {PACKAGE_PIN AD21 IOSTANDARD LVCMOS18} [get_ports o_sdcard_clk]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN AB22 IOSTANDARD LVCMOS18} [get_ports io_sdcard_cmd]
|
||||
#set_property -dict {PACKAGE_PIN AD24 IOSTANDARD LVCMOS18} [get_ports io_sdcard_dat[0]]
|
||||
#set_property -dict {PACKAGE_PIN AC21 IOSTANDARD LVCMOS18} [get_ports io_sdcard_dat[1]]
|
||||
#set_property -dict {PACKAGE_PIN AD23 IOSTANDARD LVCMOS18} [get_ports io_sdcard_dat[2]]
|
||||
#set_property -dict {PACKAGE_PIN AB21 IOSTANDARD LVCMOS18} [get_ports io_sdcard_dat[3]]
|
||||
## }}}
|
||||
|
||||
## Flash
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN C22 IOSTANDARD LVCMOS18} [get_ports o_flash_sel]
|
||||
## The flash clock pin is CCLK_0
|
||||
#set_property -dict {PACKAGE_PIN C23 IOSTANDARD LVCMOS18} [get_ports o_flash_cs_n]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN B24 IOSTANDARD LVCMOS18} [get_ports io_flash_dat[0]]
|
||||
#set_property -dict {PACKAGE_PIN A25 IOSTANDARD LVCMOS18} [get_ports io_flash_dat[1]]
|
||||
#set_property -dict {PACKAGE_PIN B22 IOSTANDARD LVCMOS18} [get_ports io_flash_dat[2]]
|
||||
#set_property -dict {PACKAGE_PIN A22 IOSTANDARD LVCMOS18} [get_ports io_flash_dat[3]]
|
||||
## }}}
|
||||
|
||||
## eMMC
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN C23 IOSTANDARD LVCMOS18} [get_ports o_emmc_clk]
|
||||
#set_property -dict {PACKAGE_PIN C23 IOSTANDARD LVCMOS18} [get_ports io_emmc_cmd]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN B24 IOSTANDARD LVCMOS18} [get_ports io_emmc_dat[0]]
|
||||
#set_property -dict {PACKAGE_PIN A25 IOSTANDARD LVCMOS18} [get_ports io_emmc_dat[1]]
|
||||
#set_property -dict {PACKAGE_PIN B22 IOSTANDARD LVCMOS18} [get_ports io_emmc_dat[2]]
|
||||
#set_property -dict {PACKAGE_PIN A22 IOSTANDARD LVCMOS18} [get_ports io_emmc_dat[3]]
|
||||
#set_property -dict {PACKAGE_PIN A23 IOSTANDARD LVCMOS18} [get_ports io_emmc_dat[4]]
|
||||
#set_property -dict {PACKAGE_PIN A24 IOSTANDARD LVCMOS18} [get_ports io_emmc_dat[5]]
|
||||
#set_property -dict {PACKAGE_PIN D26 IOSTANDARD LVCMOS18} [get_ports io_emmc_dat[6]]
|
||||
#set_property -dict {PACKAGE_PIN C26 IOSTANDARD LVCMOS18} [get_ports io_emmc_dat[7]]
|
||||
#set_property -dict {PACKAGE_PIN D21 IOSTANDARD LVCMOS18} [get_ports i_emmc_ds]
|
||||
## }}}
|
||||
|
||||
## SATA
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN B2} [get_ports o_sata_p]
|
||||
#set_property -dict {PACKAGE_PIN B1} [get_ports o_sata_n]
|
||||
#set_property -dict {PACKAGE_PIN C4} [get_ports i_sata_p]
|
||||
#set_property -dict {PACKAGE_PIN C3} [get_ports i_sata_n]
|
||||
## }}}
|
||||
|
||||
## DDR3
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN V11 IOSTANDARD LVCMOS15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_reset_n]
|
||||
#set_property -dict {PACKAGE_PIN AB11 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_clk_p]
|
||||
#set_property -dict {PACKAGE_PIN AC11 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_clk_n]
|
||||
#set_property -dict {PACKAGE_PIN AA9 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_clk_p_1]
|
||||
#set_property -dict {PACKAGE_PIN AB9 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_clk_n_1]
|
||||
#set_property -dict {PACKAGE_PIN Y10 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_cke[0]]
|
||||
#set_property -dict {PACKAGE_PIN W9 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_cke[1]]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN AA10 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_ras_n]
|
||||
#set_property -dict {PACKAGE_PIN AA7 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_cas_n]
|
||||
#set_property -dict {PACKAGE_PIN Y7 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_we_n]
|
||||
#set_property -dict {PACKAGE_PIN Y8 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_s_n[0]]
|
||||
#set_property -dict {PACKAGE_PIN V7 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_s_n[1]]
|
||||
#set_property -dict {PACKAGE_PIN AA8 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_odt[0]]
|
||||
#set_property -dict {PACKAGE_PIN V9 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_odt[1]]
|
||||
#set_property -dict {PACKAGE_PIN W10 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports i_ddr3_event]
|
||||
|
||||
### Address lines
|
||||
### {{{
|
||||
#set_property -dict {PACKAGE_PIN AC7 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_ba[0]]
|
||||
#set_property -dict {PACKAGE_PIN V8 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_ba[1]]
|
||||
#set_property -dict {PACKAGE_PIN AC13 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_ba[2]]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN AF7 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[0]]
|
||||
#set_property -dict {PACKAGE_PIN AD8 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[1]]
|
||||
#set_property -dict {PACKAGE_PIN AB10 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[2]]
|
||||
#set_property -dict {PACKAGE_PIN AC8 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[3]]
|
||||
#set_property -dict {PACKAGE_PIN W11 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[4]]
|
||||
#set_property -dict {PACKAGE_PIN AA12 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[5]]
|
||||
#set_property -dict {PACKAGE_PIN AC12 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[6]]
|
||||
#set_property -dict {PACKAGE_PIN AD13 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[7]]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN AB12 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[8]]
|
||||
#set_property -dict {PACKAGE_PIN AD11 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[9]]
|
||||
#set_property -dict {PACKAGE_PIN AE7 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[10]]
|
||||
#set_property -dict {PACKAGE_PIN Y11 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[11]]
|
||||
#set_property -dict {PACKAGE_PIN AA13 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[12]]
|
||||
#set_property -dict {PACKAGE_PIN AB7 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[13]]
|
||||
#set_property -dict {PACKAGE_PIN Y13 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[14]]
|
||||
#set_property -dict {PACKAGE_PIN Y12 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[15]]
|
||||
### }}}
|
||||
|
||||
### Byte lane #0
|
||||
### {{{
|
||||
#set_property -dict {PACKAGE_PIN AB17 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[0]]
|
||||
#set_property -dict {PACKAGE_PIN AC18 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[1]]
|
||||
#set_property -dict {PACKAGE_PIN AC17 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[2]]
|
||||
#set_property -dict {PACKAGE_PIN AD19 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[3]]
|
||||
#set_property -dict {PACKAGE_PIN AA19 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[4]]
|
||||
#set_property -dict {PACKAGE_PIN AA20 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[5]]
|
||||
#set_property -dict {PACKAGE_PIN AD18 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[6]]
|
||||
#set_property -dict {PACKAGE_PIN AC16 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[7]]
|
||||
#set_property -dict {PACKAGE_PIN AD20 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_p[0]]
|
||||
#set_property -dict {PACKAGE_PIN AE20 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_n[0]]
|
||||
#set_property -dict {PACKAGE_PIN AC19 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_dm[0]]
|
||||
### }}}
|
||||
|
||||
### Byte lane #1
|
||||
### {{{
|
||||
#set_property -dict {PACKAGE_PIN V16 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[8]]
|
||||
#set_property -dict {PACKAGE_PIN V18 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[9]]
|
||||
#set_property -dict {PACKAGE_PIN AB20 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[10]]
|
||||
#set_property -dict {PACKAGE_PIN AB19 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[11]]
|
||||
#set_property -dict {PACKAGE_PIN W15 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[12]]
|
||||
#set_property -dict {PACKAGE_PIN V19 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[13]]
|
||||
#set_property -dict {PACKAGE_PIN W16 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[14]]
|
||||
#set_property -dict {PACKAGE_PIN Y17 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[15]]
|
||||
#set_property -dict {PACKAGE_PIN W18 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_p[1]]
|
||||
#set_property -dict {PACKAGE_PIN W19 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_n[1]]
|
||||
#set_property -dict {PACKAGE_PIN V17 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_dm[1]]
|
||||
### }}}
|
||||
|
||||
### Byte lane #2
|
||||
### {{{
|
||||
#set_property -dict {PACKAGE_PIN AF19 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[16]]
|
||||
#set_property -dict {PACKAGE_PIN AE17 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[17]]
|
||||
#set_property -dict {PACKAGE_PIN AE15 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[18]]
|
||||
#set_property -dict {PACKAGE_PIN AF15 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[19]]
|
||||
#set_property -dict {PACKAGE_PIN AF20 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[20]]
|
||||
#set_property -dict {PACKAGE_PIN AD16 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[21]]
|
||||
#set_property -dict {PACKAGE_PIN AD15 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[22]]
|
||||
#set_property -dict {PACKAGE_PIN AF14 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[23]]
|
||||
#set_property -dict {PACKAGE_PIN AE18 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_p[2]]
|
||||
#set_property -dict {PACKAGE_PIN AF18 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_n[2]]
|
||||
#set_property -dict {PACKAGE_PIN AF17 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_dm[2]]
|
||||
### }}}
|
||||
|
||||
### Byte lane #3
|
||||
### {{{
|
||||
#set_property -dict {PACKAGE_PIN AA15 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[24]]
|
||||
#set_property -dict {PACKAGE_PIN AB16 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[25]]
|
||||
#set_property -dict {PACKAGE_PIN AD14 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[26]]
|
||||
#set_property -dict {PACKAGE_PIN AB14 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[27]]
|
||||
#set_property -dict {PACKAGE_PIN AA18 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[28]]
|
||||
#set_property -dict {PACKAGE_PIN AA17 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[29]]
|
||||
#set_property -dict {PACKAGE_PIN AB15 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[30]]
|
||||
#set_property -dict {PACKAGE_PIN AC14 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[31]]
|
||||
#set_property -dict {PACKAGE_PIN Y15 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_p[3]]
|
||||
#set_property -dict {PACKAGE_PIN Y16 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_n[3]]
|
||||
#set_property -dict {PACKAGE_PIN AA14 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_dm[3]]
|
||||
### }}}
|
||||
|
||||
### Byte lane #4
|
||||
### {{{
|
||||
#set_property -dict {PACKAGE_PIN AD6 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[32]]
|
||||
#set_property -dict {PACKAGE_PIN AC6 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[33]]
|
||||
#set_property -dict {PACKAGE_PIN AC3 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[34]]
|
||||
#set_property -dict {PACKAGE_PIN AB4 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[35]]
|
||||
#set_property -dict {PACKAGE_PIN AB6 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[36]]
|
||||
#set_property -dict {PACKAGE_PIN Y6 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[37]]
|
||||
#set_property -dict {PACKAGE_PIN Y5 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[38]]
|
||||
#set_property -dict {PACKAGE_PIN AA4 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[39]]
|
||||
#set_property -dict {PACKAGE_PIN AA5 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_p[4]]
|
||||
#set_property -dict {PACKAGE_PIN AB5 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_n[4]]
|
||||
#set_property -dict {PACKAGE_PIN AC4 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_dm[4]]
|
||||
### }}}
|
||||
|
||||
### Byte lane #5
|
||||
### {{{
|
||||
#set_property -dict {PACKAGE_PIN AF3 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[40]]
|
||||
#set_property -dict {PACKAGE_PIN AE3 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[41]]
|
||||
#set_property -dict {PACKAGE_PIN AE2 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[42]]
|
||||
#set_property -dict {PACKAGE_PIN AE1 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[43]]
|
||||
#set_property -dict {PACKAGE_PIN AE6 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[44]]
|
||||
#set_property -dict {PACKAGE_PIN AE5 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[45]]
|
||||
#set_property -dict {PACKAGE_PIN AD4 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[46]]
|
||||
#set_property -dict {PACKAGE_PIN AD1 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[47]]
|
||||
#set_property -dict {PACKAGE_PIN AF5 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_p[5]]
|
||||
#set_property -dict {PACKAGE_PIN AF4 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_n[5]]
|
||||
#set_property -dict {PACKAGE_PIN AF2 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_dm[5]]
|
||||
### }}}
|
||||
|
||||
### Byte lane #6
|
||||
### {{{
|
||||
#set_property -dict {PACKAGE_PIN W3 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[48]]
|
||||
#set_property -dict {PACKAGE_PIN V4 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[49]]
|
||||
#set_property -dict {PACKAGE_PIN U2 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[50]]
|
||||
#set_property -dict {PACKAGE_PIN U5 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[51]]
|
||||
#set_property -dict {PACKAGE_PIN V6 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[52]]
|
||||
#set_property -dict {PACKAGE_PIN V3 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[53]]
|
||||
#set_property -dict {PACKAGE_PIN U1 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[54]]
|
||||
#set_property -dict {PACKAGE_PIN U6 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[55]]
|
||||
#set_property -dict {PACKAGE_PIN W6 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_p[6]]
|
||||
#set_property -dict {PACKAGE_PIN W5 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_n[6]]
|
||||
#set_property -dict {PACKAGE_PIN U7 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_dm[6]]
|
||||
### }}}
|
||||
|
||||
### Byte lane #7
|
||||
### {{{
|
||||
#set_property -dict {PACKAGE_PIN AB2 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[56]]
|
||||
#set_property -dict {PACKAGE_PIN AA3 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[57]]
|
||||
#set_property -dict {PACKAGE_PIN W1 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[58]]
|
||||
#set_property -dict {PACKAGE_PIN V2 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[59]]
|
||||
#set_property -dict {PACKAGE_PIN AC2 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[60]]
|
||||
#set_property -dict {PACKAGE_PIN Y3 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[61]]
|
||||
#set_property -dict {PACKAGE_PIN Y2 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[62]]
|
||||
#set_property -dict {PACKAGE_PIN V1 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[63]]
|
||||
#set_property -dict {PACKAGE_PIN AB1 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_p[7]]
|
||||
#set_property -dict {PACKAGE_PIN AC1 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_n[7]]
|
||||
#set_property -dict {PACKAGE_PIN Y1 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_dm[7]]
|
||||
### }}}
|
||||
|
||||
## }}}
|
||||
|
||||
## HDMI
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN N23 IOSTANDARD LVCMOS33} [get_ports io_hdmirx_cec]
|
||||
#set_property -dict {PACKAGE_PIN M22 IOSTANDARD LVCMOS33} [get_ports o_hdmirx_hpd_n]
|
||||
#set_property -dict {PACKAGE_PIN P23 IOSTANDARD LVCMOS33} [get_ports io_hdmirx_scl]
|
||||
#set_property -dict {PACKAGE_PIN M21 IOSTANDARD LVCMOS33} [get_ports io_hdmirx_sda]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN P24 IOSTANDARD TMDS_33} [get_ports i_hdmirx_p[0]]
|
||||
#set_property -dict {PACKAGE_PIN N24 IOSTANDARD TMDS_33} [get_ports i_hdmirx_n[0]]
|
||||
#set_property -dict {PACKAGE_PIN R26 IOSTANDARD TMDS_33} [get_ports i_hdmirx_p[1]]
|
||||
#set_property -dict {PACKAGE_PIN P26 IOSTANDARD TMDS_33} [get_ports i_hdmirx_n[1]]
|
||||
#set_property -dict {PACKAGE_PIN R25 IOSTANDARD TMDS_33} [get_ports i_hdmirx_p[2]]
|
||||
#set_property -dict {PACKAGE_PIN P25 IOSTANDARD TMDS_33} [get_ports i_hdmirx_n[2]]
|
||||
#set_property -dict {PACKAGE_PIN M24 IOSTANDARD TMDS_33} [get_ports i_hdmirx_clk_p]
|
||||
#set_property -dict {PACKAGE_PIN L24 IOSTANDARD TMDS_33} [get_ports i_hdmirx_clk_n]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN N26 IOSTANDARD LVCMOS33} [get_ports io_hdmitx_cec]
|
||||
#set_property -dict {PACKAGE_PIN M26 IOSTANDARD LVCMOS33} [get_ports i_hdmitx_hpd_n]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN P19 IOSTANDARD TMDS_33} [get_ports o_hdmitx_p[0]]
|
||||
#set_property -dict {PACKAGE_PIN P20 IOSTANDARD TMDS_33} [get_ports o_hdmitx_n[0]]
|
||||
#set_property -dict {PACKAGE_PIN K25 IOSTANDARD TMDS_33} [get_ports o_hdmitx_p[1]]
|
||||
#set_property -dict {PACKAGE_PIN K26 IOSTANDARD TMDS_33} [get_ports o_hdmitx_n[1]]
|
||||
#set_property -dict {PACKAGE_PIN M25 IOSTANDARD TMDS_33} [get_ports o_hdmitx_p[2]]
|
||||
#set_property -dict {PACKAGE_PIN L25 IOSTANDARD TMDS_33} [get_ports o_hdmitx_n[2]]
|
||||
#set_property -dict {PACKAGE_PIN N19 IOSTANDARD TMDS_33} [get_ports o_hdmitx_clk_p]
|
||||
#set_property -dict {PACKAGE_PIN M20 IOSTANDARD TMDS_33} [get_ports o_hdmitx_clk_n]
|
||||
## }}}
|
||||
|
||||
## PCIe
|
||||
## {{{
|
||||
#set_property -dict { PACKAGE_PIN D6 IOSTANDARD DIFF_HSTL_I_10 } [get_ports o_pcie_clk_p]
|
||||
#set_property -dict { PACKAGE_PIN D5 IOSTANDARD DIFF_HSTL_I_10 } [get_ports o_pcie_clk_n]
|
||||
#set_property -dict { PACKAGE_PIN B16 IOSTANDARD DIFF_HSTL_I_10 } [get_ports o_pcie_perst_n]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN A4 IOSTANDARD DIFF_HSTL_I_10 [get_ports o_pcie_p]
|
||||
#set_property -dict {PACKAGE_PIN A3 IOSTANDARD DIFF_HSTL_I_10 [get_ports o_pcie_n]
|
||||
#set_property -dict {PACKAGE_PIN B6 IOSTANDARD DIFF_HSTL_I_10 [get_ports i_pcie_p]
|
||||
#set_property -dict {PACKAGE_PIN B5 IOSTANDARD DIFF_HSTL_I_10 [get_ports i_pcie_n]
|
||||
## }}}
|
||||
|
||||
## CRUVI
|
||||
## {{{
|
||||
## }}}
|
||||
|
||||
## Hard test points
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN M17 IOSTANDARD LVCMOS33} [get_ports o_tp[0]]
|
||||
#set_property -dict {PACKAGE_PIN L18 IOSTANDARD LVCMOS33} [get_ports o_tp[1]]
|
||||
#set_property -dict {PACKAGE_PIN L17 IOSTANDARD LVCMOS33} [get_ports o_tp[2]]
|
||||
#set_property -dict {PACKAGE_PIN K18 IOSTANDARD LVCMOS33} [get_ports o_tp[3]]
|
||||
## }}}
|
||||
|
||||
## Bitstream options
|
||||
set_property CONFIG_MODE SPIx4 [current_design]
|
||||
set_property BITSTREAM.CONFIG.CONFIGRATE 26 [current_design]
|
||||
set_property CONFIG_VOLTAGE 2.5 [current_design]
|
||||
set_property CFGBVS VCCO [current_design]
|
||||
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
|
||||
|
||||
set_property INTERNAL_VREF 0.750 [get_iobanks 32]
|
||||
set_property INTERNAL_VREF 0.750 [get_iobanks 33]
|
||||
set_property INTERNAL_VREF 0.750 [get_iobanks 34]
|
||||
set_property BITSTREAM.CONFIG.UNUSEDPIN PULLNONE [current_design]
|
||||
set_property BITSTREAM.STARTUP.MATCH_CYCLE 6 [current_design]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Define our clocks
|
||||
## {{{
|
||||
set_property -dict { PACKAGE_PIN AC9 IOSTANDARD DIFF_SSTL15 } [get_ports i_clk_200mhz_p]
|
||||
set_property -dict { PACKAGE_PIN AD9 IOSTANDARD DIFF_SSTL15 } [get_ports i_clk_200mhz_n]
|
||||
create_clock -period 5.0 -name SYSCLK -waveform { 0.0 2.50 } -add [get_ports i_clk_200mhz_p]
|
||||
|
||||
#set_property -dict { PACKAGE_PIN F6 } [get_ports i_clk_150mhz_p]
|
||||
#set_property -dict { PACKAGE_PIN F5 } [get_ports i_clk_150mhz_n]
|
||||
#create_clock -period 6.6666 -name SATAREF -waveform { 0.0 3.3333 } -add [get_ports i_clk_150mhz_p]
|
||||
|
||||
#set_property -dict { PACKAGE_PIN H6 } [get_ports i_clk_156mhz_p]
|
||||
#set_property -dict { PACKAGE_PIN H5 } [get_ports i_clk_156mhz_n]
|
||||
#create_clock -period 6.4 -name NETREF -waveform { 0.0 3.4 } -add [get_ports i_clk_156mhz_p]
|
||||
|
||||
#set_property -dict { PACKAGE_PIN K6 } [get_ports i_clk_si_p]
|
||||
#set_property -dict { PACKAGE_PIN K5 } [get_ports i_clk_si_n]
|
||||
#create_clock -period 5.2 -name SIREF -waveform { 0.0 2.6 } -add [get_ports i_clk_si_p]
|
||||
|
||||
#set_property -dict { PACKAGE_PIN B26 } [get_ports i_emcclk]
|
||||
#create_clock -period 15.0 -name EMCCLK -waveform { 0.0 7.5 } -add [get_ports i_emcclk]
|
||||
|
||||
#set_property -dict { PACKAGE_PIN B26 IOSTANDARD LVCMOS18 } [get_ports i_clk_66mhz_p]
|
||||
#create_clock -period 15.0 -name INITREF -waveform { 0.0 7.5 } -add [get_ports i_clk_66mhz_p]
|
||||
|
||||
#set_property -dict { PACKAGE_PIN R21 IOSTANDARD TMDS_33 } [get_ports o_siref_clk_p]
|
||||
#set_property -dict { PACKAGE_PIN P21 IOSTANDARD TMDS_33 } [get_ports o_siref_clk_n]
|
||||
|
||||
#set_property -dict { PACKAGE_PIN R21 IOSTANDARD LVCMOS33 } [get_ports io_siref_clk_p]
|
||||
#set_property -dict { PACKAGE_PIN P21 IOSTANDARD LVCMOS33 } [get_ports io_siref_clk_n]
|
||||
|
||||
## }}}
|
||||
|
||||
## UART
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN A17 IOSTANDARD LVCMOS33} [get_ports o_wbu_uart_tx]
|
||||
#set_property -dict {PACKAGE_PIN K15 IOSTANDARD LVCMOS33} [get_ports i_wbu_uart_rx]
|
||||
#set_property -dict {PACKAGE_PIN B17 IOSTANDARD LVCMOS33} [get_ports i_wbu_uart_rts_n]
|
||||
#set_property -dict {PACKAGE_PIN F18 IOSTANDARD LVCMOS33} [get_ports o_wbu_uart_cts_n]
|
||||
## }}}
|
||||
|
||||
## Switches
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN E25 IOSTANDARD LVCMOS18} [get_ports i_sw[0]]
|
||||
#set_property -dict {PACKAGE_PIN E26 IOSTANDARD LVCMOS18} [get_ports i_sw[1]]
|
||||
#set_property -dict {PACKAGE_PIN D25 IOSTANDARD LVCMOS18} [get_ports i_sw[2]]
|
||||
#set_property -dict {PACKAGE_PIN F22 IOSTANDARD LVCMOS18} [get_ports i_sw[3]]
|
||||
#set_property -dict {PACKAGE_PIN D24 IOSTANDARD LVCMOS18} [get_ports i_sw[4]]
|
||||
#set_property -dict {PACKAGE_PIN D23 IOSTANDARD LVCMOS18} [get_ports i_sw[5]]
|
||||
#set_property -dict {PACKAGE_PIN E23 IOSTANDARD LVCMOS18} [get_ports i_sw[6]]
|
||||
#set_property -dict {PACKAGE_PIN E22 IOSTANDARD LVCMOS18} [get_ports i_sw[7]]
|
||||
## #set_property -dict {PACKAGE_PIN J25 IOSTANDARD LVCMOS18} [get_ports i_sw[8]]
|
||||
## }}}
|
||||
|
||||
## Buttons
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN J24 IOSTANDARD LVCMOS18} [get_ports i_nbtn_u]
|
||||
#set_property -dict {PACKAGE_PIN H22 IOSTANDARD LVCMOS18} [get_ports i_nbtn_l]
|
||||
#set_property -dict {PACKAGE_PIN H23 IOSTANDARD LVCMOS18} [get_ports i_nbtn_c]
|
||||
#set_property -dict {PACKAGE_PIN H24 IOSTANDARD LVCMOS18} [get_ports i_nbtn_r]
|
||||
#set_property -dict {PACKAGE_PIN G22 IOSTANDARD LVCMOS18} [get_ports i_nbtn_d]
|
||||
## }}}
|
||||
|
||||
## LEDs
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN F23 IOSTANDARD LVCMOS18} [get_ports o_led[0]]
|
||||
#set_property -dict {PACKAGE_PIN J26 IOSTANDARD LVCMOS18} [get_ports o_led[1]]
|
||||
#set_property -dict {PACKAGE_PIN G26 IOSTANDARD LVCMOS18} [get_ports o_led[2]]
|
||||
#set_property -dict {PACKAGE_PIN H26 IOSTANDARD LVCMOS18} [get_ports o_led[3]]
|
||||
#set_property -dict {PACKAGE_PIN G25 IOSTANDARD LVCMOS18} [get_ports o_led[4]]
|
||||
#set_property -dict {PACKAGE_PIN F24 IOSTANDARD LVCMOS18} [get_ports o_led[5]]
|
||||
#set_property -dict {PACKAGE_PIN F25 IOSTANDARD LVCMOS18} [get_ports o_led[6]]
|
||||
#set_property -dict {PACKAGE_PIN G24 IOSTANDARD LVCMOS18} [get_ports o_led[7]]
|
||||
## }}}
|
||||
|
||||
## FAN control
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN B19 IOSTANDARD LVCMOS33} [get_ports i_fan_tach]
|
||||
#set_property -dict {PACKAGE_PIN C17 IOSTANDARD LVCMOS33} [get_ports o_fan_pwm]
|
||||
#set_property -dict {PACKAGE_PIN C19 IOSTANDARD LVCMOS33} [get_ports o_fan_sys]
|
||||
## }}}
|
||||
|
||||
## External resets
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN A18 IOSTANDARD LVCMOS33} [get_ports i_pi_reset_n]
|
||||
#set_property -dict {PACKAGE_PIN A20 IOSTANDARD LVCMOS18} [get_ports i_soft_reset]
|
||||
## }}}
|
||||
|
||||
## I2C
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN W21 IOSTANDARD LVCMOS18} [get_ports o_i2c_mxrst_n]
|
||||
#set_property -dict {PACKAGE_PIN V21 IOSTANDARD LVCMOS18} [get_ports io_i2c_scl]
|
||||
#set_property -dict {PACKAGE_PIN AE22 IOSTANDARD LVCMOS18} [get_ports io_i2c_sda]
|
||||
#set_property -dict {PACKAGE_PIN AE26 IOSTANDARD LVCMOS18} [get_ports io_temp_scl]
|
||||
#set_property -dict {PACKAGE_PIN AD26 IOSTANDARD LVCMOS18} [get_ports io_temp_sda]
|
||||
#set_property -dict {PACKAGE_PIN V24 IOSTANDARD LVCMOS18} [get_ports i_si5324_int]
|
||||
#set_property -dict {PACKAGE_PIN V22 IOSTANDARD LVCMOS18} [get_ports o_si5324_rst]
|
||||
## }}}
|
||||
|
||||
## ETH10G
|
||||
## {{{
|
||||
## LOS
|
||||
#set_property -dict {PACKAGE_PIN T19 IOSTANDARD LVCMOS33} [get_ports i_gnet_los[0]]
|
||||
#set_property -dict {PACKAGE_PIN M19 IOSTANDARD LVCMOS33} [get_ports i_gnet_los[1]]
|
||||
#set_property -dict {PACKAGE_PIN R17 IOSTANDARD LVCMOS33} [get_ports i_gnet_los[2]]
|
||||
#set_property -dict {PACKAGE_PIN R16 IOSTANDARD LVCMOS33} [get_ports i_gnet_los[3]]
|
||||
|
||||
## TX Disable
|
||||
#set_property -dict {PACKAGE_PIN R18 IOSTANDARD LVCMOS33} [get_ports o_gnettx_disable[0]]
|
||||
#set_property -dict {PACKAGE_PIN N18 IOSTANDARD LVCMOS33} [get_ports o_gnettx_disable[1]]
|
||||
#set_property -dict {PACKAGE_PIN N17 IOSTANDARD LVCMOS33} [get_ports o_gnettx_disable[2]]
|
||||
#set_property -dict {PACKAGE_PIN P16 IOSTANDARD LVCMOS33} [get_ports o_gnettx_disable[3]]
|
||||
|
||||
## LinkUp LEDs
|
||||
#set_property -dict {PACKAGE_PIN T24 IOSTANDARD LVCMOS33} [get_ports o_gnet_linkup[0]]
|
||||
#set_property -dict {PACKAGE_PIN T22 IOSTANDARD LVCMOS33} [get_ports o_gnet_linkup[1]]
|
||||
#set_property -dict {PACKAGE_PIN N22 IOSTANDARD LVCMOS33} [get_ports o_gnet_linkup[2]]
|
||||
#set_property -dict {PACKAGE_PIN R20 IOSTANDARD LVCMOS33} [get_ports o_gnet_linkup[3]]
|
||||
|
||||
## Activity LEDs
|
||||
#set_property -dict {PACKAGE_PIN T25 IOSTANDARD LVCMOS33} [get_ports o_gnet_activity[0]]
|
||||
#set_property -dict {PACKAGE_PIN R23 IOSTANDARD LVCMOS33} [get_ports o_gnet_activity[1]]
|
||||
#set_property -dict {PACKAGE_PIN N21 IOSTANDARD LVCMOS33} [get_ports o_gnet_activity[2]]
|
||||
#set_property -dict {PACKAGE_PIN R22 IOSTANDARD LVCMOS33} [get_ports o_gnet_activity[3]]
|
||||
|
||||
## Network transmit/outputs
|
||||
#set_property -dict {PACKAGE_PIN P2} [get_ports o_gnet_p[0]]
|
||||
#set_property -dict {PACKAGE_PIN P1} [get_ports o_gnet_n[0]]
|
||||
#set_property -dict {PACKAGE_PIN M2} [get_ports o_gnet_p[1]]
|
||||
#set_property -dict {PACKAGE_PIN M1} [get_ports o_gnet_n[1]]
|
||||
#set_property -dict {PACKAGE_PIN K2} [get_ports o_gnet_p[2]]
|
||||
#set_property -dict {PACKAGE_PIN K1} [get_ports o_gnet_n[2]]
|
||||
#set_property -dict {PACKAGE_PIN H2} [get_ports o_gnet_p[3]]
|
||||
#set_property -dict {PACKAGE_PIN H1} [get_ports o_gnet_n[3]]
|
||||
|
||||
## Network receive/input
|
||||
#set_property -dict {PACKAGE_PIN R4} [get_ports i_gnet_p[0]]
|
||||
#set_property -dict {PACKAGE_PIN R3} [get_ports i_gnet_n[0]]
|
||||
#set_property -dict {PACKAGE_PIN N4} [get_ports i_gnet_p[1]]
|
||||
#set_property -dict {PACKAGE_PIN N3} [get_ports i_gnet_n[1]]
|
||||
#set_property -dict {PACKAGE_PIN L4} [get_ports i_gnet_p[2]]
|
||||
#set_property -dict {PACKAGE_PIN L3} [get_ports i_gnet_n[2]]
|
||||
#set_property -dict {PACKAGE_PIN J4} [get_ports i_gnet_p[3]]
|
||||
#set_property -dict {PACKAGE_PIN J3} [get_ports i_gnet_n[3]]
|
||||
|
||||
## }}}
|
||||
|
||||
## SMI
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN AC24 IOSTANDARD LVCMOS18} [get_ports i_smi_oen]
|
||||
#set_property -dict {PACKAGE_PIN W23 IOSTANDARD LVCMOS18} [get_ports i_smi_wen]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN AB26 IOSTANDARD LVCMOS18} [get_ports i_smi_sa[0]]
|
||||
#set_property -dict {PACKAGE_PIN V26 IOSTANDARD LVCMOS18} [get_ports i_smi_sa[1]]
|
||||
#set_property -dict {PACKAGE_PIN U24 IOSTANDARD LVCMOS18} [get_ports i_smi_sa[2]]
|
||||
#set_property -dict {PACKAGE_PIN U26 IOSTANDARD LVCMOS18} [get_ports i_smi_sa[3]]
|
||||
#set_property -dict {PACKAGE_PIN AB25 IOSTANDARD LVCMOS18} [get_ports i_smi_sa[4]]
|
||||
#set_property -dict {PACKAGE_PIN V23 IOSTANDARD LVCMOS18} [get_ports i_smi_sa[5]]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN W24 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[0]]
|
||||
#set_property -dict {PACKAGE_PIN Y26 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[1]]
|
||||
#set_property -dict {PACKAGE_PIN Y25 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[2]]
|
||||
#set_property -dict {PACKAGE_PIN AA25 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[3]]
|
||||
#set_property -dict {PACKAGE_PIN U22 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[4]]
|
||||
#set_property -dict {PACKAGE_PIN AC26 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[5]]
|
||||
#set_property -dict {PACKAGE_PIN U25 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[6]]
|
||||
#set_property -dict {PACKAGE_PIN AB24 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[7]]
|
||||
#set_property -dict {PACKAGE_PIN Y22 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[8]]
|
||||
#set_property -dict {PACKAGE_PIN W25 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[9]]
|
||||
#set_property -dict {PACKAGE_PIN Y23 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[10]]
|
||||
#set_property -dict {PACKAGE_PIN AC23 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[11]]
|
||||
#set_property -dict {PACKAGE_PIN Y21 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[12]]
|
||||
#set_property -dict {PACKAGE_PIN W20 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[13]]
|
||||
#set_property -dict {PACKAGE_PIN W26 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[14]]
|
||||
#set_property -dict {PACKAGE_PIN AA23 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[15]]
|
||||
#set_property -dict {PACKAGE_PIN AA24 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[16]]
|
||||
#set_property -dict {PACKAGE_PIN AA22 IOSTANDARD LVCMOS18} [get_ports io_smi_sd[17]]
|
||||
## }}}
|
||||
|
||||
## uSD
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN AC22 IOSTANDARD LVCMOS18} [get_ports i_sdcard_cd_n]
|
||||
#set_property -dict {PACKAGE_PIN AD21 IOSTANDARD LVCMOS18} [get_ports o_sdcard_clk]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN AB22 IOSTANDARD LVCMOS18} [get_ports io_sdcard_cmd]
|
||||
#set_property -dict {PACKAGE_PIN AD24 IOSTANDARD LVCMOS18} [get_ports io_sdcard_dat[0]]
|
||||
#set_property -dict {PACKAGE_PIN AC21 IOSTANDARD LVCMOS18} [get_ports io_sdcard_dat[1]]
|
||||
#set_property -dict {PACKAGE_PIN AD23 IOSTANDARD LVCMOS18} [get_ports io_sdcard_dat[2]]
|
||||
#set_property -dict {PACKAGE_PIN AB21 IOSTANDARD LVCMOS18} [get_ports io_sdcard_dat[3]]
|
||||
## }}}
|
||||
|
||||
## Flash
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN C22 IOSTANDARD LVCMOS18} [get_ports o_flash_sel]
|
||||
## The flash clock pin is CCLK_0
|
||||
#set_property -dict {PACKAGE_PIN C23 IOSTANDARD LVCMOS18} [get_ports o_flash_cs_n]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN B24 IOSTANDARD LVCMOS18} [get_ports io_flash_dat[0]]
|
||||
#set_property -dict {PACKAGE_PIN A25 IOSTANDARD LVCMOS18} [get_ports io_flash_dat[1]]
|
||||
#set_property -dict {PACKAGE_PIN B22 IOSTANDARD LVCMOS18} [get_ports io_flash_dat[2]]
|
||||
#set_property -dict {PACKAGE_PIN A22 IOSTANDARD LVCMOS18} [get_ports io_flash_dat[3]]
|
||||
## }}}
|
||||
|
||||
## eMMC
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN C23 IOSTANDARD LVCMOS18} [get_ports o_emmc_clk]
|
||||
#set_property -dict {PACKAGE_PIN C23 IOSTANDARD LVCMOS18} [get_ports io_emmc_cmd]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN B24 IOSTANDARD LVCMOS18} [get_ports io_emmc_dat[0]]
|
||||
#set_property -dict {PACKAGE_PIN A25 IOSTANDARD LVCMOS18} [get_ports io_emmc_dat[1]]
|
||||
#set_property -dict {PACKAGE_PIN B22 IOSTANDARD LVCMOS18} [get_ports io_emmc_dat[2]]
|
||||
#set_property -dict {PACKAGE_PIN A22 IOSTANDARD LVCMOS18} [get_ports io_emmc_dat[3]]
|
||||
#set_property -dict {PACKAGE_PIN A23 IOSTANDARD LVCMOS18} [get_ports io_emmc_dat[4]]
|
||||
#set_property -dict {PACKAGE_PIN A24 IOSTANDARD LVCMOS18} [get_ports io_emmc_dat[5]]
|
||||
#set_property -dict {PACKAGE_PIN D26 IOSTANDARD LVCMOS18} [get_ports io_emmc_dat[6]]
|
||||
#set_property -dict {PACKAGE_PIN C26 IOSTANDARD LVCMOS18} [get_ports io_emmc_dat[7]]
|
||||
#set_property -dict {PACKAGE_PIN D21 IOSTANDARD LVCMOS18} [get_ports i_emmc_ds]
|
||||
## }}}
|
||||
|
||||
## SATA
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN B2} [get_ports o_sata_p]
|
||||
#set_property -dict {PACKAGE_PIN B1} [get_ports o_sata_n]
|
||||
#set_property -dict {PACKAGE_PIN C4} [get_ports i_sata_p]
|
||||
#set_property -dict {PACKAGE_PIN C3} [get_ports i_sata_n]
|
||||
## }}}
|
||||
|
||||
## DDR3
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN V11 IOSTANDARD LVCMOS15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_reset_n]
|
||||
#set_property -dict {PACKAGE_PIN AB11 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_clk_p]
|
||||
#set_property -dict {PACKAGE_PIN AC11 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_clk_n]
|
||||
#set_property -dict {PACKAGE_PIN AA9 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_clk_p_1]
|
||||
#set_property -dict {PACKAGE_PIN AB9 IOSTANDARD DIFF_SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_clk_n_1]
|
||||
#set_property -dict {PACKAGE_PIN Y10 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_cke[0]]
|
||||
#set_property -dict {PACKAGE_PIN W9 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_cke[1]]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN AA10 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_ras_n]
|
||||
#set_property -dict {PACKAGE_PIN AA7 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_cas_n]
|
||||
#set_property -dict {PACKAGE_PIN Y7 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_we_n]
|
||||
#set_property -dict {PACKAGE_PIN Y8 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_s_n[0]]
|
||||
#set_property -dict {PACKAGE_PIN V7 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_s_n[1]]
|
||||
#set_property -dict {PACKAGE_PIN AA8 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_odt[0]]
|
||||
#set_property -dict {PACKAGE_PIN V9 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_odt[1]]
|
||||
#set_property -dict {PACKAGE_PIN W10 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports i_ddr3_event]
|
||||
|
||||
### Address lines
|
||||
### {{{
|
||||
#set_property -dict {PACKAGE_PIN AC7 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_ba[0]]
|
||||
#set_property -dict {PACKAGE_PIN V8 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_ba[1]]
|
||||
#set_property -dict {PACKAGE_PIN AC13 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_ba[2]]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN AF7 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[0]]
|
||||
#set_property -dict {PACKAGE_PIN AD8 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[1]]
|
||||
#set_property -dict {PACKAGE_PIN AB10 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[2]]
|
||||
#set_property -dict {PACKAGE_PIN AC8 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[3]]
|
||||
#set_property -dict {PACKAGE_PIN W11 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[4]]
|
||||
#set_property -dict {PACKAGE_PIN AA12 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[5]]
|
||||
#set_property -dict {PACKAGE_PIN AC12 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[6]]
|
||||
#set_property -dict {PACKAGE_PIN AD13 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[7]]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN AB12 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[8]]
|
||||
#set_property -dict {PACKAGE_PIN AD11 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[9]]
|
||||
#set_property -dict {PACKAGE_PIN AE7 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[10]]
|
||||
#set_property -dict {PACKAGE_PIN Y11 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[11]]
|
||||
#set_property -dict {PACKAGE_PIN AA13 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[12]]
|
||||
#set_property -dict {PACKAGE_PIN AB7 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[13]]
|
||||
#set_property -dict {PACKAGE_PIN Y13 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[14]]
|
||||
#set_property -dict {PACKAGE_PIN Y12 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_a[15]]
|
||||
### }}}
|
||||
|
||||
### Byte lane #0
|
||||
### {{{
|
||||
#set_property -dict {PACKAGE_PIN AB17 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[0]]
|
||||
#set_property -dict {PACKAGE_PIN AC18 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[1]]
|
||||
#set_property -dict {PACKAGE_PIN AC17 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[2]]
|
||||
#set_property -dict {PACKAGE_PIN AD19 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[3]]
|
||||
#set_property -dict {PACKAGE_PIN AA19 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[4]]
|
||||
#set_property -dict {PACKAGE_PIN AA20 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[5]]
|
||||
#set_property -dict {PACKAGE_PIN AD18 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[6]]
|
||||
#set_property -dict {PACKAGE_PIN AC16 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[7]]
|
||||
#set_property -dict {PACKAGE_PIN AD20 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_p[0]]
|
||||
#set_property -dict {PACKAGE_PIN AE20 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_n[0]]
|
||||
#set_property -dict {PACKAGE_PIN AC19 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_dm[0]]
|
||||
### }}}
|
||||
|
||||
### Byte lane #1
|
||||
### {{{
|
||||
#set_property -dict {PACKAGE_PIN V16 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[8]]
|
||||
#set_property -dict {PACKAGE_PIN V18 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[9]]
|
||||
#set_property -dict {PACKAGE_PIN AB20 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[10]]
|
||||
#set_property -dict {PACKAGE_PIN AB19 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[11]]
|
||||
#set_property -dict {PACKAGE_PIN W15 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[12]]
|
||||
#set_property -dict {PACKAGE_PIN V19 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[13]]
|
||||
#set_property -dict {PACKAGE_PIN W16 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[14]]
|
||||
#set_property -dict {PACKAGE_PIN Y17 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[15]]
|
||||
#set_property -dict {PACKAGE_PIN W18 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_p[1]]
|
||||
#set_property -dict {PACKAGE_PIN W19 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_n[1]]
|
||||
#set_property -dict {PACKAGE_PIN V17 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_dm[1]]
|
||||
### }}}
|
||||
|
||||
### Byte lane #2
|
||||
### {{{
|
||||
#set_property -dict {PACKAGE_PIN AF19 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[16]]
|
||||
#set_property -dict {PACKAGE_PIN AE17 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[17]]
|
||||
#set_property -dict {PACKAGE_PIN AE15 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[18]]
|
||||
#set_property -dict {PACKAGE_PIN AF15 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[19]]
|
||||
#set_property -dict {PACKAGE_PIN AF20 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[20]]
|
||||
#set_property -dict {PACKAGE_PIN AD16 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[21]]
|
||||
#set_property -dict {PACKAGE_PIN AD15 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[22]]
|
||||
#set_property -dict {PACKAGE_PIN AF14 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[23]]
|
||||
#set_property -dict {PACKAGE_PIN AE18 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_p[2]]
|
||||
#set_property -dict {PACKAGE_PIN AF18 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_n[2]]
|
||||
#set_property -dict {PACKAGE_PIN AF17 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_dm[2]]
|
||||
### }}}
|
||||
|
||||
### Byte lane #3
|
||||
### {{{
|
||||
#set_property -dict {PACKAGE_PIN AA15 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[24]]
|
||||
#set_property -dict {PACKAGE_PIN AB16 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[25]]
|
||||
#set_property -dict {PACKAGE_PIN AD14 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[26]]
|
||||
#set_property -dict {PACKAGE_PIN AB14 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[27]]
|
||||
#set_property -dict {PACKAGE_PIN AA18 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[28]]
|
||||
#set_property -dict {PACKAGE_PIN AA17 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[29]]
|
||||
#set_property -dict {PACKAGE_PIN AB15 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[30]]
|
||||
#set_property -dict {PACKAGE_PIN AC14 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[31]]
|
||||
#set_property -dict {PACKAGE_PIN Y15 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_p[3]]
|
||||
#set_property -dict {PACKAGE_PIN Y16 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_n[3]]
|
||||
#set_property -dict {PACKAGE_PIN AA14 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_dm[3]]
|
||||
### }}}
|
||||
|
||||
### Byte lane #4
|
||||
### {{{
|
||||
#set_property -dict {PACKAGE_PIN AD6 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[32]]
|
||||
#set_property -dict {PACKAGE_PIN AC6 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[33]]
|
||||
#set_property -dict {PACKAGE_PIN AC3 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[34]]
|
||||
#set_property -dict {PACKAGE_PIN AB4 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[35]]
|
||||
#set_property -dict {PACKAGE_PIN AB6 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[36]]
|
||||
#set_property -dict {PACKAGE_PIN Y6 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[37]]
|
||||
#set_property -dict {PACKAGE_PIN Y5 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[38]]
|
||||
#set_property -dict {PACKAGE_PIN AA4 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[39]]
|
||||
#set_property -dict {PACKAGE_PIN AA5 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_p[4]]
|
||||
#set_property -dict {PACKAGE_PIN AB5 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_n[4]]
|
||||
#set_property -dict {PACKAGE_PIN AC4 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_dm[4]]
|
||||
### }}}
|
||||
|
||||
### Byte lane #5
|
||||
### {{{
|
||||
#set_property -dict {PACKAGE_PIN AF3 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[40]]
|
||||
#set_property -dict {PACKAGE_PIN AE3 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[41]]
|
||||
#set_property -dict {PACKAGE_PIN AE2 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[42]]
|
||||
#set_property -dict {PACKAGE_PIN AE1 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[43]]
|
||||
#set_property -dict {PACKAGE_PIN AE6 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[44]]
|
||||
#set_property -dict {PACKAGE_PIN AE5 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[45]]
|
||||
#set_property -dict {PACKAGE_PIN AD4 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[46]]
|
||||
#set_property -dict {PACKAGE_PIN AD1 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[47]]
|
||||
#set_property -dict {PACKAGE_PIN AF5 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_p[5]]
|
||||
#set_property -dict {PACKAGE_PIN AF4 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_n[5]]
|
||||
#set_property -dict {PACKAGE_PIN AF2 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_dm[5]]
|
||||
### }}}
|
||||
|
||||
### Byte lane #6
|
||||
### {{{
|
||||
#set_property -dict {PACKAGE_PIN W3 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[48]]
|
||||
#set_property -dict {PACKAGE_PIN V4 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[49]]
|
||||
#set_property -dict {PACKAGE_PIN U2 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[50]]
|
||||
#set_property -dict {PACKAGE_PIN U5 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[51]]
|
||||
#set_property -dict {PACKAGE_PIN V6 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[52]]
|
||||
#set_property -dict {PACKAGE_PIN V3 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[53]]
|
||||
#set_property -dict {PACKAGE_PIN U1 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[54]]
|
||||
#set_property -dict {PACKAGE_PIN U6 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[55]]
|
||||
#set_property -dict {PACKAGE_PIN W6 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_p[6]]
|
||||
#set_property -dict {PACKAGE_PIN W5 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_n[6]]
|
||||
#set_property -dict {PACKAGE_PIN U7 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_dm[6]]
|
||||
### }}}
|
||||
|
||||
### Byte lane #7
|
||||
### {{{
|
||||
#set_property -dict {PACKAGE_PIN AB2 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[56]]
|
||||
#set_property -dict {PACKAGE_PIN AA3 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[57]]
|
||||
#set_property -dict {PACKAGE_PIN W1 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[58]]
|
||||
#set_property -dict {PACKAGE_PIN V2 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[59]]
|
||||
#set_property -dict {PACKAGE_PIN AC2 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[60]]
|
||||
#set_property -dict {PACKAGE_PIN Y3 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[61]]
|
||||
#set_property -dict {PACKAGE_PIN Y2 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[62]]
|
||||
#set_property -dict {PACKAGE_PIN V1 IOSTANDARD SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dq[63]]
|
||||
#set_property -dict {PACKAGE_PIN AB1 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_p[7]]
|
||||
#set_property -dict {PACKAGE_PIN AC1 IOSTANDARD DIFF_SSTL15_T_DCI SLEW FAST VCCAUX_IO HIGH} [get_ports io_ddr3_dqs_n[7]]
|
||||
#set_property -dict {PACKAGE_PIN Y1 IOSTANDARD SSTL15 SLEW FAST VCCAUX_IO HIGH} [get_ports o_ddr3_dm[7]]
|
||||
### }}}
|
||||
|
||||
## }}}
|
||||
|
||||
## HDMI
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN N23 IOSTANDARD LVCMOS33} [get_ports io_hdmirx_cec]
|
||||
#set_property -dict {PACKAGE_PIN M22 IOSTANDARD LVCMOS33} [get_ports o_hdmirx_hpd_n]
|
||||
#set_property -dict {PACKAGE_PIN P23 IOSTANDARD LVCMOS33} [get_ports io_hdmirx_scl]
|
||||
#set_property -dict {PACKAGE_PIN M21 IOSTANDARD LVCMOS33} [get_ports io_hdmirx_sda]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN P24 IOSTANDARD TMDS_33} [get_ports i_hdmirx_p[0]]
|
||||
#set_property -dict {PACKAGE_PIN N24 IOSTANDARD TMDS_33} [get_ports i_hdmirx_n[0]]
|
||||
#set_property -dict {PACKAGE_PIN R26 IOSTANDARD TMDS_33} [get_ports i_hdmirx_p[1]]
|
||||
#set_property -dict {PACKAGE_PIN P26 IOSTANDARD TMDS_33} [get_ports i_hdmirx_n[1]]
|
||||
#set_property -dict {PACKAGE_PIN R25 IOSTANDARD TMDS_33} [get_ports i_hdmirx_p[2]]
|
||||
#set_property -dict {PACKAGE_PIN P25 IOSTANDARD TMDS_33} [get_ports i_hdmirx_n[2]]
|
||||
#set_property -dict {PACKAGE_PIN M24 IOSTANDARD TMDS_33} [get_ports i_hdmirx_clk_p]
|
||||
#set_property -dict {PACKAGE_PIN L24 IOSTANDARD TMDS_33} [get_ports i_hdmirx_clk_n]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN N26 IOSTANDARD LVCMOS33} [get_ports io_hdmitx_cec]
|
||||
#set_property -dict {PACKAGE_PIN M26 IOSTANDARD LVCMOS33} [get_ports i_hdmitx_hpd_n]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN P19 IOSTANDARD TMDS_33} [get_ports o_hdmitx_p[0]]
|
||||
#set_property -dict {PACKAGE_PIN P20 IOSTANDARD TMDS_33} [get_ports o_hdmitx_n[0]]
|
||||
#set_property -dict {PACKAGE_PIN K25 IOSTANDARD TMDS_33} [get_ports o_hdmitx_p[1]]
|
||||
#set_property -dict {PACKAGE_PIN K26 IOSTANDARD TMDS_33} [get_ports o_hdmitx_n[1]]
|
||||
#set_property -dict {PACKAGE_PIN M25 IOSTANDARD TMDS_33} [get_ports o_hdmitx_p[2]]
|
||||
#set_property -dict {PACKAGE_PIN L25 IOSTANDARD TMDS_33} [get_ports o_hdmitx_n[2]]
|
||||
#set_property -dict {PACKAGE_PIN N19 IOSTANDARD TMDS_33} [get_ports o_hdmitx_clk_p]
|
||||
#set_property -dict {PACKAGE_PIN M20 IOSTANDARD TMDS_33} [get_ports o_hdmitx_clk_n]
|
||||
## }}}
|
||||
|
||||
## PCIe
|
||||
## {{{
|
||||
#set_property -dict { PACKAGE_PIN D6 IOSTANDARD DIFF_HSTL_I_10 } [get_ports o_pcie_clk_p]
|
||||
#set_property -dict { PACKAGE_PIN D5 IOSTANDARD DIFF_HSTL_I_10 } [get_ports o_pcie_clk_n]
|
||||
#set_property -dict { PACKAGE_PIN B16 IOSTANDARD DIFF_HSTL_I_10 } [get_ports o_pcie_perst_n]
|
||||
|
||||
#set_property -dict {PACKAGE_PIN A4 IOSTANDARD DIFF_HSTL_I_10 [get_ports o_pcie_p]
|
||||
#set_property -dict {PACKAGE_PIN A3 IOSTANDARD DIFF_HSTL_I_10 [get_ports o_pcie_n]
|
||||
#set_property -dict {PACKAGE_PIN B6 IOSTANDARD DIFF_HSTL_I_10 [get_ports i_pcie_p]
|
||||
#set_property -dict {PACKAGE_PIN B5 IOSTANDARD DIFF_HSTL_I_10 [get_ports i_pcie_n]
|
||||
## }}}
|
||||
|
||||
## CRUVI
|
||||
## {{{
|
||||
## }}}
|
||||
|
||||
## Hard test points
|
||||
## {{{
|
||||
#set_property -dict {PACKAGE_PIN M17 IOSTANDARD LVCMOS33} [get_ports o_tp[0]]
|
||||
#set_property -dict {PACKAGE_PIN L18 IOSTANDARD LVCMOS33} [get_ports o_tp[1]]
|
||||
#set_property -dict {PACKAGE_PIN L17 IOSTANDARD LVCMOS33} [get_ports o_tp[2]]
|
||||
#set_property -dict {PACKAGE_PIN K18 IOSTANDARD LVCMOS33} [get_ports o_tp[3]]
|
||||
## }}}
|
||||
|
||||
## Bitstream options
|
||||
set_property CONFIG_MODE SPIx4 [current_design]
|
||||
set_property BITSTREAM.CONFIG.CONFIGRATE 26 [current_design]
|
||||
set_property CONFIG_VOLTAGE 2.5 [current_design]
|
||||
set_property CFGBVS VCCO [current_design]
|
||||
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
|
||||
|
||||
set_property INTERNAL_VREF 0.750 [get_iobanks 32]
|
||||
set_property INTERNAL_VREF 0.750 [get_iobanks 33]
|
||||
set_property INTERNAL_VREF 0.750 [get_iobanks 34]
|
||||
set_property BITSTREAM.CONFIG.UNUSEDPIN PULLNONE [current_design]
|
||||
set_property BITSTREAM.STARTUP.MATCH_CYCLE 6 [current_design]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,70 +1,70 @@
|
|||
PROJECT = nexysvideo_ddr3
|
||||
FAMILY = artix7
|
||||
PART = xc7a200tsbg484-1
|
||||
CHIPDB = ${ARTIX7_CHIPDB}
|
||||
ADDITIONAL_SOURCES = ../../rtl/ddr3_controller.v ../../rtl/ddr3_phy.v ../../rtl/ddr3_top.v uart_rx.v uart_tx.v clk_wiz.v
|
||||
|
||||
#############################################################################################
|
||||
NEXTPNR_XILINX_DIR ?= /snap/openxc7/current/opt/nextpnr-xilinx
|
||||
NEXTPNR_XILINX_PYTHON_DIR ?= ${NEXTPNR_XILINX_DIR}/python
|
||||
PRJXRAY_DB_DIR ?= ${NEXTPNR_XILINX_DIR}/external/prjxray-db
|
||||
|
||||
DBPART = $(shell echo ${PART} | sed -e 's/-[0-9]//g')
|
||||
SPEEDGRADE = $(shell echo ${PART} | sed -e 's/.*\-\([0-9]\)/\1/g')
|
||||
|
||||
CHIPDB ?= ./
|
||||
ifeq ($(CHIPDB),)
|
||||
CHIPDB = ./
|
||||
endif
|
||||
|
||||
PYPY3 ?= pypy3
|
||||
|
||||
TOP ?= ${PROJECT}
|
||||
TOP_MODULE ?= ${TOP}
|
||||
TOP_VERILOG ?= ${TOP}.v
|
||||
|
||||
PNR_DEBUG ?= # --verbose --debug
|
||||
|
||||
BOARD ?= UNKNOWN
|
||||
JTAG_LINK ?= --board ${BOARD}
|
||||
|
||||
XDC ?= ${PROJECT}.xdc
|
||||
|
||||
.PHONY: all
|
||||
all: ${PROJECT}.bit
|
||||
|
||||
.PHONY: program
|
||||
program: ${PROJECT}.bit
|
||||
openFPGALoader ${JTAG_LINK} --bitstream $<
|
||||
|
||||
${PROJECT}.json: ${TOP_VERILOG} ${ADDITIONAL_SOURCES}
|
||||
yosys -p "synth_xilinx -flatten -abc9 ${SYNTH_OPTS} -arch xc7 -top ${TOP_MODULE}; write_json ${PROJECT}.json" $< ${ADDITIONAL_SOURCES}
|
||||
|
||||
# The chip database only needs to be generated once
|
||||
# that is why we don't clean it with make clean
|
||||
${CHIPDB}/${DBPART}.bin:
|
||||
${PYPY3} ${NEXTPNR_XILINX_PYTHON_DIR}/bbaexport.py --device ${PART} --bba ${DBPART}.bba
|
||||
bbasm -l ${DBPART}.bba ${CHIPDB}/${DBPART}.bin
|
||||
rm -f ${DBPART}.bba
|
||||
|
||||
${PROJECT}.fasm: ${PROJECT}.json ${CHIPDB}/${DBPART}.bin ${XDC}
|
||||
nextpnr-xilinx --chipdb ${CHIPDB}/${DBPART}.bin --xdc ${XDC} --json ${PROJECT}.json --fasm $@ ${PNR_ARGS} ${PNR_DEBUG}
|
||||
|
||||
${PROJECT}.frames: ${PROJECT}.fasm
|
||||
fasm2frames --part ${PART} --db-root ${PRJXRAY_DB_DIR}/${FAMILY} $< > $@
|
||||
|
||||
${PROJECT}.bit: ${PROJECT}.frames
|
||||
xc7frames2bit --part_file ${PRJXRAY_DB_DIR}/${FAMILY}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -f *.bit
|
||||
@rm -f *.frames
|
||||
@rm -f *.fasm
|
||||
@rm -f *.json
|
||||
@rm -f *.bin
|
||||
@rm -f *.bba
|
||||
|
||||
.PHONY: pnrclean
|
||||
pnrclean:
|
||||
PROJECT = nexysvideo_ddr3
|
||||
FAMILY = artix7
|
||||
PART = xc7a200tsbg484-1
|
||||
CHIPDB = ${ARTIX7_CHIPDB}
|
||||
ADDITIONAL_SOURCES = ../../rtl/ddr3_controller.v ../../rtl/ddr3_phy.v ../../rtl/ddr3_top.v uart_rx.v uart_tx.v clk_wiz.v
|
||||
|
||||
#############################################################################################
|
||||
NEXTPNR_XILINX_DIR ?= /snap/openxc7/current/opt/nextpnr-xilinx
|
||||
NEXTPNR_XILINX_PYTHON_DIR ?= ${NEXTPNR_XILINX_DIR}/python
|
||||
PRJXRAY_DB_DIR ?= ${NEXTPNR_XILINX_DIR}/external/prjxray-db
|
||||
|
||||
DBPART = $(shell echo ${PART} | sed -e 's/-[0-9]//g')
|
||||
SPEEDGRADE = $(shell echo ${PART} | sed -e 's/.*\-\([0-9]\)/\1/g')
|
||||
|
||||
CHIPDB ?= ./
|
||||
ifeq ($(CHIPDB),)
|
||||
CHIPDB = ./
|
||||
endif
|
||||
|
||||
PYPY3 ?= pypy3
|
||||
|
||||
TOP ?= ${PROJECT}
|
||||
TOP_MODULE ?= ${TOP}
|
||||
TOP_VERILOG ?= ${TOP}.v
|
||||
|
||||
PNR_DEBUG ?= # --verbose --debug
|
||||
|
||||
BOARD ?= UNKNOWN
|
||||
JTAG_LINK ?= --board ${BOARD}
|
||||
|
||||
XDC ?= ${PROJECT}.xdc
|
||||
|
||||
.PHONY: all
|
||||
all: ${PROJECT}.bit
|
||||
|
||||
.PHONY: program
|
||||
program: ${PROJECT}.bit
|
||||
openFPGALoader ${JTAG_LINK} --bitstream $<
|
||||
|
||||
${PROJECT}.json: ${TOP_VERILOG} ${ADDITIONAL_SOURCES}
|
||||
yosys -p "synth_xilinx -flatten -abc9 ${SYNTH_OPTS} -arch xc7 -top ${TOP_MODULE}; write_json ${PROJECT}.json" $< ${ADDITIONAL_SOURCES}
|
||||
|
||||
# The chip database only needs to be generated once
|
||||
# that is why we don't clean it with make clean
|
||||
${CHIPDB}/${DBPART}.bin:
|
||||
${PYPY3} ${NEXTPNR_XILINX_PYTHON_DIR}/bbaexport.py --device ${PART} --bba ${DBPART}.bba
|
||||
bbasm -l ${DBPART}.bba ${CHIPDB}/${DBPART}.bin
|
||||
rm -f ${DBPART}.bba
|
||||
|
||||
${PROJECT}.fasm: ${PROJECT}.json ${CHIPDB}/${DBPART}.bin ${XDC}
|
||||
nextpnr-xilinx --chipdb ${CHIPDB}/${DBPART}.bin --xdc ${XDC} --json ${PROJECT}.json --fasm $@ ${PNR_ARGS} ${PNR_DEBUG}
|
||||
|
||||
${PROJECT}.frames: ${PROJECT}.fasm
|
||||
fasm2frames --part ${PART} --db-root ${PRJXRAY_DB_DIR}/${FAMILY} $< > $@
|
||||
|
||||
${PROJECT}.bit: ${PROJECT}.frames
|
||||
xc7frames2bit --part_file ${PRJXRAY_DB_DIR}/${FAMILY}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -f *.bit
|
||||
@rm -f *.frames
|
||||
@rm -f *.fasm
|
||||
@rm -f *.json
|
||||
@rm -f *.bin
|
||||
@rm -f *.bba
|
||||
|
||||
.PHONY: pnrclean
|
||||
pnrclean:
|
||||
rm *.fasm *.frames *.bit
|
||||
|
|
@ -1,66 +1,66 @@
|
|||
`timescale 1ps/1ps
|
||||
|
||||
module clk_wiz
|
||||
(
|
||||
input clk_in1,
|
||||
output clk_out1,
|
||||
output clk_out2,
|
||||
output clk_out3,
|
||||
output clk_out4,
|
||||
input reset,
|
||||
output locked
|
||||
);
|
||||
wire clk_out1_clk_wiz_0;
|
||||
wire clk_out2_clk_wiz_0;
|
||||
wire clk_out3_clk_wiz_0;
|
||||
wire clk_out4_clk_wiz_0;
|
||||
|
||||
wire clkfbout;
|
||||
|
||||
PLLE2_ADV
|
||||
#(.BANDWIDTH ("OPTIMIZED"),
|
||||
.COMPENSATION ("INTERNAL"),
|
||||
.STARTUP_WAIT ("FALSE"),
|
||||
.DIVCLK_DIVIDE (1),
|
||||
.CLKFBOUT_MULT (10), // 100 MHz * 10 = 1000 MHz
|
||||
.CLKFBOUT_PHASE (0.000),
|
||||
.CLKOUT0_DIVIDE (12), // 1000 MHz / 12 = 83.333 MHz
|
||||
.CLKOUT0_PHASE (0.000),
|
||||
.CLKOUT0_DUTY_CYCLE (0.500),
|
||||
.CLKOUT1_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz
|
||||
.CLKOUT1_PHASE (0.000),
|
||||
.CLKOUT1_DUTY_CYCLE (0.500),
|
||||
.CLKOUT2_DIVIDE (5), // 1000 MHz / 5 = 200 MHz
|
||||
.CLKOUT2_PHASE (0.000),
|
||||
.CLKOUT2_DUTY_CYCLE (0.500),
|
||||
.CLKOUT3_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz, 90 phase
|
||||
.CLKOUT3_PHASE (90.000),
|
||||
.CLKOUT3_DUTY_CYCLE (0.500),
|
||||
.CLKIN1_PERIOD (10.000) // 100 MHz input
|
||||
)
|
||||
plle2_adv_inst
|
||||
(
|
||||
.CLKFBOUT (clkfbout),
|
||||
.CLKOUT0 (clk_out1_clk_wiz_0),
|
||||
.CLKOUT1 (clk_out2_clk_wiz_0),
|
||||
.CLKOUT2 (clk_out3_clk_wiz_0),
|
||||
.CLKOUT3 (clk_out4_clk_wiz_0),
|
||||
.CLKFBIN (clkfbout),
|
||||
.CLKIN1 (clk_in1),
|
||||
.LOCKED (locked),
|
||||
.RST (reset)
|
||||
);
|
||||
BUFG clkout1_buf
|
||||
(.O (clk_out1),
|
||||
.I (clk_out1_clk_wiz_0));
|
||||
BUFG clkout2_buf
|
||||
(.O (clk_out2),
|
||||
.I (clk_out2_clk_wiz_0));
|
||||
BUFG clkout3_buf
|
||||
(.O (clk_out3),
|
||||
.I (clk_out3_clk_wiz_0));
|
||||
BUFG clkout4_buf
|
||||
(.O (clk_out4),
|
||||
.I (clk_out4_clk_wiz_0));
|
||||
|
||||
endmodule
|
||||
`timescale 1ps/1ps
|
||||
|
||||
module clk_wiz
|
||||
(
|
||||
input clk_in1,
|
||||
output clk_out1,
|
||||
output clk_out2,
|
||||
output clk_out3,
|
||||
output clk_out4,
|
||||
input reset,
|
||||
output locked
|
||||
);
|
||||
wire clk_out1_clk_wiz_0;
|
||||
wire clk_out2_clk_wiz_0;
|
||||
wire clk_out3_clk_wiz_0;
|
||||
wire clk_out4_clk_wiz_0;
|
||||
|
||||
wire clkfbout;
|
||||
|
||||
PLLE2_ADV
|
||||
#(.BANDWIDTH ("OPTIMIZED"),
|
||||
.COMPENSATION ("INTERNAL"),
|
||||
.STARTUP_WAIT ("FALSE"),
|
||||
.DIVCLK_DIVIDE (1),
|
||||
.CLKFBOUT_MULT (10), // 100 MHz * 10 = 1000 MHz
|
||||
.CLKFBOUT_PHASE (0.000),
|
||||
.CLKOUT0_DIVIDE (12), // 1000 MHz / 12 = 83.333 MHz
|
||||
.CLKOUT0_PHASE (0.000),
|
||||
.CLKOUT0_DUTY_CYCLE (0.500),
|
||||
.CLKOUT1_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz
|
||||
.CLKOUT1_PHASE (0.000),
|
||||
.CLKOUT1_DUTY_CYCLE (0.500),
|
||||
.CLKOUT2_DIVIDE (5), // 1000 MHz / 5 = 200 MHz
|
||||
.CLKOUT2_PHASE (0.000),
|
||||
.CLKOUT2_DUTY_CYCLE (0.500),
|
||||
.CLKOUT3_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz, 90 phase
|
||||
.CLKOUT3_PHASE (90.000),
|
||||
.CLKOUT3_DUTY_CYCLE (0.500),
|
||||
.CLKIN1_PERIOD (10.000) // 100 MHz input
|
||||
)
|
||||
plle2_adv_inst
|
||||
(
|
||||
.CLKFBOUT (clkfbout),
|
||||
.CLKOUT0 (clk_out1_clk_wiz_0),
|
||||
.CLKOUT1 (clk_out2_clk_wiz_0),
|
||||
.CLKOUT2 (clk_out3_clk_wiz_0),
|
||||
.CLKOUT3 (clk_out4_clk_wiz_0),
|
||||
.CLKFBIN (clkfbout),
|
||||
.CLKIN1 (clk_in1),
|
||||
.LOCKED (locked),
|
||||
.RST (reset)
|
||||
);
|
||||
BUFG clkout1_buf
|
||||
(.O (clk_out1),
|
||||
.I (clk_out1_clk_wiz_0));
|
||||
BUFG clkout2_buf
|
||||
(.O (clk_out2),
|
||||
.I (clk_out2_clk_wiz_0));
|
||||
BUFG clkout3_buf
|
||||
(.O (clk_out3),
|
||||
.I (clk_out3_clk_wiz_0));
|
||||
BUFG clkout4_buf
|
||||
(.O (clk_out4),
|
||||
.I (clk_out4_clk_wiz_0));
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,242 +1,242 @@
|
|||
set_property -dict {PACKAGE_PIN R4 IOSTANDARD LVCMOS33} [get_ports i_clk]
|
||||
create_clock -period 10.000 -name sys_clk_pin -waveform {0.000 5.000} -add [get_ports i_clk]
|
||||
|
||||
set_property -dict {PACKAGE_PIN T14 IOSTANDARD LVCMOS33} [get_ports {led[0]}]
|
||||
set_property -dict {PACKAGE_PIN T15 IOSTANDARD LVCMOS33} [get_ports {led[1]}]
|
||||
set_property -dict {PACKAGE_PIN T16 IOSTANDARD LVCMOS33} [get_ports {led[2]}]
|
||||
set_property -dict {PACKAGE_PIN U16 IOSTANDARD LVCMOS33} [get_ports {led[3]}]
|
||||
set_property -dict {PACKAGE_PIN V15 IOSTANDARD LVCMOS33} [get_ports {led[4]}]
|
||||
set_property -dict {PACKAGE_PIN W16 IOSTANDARD LVCMOS33} [get_ports {led[5]}]
|
||||
set_property -dict {PACKAGE_PIN W15 IOSTANDARD LVCMOS33} [get_ports {led[6]}]
|
||||
set_property -dict {PACKAGE_PIN Y13 IOSTANDARD LVCMOS33} [get_ports {led[7]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN B22 IOSTANDARD LVCMOS33} [get_ports i_rst]
|
||||
set_property -dict {PACKAGE_PIN D22 IOSTANDARD LVCMOS33} [get_ports {btn[0]}]
|
||||
set_property -dict {PACKAGE_PIN C22 IOSTANDARD LVCMOS33} [get_ports {btn[1]}]
|
||||
set_property -dict {PACKAGE_PIN D14 IOSTANDARD LVCMOS33} [get_ports {btn[2]}]
|
||||
set_property -dict {PACKAGE_PIN F15 IOSTANDARD LVCMOS33} [get_ports {btn[3]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AA19 IOSTANDARD LVCMOS33} [get_ports tx]
|
||||
set_property -dict {PACKAGE_PIN V18 IOSTANDARD LVCMOS33} [get_ports rx]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[0]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[0]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[0]}]
|
||||
set_property PACKAGE_PIN G2 [get_ports {ddr3_dq[0]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[1]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[1]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[1]}]
|
||||
set_property PACKAGE_PIN H4 [get_ports {ddr3_dq[1]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[2]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[2]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[2]}]
|
||||
set_property PACKAGE_PIN H5 [get_ports {ddr3_dq[2]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[3]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[3]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[3]}]
|
||||
set_property PACKAGE_PIN J1 [get_ports {ddr3_dq[3]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[4]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[4]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[4]}]
|
||||
set_property PACKAGE_PIN K1 [get_ports {ddr3_dq[4]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[5]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[5]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[5]}]
|
||||
set_property PACKAGE_PIN H3 [get_ports {ddr3_dq[5]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[6]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[6]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[6]}]
|
||||
set_property PACKAGE_PIN H2 [get_ports {ddr3_dq[6]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[7]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[7]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[7]}]
|
||||
set_property PACKAGE_PIN J5 [get_ports {ddr3_dq[7]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[8]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[8]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[8]}]
|
||||
set_property PACKAGE_PIN E3 [get_ports {ddr3_dq[8]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[9]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[9]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[9]}]
|
||||
set_property PACKAGE_PIN B2 [get_ports {ddr3_dq[9]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[10]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[10]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[10]}]
|
||||
set_property PACKAGE_PIN F3 [get_ports {ddr3_dq[10]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[11]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[11]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[11]}]
|
||||
set_property PACKAGE_PIN D2 [get_ports {ddr3_dq[11]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[12]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[12]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[12]}]
|
||||
set_property PACKAGE_PIN C2 [get_ports {ddr3_dq[12]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[13]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[13]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[13]}]
|
||||
set_property PACKAGE_PIN A1 [get_ports {ddr3_dq[13]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[14]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[14]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[14]}]
|
||||
set_property PACKAGE_PIN E2 [get_ports {ddr3_dq[14]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[15]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[15]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[15]}]
|
||||
set_property PACKAGE_PIN B1 [get_ports {ddr3_dq[15]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[14]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[14]}]
|
||||
set_property PACKAGE_PIN P6 [get_ports {ddr3_addr[14]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[13]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[13]}]
|
||||
set_property PACKAGE_PIN P2 [get_ports {ddr3_addr[13]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[12]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[12]}]
|
||||
set_property PACKAGE_PIN N4 [get_ports {ddr3_addr[12]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[11]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[11]}]
|
||||
set_property PACKAGE_PIN N5 [get_ports {ddr3_addr[11]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[10]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[10]}]
|
||||
set_property PACKAGE_PIN L5 [get_ports {ddr3_addr[10]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[9]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[9]}]
|
||||
set_property PACKAGE_PIN R1 [get_ports {ddr3_addr[9]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[8]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[8]}]
|
||||
set_property PACKAGE_PIN M6 [get_ports {ddr3_addr[8]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[7]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[7]}]
|
||||
set_property PACKAGE_PIN N2 [get_ports {ddr3_addr[7]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[6]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[6]}]
|
||||
set_property PACKAGE_PIN N3 [get_ports {ddr3_addr[6]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[5]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[5]}]
|
||||
set_property PACKAGE_PIN P1 [get_ports {ddr3_addr[5]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[4]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[4]}]
|
||||
set_property PACKAGE_PIN L6 [get_ports {ddr3_addr[4]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[3]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[3]}]
|
||||
set_property PACKAGE_PIN M1 [get_ports {ddr3_addr[3]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[2]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[2]}]
|
||||
set_property PACKAGE_PIN M3 [get_ports {ddr3_addr[2]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[1]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[1]}]
|
||||
set_property PACKAGE_PIN M5 [get_ports {ddr3_addr[1]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[0]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[0]}]
|
||||
set_property PACKAGE_PIN M2 [get_ports {ddr3_addr[0]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_ba[2]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_ba[2]}]
|
||||
set_property PACKAGE_PIN L4 [get_ports {ddr3_ba[2]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_ba[1]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_ba[1]}]
|
||||
set_property PACKAGE_PIN K6 [get_ports {ddr3_ba[1]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_ba[0]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_ba[0]}]
|
||||
set_property PACKAGE_PIN L3 [get_ports {ddr3_ba[0]}]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_ras_n]
|
||||
set_property IOSTANDARD SSTL15 [get_ports ddr3_ras_n]
|
||||
set_property PACKAGE_PIN J4 [get_ports ddr3_ras_n]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_cas_n]
|
||||
set_property IOSTANDARD SSTL15 [get_ports ddr3_cas_n]
|
||||
set_property PACKAGE_PIN K3 [get_ports ddr3_cas_n]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_we_n]
|
||||
set_property IOSTANDARD SSTL15 [get_ports ddr3_we_n]
|
||||
set_property PACKAGE_PIN L1 [get_ports ddr3_we_n]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_reset_n]
|
||||
set_property IOSTANDARD SSTL15 [get_ports ddr3_reset_n]
|
||||
set_property PACKAGE_PIN G1 [get_ports ddr3_reset_n]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_cke]
|
||||
set_property IOSTANDARD SSTL15 [get_ports ddr3_cke]
|
||||
set_property PACKAGE_PIN J6 [get_ports ddr3_cke]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_odt]
|
||||
set_property IOSTANDARD SSTL15 [get_ports ddr3_odt]
|
||||
set_property PACKAGE_PIN K4 [get_ports ddr3_odt]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_cs_n]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports ddr3_cs_n]
|
||||
set_property PACKAGE_PIN R3 [get_ports ddr3_cs_n]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dm[0]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dm[0]}]
|
||||
set_property PACKAGE_PIN G3 [get_ports {ddr3_dm[0]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dm[1]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dm[1]}]
|
||||
set_property PACKAGE_PIN F1 [get_ports {ddr3_dm[1]}]
|
||||
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dqs_p}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dqs_p}]
|
||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddr3_dqs_p}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dqs_n}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dqs_n}]
|
||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddr3_dqs_n}]
|
||||
set_property PACKAGE_PIN K2 [get_ports {ddr3_dqs_p}]
|
||||
set_property PACKAGE_PIN J2 [get_ports {ddr3_dqs_n}]
|
||||
|
||||
#set_property SLEW FAST [get_ports {ddr3_dqs_p[1]}]
|
||||
#set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dqs_p[1]}]
|
||||
#set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddr3_dqs_p[1]}]
|
||||
|
||||
#set_property SLEW FAST [get_ports {ddr3_dqs_n[1]}]
|
||||
#set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dqs_n[1]}]
|
||||
#set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddr3_dqs_n[1]}]
|
||||
#set_property PACKAGE_PIN E1 [get_ports {ddr3_dqs_p[1]}]
|
||||
#set_property PACKAGE_PIN D1 [get_ports {ddr3_dqs_n[1]}]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_clk_p]
|
||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports ddr3_clk_p]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_clk_n]
|
||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports ddr3_clk_n]
|
||||
set_property PACKAGE_PIN P5 [get_ports ddr3_clk_p]
|
||||
set_property PACKAGE_PIN P4 [get_ports ddr3_clk_n]
|
||||
|
||||
#set_property INTERNAL_VREF 0.75 [get_iobanks 35]
|
||||
#set_property CONFIG_VOLTAGE 3.3 [current_design]
|
||||
#set_property CFGBVS VCCO [current_design]
|
||||
|
||||
set_property -dict {PACKAGE_PIN R4 IOSTANDARD LVCMOS33} [get_ports i_clk]
|
||||
create_clock -period 10.000 -name sys_clk_pin -waveform {0.000 5.000} -add [get_ports i_clk]
|
||||
|
||||
set_property -dict {PACKAGE_PIN T14 IOSTANDARD LVCMOS33} [get_ports {led[0]}]
|
||||
set_property -dict {PACKAGE_PIN T15 IOSTANDARD LVCMOS33} [get_ports {led[1]}]
|
||||
set_property -dict {PACKAGE_PIN T16 IOSTANDARD LVCMOS33} [get_ports {led[2]}]
|
||||
set_property -dict {PACKAGE_PIN U16 IOSTANDARD LVCMOS33} [get_ports {led[3]}]
|
||||
set_property -dict {PACKAGE_PIN V15 IOSTANDARD LVCMOS33} [get_ports {led[4]}]
|
||||
set_property -dict {PACKAGE_PIN W16 IOSTANDARD LVCMOS33} [get_ports {led[5]}]
|
||||
set_property -dict {PACKAGE_PIN W15 IOSTANDARD LVCMOS33} [get_ports {led[6]}]
|
||||
set_property -dict {PACKAGE_PIN Y13 IOSTANDARD LVCMOS33} [get_ports {led[7]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN B22 IOSTANDARD LVCMOS33} [get_ports i_rst]
|
||||
set_property -dict {PACKAGE_PIN D22 IOSTANDARD LVCMOS33} [get_ports {btn[0]}]
|
||||
set_property -dict {PACKAGE_PIN C22 IOSTANDARD LVCMOS33} [get_ports {btn[1]}]
|
||||
set_property -dict {PACKAGE_PIN D14 IOSTANDARD LVCMOS33} [get_ports {btn[2]}]
|
||||
set_property -dict {PACKAGE_PIN F15 IOSTANDARD LVCMOS33} [get_ports {btn[3]}]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AA19 IOSTANDARD LVCMOS33} [get_ports tx]
|
||||
set_property -dict {PACKAGE_PIN V18 IOSTANDARD LVCMOS33} [get_ports rx]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[0]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[0]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[0]}]
|
||||
set_property PACKAGE_PIN G2 [get_ports {ddr3_dq[0]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[1]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[1]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[1]}]
|
||||
set_property PACKAGE_PIN H4 [get_ports {ddr3_dq[1]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[2]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[2]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[2]}]
|
||||
set_property PACKAGE_PIN H5 [get_ports {ddr3_dq[2]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[3]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[3]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[3]}]
|
||||
set_property PACKAGE_PIN J1 [get_ports {ddr3_dq[3]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[4]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[4]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[4]}]
|
||||
set_property PACKAGE_PIN K1 [get_ports {ddr3_dq[4]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[5]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[5]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[5]}]
|
||||
set_property PACKAGE_PIN H3 [get_ports {ddr3_dq[5]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[6]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[6]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[6]}]
|
||||
set_property PACKAGE_PIN H2 [get_ports {ddr3_dq[6]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[7]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[7]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[7]}]
|
||||
set_property PACKAGE_PIN J5 [get_ports {ddr3_dq[7]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[8]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[8]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[8]}]
|
||||
set_property PACKAGE_PIN E3 [get_ports {ddr3_dq[8]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[9]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[9]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[9]}]
|
||||
set_property PACKAGE_PIN B2 [get_ports {ddr3_dq[9]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[10]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[10]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[10]}]
|
||||
set_property PACKAGE_PIN F3 [get_ports {ddr3_dq[10]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[11]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[11]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[11]}]
|
||||
set_property PACKAGE_PIN D2 [get_ports {ddr3_dq[11]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[12]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[12]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[12]}]
|
||||
set_property PACKAGE_PIN C2 [get_ports {ddr3_dq[12]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[13]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[13]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[13]}]
|
||||
set_property PACKAGE_PIN A1 [get_ports {ddr3_dq[13]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[14]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[14]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[14]}]
|
||||
set_property PACKAGE_PIN E2 [get_ports {ddr3_dq[14]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dq[15]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dq[15]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dq[15]}]
|
||||
set_property PACKAGE_PIN B1 [get_ports {ddr3_dq[15]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[14]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[14]}]
|
||||
set_property PACKAGE_PIN P6 [get_ports {ddr3_addr[14]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[13]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[13]}]
|
||||
set_property PACKAGE_PIN P2 [get_ports {ddr3_addr[13]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[12]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[12]}]
|
||||
set_property PACKAGE_PIN N4 [get_ports {ddr3_addr[12]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[11]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[11]}]
|
||||
set_property PACKAGE_PIN N5 [get_ports {ddr3_addr[11]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[10]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[10]}]
|
||||
set_property PACKAGE_PIN L5 [get_ports {ddr3_addr[10]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[9]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[9]}]
|
||||
set_property PACKAGE_PIN R1 [get_ports {ddr3_addr[9]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[8]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[8]}]
|
||||
set_property PACKAGE_PIN M6 [get_ports {ddr3_addr[8]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[7]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[7]}]
|
||||
set_property PACKAGE_PIN N2 [get_ports {ddr3_addr[7]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[6]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[6]}]
|
||||
set_property PACKAGE_PIN N3 [get_ports {ddr3_addr[6]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[5]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[5]}]
|
||||
set_property PACKAGE_PIN P1 [get_ports {ddr3_addr[5]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[4]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[4]}]
|
||||
set_property PACKAGE_PIN L6 [get_ports {ddr3_addr[4]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[3]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[3]}]
|
||||
set_property PACKAGE_PIN M1 [get_ports {ddr3_addr[3]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[2]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[2]}]
|
||||
set_property PACKAGE_PIN M3 [get_ports {ddr3_addr[2]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[1]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[1]}]
|
||||
set_property PACKAGE_PIN M5 [get_ports {ddr3_addr[1]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_addr[0]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[0]}]
|
||||
set_property PACKAGE_PIN M2 [get_ports {ddr3_addr[0]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_ba[2]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_ba[2]}]
|
||||
set_property PACKAGE_PIN L4 [get_ports {ddr3_ba[2]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_ba[1]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_ba[1]}]
|
||||
set_property PACKAGE_PIN K6 [get_ports {ddr3_ba[1]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_ba[0]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_ba[0]}]
|
||||
set_property PACKAGE_PIN L3 [get_ports {ddr3_ba[0]}]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_ras_n]
|
||||
set_property IOSTANDARD SSTL15 [get_ports ddr3_ras_n]
|
||||
set_property PACKAGE_PIN J4 [get_ports ddr3_ras_n]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_cas_n]
|
||||
set_property IOSTANDARD SSTL15 [get_ports ddr3_cas_n]
|
||||
set_property PACKAGE_PIN K3 [get_ports ddr3_cas_n]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_we_n]
|
||||
set_property IOSTANDARD SSTL15 [get_ports ddr3_we_n]
|
||||
set_property PACKAGE_PIN L1 [get_ports ddr3_we_n]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_reset_n]
|
||||
set_property IOSTANDARD SSTL15 [get_ports ddr3_reset_n]
|
||||
set_property PACKAGE_PIN G1 [get_ports ddr3_reset_n]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_cke]
|
||||
set_property IOSTANDARD SSTL15 [get_ports ddr3_cke]
|
||||
set_property PACKAGE_PIN J6 [get_ports ddr3_cke]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_odt]
|
||||
set_property IOSTANDARD SSTL15 [get_ports ddr3_odt]
|
||||
set_property PACKAGE_PIN K4 [get_ports ddr3_odt]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_cs_n]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports ddr3_cs_n]
|
||||
set_property PACKAGE_PIN R3 [get_ports ddr3_cs_n]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dm[0]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dm[0]}]
|
||||
set_property PACKAGE_PIN G3 [get_ports {ddr3_dm[0]}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dm[1]}]
|
||||
set_property IOSTANDARD SSTL15 [get_ports {ddr3_dm[1]}]
|
||||
set_property PACKAGE_PIN F1 [get_ports {ddr3_dm[1]}]
|
||||
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dqs_p}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dqs_p}]
|
||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddr3_dqs_p}]
|
||||
|
||||
set_property SLEW FAST [get_ports {ddr3_dqs_n}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dqs_n}]
|
||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddr3_dqs_n}]
|
||||
set_property PACKAGE_PIN K2 [get_ports {ddr3_dqs_p}]
|
||||
set_property PACKAGE_PIN J2 [get_ports {ddr3_dqs_n}]
|
||||
|
||||
#set_property SLEW FAST [get_ports {ddr3_dqs_p[1]}]
|
||||
#set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dqs_p[1]}]
|
||||
#set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddr3_dqs_p[1]}]
|
||||
|
||||
#set_property SLEW FAST [get_ports {ddr3_dqs_n[1]}]
|
||||
#set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddr3_dqs_n[1]}]
|
||||
#set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddr3_dqs_n[1]}]
|
||||
#set_property PACKAGE_PIN E1 [get_ports {ddr3_dqs_p[1]}]
|
||||
#set_property PACKAGE_PIN D1 [get_ports {ddr3_dqs_n[1]}]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_clk_p]
|
||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports ddr3_clk_p]
|
||||
|
||||
set_property SLEW FAST [get_ports ddr3_clk_n]
|
||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports ddr3_clk_n]
|
||||
set_property PACKAGE_PIN P5 [get_ports ddr3_clk_p]
|
||||
set_property PACKAGE_PIN P4 [get_ports ddr3_clk_n]
|
||||
|
||||
#set_property INTERNAL_VREF 0.75 [get_iobanks 35]
|
||||
#set_property CONFIG_VOLTAGE 3.3 [current_design]
|
||||
#set_property CFGBVS VCCO [current_design]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,207 +1,207 @@
|
|||
|
||||
//
|
||||
// Module: uart_rx
|
||||
//
|
||||
// Notes:
|
||||
// - UART reciever module.
|
||||
//
|
||||
|
||||
module uart_rx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
input wire uart_rxd , // UART Recieve pin.
|
||||
input wire uart_rx_en , // Recieve enable
|
||||
output wire uart_rx_break, // Did we get a BREAK message?
|
||||
output wire uart_rx_valid, // Valid data recieved and available.
|
||||
output reg [PAYLOAD_BITS-1:0] uart_rx_data // The recieved data.
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_rxd line. Helps break long timing
|
||||
// paths from input pins into the logic.
|
||||
reg rxd_reg;
|
||||
reg rxd_reg_0;
|
||||
|
||||
//
|
||||
// Storage for the recieved serial data.
|
||||
reg [PAYLOAD_BITS-1:0] recieved_data;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of recieved bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Sample of the UART input line whenever we are in the middle of a bit frame.
|
||||
reg bit_sample;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_RECV = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Output assignment
|
||||
//
|
||||
|
||||
assign uart_rx_break = uart_rx_valid && ~|recieved_data;
|
||||
assign uart_rx_valid = fsm_state == FSM_STOP && n_fsm_state == FSM_IDLE;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(!resetn) begin
|
||||
uart_rx_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if (fsm_state == FSM_STOP) begin
|
||||
uart_rx_data <= recieved_data;
|
||||
end
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT ||
|
||||
fsm_state == FSM_STOP &&
|
||||
cycle_counter == CYCLES_PER_BIT/2;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = rxd_reg ? FSM_IDLE : FSM_START;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_RECV : FSM_START;
|
||||
FSM_RECV : n_fsm_state = payload_done ? FSM_STOP : FSM_RECV ;
|
||||
FSM_STOP : n_fsm_state = next_bit ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the recieved data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_recieved_data
|
||||
if(!resetn) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE ) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit ) begin
|
||||
recieved_data[PAYLOAD_BITS-1] <= bit_sample;
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
recieved_data[i] <= recieved_data[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Increments the bit counter when recieving.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_RECV) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Sample the recieved bit when in the middle of a bit frame.
|
||||
always @(posedge clk) begin : p_bit_sample
|
||||
if(!resetn) begin
|
||||
bit_sample <= 1'b0;
|
||||
end else if (cycle_counter == CYCLES_PER_BIT/2) begin
|
||||
bit_sample <= rxd_reg;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when recieving.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_RECV ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the rxd_reg.
|
||||
always @(posedge clk) begin : p_rxd_reg
|
||||
if(!resetn) begin
|
||||
rxd_reg <= 1'b1;
|
||||
rxd_reg_0 <= 1'b1;
|
||||
end else if(uart_rx_en) begin
|
||||
rxd_reg <= rxd_reg_0;
|
||||
rxd_reg_0 <= uart_rxd;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
//
|
||||
// Module: uart_rx
|
||||
//
|
||||
// Notes:
|
||||
// - UART reciever module.
|
||||
//
|
||||
|
||||
module uart_rx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
input wire uart_rxd , // UART Recieve pin.
|
||||
input wire uart_rx_en , // Recieve enable
|
||||
output wire uart_rx_break, // Did we get a BREAK message?
|
||||
output wire uart_rx_valid, // Valid data recieved and available.
|
||||
output reg [PAYLOAD_BITS-1:0] uart_rx_data // The recieved data.
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_rxd line. Helps break long timing
|
||||
// paths from input pins into the logic.
|
||||
reg rxd_reg;
|
||||
reg rxd_reg_0;
|
||||
|
||||
//
|
||||
// Storage for the recieved serial data.
|
||||
reg [PAYLOAD_BITS-1:0] recieved_data;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of recieved bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Sample of the UART input line whenever we are in the middle of a bit frame.
|
||||
reg bit_sample;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_RECV = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Output assignment
|
||||
//
|
||||
|
||||
assign uart_rx_break = uart_rx_valid && ~|recieved_data;
|
||||
assign uart_rx_valid = fsm_state == FSM_STOP && n_fsm_state == FSM_IDLE;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(!resetn) begin
|
||||
uart_rx_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if (fsm_state == FSM_STOP) begin
|
||||
uart_rx_data <= recieved_data;
|
||||
end
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT ||
|
||||
fsm_state == FSM_STOP &&
|
||||
cycle_counter == CYCLES_PER_BIT/2;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = rxd_reg ? FSM_IDLE : FSM_START;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_RECV : FSM_START;
|
||||
FSM_RECV : n_fsm_state = payload_done ? FSM_STOP : FSM_RECV ;
|
||||
FSM_STOP : n_fsm_state = next_bit ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the recieved data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_recieved_data
|
||||
if(!resetn) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE ) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit ) begin
|
||||
recieved_data[PAYLOAD_BITS-1] <= bit_sample;
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
recieved_data[i] <= recieved_data[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Increments the bit counter when recieving.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_RECV) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Sample the recieved bit when in the middle of a bit frame.
|
||||
always @(posedge clk) begin : p_bit_sample
|
||||
if(!resetn) begin
|
||||
bit_sample <= 1'b0;
|
||||
end else if (cycle_counter == CYCLES_PER_BIT/2) begin
|
||||
bit_sample <= rxd_reg;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when recieving.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_RECV ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the rxd_reg.
|
||||
always @(posedge clk) begin : p_rxd_reg
|
||||
if(!resetn) begin
|
||||
rxd_reg <= 1'b1;
|
||||
rxd_reg_0 <= 1'b1;
|
||||
end else if(uart_rx_en) begin
|
||||
rxd_reg <= rxd_reg_0;
|
||||
rxd_reg_0 <= uart_rxd;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,187 +1,187 @@
|
|||
|
||||
|
||||
//
|
||||
// Module: uart_tx
|
||||
//
|
||||
// Notes:
|
||||
// - UART transmitter module.
|
||||
//
|
||||
|
||||
module uart_tx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
output wire uart_txd , // UART transmit pin.
|
||||
output wire uart_tx_busy, // Module busy sending previous item.
|
||||
input wire uart_tx_en , // Send the data on uart_tx_data
|
||||
input wire [PAYLOAD_BITS-1:0] uart_tx_data // The data to be sent
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_txd line. Helps break long timing
|
||||
// paths from the logic to the output pins.
|
||||
reg txd_reg;
|
||||
|
||||
//
|
||||
// Storage for the serial data to be sent.
|
||||
reg [PAYLOAD_BITS-1:0] data_to_send;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of sent bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_SEND = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
assign uart_tx_busy = fsm_state != FSM_IDLE;
|
||||
assign uart_txd = txd_reg;
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
wire stop_done = bit_counter == STOP_BITS && fsm_state == FSM_STOP;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = uart_tx_en ? FSM_START: FSM_IDLE ;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_SEND : FSM_START;
|
||||
FSM_SEND : n_fsm_state = payload_done ? FSM_STOP : FSM_SEND ;
|
||||
FSM_STOP : n_fsm_state = stop_done ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the sent data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_data_to_send
|
||||
if(!resetn) begin
|
||||
data_to_send <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE && uart_tx_en) begin
|
||||
data_to_send <= uart_tx_data;
|
||||
end else if(fsm_state == FSM_SEND && next_bit ) begin
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
data_to_send[i] <= data_to_send[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the bit counter each time a new bit frame is sent.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_SEND && fsm_state != FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_SEND && n_fsm_state == FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_STOP&& next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end else if(fsm_state == FSM_SEND && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when sending.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_SEND ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the txd_reg.
|
||||
always @(posedge clk) begin : p_txd_reg
|
||||
if(!resetn) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_IDLE) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_START) begin
|
||||
txd_reg <= 1'b0;
|
||||
end else if(fsm_state == FSM_SEND) begin
|
||||
txd_reg <= data_to_send[0];
|
||||
end else if(fsm_state == FSM_STOP) begin
|
||||
txd_reg <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
//
|
||||
// Module: uart_tx
|
||||
//
|
||||
// Notes:
|
||||
// - UART transmitter module.
|
||||
//
|
||||
|
||||
module uart_tx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
output wire uart_txd , // UART transmit pin.
|
||||
output wire uart_tx_busy, // Module busy sending previous item.
|
||||
input wire uart_tx_en , // Send the data on uart_tx_data
|
||||
input wire [PAYLOAD_BITS-1:0] uart_tx_data // The data to be sent
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_txd line. Helps break long timing
|
||||
// paths from the logic to the output pins.
|
||||
reg txd_reg;
|
||||
|
||||
//
|
||||
// Storage for the serial data to be sent.
|
||||
reg [PAYLOAD_BITS-1:0] data_to_send;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of sent bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_SEND = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
assign uart_tx_busy = fsm_state != FSM_IDLE;
|
||||
assign uart_txd = txd_reg;
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
wire stop_done = bit_counter == STOP_BITS && fsm_state == FSM_STOP;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = uart_tx_en ? FSM_START: FSM_IDLE ;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_SEND : FSM_START;
|
||||
FSM_SEND : n_fsm_state = payload_done ? FSM_STOP : FSM_SEND ;
|
||||
FSM_STOP : n_fsm_state = stop_done ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the sent data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_data_to_send
|
||||
if(!resetn) begin
|
||||
data_to_send <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE && uart_tx_en) begin
|
||||
data_to_send <= uart_tx_data;
|
||||
end else if(fsm_state == FSM_SEND && next_bit ) begin
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
data_to_send[i] <= data_to_send[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the bit counter each time a new bit frame is sent.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_SEND && fsm_state != FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_SEND && n_fsm_state == FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_STOP&& next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end else if(fsm_state == FSM_SEND && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when sending.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_SEND ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the txd_reg.
|
||||
always @(posedge clk) begin : p_txd_reg
|
||||
if(!resetn) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_IDLE) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_START) begin
|
||||
txd_reg <= 1'b0;
|
||||
end else if(fsm_state == FSM_SEND) begin
|
||||
txd_reg <= data_to_send[0];
|
||||
end else if(fsm_state == FSM_STOP) begin
|
||||
txd_reg <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,71 +1,71 @@
|
|||
PROJECT = wukong_ddr3
|
||||
FAMILY = artix7
|
||||
PART = xc7a100tfgg676-2
|
||||
CHIPDB = ${ARTIX7_CHIPDB}
|
||||
ADDITIONAL_SOURCES = ../../rtl/ddr3_controller.v ../../rtl/ddr3_phy.v ../../rtl/ddr3_top.v uart_rx.v uart_tx.v clk_wiz.v
|
||||
|
||||
|
||||
#############################################################################################
|
||||
NEXTPNR_XILINX_DIR ?= /snap/openxc7/current/opt/nextpnr-xilinx
|
||||
NEXTPNR_XILINX_PYTHON_DIR ?= ${NEXTPNR_XILINX_DIR}/python
|
||||
PRJXRAY_DB_DIR ?= ${NEXTPNR_XILINX_DIR}/external/prjxray-db
|
||||
|
||||
DBPART = $(shell echo ${PART} | sed -e 's/-[0-9]//g')
|
||||
SPEEDGRADE = $(shell echo ${PART} | sed -e 's/.*\-\([0-9]\)/\1/g')
|
||||
|
||||
CHIPDB ?= ./
|
||||
ifeq ($(CHIPDB),)
|
||||
CHIPDB = ./
|
||||
endif
|
||||
|
||||
PYPY3 ?= pypy3
|
||||
|
||||
TOP ?= ${PROJECT}
|
||||
TOP_MODULE ?= ${TOP}
|
||||
TOP_VERILOG ?= ${TOP}.v
|
||||
|
||||
PNR_DEBUG ?= # --verbose --debug
|
||||
|
||||
BOARD ?= UNKNOWN
|
||||
JTAG_LINK ?= --board ${BOARD}
|
||||
|
||||
XDC ?= ${PROJECT}.xdc
|
||||
|
||||
.PHONY: all
|
||||
all: ${PROJECT}.bit
|
||||
|
||||
.PHONY: program
|
||||
program: ${PROJECT}.bit
|
||||
openFPGALoader ${JTAG_LINK} --bitstream $<
|
||||
|
||||
${PROJECT}.json: ${TOP_VERILOG} ${ADDITIONAL_SOURCES}
|
||||
yosys -p "synth_xilinx -flatten -abc9 ${SYNTH_OPTS} -arch xc7 -top ${TOP_MODULE}; write_json ${PROJECT}.json" $< ${ADDITIONAL_SOURCES}
|
||||
|
||||
# The chip database only needs to be generated once
|
||||
# that is why we don't clean it with make clean
|
||||
${CHIPDB}/${DBPART}.bin:
|
||||
${PYPY3} ${NEXTPNR_XILINX_PYTHON_DIR}/bbaexport.py --device ${PART} --bba ${DBPART}.bba
|
||||
bbasm -l ${DBPART}.bba ${CHIPDB}/${DBPART}.bin
|
||||
rm -f ${DBPART}.bba
|
||||
|
||||
${PROJECT}.fasm: ${PROJECT}.json ${CHIPDB}/${DBPART}.bin ${XDC}
|
||||
nextpnr-xilinx --chipdb ${CHIPDB}/${DBPART}.bin --xdc ${XDC} --json ${PROJECT}.json --fasm $@ ${PNR_ARGS} ${PNR_DEBUG}
|
||||
|
||||
${PROJECT}.frames: ${PROJECT}.fasm
|
||||
fasm2frames --part ${PART} --db-root ${PRJXRAY_DB_DIR}/${FAMILY} $< > $@
|
||||
|
||||
${PROJECT}.bit: ${PROJECT}.frames
|
||||
xc7frames2bit --part_file ${PRJXRAY_DB_DIR}/${FAMILY}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -f *.bit
|
||||
@rm -f *.frames
|
||||
@rm -f *.fasm
|
||||
@rm -f *.json
|
||||
@rm -f *.bin
|
||||
@rm -f *.bba
|
||||
|
||||
.PHONY: pnrclean
|
||||
pnrclean:
|
||||
rm *.fasm *.frames *.bit
|
||||
PROJECT = wukong_ddr3
|
||||
FAMILY = artix7
|
||||
PART = xc7a100tfgg676-2
|
||||
CHIPDB = ${ARTIX7_CHIPDB}
|
||||
ADDITIONAL_SOURCES = ../../rtl/ddr3_controller.v ../../rtl/ddr3_phy.v ../../rtl/ddr3_top.v uart_rx.v uart_tx.v clk_wiz.v
|
||||
|
||||
|
||||
#############################################################################################
|
||||
NEXTPNR_XILINX_DIR ?= /snap/openxc7/current/opt/nextpnr-xilinx
|
||||
NEXTPNR_XILINX_PYTHON_DIR ?= ${NEXTPNR_XILINX_DIR}/python
|
||||
PRJXRAY_DB_DIR ?= ${NEXTPNR_XILINX_DIR}/external/prjxray-db
|
||||
|
||||
DBPART = $(shell echo ${PART} | sed -e 's/-[0-9]//g')
|
||||
SPEEDGRADE = $(shell echo ${PART} | sed -e 's/.*\-\([0-9]\)/\1/g')
|
||||
|
||||
CHIPDB ?= ./
|
||||
ifeq ($(CHIPDB),)
|
||||
CHIPDB = ./
|
||||
endif
|
||||
|
||||
PYPY3 ?= pypy3
|
||||
|
||||
TOP ?= ${PROJECT}
|
||||
TOP_MODULE ?= ${TOP}
|
||||
TOP_VERILOG ?= ${TOP}.v
|
||||
|
||||
PNR_DEBUG ?= # --verbose --debug
|
||||
|
||||
BOARD ?= UNKNOWN
|
||||
JTAG_LINK ?= --board ${BOARD}
|
||||
|
||||
XDC ?= ${PROJECT}.xdc
|
||||
|
||||
.PHONY: all
|
||||
all: ${PROJECT}.bit
|
||||
|
||||
.PHONY: program
|
||||
program: ${PROJECT}.bit
|
||||
openFPGALoader ${JTAG_LINK} --bitstream $<
|
||||
|
||||
${PROJECT}.json: ${TOP_VERILOG} ${ADDITIONAL_SOURCES}
|
||||
yosys -p "synth_xilinx -flatten -abc9 ${SYNTH_OPTS} -arch xc7 -top ${TOP_MODULE}; write_json ${PROJECT}.json" $< ${ADDITIONAL_SOURCES}
|
||||
|
||||
# The chip database only needs to be generated once
|
||||
# that is why we don't clean it with make clean
|
||||
${CHIPDB}/${DBPART}.bin:
|
||||
${PYPY3} ${NEXTPNR_XILINX_PYTHON_DIR}/bbaexport.py --device ${PART} --bba ${DBPART}.bba
|
||||
bbasm -l ${DBPART}.bba ${CHIPDB}/${DBPART}.bin
|
||||
rm -f ${DBPART}.bba
|
||||
|
||||
${PROJECT}.fasm: ${PROJECT}.json ${CHIPDB}/${DBPART}.bin ${XDC}
|
||||
nextpnr-xilinx --chipdb ${CHIPDB}/${DBPART}.bin --xdc ${XDC} --json ${PROJECT}.json --fasm $@ ${PNR_ARGS} ${PNR_DEBUG}
|
||||
|
||||
${PROJECT}.frames: ${PROJECT}.fasm
|
||||
fasm2frames --part ${PART} --db-root ${PRJXRAY_DB_DIR}/${FAMILY} $< > $@
|
||||
|
||||
${PROJECT}.bit: ${PROJECT}.frames
|
||||
xc7frames2bit --part_file ${PRJXRAY_DB_DIR}/${FAMILY}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -f *.bit
|
||||
@rm -f *.frames
|
||||
@rm -f *.fasm
|
||||
@rm -f *.json
|
||||
@rm -f *.bin
|
||||
@rm -f *.bba
|
||||
|
||||
.PHONY: pnrclean
|
||||
pnrclean:
|
||||
rm *.fasm *.frames *.bit
|
||||
|
|
|
|||
|
|
@ -1,66 +1,66 @@
|
|||
`timescale 1ps/1ps
|
||||
|
||||
module clk_wiz
|
||||
(
|
||||
input clk_in1,
|
||||
output clk_out1,
|
||||
output clk_out2,
|
||||
output clk_out3,
|
||||
output clk_out4,
|
||||
input reset,
|
||||
output locked
|
||||
);
|
||||
wire clk_out1_clk_wiz_0;
|
||||
wire clk_out2_clk_wiz_0;
|
||||
wire clk_out3_clk_wiz_0;
|
||||
wire clk_out4_clk_wiz_0;
|
||||
|
||||
wire clkfbout;
|
||||
|
||||
PLLE2_ADV
|
||||
#(.BANDWIDTH ("OPTIMIZED"),
|
||||
.COMPENSATION ("INTERNAL"),
|
||||
.STARTUP_WAIT ("FALSE"),
|
||||
.DIVCLK_DIVIDE (1),
|
||||
.CLKFBOUT_MULT (20), // 50 MHz * 20 = 1000 MHz
|
||||
.CLKFBOUT_PHASE (0.000),
|
||||
.CLKOUT0_DIVIDE (12), // 1000 MHz / 12 = 83.333 MHz
|
||||
.CLKOUT0_PHASE (0.000),
|
||||
.CLKOUT0_DUTY_CYCLE (0.500),
|
||||
.CLKOUT1_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz
|
||||
.CLKOUT1_PHASE (0.000),
|
||||
.CLKOUT1_DUTY_CYCLE (0.500),
|
||||
.CLKOUT2_DIVIDE (5), // 1000 MHz / 5 = 200 MHz
|
||||
.CLKOUT2_PHASE (0.000),
|
||||
.CLKOUT2_DUTY_CYCLE (0.500),
|
||||
.CLKOUT3_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz, 90 phase
|
||||
.CLKOUT3_PHASE (90.000),
|
||||
.CLKOUT3_DUTY_CYCLE (0.500),
|
||||
.CLKIN1_PERIOD (20.000) // 50 MHz input
|
||||
)
|
||||
plle2_adv_inst
|
||||
(
|
||||
.CLKFBOUT (clkfbout),
|
||||
.CLKOUT0 (clk_out1_clk_wiz_0),
|
||||
.CLKOUT1 (clk_out2_clk_wiz_0),
|
||||
.CLKOUT2 (clk_out3_clk_wiz_0),
|
||||
.CLKOUT3 (clk_out4_clk_wiz_0),
|
||||
.CLKFBIN (clkfbout),
|
||||
.CLKIN1 (clk_in1),
|
||||
.LOCKED (locked),
|
||||
.RST (reset)
|
||||
);
|
||||
BUFG clkout1_buf
|
||||
(.O (clk_out1),
|
||||
.I (clk_out1_clk_wiz_0));
|
||||
BUFG clkout2_buf
|
||||
(.O (clk_out2),
|
||||
.I (clk_out2_clk_wiz_0));
|
||||
BUFG clkout3_buf
|
||||
(.O (clk_out3),
|
||||
.I (clk_out3_clk_wiz_0));
|
||||
BUFG clkout4_buf
|
||||
(.O (clk_out4),
|
||||
.I (clk_out4_clk_wiz_0));
|
||||
|
||||
endmodule
|
||||
`timescale 1ps/1ps
|
||||
|
||||
module clk_wiz
|
||||
(
|
||||
input clk_in1,
|
||||
output clk_out1,
|
||||
output clk_out2,
|
||||
output clk_out3,
|
||||
output clk_out4,
|
||||
input reset,
|
||||
output locked
|
||||
);
|
||||
wire clk_out1_clk_wiz_0;
|
||||
wire clk_out2_clk_wiz_0;
|
||||
wire clk_out3_clk_wiz_0;
|
||||
wire clk_out4_clk_wiz_0;
|
||||
|
||||
wire clkfbout;
|
||||
|
||||
PLLE2_ADV
|
||||
#(.BANDWIDTH ("OPTIMIZED"),
|
||||
.COMPENSATION ("INTERNAL"),
|
||||
.STARTUP_WAIT ("FALSE"),
|
||||
.DIVCLK_DIVIDE (1),
|
||||
.CLKFBOUT_MULT (20), // 50 MHz * 20 = 1000 MHz
|
||||
.CLKFBOUT_PHASE (0.000),
|
||||
.CLKOUT0_DIVIDE (12), // 1000 MHz / 12 = 83.333 MHz
|
||||
.CLKOUT0_PHASE (0.000),
|
||||
.CLKOUT0_DUTY_CYCLE (0.500),
|
||||
.CLKOUT1_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz
|
||||
.CLKOUT1_PHASE (0.000),
|
||||
.CLKOUT1_DUTY_CYCLE (0.500),
|
||||
.CLKOUT2_DIVIDE (5), // 1000 MHz / 5 = 200 MHz
|
||||
.CLKOUT2_PHASE (0.000),
|
||||
.CLKOUT2_DUTY_CYCLE (0.500),
|
||||
.CLKOUT3_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz, 90 phase
|
||||
.CLKOUT3_PHASE (90.000),
|
||||
.CLKOUT3_DUTY_CYCLE (0.500),
|
||||
.CLKIN1_PERIOD (20.000) // 50 MHz input
|
||||
)
|
||||
plle2_adv_inst
|
||||
(
|
||||
.CLKFBOUT (clkfbout),
|
||||
.CLKOUT0 (clk_out1_clk_wiz_0),
|
||||
.CLKOUT1 (clk_out2_clk_wiz_0),
|
||||
.CLKOUT2 (clk_out3_clk_wiz_0),
|
||||
.CLKOUT3 (clk_out4_clk_wiz_0),
|
||||
.CLKFBIN (clkfbout),
|
||||
.CLKIN1 (clk_in1),
|
||||
.LOCKED (locked),
|
||||
.RST (reset)
|
||||
);
|
||||
BUFG clkout1_buf
|
||||
(.O (clk_out1),
|
||||
.I (clk_out1_clk_wiz_0));
|
||||
BUFG clkout2_buf
|
||||
(.O (clk_out2),
|
||||
.I (clk_out2_clk_wiz_0));
|
||||
BUFG clkout3_buf
|
||||
(.O (clk_out3),
|
||||
.I (clk_out3_clk_wiz_0));
|
||||
BUFG clkout4_buf
|
||||
(.O (clk_out4),
|
||||
.I (clk_out4_clk_wiz_0));
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,207 +1,207 @@
|
|||
|
||||
//
|
||||
// Module: uart_rx
|
||||
//
|
||||
// Notes:
|
||||
// - UART reciever module.
|
||||
//
|
||||
|
||||
module uart_rx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
input wire uart_rxd , // UART Recieve pin.
|
||||
input wire uart_rx_en , // Recieve enable
|
||||
output wire uart_rx_break, // Did we get a BREAK message?
|
||||
output wire uart_rx_valid, // Valid data recieved and available.
|
||||
output reg [PAYLOAD_BITS-1:0] uart_rx_data // The recieved data.
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_rxd line. Helps break long timing
|
||||
// paths from input pins into the logic.
|
||||
reg rxd_reg;
|
||||
reg rxd_reg_0;
|
||||
|
||||
//
|
||||
// Storage for the recieved serial data.
|
||||
reg [PAYLOAD_BITS-1:0] recieved_data;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of recieved bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Sample of the UART input line whenever we are in the middle of a bit frame.
|
||||
reg bit_sample;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_RECV = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Output assignment
|
||||
//
|
||||
|
||||
assign uart_rx_break = uart_rx_valid && ~|recieved_data;
|
||||
assign uart_rx_valid = fsm_state == FSM_STOP && n_fsm_state == FSM_IDLE;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(!resetn) begin
|
||||
uart_rx_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if (fsm_state == FSM_STOP) begin
|
||||
uart_rx_data <= recieved_data;
|
||||
end
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT ||
|
||||
fsm_state == FSM_STOP &&
|
||||
cycle_counter == CYCLES_PER_BIT/2;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = rxd_reg ? FSM_IDLE : FSM_START;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_RECV : FSM_START;
|
||||
FSM_RECV : n_fsm_state = payload_done ? FSM_STOP : FSM_RECV ;
|
||||
FSM_STOP : n_fsm_state = next_bit ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the recieved data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_recieved_data
|
||||
if(!resetn) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE ) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit ) begin
|
||||
recieved_data[PAYLOAD_BITS-1] <= bit_sample;
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
recieved_data[i] <= recieved_data[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Increments the bit counter when recieving.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_RECV) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Sample the recieved bit when in the middle of a bit frame.
|
||||
always @(posedge clk) begin : p_bit_sample
|
||||
if(!resetn) begin
|
||||
bit_sample <= 1'b0;
|
||||
end else if (cycle_counter == CYCLES_PER_BIT/2) begin
|
||||
bit_sample <= rxd_reg;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when recieving.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_RECV ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the rxd_reg.
|
||||
always @(posedge clk) begin : p_rxd_reg
|
||||
if(!resetn) begin
|
||||
rxd_reg <= 1'b1;
|
||||
rxd_reg_0 <= 1'b1;
|
||||
end else if(uart_rx_en) begin
|
||||
rxd_reg <= rxd_reg_0;
|
||||
rxd_reg_0 <= uart_rxd;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
//
|
||||
// Module: uart_rx
|
||||
//
|
||||
// Notes:
|
||||
// - UART reciever module.
|
||||
//
|
||||
|
||||
module uart_rx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
input wire uart_rxd , // UART Recieve pin.
|
||||
input wire uart_rx_en , // Recieve enable
|
||||
output wire uart_rx_break, // Did we get a BREAK message?
|
||||
output wire uart_rx_valid, // Valid data recieved and available.
|
||||
output reg [PAYLOAD_BITS-1:0] uart_rx_data // The recieved data.
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_rxd line. Helps break long timing
|
||||
// paths from input pins into the logic.
|
||||
reg rxd_reg;
|
||||
reg rxd_reg_0;
|
||||
|
||||
//
|
||||
// Storage for the recieved serial data.
|
||||
reg [PAYLOAD_BITS-1:0] recieved_data;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of recieved bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Sample of the UART input line whenever we are in the middle of a bit frame.
|
||||
reg bit_sample;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_RECV = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Output assignment
|
||||
//
|
||||
|
||||
assign uart_rx_break = uart_rx_valid && ~|recieved_data;
|
||||
assign uart_rx_valid = fsm_state == FSM_STOP && n_fsm_state == FSM_IDLE;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(!resetn) begin
|
||||
uart_rx_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if (fsm_state == FSM_STOP) begin
|
||||
uart_rx_data <= recieved_data;
|
||||
end
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT ||
|
||||
fsm_state == FSM_STOP &&
|
||||
cycle_counter == CYCLES_PER_BIT/2;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = rxd_reg ? FSM_IDLE : FSM_START;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_RECV : FSM_START;
|
||||
FSM_RECV : n_fsm_state = payload_done ? FSM_STOP : FSM_RECV ;
|
||||
FSM_STOP : n_fsm_state = next_bit ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the recieved data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_recieved_data
|
||||
if(!resetn) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE ) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit ) begin
|
||||
recieved_data[PAYLOAD_BITS-1] <= bit_sample;
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
recieved_data[i] <= recieved_data[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Increments the bit counter when recieving.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_RECV) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Sample the recieved bit when in the middle of a bit frame.
|
||||
always @(posedge clk) begin : p_bit_sample
|
||||
if(!resetn) begin
|
||||
bit_sample <= 1'b0;
|
||||
end else if (cycle_counter == CYCLES_PER_BIT/2) begin
|
||||
bit_sample <= rxd_reg;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when recieving.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_RECV ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the rxd_reg.
|
||||
always @(posedge clk) begin : p_rxd_reg
|
||||
if(!resetn) begin
|
||||
rxd_reg <= 1'b1;
|
||||
rxd_reg_0 <= 1'b1;
|
||||
end else if(uart_rx_en) begin
|
||||
rxd_reg <= rxd_reg_0;
|
||||
rxd_reg_0 <= uart_rxd;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,187 +1,187 @@
|
|||
|
||||
|
||||
//
|
||||
// Module: uart_tx
|
||||
//
|
||||
// Notes:
|
||||
// - UART transmitter module.
|
||||
//
|
||||
|
||||
module uart_tx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
output wire uart_txd , // UART transmit pin.
|
||||
output wire uart_tx_busy, // Module busy sending previous item.
|
||||
input wire uart_tx_en , // Send the data on uart_tx_data
|
||||
input wire [PAYLOAD_BITS-1:0] uart_tx_data // The data to be sent
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_txd line. Helps break long timing
|
||||
// paths from the logic to the output pins.
|
||||
reg txd_reg;
|
||||
|
||||
//
|
||||
// Storage for the serial data to be sent.
|
||||
reg [PAYLOAD_BITS-1:0] data_to_send;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of sent bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_SEND = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
assign uart_tx_busy = fsm_state != FSM_IDLE;
|
||||
assign uart_txd = txd_reg;
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
wire stop_done = bit_counter == STOP_BITS && fsm_state == FSM_STOP;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = uart_tx_en ? FSM_START: FSM_IDLE ;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_SEND : FSM_START;
|
||||
FSM_SEND : n_fsm_state = payload_done ? FSM_STOP : FSM_SEND ;
|
||||
FSM_STOP : n_fsm_state = stop_done ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the sent data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_data_to_send
|
||||
if(!resetn) begin
|
||||
data_to_send <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE && uart_tx_en) begin
|
||||
data_to_send <= uart_tx_data;
|
||||
end else if(fsm_state == FSM_SEND && next_bit ) begin
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
data_to_send[i] <= data_to_send[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the bit counter each time a new bit frame is sent.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_SEND && fsm_state != FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_SEND && n_fsm_state == FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_STOP&& next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end else if(fsm_state == FSM_SEND && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when sending.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_SEND ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the txd_reg.
|
||||
always @(posedge clk) begin : p_txd_reg
|
||||
if(!resetn) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_IDLE) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_START) begin
|
||||
txd_reg <= 1'b0;
|
||||
end else if(fsm_state == FSM_SEND) begin
|
||||
txd_reg <= data_to_send[0];
|
||||
end else if(fsm_state == FSM_STOP) begin
|
||||
txd_reg <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
//
|
||||
// Module: uart_tx
|
||||
//
|
||||
// Notes:
|
||||
// - UART transmitter module.
|
||||
//
|
||||
|
||||
module uart_tx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
output wire uart_txd , // UART transmit pin.
|
||||
output wire uart_tx_busy, // Module busy sending previous item.
|
||||
input wire uart_tx_en , // Send the data on uart_tx_data
|
||||
input wire [PAYLOAD_BITS-1:0] uart_tx_data // The data to be sent
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_txd line. Helps break long timing
|
||||
// paths from the logic to the output pins.
|
||||
reg txd_reg;
|
||||
|
||||
//
|
||||
// Storage for the serial data to be sent.
|
||||
reg [PAYLOAD_BITS-1:0] data_to_send;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of sent bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_SEND = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
assign uart_tx_busy = fsm_state != FSM_IDLE;
|
||||
assign uart_txd = txd_reg;
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
wire stop_done = bit_counter == STOP_BITS && fsm_state == FSM_STOP;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = uart_tx_en ? FSM_START: FSM_IDLE ;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_SEND : FSM_START;
|
||||
FSM_SEND : n_fsm_state = payload_done ? FSM_STOP : FSM_SEND ;
|
||||
FSM_STOP : n_fsm_state = stop_done ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the sent data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_data_to_send
|
||||
if(!resetn) begin
|
||||
data_to_send <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE && uart_tx_en) begin
|
||||
data_to_send <= uart_tx_data;
|
||||
end else if(fsm_state == FSM_SEND && next_bit ) begin
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
data_to_send[i] <= data_to_send[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the bit counter each time a new bit frame is sent.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_SEND && fsm_state != FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_SEND && n_fsm_state == FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_STOP&& next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end else if(fsm_state == FSM_SEND && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when sending.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_SEND ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the txd_reg.
|
||||
always @(posedge clk) begin : p_txd_reg
|
||||
if(!resetn) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_IDLE) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_START) begin
|
||||
txd_reg <= 1'b0;
|
||||
end else if(fsm_state == FSM_SEND) begin
|
||||
txd_reg <= data_to_send[0];
|
||||
end else if(fsm_state == FSM_STOP) begin
|
||||
txd_reg <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,69 +1,69 @@
|
|||
PROJECT = sechzig_mx2_ddr3
|
||||
FAMILY = artix7
|
||||
PART = xc7a35tftg256-2
|
||||
CHIPDB = ${ARTIX7_CHIPDB}
|
||||
ADDITIONAL_SOURCES = ../../rtl/ddr3_controller.v ../../rtl/ddr3_phy.v ../../rtl/ddr3_top.v uart_rx.v uart_tx.v clk_wiz.v
|
||||
|
||||
#############################################################################################
|
||||
NEXTPNR_XILINX_DIR ?= /snap/openxc7/current/opt/nextpnr-xilinx
|
||||
NEXTPNR_XILINX_PYTHON_DIR ?= ${NEXTPNR_XILINX_DIR}/python
|
||||
PRJXRAY_DB_DIR ?= ${NEXTPNR_XILINX_DIR}/external/prjxray-db
|
||||
|
||||
DBPART = $(shell echo ${PART} | sed -e 's/-[0-9]//g')
|
||||
SPEEDGRADE = $(shell echo ${PART} | sed -e 's/.*\-\([0-9]\)/\1/g')
|
||||
|
||||
CHIPDB ?= ./
|
||||
ifeq ($(CHIPDB),)
|
||||
CHIPDB = ./
|
||||
endif
|
||||
|
||||
PYPY3 ?= pypy3
|
||||
|
||||
TOP ?= ${PROJECT}
|
||||
TOP_MODULE ?= ${TOP}
|
||||
TOP_VERILOG ?= ${TOP}.v
|
||||
|
||||
PNR_DEBUG ?= # --verbose --debug
|
||||
|
||||
BOARD ?= UNKNOWN
|
||||
JTAG_LINK ?= --board ${BOARD}
|
||||
|
||||
XDC ?= ${PROJECT}.xdc
|
||||
|
||||
.PHONY: all
|
||||
all: ${PROJECT}.bit
|
||||
|
||||
.PHONY: program
|
||||
program: ${PROJECT}.bit
|
||||
openFPGALoader ${JTAG_LINK} --bitstream $<
|
||||
|
||||
${PROJECT}.json: ${TOP_VERILOG} ${ADDITIONAL_SOURCES}
|
||||
yosys -p "synth_xilinx -flatten -abc9 ${SYNTH_OPTS} -arch xc7 -top ${TOP_MODULE}; write_json ${PROJECT}.json" $< ${ADDITIONAL_SOURCES}
|
||||
|
||||
# The chip database only needs to be generated once
|
||||
# that is why we don't clean it with make clean
|
||||
${CHIPDB}/${DBPART}.bin:
|
||||
${PYPY3} ${NEXTPNR_XILINX_PYTHON_DIR}/bbaexport.py --device ${PART} --bba ${DBPART}.bba
|
||||
bbasm -l ${DBPART}.bba ${CHIPDB}/${DBPART}.bin
|
||||
rm -f ${DBPART}.bba
|
||||
|
||||
${PROJECT}.fasm: ${PROJECT}.json ${CHIPDB}/${DBPART}.bin ${XDC}
|
||||
nextpnr-xilinx --chipdb ${CHIPDB}/${DBPART}.bin --xdc ${XDC} --json ${PROJECT}.json --fasm $@ ${PNR_ARGS} ${PNR_DEBUG}
|
||||
|
||||
${PROJECT}.frames: ${PROJECT}.fasm
|
||||
fasm2frames --part ${PART} --db-root ${PRJXRAY_DB_DIR}/${FAMILY} $< > $@
|
||||
|
||||
${PROJECT}.bit: ${PROJECT}.frames
|
||||
xc7frames2bit --part_file ${PRJXRAY_DB_DIR}/${FAMILY}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -f *.frames
|
||||
@rm -f *.fasm
|
||||
@rm -f *.json
|
||||
@rm -f *.bin
|
||||
@rm -f *.bba
|
||||
|
||||
.PHONY: pnrclean
|
||||
pnrclean:
|
||||
PROJECT = sechzig_mx2_ddr3
|
||||
FAMILY = artix7
|
||||
PART = xc7a35tftg256-2
|
||||
CHIPDB = ${ARTIX7_CHIPDB}
|
||||
ADDITIONAL_SOURCES = ../../rtl/ddr3_controller.v ../../rtl/ddr3_phy.v ../../rtl/ddr3_top.v uart_rx.v uart_tx.v clk_wiz.v
|
||||
|
||||
#############################################################################################
|
||||
NEXTPNR_XILINX_DIR ?= /snap/openxc7/current/opt/nextpnr-xilinx
|
||||
NEXTPNR_XILINX_PYTHON_DIR ?= ${NEXTPNR_XILINX_DIR}/python
|
||||
PRJXRAY_DB_DIR ?= ${NEXTPNR_XILINX_DIR}/external/prjxray-db
|
||||
|
||||
DBPART = $(shell echo ${PART} | sed -e 's/-[0-9]//g')
|
||||
SPEEDGRADE = $(shell echo ${PART} | sed -e 's/.*\-\([0-9]\)/\1/g')
|
||||
|
||||
CHIPDB ?= ./
|
||||
ifeq ($(CHIPDB),)
|
||||
CHIPDB = ./
|
||||
endif
|
||||
|
||||
PYPY3 ?= pypy3
|
||||
|
||||
TOP ?= ${PROJECT}
|
||||
TOP_MODULE ?= ${TOP}
|
||||
TOP_VERILOG ?= ${TOP}.v
|
||||
|
||||
PNR_DEBUG ?= # --verbose --debug
|
||||
|
||||
BOARD ?= UNKNOWN
|
||||
JTAG_LINK ?= --board ${BOARD}
|
||||
|
||||
XDC ?= ${PROJECT}.xdc
|
||||
|
||||
.PHONY: all
|
||||
all: ${PROJECT}.bit
|
||||
|
||||
.PHONY: program
|
||||
program: ${PROJECT}.bit
|
||||
openFPGALoader ${JTAG_LINK} --bitstream $<
|
||||
|
||||
${PROJECT}.json: ${TOP_VERILOG} ${ADDITIONAL_SOURCES}
|
||||
yosys -p "synth_xilinx -flatten -abc9 ${SYNTH_OPTS} -arch xc7 -top ${TOP_MODULE}; write_json ${PROJECT}.json" $< ${ADDITIONAL_SOURCES}
|
||||
|
||||
# The chip database only needs to be generated once
|
||||
# that is why we don't clean it with make clean
|
||||
${CHIPDB}/${DBPART}.bin:
|
||||
${PYPY3} ${NEXTPNR_XILINX_PYTHON_DIR}/bbaexport.py --device ${PART} --bba ${DBPART}.bba
|
||||
bbasm -l ${DBPART}.bba ${CHIPDB}/${DBPART}.bin
|
||||
rm -f ${DBPART}.bba
|
||||
|
||||
${PROJECT}.fasm: ${PROJECT}.json ${CHIPDB}/${DBPART}.bin ${XDC}
|
||||
nextpnr-xilinx --chipdb ${CHIPDB}/${DBPART}.bin --xdc ${XDC} --json ${PROJECT}.json --fasm $@ ${PNR_ARGS} ${PNR_DEBUG}
|
||||
|
||||
${PROJECT}.frames: ${PROJECT}.fasm
|
||||
fasm2frames --part ${PART} --db-root ${PRJXRAY_DB_DIR}/${FAMILY} $< > $@
|
||||
|
||||
${PROJECT}.bit: ${PROJECT}.frames
|
||||
xc7frames2bit --part_file ${PRJXRAY_DB_DIR}/${FAMILY}/${PART}/part.yaml --part_name ${PART} --frm_file $< --output_file $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -f *.frames
|
||||
@rm -f *.fasm
|
||||
@rm -f *.json
|
||||
@rm -f *.bin
|
||||
@rm -f *.bba
|
||||
|
||||
.PHONY: pnrclean
|
||||
pnrclean:
|
||||
rm *.fasm *.frames *.bit
|
||||
|
|
@ -1,66 +1,66 @@
|
|||
`timescale 1ps/1ps
|
||||
|
||||
module clk_wiz
|
||||
(
|
||||
input clk_in1,
|
||||
output clk_out1,
|
||||
output clk_out2,
|
||||
output clk_out3,
|
||||
output clk_out4,
|
||||
input reset,
|
||||
output locked
|
||||
);
|
||||
wire clk_out1_clk_wiz_0;
|
||||
wire clk_out2_clk_wiz_0;
|
||||
wire clk_out3_clk_wiz_0;
|
||||
wire clk_out4_clk_wiz_0;
|
||||
|
||||
wire clkfbout;
|
||||
|
||||
PLLE2_ADV
|
||||
#(.BANDWIDTH ("OPTIMIZED"),
|
||||
.COMPENSATION ("INTERNAL"),
|
||||
.STARTUP_WAIT ("FALSE"),
|
||||
.DIVCLK_DIVIDE (1),
|
||||
.CLKFBOUT_MULT (20), // 50 MHz * 20 = 1000 MHz
|
||||
.CLKFBOUT_PHASE (0.000),
|
||||
.CLKOUT0_DIVIDE (12), // 1000 MHz / 12 = 83.333 MHz
|
||||
.CLKOUT0_PHASE (0.000),
|
||||
.CLKOUT0_DUTY_CYCLE (0.500),
|
||||
.CLKOUT1_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz
|
||||
.CLKOUT1_PHASE (0.000),
|
||||
.CLKOUT1_DUTY_CYCLE (0.500),
|
||||
.CLKOUT2_DIVIDE (5), // 1000 MHz / 5 = 200 MHz
|
||||
.CLKOUT2_PHASE (0.000),
|
||||
.CLKOUT2_DUTY_CYCLE (0.500),
|
||||
.CLKOUT3_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz, 90 phase
|
||||
.CLKOUT3_PHASE (90.000),
|
||||
.CLKOUT3_DUTY_CYCLE (0.500),
|
||||
.CLKIN1_PERIOD (20.000) // 50 MHz input
|
||||
)
|
||||
plle2_adv_inst
|
||||
(
|
||||
.CLKFBOUT (clkfbout),
|
||||
.CLKOUT0 (clk_out1_clk_wiz_0),
|
||||
.CLKOUT1 (clk_out2_clk_wiz_0),
|
||||
.CLKOUT2 (clk_out3_clk_wiz_0),
|
||||
.CLKOUT3 (clk_out4_clk_wiz_0),
|
||||
.CLKFBIN (clkfbout),
|
||||
.CLKIN1 (clk_in1),
|
||||
.LOCKED (locked),
|
||||
.RST (reset)
|
||||
);
|
||||
BUFG clkout1_buf
|
||||
(.O (clk_out1),
|
||||
.I (clk_out1_clk_wiz_0));
|
||||
BUFG clkout2_buf
|
||||
(.O (clk_out2),
|
||||
.I (clk_out2_clk_wiz_0));
|
||||
BUFG clkout3_buf
|
||||
(.O (clk_out3),
|
||||
.I (clk_out3_clk_wiz_0));
|
||||
BUFG clkout4_buf
|
||||
(.O (clk_out4),
|
||||
.I (clk_out4_clk_wiz_0));
|
||||
|
||||
endmodule
|
||||
`timescale 1ps/1ps
|
||||
|
||||
module clk_wiz
|
||||
(
|
||||
input clk_in1,
|
||||
output clk_out1,
|
||||
output clk_out2,
|
||||
output clk_out3,
|
||||
output clk_out4,
|
||||
input reset,
|
||||
output locked
|
||||
);
|
||||
wire clk_out1_clk_wiz_0;
|
||||
wire clk_out2_clk_wiz_0;
|
||||
wire clk_out3_clk_wiz_0;
|
||||
wire clk_out4_clk_wiz_0;
|
||||
|
||||
wire clkfbout;
|
||||
|
||||
PLLE2_ADV
|
||||
#(.BANDWIDTH ("OPTIMIZED"),
|
||||
.COMPENSATION ("INTERNAL"),
|
||||
.STARTUP_WAIT ("FALSE"),
|
||||
.DIVCLK_DIVIDE (1),
|
||||
.CLKFBOUT_MULT (20), // 50 MHz * 20 = 1000 MHz
|
||||
.CLKFBOUT_PHASE (0.000),
|
||||
.CLKOUT0_DIVIDE (12), // 1000 MHz / 12 = 83.333 MHz
|
||||
.CLKOUT0_PHASE (0.000),
|
||||
.CLKOUT0_DUTY_CYCLE (0.500),
|
||||
.CLKOUT1_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz
|
||||
.CLKOUT1_PHASE (0.000),
|
||||
.CLKOUT1_DUTY_CYCLE (0.500),
|
||||
.CLKOUT2_DIVIDE (5), // 1000 MHz / 5 = 200 MHz
|
||||
.CLKOUT2_PHASE (0.000),
|
||||
.CLKOUT2_DUTY_CYCLE (0.500),
|
||||
.CLKOUT3_DIVIDE (3), // 1000 MHz / 3 = 333.333 MHz, 90 phase
|
||||
.CLKOUT3_PHASE (90.000),
|
||||
.CLKOUT3_DUTY_CYCLE (0.500),
|
||||
.CLKIN1_PERIOD (20.000) // 50 MHz input
|
||||
)
|
||||
plle2_adv_inst
|
||||
(
|
||||
.CLKFBOUT (clkfbout),
|
||||
.CLKOUT0 (clk_out1_clk_wiz_0),
|
||||
.CLKOUT1 (clk_out2_clk_wiz_0),
|
||||
.CLKOUT2 (clk_out3_clk_wiz_0),
|
||||
.CLKOUT3 (clk_out4_clk_wiz_0),
|
||||
.CLKFBIN (clkfbout),
|
||||
.CLKIN1 (clk_in1),
|
||||
.LOCKED (locked),
|
||||
.RST (reset)
|
||||
);
|
||||
BUFG clkout1_buf
|
||||
(.O (clk_out1),
|
||||
.I (clk_out1_clk_wiz_0));
|
||||
BUFG clkout2_buf
|
||||
(.O (clk_out2),
|
||||
.I (clk_out2_clk_wiz_0));
|
||||
BUFG clkout3_buf
|
||||
(.O (clk_out3),
|
||||
.I (clk_out3_clk_wiz_0));
|
||||
BUFG clkout4_buf
|
||||
(.O (clk_out4),
|
||||
.I (clk_out4_clk_wiz_0));
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,276 +1,276 @@
|
|||
################################################################################
|
||||
# IO constraints
|
||||
################################################################################
|
||||
# clk48:0
|
||||
set_property LOC F5 [get_ports {clk48}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {clk48}]
|
||||
|
||||
# clk50:0
|
||||
set_property LOC D4 [get_ports {clk50}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {clk50}]
|
||||
|
||||
# led
|
||||
set_property LOC R16 [get_ports {led}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {led}]
|
||||
|
||||
# led (n/c)
|
||||
set_property LOC T14 [get_ports {led[1]}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
|
||||
|
||||
# serial:0.tx
|
||||
set_property LOC L2 [get_ports {tx}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {tx}]
|
||||
|
||||
# serial:0.rx
|
||||
set_property LOC L3 [get_ports {rx}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {rx}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC F12 [get_ports {ddr3_addr[0]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[0]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC D15 [get_ports {ddr3_addr[1]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[1]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC J15 [get_ports {ddr3_addr[2]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[2]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC E16 [get_ports {ddr3_addr[3]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[3]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC G11 [get_ports {ddr3_addr[4]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[4]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC F15 [get_ports {ddr3_addr[5]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[5]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC H13 [get_ports {ddr3_addr[6]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[6]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC G15 [get_ports {ddr3_addr[7]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[7]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC H12 [get_ports {ddr3_addr[8]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[8]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC H16 [get_ports {ddr3_addr[9]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[9]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC H11 [get_ports {ddr3_addr[10]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[10]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC H14 [get_ports {ddr3_addr[11]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[11]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC E12 [get_ports {ddr3_addr[12]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[12]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC G16 [get_ports {ddr3_addr[13]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[13]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC J16 [get_ports {ddr3_addr[14]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[14]}]
|
||||
|
||||
# ddr3:0.ba
|
||||
set_property LOC E15 [get_ports {ddr3_ba[0]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_ba[0]}]
|
||||
|
||||
# ddr3:0.ba
|
||||
set_property LOC D11 [get_ports {ddr3_ba[1]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_ba[1]}]
|
||||
|
||||
# ddr3:0.ba
|
||||
set_property LOC F13 [get_ports {ddr3_ba[2]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_ba[2]}]
|
||||
|
||||
# ddr3:0.ras_n
|
||||
set_property LOC D14 [get_ports {ddr3_ras_n}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_ras_n}]
|
||||
|
||||
# ddr3:0.cas_n
|
||||
set_property LOC E13 [get_ports {ddr3_cas_n}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_cas_n}]
|
||||
|
||||
# ddr3:0.we_n
|
||||
set_property LOC G12 [get_ports {ddr3_we_n}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_we_n}]
|
||||
|
||||
# ddr3:0.dm
|
||||
set_property LOC A13 [get_ports {ddr3_dm[0]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dm[0]}]
|
||||
|
||||
# ddr3:0.dm
|
||||
set_property LOC D9 [get_ports {ddr3_dm[1]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dm[1]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC A14 [get_ports {ddr3_dq[0]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[0]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[0]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC C12 [get_ports {ddr3_dq[1]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[1]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[1]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC B14 [get_ports {ddr3_dq[2]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[2]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[2]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC D13 [get_ports {ddr3_dq[3]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[3]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[3]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC B16 [get_ports {ddr3_dq[4]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[4]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[4]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC C11 [get_ports {ddr3_dq[5]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[5]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[5]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC C16 [get_ports {ddr3_dq[6]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[6]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[6]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC C14 [get_ports {ddr3_dq[7]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[7]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[7]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC A9 [get_ports {ddr3_dq[8]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[8]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[8]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC B10 [get_ports {ddr3_dq[9]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[9]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[9]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC C8 [get_ports {ddr3_dq[10]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[10]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[10]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC B12 [get_ports {ddr3_dq[11]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[11]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[11]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC A8 [get_ports {ddr3_dq[12]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[12]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[12]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC A12 [get_ports {ddr3_dq[13]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[13]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[13]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC C9 [get_ports {ddr3_dq[14]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[14]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[14]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC B11 [get_ports {ddr3_dq[15]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[15]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[15]}]
|
||||
|
||||
# ddr3:0.dqs_p
|
||||
set_property LOC B15 [get_ports {ddr3_dqs_p[0]}]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddr3_dqs_p[0]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dqs_p[0]}]
|
||||
|
||||
# ddr3:0.dqs_p
|
||||
set_property LOC B9 [get_ports {ddr3_dqs_p[1]}]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddr3_dqs_p[1]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dqs_p[1]}]
|
||||
|
||||
# ddr3:0.dqs_n
|
||||
set_property LOC A15 [get_ports {ddr3_dqs_n[0]}]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddr3_dqs_n[0]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dqs_n[0]}]
|
||||
|
||||
# ddr3:0.dqs_n
|
||||
set_property LOC A10 [get_ports {ddr3_dqs_n[1]}]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddr3_dqs_n[1]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dqs_n[1]}]
|
||||
|
||||
# ddr3:0.clk_p
|
||||
set_property LOC G14 [get_ports {ddr3_clk_p}]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddr3_clk_p}]
|
||||
|
||||
# ddr3:0.clk_n
|
||||
set_property LOC F14 [get_ports {ddr3_clk_n}]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddr3_clk_n}]
|
||||
|
||||
# ddr3:0.cke
|
||||
set_property LOC E11 [get_ports {ddr3_cke}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_cke}]
|
||||
|
||||
# ddr3:0.odt
|
||||
set_property LOC D16 [get_ports {ddr3_odt}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_odt}]
|
||||
|
||||
# ddr3:0.reset_n
|
||||
set_property LOC M16 [get_ports {ddr3_reset_n}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {ddr3_reset_n}]
|
||||
|
||||
################################################################################
|
||||
# Design constraints
|
||||
################################################################################
|
||||
|
||||
# set_property INTERNAL_VREF 0.675 [get_iobanks 34]
|
||||
|
||||
# set_property INTERNAL_VREF 0.675 [get_iobanks 15]
|
||||
|
||||
################################################################################
|
||||
# Clock constraints
|
||||
################################################################################
|
||||
|
||||
|
||||
# create_clock -name clk48 -period 20.833 [get_ports clk48]
|
||||
|
||||
# create_clock -name clk50 -period 20.0 [get_ports clk50]
|
||||
|
||||
# create_clock -name eth_rx_clk -period 20.0 [get_nets eth_rx_clk]
|
||||
|
||||
# create_clock -name eth_tx_clk -period 20.0 [get_nets eth_tx_clk]
|
||||
|
||||
# set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets sys_clk]] -group [get_clocks -include_generated_clocks -of [get_nets eth_rx_clk]] -asynchronous
|
||||
|
||||
# set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets sys_clk]] -group [get_clocks -include_generated_clocks -of [get_nets eth_tx_clk]] -asynchronous
|
||||
|
||||
# set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets eth_rx_clk]] -group [get_clocks -include_generated_clocks -of [get_nets eth_tx_clk]] -asynchronous
|
||||
|
||||
# ################################################################################
|
||||
# # False path constraints
|
||||
# ################################################################################
|
||||
|
||||
|
||||
# set_false_path -quiet -through [get_nets -hierarchical -filter {mr_ff == TRUE}]
|
||||
|
||||
# set_false_path -quiet -to [get_pins -filter {REF_PIN_NAME == PRE} -of_objects [get_cells -hierarchical -filter {ars_ff1 == TRUE || ars_ff2 == TRUE}]]
|
||||
|
||||
# set_max_delay 2 -quiet -from [get_pins -filter {REF_PIN_NAME == C} -of_objects [get_cells -hierarchical -filter {ars_ff1 == TRUE}]] -to [get_pins -filter {REF_PIN_NAME == D} -of_objects [get_cells -hierarchical -filter {ars_ff2 == TRUE}]]
|
||||
################################################################################
|
||||
# IO constraints
|
||||
################################################################################
|
||||
# clk48:0
|
||||
set_property LOC F5 [get_ports {clk48}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {clk48}]
|
||||
|
||||
# clk50:0
|
||||
set_property LOC D4 [get_ports {clk50}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {clk50}]
|
||||
|
||||
# led
|
||||
set_property LOC R16 [get_ports {led}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {led}]
|
||||
|
||||
# led (n/c)
|
||||
set_property LOC T14 [get_ports {led[1]}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
|
||||
|
||||
# serial:0.tx
|
||||
set_property LOC L2 [get_ports {tx}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {tx}]
|
||||
|
||||
# serial:0.rx
|
||||
set_property LOC L3 [get_ports {rx}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {rx}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC F12 [get_ports {ddr3_addr[0]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[0]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC D15 [get_ports {ddr3_addr[1]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[1]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC J15 [get_ports {ddr3_addr[2]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[2]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC E16 [get_ports {ddr3_addr[3]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[3]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC G11 [get_ports {ddr3_addr[4]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[4]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC F15 [get_ports {ddr3_addr[5]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[5]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC H13 [get_ports {ddr3_addr[6]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[6]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC G15 [get_ports {ddr3_addr[7]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[7]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC H12 [get_ports {ddr3_addr[8]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[8]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC H16 [get_ports {ddr3_addr[9]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[9]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC H11 [get_ports {ddr3_addr[10]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[10]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC H14 [get_ports {ddr3_addr[11]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[11]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC E12 [get_ports {ddr3_addr[12]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[12]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC G16 [get_ports {ddr3_addr[13]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[13]}]
|
||||
|
||||
# ddr3:0.a
|
||||
set_property LOC J16 [get_ports {ddr3_addr[14]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_addr[14]}]
|
||||
|
||||
# ddr3:0.ba
|
||||
set_property LOC E15 [get_ports {ddr3_ba[0]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_ba[0]}]
|
||||
|
||||
# ddr3:0.ba
|
||||
set_property LOC D11 [get_ports {ddr3_ba[1]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_ba[1]}]
|
||||
|
||||
# ddr3:0.ba
|
||||
set_property LOC F13 [get_ports {ddr3_ba[2]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_ba[2]}]
|
||||
|
||||
# ddr3:0.ras_n
|
||||
set_property LOC D14 [get_ports {ddr3_ras_n}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_ras_n}]
|
||||
|
||||
# ddr3:0.cas_n
|
||||
set_property LOC E13 [get_ports {ddr3_cas_n}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_cas_n}]
|
||||
|
||||
# ddr3:0.we_n
|
||||
set_property LOC G12 [get_ports {ddr3_we_n}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_we_n}]
|
||||
|
||||
# ddr3:0.dm
|
||||
set_property LOC A13 [get_ports {ddr3_dm[0]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dm[0]}]
|
||||
|
||||
# ddr3:0.dm
|
||||
set_property LOC D9 [get_ports {ddr3_dm[1]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dm[1]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC A14 [get_ports {ddr3_dq[0]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[0]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[0]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC C12 [get_ports {ddr3_dq[1]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[1]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[1]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC B14 [get_ports {ddr3_dq[2]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[2]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[2]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC D13 [get_ports {ddr3_dq[3]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[3]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[3]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC B16 [get_ports {ddr3_dq[4]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[4]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[4]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC C11 [get_ports {ddr3_dq[5]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[5]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[5]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC C16 [get_ports {ddr3_dq[6]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[6]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[6]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC C14 [get_ports {ddr3_dq[7]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[7]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[7]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC A9 [get_ports {ddr3_dq[8]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[8]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[8]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC B10 [get_ports {ddr3_dq[9]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[9]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[9]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC C8 [get_ports {ddr3_dq[10]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[10]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[10]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC B12 [get_ports {ddr3_dq[11]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[11]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[11]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC A8 [get_ports {ddr3_dq[12]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[12]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[12]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC A12 [get_ports {ddr3_dq[13]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[13]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[13]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC C9 [get_ports {ddr3_dq[14]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[14]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[14]}]
|
||||
|
||||
# ddr3:0.dq
|
||||
set_property LOC B11 [get_ports {ddr3_dq[15]}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_dq[15]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dq[15]}]
|
||||
|
||||
# ddr3:0.dqs_p
|
||||
set_property LOC B15 [get_ports {ddr3_dqs_p[0]}]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddr3_dqs_p[0]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dqs_p[0]}]
|
||||
|
||||
# ddr3:0.dqs_p
|
||||
set_property LOC B9 [get_ports {ddr3_dqs_p[1]}]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddr3_dqs_p[1]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dqs_p[1]}]
|
||||
|
||||
# ddr3:0.dqs_n
|
||||
set_property LOC A15 [get_ports {ddr3_dqs_n[0]}]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddr3_dqs_n[0]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dqs_n[0]}]
|
||||
|
||||
# ddr3:0.dqs_n
|
||||
set_property LOC A10 [get_ports {ddr3_dqs_n[1]}]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddr3_dqs_n[1]}]
|
||||
set_property IN_TERM UNTUNED_SPLIT_60 [get_ports {ddr3_dqs_n[1]}]
|
||||
|
||||
# ddr3:0.clk_p
|
||||
set_property LOC G14 [get_ports {ddr3_clk_p}]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddr3_clk_p}]
|
||||
|
||||
# ddr3:0.clk_n
|
||||
set_property LOC F14 [get_ports {ddr3_clk_n}]
|
||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddr3_clk_n}]
|
||||
|
||||
# ddr3:0.cke
|
||||
set_property LOC E11 [get_ports {ddr3_cke}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_cke}]
|
||||
|
||||
# ddr3:0.odt
|
||||
set_property LOC D16 [get_ports {ddr3_odt}]
|
||||
set_property IOSTANDARD SSTL135 [get_ports {ddr3_odt}]
|
||||
|
||||
# ddr3:0.reset_n
|
||||
set_property LOC M16 [get_ports {ddr3_reset_n}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {ddr3_reset_n}]
|
||||
|
||||
################################################################################
|
||||
# Design constraints
|
||||
################################################################################
|
||||
|
||||
# set_property INTERNAL_VREF 0.675 [get_iobanks 34]
|
||||
|
||||
# set_property INTERNAL_VREF 0.675 [get_iobanks 15]
|
||||
|
||||
################################################################################
|
||||
# Clock constraints
|
||||
################################################################################
|
||||
|
||||
|
||||
# create_clock -name clk48 -period 20.833 [get_ports clk48]
|
||||
|
||||
# create_clock -name clk50 -period 20.0 [get_ports clk50]
|
||||
|
||||
# create_clock -name eth_rx_clk -period 20.0 [get_nets eth_rx_clk]
|
||||
|
||||
# create_clock -name eth_tx_clk -period 20.0 [get_nets eth_tx_clk]
|
||||
|
||||
# set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets sys_clk]] -group [get_clocks -include_generated_clocks -of [get_nets eth_rx_clk]] -asynchronous
|
||||
|
||||
# set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets sys_clk]] -group [get_clocks -include_generated_clocks -of [get_nets eth_tx_clk]] -asynchronous
|
||||
|
||||
# set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets eth_rx_clk]] -group [get_clocks -include_generated_clocks -of [get_nets eth_tx_clk]] -asynchronous
|
||||
|
||||
# ################################################################################
|
||||
# # False path constraints
|
||||
# ################################################################################
|
||||
|
||||
|
||||
# set_false_path -quiet -through [get_nets -hierarchical -filter {mr_ff == TRUE}]
|
||||
|
||||
# set_false_path -quiet -to [get_pins -filter {REF_PIN_NAME == PRE} -of_objects [get_cells -hierarchical -filter {ars_ff1 == TRUE || ars_ff2 == TRUE}]]
|
||||
|
||||
# set_max_delay 2 -quiet -from [get_pins -filter {REF_PIN_NAME == C} -of_objects [get_cells -hierarchical -filter {ars_ff1 == TRUE}]] -to [get_pins -filter {REF_PIN_NAME == D} -of_objects [get_cells -hierarchical -filter {ars_ff2 == TRUE}]]
|
||||
|
|
|
|||
|
|
@ -1,207 +1,207 @@
|
|||
|
||||
//
|
||||
// Module: uart_rx
|
||||
//
|
||||
// Notes:
|
||||
// - UART reciever module.
|
||||
//
|
||||
|
||||
module uart_rx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
input wire uart_rxd , // UART Recieve pin.
|
||||
input wire uart_rx_en , // Recieve enable
|
||||
output wire uart_rx_break, // Did we get a BREAK message?
|
||||
output wire uart_rx_valid, // Valid data recieved and available.
|
||||
output reg [PAYLOAD_BITS-1:0] uart_rx_data // The recieved data.
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_rxd line. Helps break long timing
|
||||
// paths from input pins into the logic.
|
||||
reg rxd_reg;
|
||||
reg rxd_reg_0;
|
||||
|
||||
//
|
||||
// Storage for the recieved serial data.
|
||||
reg [PAYLOAD_BITS-1:0] recieved_data;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of recieved bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Sample of the UART input line whenever we are in the middle of a bit frame.
|
||||
reg bit_sample;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_RECV = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Output assignment
|
||||
//
|
||||
|
||||
assign uart_rx_break = uart_rx_valid && ~|recieved_data;
|
||||
assign uart_rx_valid = fsm_state == FSM_STOP && n_fsm_state == FSM_IDLE;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(!resetn) begin
|
||||
uart_rx_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if (fsm_state == FSM_STOP) begin
|
||||
uart_rx_data <= recieved_data;
|
||||
end
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT ||
|
||||
fsm_state == FSM_STOP &&
|
||||
cycle_counter == CYCLES_PER_BIT/2;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = rxd_reg ? FSM_IDLE : FSM_START;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_RECV : FSM_START;
|
||||
FSM_RECV : n_fsm_state = payload_done ? FSM_STOP : FSM_RECV ;
|
||||
FSM_STOP : n_fsm_state = next_bit ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the recieved data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_recieved_data
|
||||
if(!resetn) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE ) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit ) begin
|
||||
recieved_data[PAYLOAD_BITS-1] <= bit_sample;
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
recieved_data[i] <= recieved_data[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Increments the bit counter when recieving.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_RECV) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Sample the recieved bit when in the middle of a bit frame.
|
||||
always @(posedge clk) begin : p_bit_sample
|
||||
if(!resetn) begin
|
||||
bit_sample <= 1'b0;
|
||||
end else if (cycle_counter == CYCLES_PER_BIT/2) begin
|
||||
bit_sample <= rxd_reg;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when recieving.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_RECV ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the rxd_reg.
|
||||
always @(posedge clk) begin : p_rxd_reg
|
||||
if(!resetn) begin
|
||||
rxd_reg <= 1'b1;
|
||||
rxd_reg_0 <= 1'b1;
|
||||
end else if(uart_rx_en) begin
|
||||
rxd_reg <= rxd_reg_0;
|
||||
rxd_reg_0 <= uart_rxd;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
//
|
||||
// Module: uart_rx
|
||||
//
|
||||
// Notes:
|
||||
// - UART reciever module.
|
||||
//
|
||||
|
||||
module uart_rx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
input wire uart_rxd , // UART Recieve pin.
|
||||
input wire uart_rx_en , // Recieve enable
|
||||
output wire uart_rx_break, // Did we get a BREAK message?
|
||||
output wire uart_rx_valid, // Valid data recieved and available.
|
||||
output reg [PAYLOAD_BITS-1:0] uart_rx_data // The recieved data.
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_rxd line. Helps break long timing
|
||||
// paths from input pins into the logic.
|
||||
reg rxd_reg;
|
||||
reg rxd_reg_0;
|
||||
|
||||
//
|
||||
// Storage for the recieved serial data.
|
||||
reg [PAYLOAD_BITS-1:0] recieved_data;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of recieved bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Sample of the UART input line whenever we are in the middle of a bit frame.
|
||||
reg bit_sample;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_RECV = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Output assignment
|
||||
//
|
||||
|
||||
assign uart_rx_break = uart_rx_valid && ~|recieved_data;
|
||||
assign uart_rx_valid = fsm_state == FSM_STOP && n_fsm_state == FSM_IDLE;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(!resetn) begin
|
||||
uart_rx_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if (fsm_state == FSM_STOP) begin
|
||||
uart_rx_data <= recieved_data;
|
||||
end
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT ||
|
||||
fsm_state == FSM_STOP &&
|
||||
cycle_counter == CYCLES_PER_BIT/2;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = rxd_reg ? FSM_IDLE : FSM_START;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_RECV : FSM_START;
|
||||
FSM_RECV : n_fsm_state = payload_done ? FSM_STOP : FSM_RECV ;
|
||||
FSM_STOP : n_fsm_state = next_bit ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the recieved data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_recieved_data
|
||||
if(!resetn) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE ) begin
|
||||
recieved_data <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit ) begin
|
||||
recieved_data[PAYLOAD_BITS-1] <= bit_sample;
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
recieved_data[i] <= recieved_data[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Increments the bit counter when recieving.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_RECV) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_RECV && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Sample the recieved bit when in the middle of a bit frame.
|
||||
always @(posedge clk) begin : p_bit_sample
|
||||
if(!resetn) begin
|
||||
bit_sample <= 1'b0;
|
||||
end else if (cycle_counter == CYCLES_PER_BIT/2) begin
|
||||
bit_sample <= rxd_reg;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when recieving.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_RECV ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the rxd_reg.
|
||||
always @(posedge clk) begin : p_rxd_reg
|
||||
if(!resetn) begin
|
||||
rxd_reg <= 1'b1;
|
||||
rxd_reg_0 <= 1'b1;
|
||||
end else if(uart_rx_en) begin
|
||||
rxd_reg <= rxd_reg_0;
|
||||
rxd_reg_0 <= uart_rxd;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,187 +1,187 @@
|
|||
|
||||
|
||||
//
|
||||
// Module: uart_tx
|
||||
//
|
||||
// Notes:
|
||||
// - UART transmitter module.
|
||||
//
|
||||
|
||||
module uart_tx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
output wire uart_txd , // UART transmit pin.
|
||||
output wire uart_tx_busy, // Module busy sending previous item.
|
||||
input wire uart_tx_en , // Send the data on uart_tx_data
|
||||
input wire [PAYLOAD_BITS-1:0] uart_tx_data // The data to be sent
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_txd line. Helps break long timing
|
||||
// paths from the logic to the output pins.
|
||||
reg txd_reg;
|
||||
|
||||
//
|
||||
// Storage for the serial data to be sent.
|
||||
reg [PAYLOAD_BITS-1:0] data_to_send;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of sent bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_SEND = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
assign uart_tx_busy = fsm_state != FSM_IDLE;
|
||||
assign uart_txd = txd_reg;
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
wire stop_done = bit_counter == STOP_BITS && fsm_state == FSM_STOP;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = uart_tx_en ? FSM_START: FSM_IDLE ;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_SEND : FSM_START;
|
||||
FSM_SEND : n_fsm_state = payload_done ? FSM_STOP : FSM_SEND ;
|
||||
FSM_STOP : n_fsm_state = stop_done ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the sent data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_data_to_send
|
||||
if(!resetn) begin
|
||||
data_to_send <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE && uart_tx_en) begin
|
||||
data_to_send <= uart_tx_data;
|
||||
end else if(fsm_state == FSM_SEND && next_bit ) begin
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
data_to_send[i] <= data_to_send[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the bit counter each time a new bit frame is sent.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_SEND && fsm_state != FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_SEND && n_fsm_state == FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_STOP&& next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end else if(fsm_state == FSM_SEND && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when sending.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_SEND ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the txd_reg.
|
||||
always @(posedge clk) begin : p_txd_reg
|
||||
if(!resetn) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_IDLE) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_START) begin
|
||||
txd_reg <= 1'b0;
|
||||
end else if(fsm_state == FSM_SEND) begin
|
||||
txd_reg <= data_to_send[0];
|
||||
end else if(fsm_state == FSM_STOP) begin
|
||||
txd_reg <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
//
|
||||
// Module: uart_tx
|
||||
//
|
||||
// Notes:
|
||||
// - UART transmitter module.
|
||||
//
|
||||
|
||||
module uart_tx(
|
||||
input wire clk , // Top level system clock input.
|
||||
input wire resetn , // Asynchronous active low reset.
|
||||
output wire uart_txd , // UART transmit pin.
|
||||
output wire uart_tx_busy, // Module busy sending previous item.
|
||||
input wire uart_tx_en , // Send the data on uart_tx_data
|
||||
input wire [PAYLOAD_BITS-1:0] uart_tx_data // The data to be sent
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// External parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Input bit rate of the UART line.
|
||||
parameter BIT_RATE = 9600; // bits / sec
|
||||
localparam BIT_P = 1_000_000_000 * 1/BIT_RATE; // nanoseconds
|
||||
|
||||
//
|
||||
// Clock frequency in hertz.
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
localparam CLK_P = 1_000_000_000 * 1/CLK_HZ; // nanoseconds
|
||||
|
||||
//
|
||||
// Number of data bits recieved per UART packet.
|
||||
parameter PAYLOAD_BITS = 8;
|
||||
|
||||
//
|
||||
// Number of stop bits indicating the end of a packet.
|
||||
parameter STOP_BITS = 1;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal parameters.
|
||||
//
|
||||
|
||||
//
|
||||
// Number of clock cycles per uart bit.
|
||||
localparam CYCLES_PER_BIT = BIT_P / CLK_P;
|
||||
|
||||
//
|
||||
// Size of the registers which store sample counts and bit durations.
|
||||
localparam COUNT_REG_LEN = 1+$clog2(CYCLES_PER_BIT);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal registers.
|
||||
//
|
||||
|
||||
//
|
||||
// Internally latched value of the uart_txd line. Helps break long timing
|
||||
// paths from the logic to the output pins.
|
||||
reg txd_reg;
|
||||
|
||||
//
|
||||
// Storage for the serial data to be sent.
|
||||
reg [PAYLOAD_BITS-1:0] data_to_send;
|
||||
|
||||
//
|
||||
// Counter for the number of cycles over a packet bit.
|
||||
reg [COUNT_REG_LEN-1:0] cycle_counter;
|
||||
|
||||
//
|
||||
// Counter for the number of sent bits of the packet.
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
//
|
||||
// Current and next states of the internal FSM.
|
||||
reg [2:0] fsm_state;
|
||||
reg [2:0] n_fsm_state;
|
||||
|
||||
localparam FSM_IDLE = 0;
|
||||
localparam FSM_START= 1;
|
||||
localparam FSM_SEND = 2;
|
||||
localparam FSM_STOP = 3;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSM next state selection.
|
||||
//
|
||||
|
||||
assign uart_tx_busy = fsm_state != FSM_IDLE;
|
||||
assign uart_txd = txd_reg;
|
||||
|
||||
wire next_bit = cycle_counter == CYCLES_PER_BIT;
|
||||
wire payload_done = bit_counter == PAYLOAD_BITS ;
|
||||
wire stop_done = bit_counter == STOP_BITS && fsm_state == FSM_STOP;
|
||||
|
||||
//
|
||||
// Handle picking the next state.
|
||||
always @(*) begin : p_n_fsm_state
|
||||
case(fsm_state)
|
||||
FSM_IDLE : n_fsm_state = uart_tx_en ? FSM_START: FSM_IDLE ;
|
||||
FSM_START: n_fsm_state = next_bit ? FSM_SEND : FSM_START;
|
||||
FSM_SEND : n_fsm_state = payload_done ? FSM_STOP : FSM_SEND ;
|
||||
FSM_STOP : n_fsm_state = stop_done ? FSM_IDLE : FSM_STOP ;
|
||||
default : n_fsm_state = FSM_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Internal register setting and re-setting.
|
||||
//
|
||||
|
||||
//
|
||||
// Handle updates to the sent data register.
|
||||
integer i = 0;
|
||||
always @(posedge clk) begin : p_data_to_send
|
||||
if(!resetn) begin
|
||||
data_to_send <= {PAYLOAD_BITS{1'b0}};
|
||||
end else if(fsm_state == FSM_IDLE && uart_tx_en) begin
|
||||
data_to_send <= uart_tx_data;
|
||||
end else if(fsm_state == FSM_SEND && next_bit ) begin
|
||||
for ( i = PAYLOAD_BITS-2; i >= 0; i = i - 1) begin
|
||||
data_to_send[i] <= data_to_send[i+1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the bit counter each time a new bit frame is sent.
|
||||
always @(posedge clk) begin : p_bit_counter
|
||||
if(!resetn) begin
|
||||
bit_counter <= 4'b0;
|
||||
end else if(fsm_state != FSM_SEND && fsm_state != FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_SEND && n_fsm_state == FSM_STOP) begin
|
||||
bit_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_STOP&& next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end else if(fsm_state == FSM_SEND && next_bit) begin
|
||||
bit_counter <= bit_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Increments the cycle counter when sending.
|
||||
always @(posedge clk) begin : p_cycle_counter
|
||||
if(!resetn) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(next_bit) begin
|
||||
cycle_counter <= {COUNT_REG_LEN{1'b0}};
|
||||
end else if(fsm_state == FSM_START ||
|
||||
fsm_state == FSM_SEND ||
|
||||
fsm_state == FSM_STOP ) begin
|
||||
cycle_counter <= cycle_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Progresses the next FSM state.
|
||||
always @(posedge clk) begin : p_fsm_state
|
||||
if(!resetn) begin
|
||||
fsm_state <= FSM_IDLE;
|
||||
end else begin
|
||||
fsm_state <= n_fsm_state;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// Responsible for updating the internal value of the txd_reg.
|
||||
always @(posedge clk) begin : p_txd_reg
|
||||
if(!resetn) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_IDLE) begin
|
||||
txd_reg <= 1'b1;
|
||||
end else if(fsm_state == FSM_START) begin
|
||||
txd_reg <= 1'b0;
|
||||
end else if(fsm_state == FSM_SEND) begin
|
||||
txd_reg <= data_to_send[0];
|
||||
end else if(fsm_state == FSM_STOP) begin
|
||||
txd_reg <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,64 +1,64 @@
|
|||
[tasks]
|
||||
prf2lanes_83MHz prf opt_2lanes opt_83MHz opt_with_ODELAY
|
||||
prf4lanes_83MHz prf opt_4lanes opt_83MHz opt_with_ODELAY
|
||||
prf8lanes_83MHz prf opt_8lanes opt_83MHz opt_with_ODELAY opt_WB_ERR
|
||||
prf2lanes_100MHz prf opt_2lanes opt_100MHz opt_with_ODELAY opt_WB_ERR
|
||||
prf4lanes_100MHz prf opt_4lanes opt_100MHz opt_with_ODELAY
|
||||
prf8lanes_100MHz prf opt_8lanes opt_100MHz opt_with_ODELAY
|
||||
prf_no_ODELAY prf opt_8lanes opt_100MHz
|
||||
|
||||
[options]
|
||||
prf: mode prove
|
||||
prf: depth 7
|
||||
|
||||
[engines]
|
||||
prf: smtbmc
|
||||
|
||||
[script]
|
||||
read -formal ddr3_controller.v
|
||||
read -formal fwb_slave.v
|
||||
|
||||
--pycode-begin--
|
||||
|
||||
# Number of Lanes
|
||||
if "opt_2lanes" in tags:
|
||||
cmd = "chparam -set LANES 2 ddr3_controller\n"
|
||||
elif "opt_4lanes" in tags:
|
||||
cmd = "chparam -set LANES 4 ddr3_controller\n"
|
||||
elif "opt_8lanes" in tags:
|
||||
cmd = "chparam -set LANES 8 ddr3_controller\n"
|
||||
else:
|
||||
cmd = "chparam -set LANES 8 ddr3_controller\n"
|
||||
|
||||
# Clock period
|
||||
if "opt_83MHz" in tags:
|
||||
cmd += "chparam -set CONTROLLER_CLK_PERIOD 12000 ddr3_controller\n"
|
||||
cmd += "chparam -set DDR3_CLK_PERIOD 3000 ddr3_controller\n"
|
||||
elif "opt_100MHz" in tags:
|
||||
cmd += "chparam -set CONTROLLER_CLK_PERIOD 10000 ddr3_controller\n"
|
||||
cmd += "chparam -set DDR3_CLK_PERIOD 2500 ddr3_controller\n"
|
||||
else:
|
||||
cmd += "chparam -set CONTROLLER_CLK_PERIOD 10000 ddr3_controller\n"
|
||||
cmd += "chparam -set DDR3_CLK_PERIOD 2500 ddr3_controller\n"
|
||||
|
||||
# ODELAY support
|
||||
if "opt_with_ODELAY" in tags:
|
||||
cmd += "chparam -set ODELAY_SUPPORTED 1 ddr3_controller\n"
|
||||
else:
|
||||
cmd += "chparam -set ODELAY_SUPPORTED 0 ddr3_controller\n"
|
||||
|
||||
# Wishbone Error
|
||||
if "opt_WB_ERR" in tags:
|
||||
cmd += "chparam -set WB_ERROR 1 ddr3_controller\n"
|
||||
else:
|
||||
cmd += "chparam -set WB_ERROR 0 ddr3_controller\n"
|
||||
|
||||
output(cmd)
|
||||
--pycode-end--
|
||||
|
||||
prep -top ddr3_controller
|
||||
|
||||
[files]
|
||||
./rtl/ddr3_controller.v
|
||||
./formal/fwb_slave.v
|
||||
|
||||
[tasks]
|
||||
prf2lanes_83MHz prf opt_2lanes opt_83MHz opt_with_ODELAY
|
||||
prf4lanes_83MHz prf opt_4lanes opt_83MHz opt_with_ODELAY
|
||||
prf8lanes_83MHz prf opt_8lanes opt_83MHz opt_with_ODELAY opt_WB_ERR
|
||||
prf2lanes_100MHz prf opt_2lanes opt_100MHz opt_with_ODELAY opt_WB_ERR
|
||||
prf4lanes_100MHz prf opt_4lanes opt_100MHz opt_with_ODELAY
|
||||
prf8lanes_100MHz prf opt_8lanes opt_100MHz opt_with_ODELAY
|
||||
prf_no_ODELAY prf opt_8lanes opt_100MHz
|
||||
|
||||
[options]
|
||||
prf: mode prove
|
||||
prf: depth 7
|
||||
|
||||
[engines]
|
||||
prf: smtbmc
|
||||
|
||||
[script]
|
||||
read -formal ddr3_controller.v
|
||||
read -formal fwb_slave.v
|
||||
|
||||
--pycode-begin--
|
||||
|
||||
# Number of Lanes
|
||||
if "opt_2lanes" in tags:
|
||||
cmd = "chparam -set LANES 2 ddr3_controller\n"
|
||||
elif "opt_4lanes" in tags:
|
||||
cmd = "chparam -set LANES 4 ddr3_controller\n"
|
||||
elif "opt_8lanes" in tags:
|
||||
cmd = "chparam -set LANES 8 ddr3_controller\n"
|
||||
else:
|
||||
cmd = "chparam -set LANES 8 ddr3_controller\n"
|
||||
|
||||
# Clock period
|
||||
if "opt_83MHz" in tags:
|
||||
cmd += "chparam -set CONTROLLER_CLK_PERIOD 12000 ddr3_controller\n"
|
||||
cmd += "chparam -set DDR3_CLK_PERIOD 3000 ddr3_controller\n"
|
||||
elif "opt_100MHz" in tags:
|
||||
cmd += "chparam -set CONTROLLER_CLK_PERIOD 10000 ddr3_controller\n"
|
||||
cmd += "chparam -set DDR3_CLK_PERIOD 2500 ddr3_controller\n"
|
||||
else:
|
||||
cmd += "chparam -set CONTROLLER_CLK_PERIOD 10000 ddr3_controller\n"
|
||||
cmd += "chparam -set DDR3_CLK_PERIOD 2500 ddr3_controller\n"
|
||||
|
||||
# ODELAY support
|
||||
if "opt_with_ODELAY" in tags:
|
||||
cmd += "chparam -set ODELAY_SUPPORTED 1 ddr3_controller\n"
|
||||
else:
|
||||
cmd += "chparam -set ODELAY_SUPPORTED 0 ddr3_controller\n"
|
||||
|
||||
# Wishbone Error
|
||||
if "opt_WB_ERR" in tags:
|
||||
cmd += "chparam -set WB_ERROR 1 ddr3_controller\n"
|
||||
else:
|
||||
cmd += "chparam -set WB_ERROR 0 ddr3_controller\n"
|
||||
|
||||
output(cmd)
|
||||
--pycode-end--
|
||||
|
||||
prep -top ddr3_controller
|
||||
|
||||
[files]
|
||||
./rtl/ddr3_controller.v
|
||||
./formal/fwb_slave.v
|
||||
|
||||
|
|
|
|||
|
|
@ -1,83 +1,83 @@
|
|||
[tasks]
|
||||
prf2lanes_83MHz_ECC_1 prf opt_2lanes opt_83MHz opt_with_ODELAY opt_ECC_1
|
||||
prf8lanes_100MHz_ECC_1 prf opt_8lanes opt_100MHz opt_ECC_1
|
||||
prf8lanes_100MHz_ECC_1_err prf opt_8lanes opt_100MHz opt_with_ODELAY opt_ECC_1 opt_WB_ERR
|
||||
|
||||
prf2lanes_83MHz_ECC_2_err prf opt_2lanes opt_83MHz opt_with_ODELAY opt_ECC_2 opt_WB_ERR
|
||||
|
||||
prf2lanes_83MHz_ECC_3 prf_ECC3 opt_2lanes opt_100MHz opt_with_ODELAY opt_ECC_3
|
||||
prf8lanes_100MHz_ECC_3 prf_ECC3 opt_8lanes opt_83MHz opt_ECC_3
|
||||
prf8lanes_100MHz_ECC_3_err prf_ECC3 opt_8lanes opt_100MHz opt_ECC_3 opt_WB_ERR
|
||||
|
||||
[options]
|
||||
prf: mode prove
|
||||
prf: depth 7
|
||||
prf_ECC3: mode prove
|
||||
prf_ECC3: depth 5
|
||||
|
||||
[engines]
|
||||
prf: smtbmc
|
||||
prf_ECC3: smtbmc
|
||||
|
||||
[script]
|
||||
read -formal ddr3_controller.v
|
||||
read -formal fwb_slave.v
|
||||
read -formal ecc_dec.sv
|
||||
read -formal ecc_enc.sv
|
||||
|
||||
--pycode-begin--
|
||||
|
||||
# Number of Lanes
|
||||
if "opt_2lanes" in tags:
|
||||
cmd = "chparam -set LANES 2 ddr3_controller\n"
|
||||
elif "opt_4lanes" in tags:
|
||||
cmd = "chparam -set LANES 4 ddr3_controller\n"
|
||||
elif "opt_8lanes" in tags:
|
||||
cmd = "chparam -set LANES 8 ddr3_controller\n"
|
||||
else:
|
||||
cmd = "chparam -set LANES 8 ddr3_controller\n"
|
||||
|
||||
# Clock period
|
||||
if "opt_83MHz" in tags:
|
||||
cmd += "chparam -set CONTROLLER_CLK_PERIOD 12000 ddr3_controller\n"
|
||||
cmd += "chparam -set DDR3_CLK_PERIOD 3000 ddr3_controller\n"
|
||||
elif "opt_100MHz" in tags:
|
||||
cmd += "chparam -set CONTROLLER_CLK_PERIOD 10000 ddr3_controller\n"
|
||||
cmd += "chparam -set DDR3_CLK_PERIOD 2500 ddr3_controller\n"
|
||||
else:
|
||||
cmd += "chparam -set CONTROLLER_CLK_PERIOD 10000 ddr3_controller\n"
|
||||
cmd += "chparam -set DDR3_CLK_PERIOD 2500 ddr3_controller\n"
|
||||
|
||||
# ODELAY support
|
||||
if "opt_with_ODELAY" in tags:
|
||||
cmd += "chparam -set ODELAY_SUPPORTED 1 ddr3_controller\n"
|
||||
else:
|
||||
cmd += "chparam -set ODELAY_SUPPORTED 0 ddr3_controller\n"
|
||||
|
||||
# ECC
|
||||
if "opt_ECC_3" in tags:
|
||||
cmd += "chparam -set ECC_ENABLE 3 ddr3_controller\n"
|
||||
elif "opt_ECC_2" in tags:
|
||||
cmd += "chparam -set ECC_ENABLE 2 ddr3_controller\n"
|
||||
elif "opt_ECC_1" in tags:
|
||||
cmd += "chparam -set ECC_ENABLE 1 ddr3_controller\n"
|
||||
else:
|
||||
cmd += "chparam -set ECC_ENABLE 0 ddr3_controller\n"
|
||||
|
||||
# Wishbone Error
|
||||
if "opt_WB_ERR" in tags:
|
||||
cmd += "chparam -set WB_ERROR 1 ddr3_controller\n"
|
||||
else:
|
||||
cmd += "chparam -set WB_ERROR 0 ddr3_controller\n"
|
||||
|
||||
output(cmd)
|
||||
--pycode-end--
|
||||
|
||||
prep -top ddr3_controller
|
||||
|
||||
[files]
|
||||
./rtl/ddr3_controller.v
|
||||
./formal/fwb_slave.v
|
||||
./rtl/ecc/ecc_dec.sv
|
||||
./rtl/ecc/ecc_enc.sv
|
||||
|
||||
[tasks]
|
||||
prf2lanes_83MHz_ECC_1 prf opt_2lanes opt_83MHz opt_with_ODELAY opt_ECC_1
|
||||
prf8lanes_100MHz_ECC_1 prf opt_8lanes opt_100MHz opt_ECC_1
|
||||
prf8lanes_100MHz_ECC_1_err prf opt_8lanes opt_100MHz opt_with_ODELAY opt_ECC_1 opt_WB_ERR
|
||||
|
||||
prf2lanes_83MHz_ECC_2_err prf opt_2lanes opt_83MHz opt_with_ODELAY opt_ECC_2 opt_WB_ERR
|
||||
|
||||
prf2lanes_83MHz_ECC_3 prf_ECC3 opt_2lanes opt_100MHz opt_with_ODELAY opt_ECC_3
|
||||
prf8lanes_100MHz_ECC_3 prf_ECC3 opt_8lanes opt_83MHz opt_ECC_3
|
||||
prf8lanes_100MHz_ECC_3_err prf_ECC3 opt_8lanes opt_100MHz opt_ECC_3 opt_WB_ERR
|
||||
|
||||
[options]
|
||||
prf: mode prove
|
||||
prf: depth 7
|
||||
prf_ECC3: mode prove
|
||||
prf_ECC3: depth 5
|
||||
|
||||
[engines]
|
||||
prf: smtbmc
|
||||
prf_ECC3: smtbmc
|
||||
|
||||
[script]
|
||||
read -formal ddr3_controller.v
|
||||
read -formal fwb_slave.v
|
||||
read -formal ecc_dec.sv
|
||||
read -formal ecc_enc.sv
|
||||
|
||||
--pycode-begin--
|
||||
|
||||
# Number of Lanes
|
||||
if "opt_2lanes" in tags:
|
||||
cmd = "chparam -set LANES 2 ddr3_controller\n"
|
||||
elif "opt_4lanes" in tags:
|
||||
cmd = "chparam -set LANES 4 ddr3_controller\n"
|
||||
elif "opt_8lanes" in tags:
|
||||
cmd = "chparam -set LANES 8 ddr3_controller\n"
|
||||
else:
|
||||
cmd = "chparam -set LANES 8 ddr3_controller\n"
|
||||
|
||||
# Clock period
|
||||
if "opt_83MHz" in tags:
|
||||
cmd += "chparam -set CONTROLLER_CLK_PERIOD 12000 ddr3_controller\n"
|
||||
cmd += "chparam -set DDR3_CLK_PERIOD 3000 ddr3_controller\n"
|
||||
elif "opt_100MHz" in tags:
|
||||
cmd += "chparam -set CONTROLLER_CLK_PERIOD 10000 ddr3_controller\n"
|
||||
cmd += "chparam -set DDR3_CLK_PERIOD 2500 ddr3_controller\n"
|
||||
else:
|
||||
cmd += "chparam -set CONTROLLER_CLK_PERIOD 10000 ddr3_controller\n"
|
||||
cmd += "chparam -set DDR3_CLK_PERIOD 2500 ddr3_controller\n"
|
||||
|
||||
# ODELAY support
|
||||
if "opt_with_ODELAY" in tags:
|
||||
cmd += "chparam -set ODELAY_SUPPORTED 1 ddr3_controller\n"
|
||||
else:
|
||||
cmd += "chparam -set ODELAY_SUPPORTED 0 ddr3_controller\n"
|
||||
|
||||
# ECC
|
||||
if "opt_ECC_3" in tags:
|
||||
cmd += "chparam -set ECC_ENABLE 3 ddr3_controller\n"
|
||||
elif "opt_ECC_2" in tags:
|
||||
cmd += "chparam -set ECC_ENABLE 2 ddr3_controller\n"
|
||||
elif "opt_ECC_1" in tags:
|
||||
cmd += "chparam -set ECC_ENABLE 1 ddr3_controller\n"
|
||||
else:
|
||||
cmd += "chparam -set ECC_ENABLE 0 ddr3_controller\n"
|
||||
|
||||
# Wishbone Error
|
||||
if "opt_WB_ERR" in tags:
|
||||
cmd += "chparam -set WB_ERROR 1 ddr3_controller\n"
|
||||
else:
|
||||
cmd += "chparam -set WB_ERROR 0 ddr3_controller\n"
|
||||
|
||||
output(cmd)
|
||||
--pycode-end--
|
||||
|
||||
prep -top ddr3_controller
|
||||
|
||||
[files]
|
||||
./rtl/ddr3_controller.v
|
||||
./formal/fwb_slave.v
|
||||
./rtl/ecc/ecc_dec.sv
|
||||
./rtl/ecc/ecc_enc.sv
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
[options]
|
||||
mode prove
|
||||
depth 7 # minimum for 100MHz controller clk
|
||||
#mode cover
|
||||
#depth 50
|
||||
|
||||
[engines]
|
||||
smtbmc
|
||||
|
||||
[script]
|
||||
read -formal ddr3_controller.v
|
||||
read -formal fwb_slave.v
|
||||
read -formal ecc_dec.sv
|
||||
read -formal ecc_enc.sv
|
||||
prep -top ddr3_controller
|
||||
|
||||
|
||||
[files]
|
||||
./rtl/ddr3_controller.v
|
||||
./formal/fwb_slave.v
|
||||
./rtl/ecc/ecc_dec.sv
|
||||
./rtl/ecc/ecc_enc.sv
|
||||
[options]
|
||||
mode prove
|
||||
depth 7 # minimum for 100MHz controller clk
|
||||
#mode cover
|
||||
#depth 50
|
||||
|
||||
[engines]
|
||||
smtbmc
|
||||
|
||||
[script]
|
||||
read -formal ddr3_controller.v
|
||||
read -formal fwb_slave.v
|
||||
read -formal ecc_dec.sv
|
||||
read -formal ecc_enc.sv
|
||||
prep -top ddr3_controller
|
||||
|
||||
|
||||
[files]
|
||||
./rtl/ddr3_controller.v
|
||||
./formal/fwb_slave.v
|
||||
./rtl/ecc/ecc_dec.sv
|
||||
./rtl/ecc/ecc_enc.sv
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
[options]
|
||||
mode prove
|
||||
depth 1
|
||||
#mode cover
|
||||
#depth 50
|
||||
|
||||
[engines]
|
||||
smtbmc
|
||||
|
||||
[script]
|
||||
read -formal ecc_formal.v
|
||||
read -formal ecc_dec.sv
|
||||
read -formal ecc_enc.sv
|
||||
prep -top ecc_formal
|
||||
|
||||
|
||||
[files]
|
||||
./formal/ecc_formal.v
|
||||
./rtl/ecc/ecc_dec.sv
|
||||
./rtl/ecc/ecc_enc.sv
|
||||
[options]
|
||||
mode prove
|
||||
depth 1
|
||||
#mode cover
|
||||
#depth 50
|
||||
|
||||
[engines]
|
||||
smtbmc
|
||||
|
||||
[script]
|
||||
read -formal ecc_formal.v
|
||||
read -formal ecc_dec.sv
|
||||
read -formal ecc_enc.sv
|
||||
prep -top ecc_formal
|
||||
|
||||
|
||||
[files]
|
||||
./formal/ecc_formal.v
|
||||
./rtl/ecc/ecc_dec.sv
|
||||
./rtl/ecc/ecc_enc.sv
|
||||
|
|
|
|||
|
|
@ -1,125 +1,125 @@
|
|||
module ecc_formal;
|
||||
parameter K = 8,
|
||||
P0_LSB = 0;
|
||||
|
||||
// function to find number of check bits
|
||||
function integer calculate_m;
|
||||
input integer k;
|
||||
integer m;
|
||||
begin
|
||||
m=1;
|
||||
while (2**m < m+k+1) m=m+1;
|
||||
calculate_m = m;
|
||||
end
|
||||
endfunction
|
||||
|
||||
// anyseq indicates nets that are controllable by engine
|
||||
(*anyseq*)wire[K-1:0] d_i; // information input
|
||||
(*anyseq*) wire[1:0] corrupted; // 0 or 3 = not corrupted bit, 1 = 1 corrupted bit, 2 = 2 corrupted bits
|
||||
(*anyseq*) wire[$clog2(K+calculate_m(K))-1:0] corrupted_bit1, corrupted_bit2; // which bit will be corrupted
|
||||
|
||||
wire[K-1:0] q_o_dec;
|
||||
wire[K+calculate_m(K):0] q_o_enc;
|
||||
reg[K+calculate_m(K):0] q_o_enc_corrupted;
|
||||
wire sb_err_o;
|
||||
wire db_err_o;
|
||||
|
||||
ecc_enc #(
|
||||
.K(K), //Information bit vector size
|
||||
.P0_LSB(P0_LSB) //0: p0 is located at MSB
|
||||
//1: p0 is located at LSB
|
||||
) ecc_enc_inst (
|
||||
.d_i(d_i), //information bit vector input
|
||||
.q_o(q_o_enc), //encoded data word output
|
||||
.p_o(), //parity vector output
|
||||
.p0_o() //extended parity bit
|
||||
);
|
||||
|
||||
ecc_dec #(
|
||||
.K(K), //Information bit vector size
|
||||
.LATENCY(0), //0: no latency (combinatorial design)
|
||||
//1: registered outputs
|
||||
//2: registered inputs+outputs
|
||||
.P0_LSB(P0_LSB) //0: p0 is located at MSB
|
||||
//1: p0 is located at LSB
|
||||
) ecc_dec_inst (
|
||||
//clock/reset ports (if LATENCY > 0)
|
||||
.rst_ni(1'b1), //asynchronous reset
|
||||
.clk_i(1'b0), //clock input
|
||||
.clkena_i(1'b0), //clock enable input
|
||||
//data ports
|
||||
.d_i(q_o_enc_corrupted), //encoded code word input
|
||||
.q_o(q_o_dec), //information bit vector output
|
||||
.syndrome_o(), //syndrome vector output
|
||||
//flags
|
||||
.sb_err_o(sb_err_o), //single bit error detected
|
||||
.db_err_o(db_err_o), //double bit error detected
|
||||
.sb_fix_o() //repaired error in the information bits
|
||||
);
|
||||
|
||||
`ifdef FORMAL
|
||||
(*gclk*) reg f_clk = 0; // reference: https://symbiyosys.readthedocs.io/en/latest/verilog.html#global-clock
|
||||
reg[9:0] f_counter = 0;
|
||||
|
||||
// corrupt the information based on the value of "corrupted" which is controllable by formal engine:
|
||||
// 0 = no corrupted bits , 1 = 1 corrupted bit, 2 = 2 corrupted bits, 3 = no corrupted bits
|
||||
always @* begin
|
||||
q_o_enc_corrupted = q_o_enc;
|
||||
if(corrupted == 1) begin
|
||||
q_o_enc_corrupted[corrupted_bit1] = !q_o_enc_corrupted[corrupted_bit1]; //corrupt 1 random bit
|
||||
assume(corrupted_bit1 != (K+calculate_m(K))); //
|
||||
end
|
||||
else if (corrupted == 2) begin // flip 2 bits
|
||||
q_o_enc_corrupted[corrupted_bit1] = !q_o_enc_corrupted[corrupted_bit1]; //corrupt 2 random bits
|
||||
q_o_enc_corrupted[corrupted_bit2] = !q_o_enc_corrupted[corrupted_bit2];
|
||||
end
|
||||
assume(corrupted_bit1 != corrupted_bit2); // corrupted bit should be different (in case of 2 corrupted bits)
|
||||
assume(corrupted_bit1 <= (K+calculate_m(K))); // corrupted bit should be within the index of q_o_enc_corrupted
|
||||
assume(corrupted_bit2 <= (K+calculate_m(K))); // corrupted bit should be within the index of q_o_enc_corrupted
|
||||
end
|
||||
|
||||
// main contract of this design
|
||||
always @* begin
|
||||
// if no corrupted bits, then decoded info must be equal to original info, and error flags should be low
|
||||
// OR there is 1 corrupted bit but its the MSB p0 that is corrupted
|
||||
if( (corrupted == 0 || corrupted == 3) || ( (corrupted == 1) && (corrupted_bit1 == (K+calculate_m(K))) ) ) begin
|
||||
assert(d_i == q_o_dec);
|
||||
assert(!sb_err_o);
|
||||
assert(!db_err_o);
|
||||
end
|
||||
// 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
|
||||
else if(corrupted == 1) begin
|
||||
assert(d_i == q_o_dec);
|
||||
assert(sb_err_o);
|
||||
assert(!db_err_o);
|
||||
end
|
||||
// if 2 corrupted bits, then single-bit error flag must be low, double-bit error flag must be high
|
||||
else if(corrupted == 2) begin
|
||||
assert(!sb_err_o);
|
||||
assert(db_err_o);
|
||||
end
|
||||
end
|
||||
|
||||
// cover 10 cycles
|
||||
always @(posedge f_clk) begin
|
||||
f_counter <= f_counter + 1;
|
||||
assume(corrupted == f_counter[1:0]); // number of corrupted bits change per clock cycle
|
||||
cover((f_counter == 10));
|
||||
end
|
||||
|
||||
// simulate random information
|
||||
always @(posedge f_clk) begin
|
||||
assume(d_i != $past(d_i,1));
|
||||
assume(d_i != $past(d_i,2));
|
||||
assume(d_i != $past(d_i,3));
|
||||
assume(d_i != $past(d_i,4));
|
||||
assume(d_i != $past(d_i,5));
|
||||
assume(d_i != $past(d_i,6));
|
||||
assume(d_i != $past(d_i,7));
|
||||
assume(d_i != $past(d_i,8));
|
||||
assume(d_i != $past(d_i,9));
|
||||
assume(d_i != $past(d_i,10));
|
||||
end
|
||||
|
||||
`endif
|
||||
module ecc_formal;
|
||||
parameter K = 8,
|
||||
P0_LSB = 0;
|
||||
|
||||
// function to find number of check bits
|
||||
function integer calculate_m;
|
||||
input integer k;
|
||||
integer m;
|
||||
begin
|
||||
m=1;
|
||||
while (2**m < m+k+1) m=m+1;
|
||||
calculate_m = m;
|
||||
end
|
||||
endfunction
|
||||
|
||||
// anyseq indicates nets that are controllable by engine
|
||||
(*anyseq*)wire[K-1:0] d_i; // information input
|
||||
(*anyseq*) wire[1:0] corrupted; // 0 or 3 = not corrupted bit, 1 = 1 corrupted bit, 2 = 2 corrupted bits
|
||||
(*anyseq*) wire[$clog2(K+calculate_m(K))-1:0] corrupted_bit1, corrupted_bit2; // which bit will be corrupted
|
||||
|
||||
wire[K-1:0] q_o_dec;
|
||||
wire[K+calculate_m(K):0] q_o_enc;
|
||||
reg[K+calculate_m(K):0] q_o_enc_corrupted;
|
||||
wire sb_err_o;
|
||||
wire db_err_o;
|
||||
|
||||
ecc_enc #(
|
||||
.K(K), //Information bit vector size
|
||||
.P0_LSB(P0_LSB) //0: p0 is located at MSB
|
||||
//1: p0 is located at LSB
|
||||
) ecc_enc_inst (
|
||||
.d_i(d_i), //information bit vector input
|
||||
.q_o(q_o_enc), //encoded data word output
|
||||
.p_o(), //parity vector output
|
||||
.p0_o() //extended parity bit
|
||||
);
|
||||
|
||||
ecc_dec #(
|
||||
.K(K), //Information bit vector size
|
||||
.LATENCY(0), //0: no latency (combinatorial design)
|
||||
//1: registered outputs
|
||||
//2: registered inputs+outputs
|
||||
.P0_LSB(P0_LSB) //0: p0 is located at MSB
|
||||
//1: p0 is located at LSB
|
||||
) ecc_dec_inst (
|
||||
//clock/reset ports (if LATENCY > 0)
|
||||
.rst_ni(1'b1), //asynchronous reset
|
||||
.clk_i(1'b0), //clock input
|
||||
.clkena_i(1'b0), //clock enable input
|
||||
//data ports
|
||||
.d_i(q_o_enc_corrupted), //encoded code word input
|
||||
.q_o(q_o_dec), //information bit vector output
|
||||
.syndrome_o(), //syndrome vector output
|
||||
//flags
|
||||
.sb_err_o(sb_err_o), //single bit error detected
|
||||
.db_err_o(db_err_o), //double bit error detected
|
||||
.sb_fix_o() //repaired error in the information bits
|
||||
);
|
||||
|
||||
`ifdef FORMAL
|
||||
(*gclk*) reg f_clk = 0; // reference: https://symbiyosys.readthedocs.io/en/latest/verilog.html#global-clock
|
||||
reg[9:0] f_counter = 0;
|
||||
|
||||
// corrupt the information based on the value of "corrupted" which is controllable by formal engine:
|
||||
// 0 = no corrupted bits , 1 = 1 corrupted bit, 2 = 2 corrupted bits, 3 = no corrupted bits
|
||||
always @* begin
|
||||
q_o_enc_corrupted = q_o_enc;
|
||||
if(corrupted == 1) begin
|
||||
q_o_enc_corrupted[corrupted_bit1] = !q_o_enc_corrupted[corrupted_bit1]; //corrupt 1 random bit
|
||||
assume(corrupted_bit1 != (K+calculate_m(K))); //
|
||||
end
|
||||
else if (corrupted == 2) begin // flip 2 bits
|
||||
q_o_enc_corrupted[corrupted_bit1] = !q_o_enc_corrupted[corrupted_bit1]; //corrupt 2 random bits
|
||||
q_o_enc_corrupted[corrupted_bit2] = !q_o_enc_corrupted[corrupted_bit2];
|
||||
end
|
||||
assume(corrupted_bit1 != corrupted_bit2); // corrupted bit should be different (in case of 2 corrupted bits)
|
||||
assume(corrupted_bit1 <= (K+calculate_m(K))); // corrupted bit should be within the index of q_o_enc_corrupted
|
||||
assume(corrupted_bit2 <= (K+calculate_m(K))); // corrupted bit should be within the index of q_o_enc_corrupted
|
||||
end
|
||||
|
||||
// main contract of this design
|
||||
always @* begin
|
||||
// if no corrupted bits, then decoded info must be equal to original info, and error flags should be low
|
||||
// OR there is 1 corrupted bit but its the MSB p0 that is corrupted
|
||||
if( (corrupted == 0 || corrupted == 3) || ( (corrupted == 1) && (corrupted_bit1 == (K+calculate_m(K))) ) ) begin
|
||||
assert(d_i == q_o_dec);
|
||||
assert(!sb_err_o);
|
||||
assert(!db_err_o);
|
||||
end
|
||||
// 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
|
||||
else if(corrupted == 1) begin
|
||||
assert(d_i == q_o_dec);
|
||||
assert(sb_err_o);
|
||||
assert(!db_err_o);
|
||||
end
|
||||
// if 2 corrupted bits, then single-bit error flag must be low, double-bit error flag must be high
|
||||
else if(corrupted == 2) begin
|
||||
assert(!sb_err_o);
|
||||
assert(db_err_o);
|
||||
end
|
||||
end
|
||||
|
||||
// cover 10 cycles
|
||||
always @(posedge f_clk) begin
|
||||
f_counter <= f_counter + 1;
|
||||
assume(corrupted == f_counter[1:0]); // number of corrupted bits change per clock cycle
|
||||
cover((f_counter == 10));
|
||||
end
|
||||
|
||||
// simulate random information
|
||||
always @(posedge f_clk) begin
|
||||
assume(d_i != $past(d_i,1));
|
||||
assume(d_i != $past(d_i,2));
|
||||
assume(d_i != $past(d_i,3));
|
||||
assume(d_i != $past(d_i,4));
|
||||
assume(d_i != $past(d_i,5));
|
||||
assume(d_i != $past(d_i,6));
|
||||
assume(d_i != $past(d_i,7));
|
||||
assume(d_i != $past(d_i,8));
|
||||
assume(d_i != $past(d_i,9));
|
||||
assume(d_i != $past(d_i,10));
|
||||
end
|
||||
|
||||
`endif
|
||||
endmodule
|
||||
|
|
@ -1,495 +1,495 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Filename: fwb_slave.v
|
||||
// {{{
|
||||
// Project: WB2AXIPSP: bus bridges and other odds and ends
|
||||
//
|
||||
// Purpose: This file describes the rules of a wishbone interaction from the
|
||||
// perspective of a wishbone slave. These formal rules may be used
|
||||
// with yosys-smtbmc to *prove* that the slave properly handles outgoing
|
||||
// responses to (assumed correct) incoming requests.
|
||||
//
|
||||
// This module contains no functional logic. It is intended for formal
|
||||
// verification only. The outputs returned, the number of requests that
|
||||
// have been made, the number of acknowledgements received, and the number
|
||||
// of outstanding requests, are designed for further formal verification
|
||||
// purposes *only*.
|
||||
//
|
||||
// This file is different from a companion formal_master.v file in that
|
||||
// assumptions are made about the inputs to the slave: i_wb_cyc,
|
||||
// i_wb_stb, i_wb_we, i_wb_addr, i_wb_data, and i_wb_sel, while full
|
||||
// assertions are made about the outputs: o_wb_stall, o_wb_ack, o_wb_data,
|
||||
// o_wb_err. In the formal_master.v, assertions are made about the
|
||||
// master outputs (slave inputs)), and assumptions are made about the
|
||||
// master inputs (the slave outputs).
|
||||
//
|
||||
// In order to make it easier to compare the slave against the master,
|
||||
// assumptions with respect to the slave have been marked with the
|
||||
// `SLAVE_ASSUME macro. Similarly, assertions the slave would make have
|
||||
// been marked with `SLAVE_ASSERT. This allows the master to redefine
|
||||
// these two macros to be from his perspective, and therefore the
|
||||
// diffs between the two files actually show true differences, rather
|
||||
// than just these differences in perspective.
|
||||
//
|
||||
//
|
||||
// Creator: Dan Gisselquist, Ph.D.
|
||||
// Gisselquist Technology, LLC
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// }}}
|
||||
// Copyright (C) 2017-2022, Gisselquist Technology, LLC
|
||||
// {{{
|
||||
// This file is part of the WB2AXIP project.
|
||||
//
|
||||
// The WB2AXIP project contains free software and gateware, licensed under the
|
||||
// Apache License, Version 2.0 (the "License"). You may not use this project,
|
||||
// or this file, except in compliance with the License. You may obtain a copy
|
||||
// of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
`default_nettype none
|
||||
// }}}
|
||||
module fwb_slave #(
|
||||
// {{{
|
||||
parameter AW=32, DW=32,
|
||||
parameter F_MAX_STALL = 0,
|
||||
F_MAX_ACK_DELAY = 0,
|
||||
parameter F_LGDEPTH = 4,
|
||||
parameter [(F_LGDEPTH-1):0] F_MAX_REQUESTS = 0,
|
||||
// OPT_BUS_ABORT: If true, the master can drop CYC at any time
|
||||
// and must drop CYC following any bus error
|
||||
parameter [0:0] OPT_BUS_ABORT = 1'b1,
|
||||
//
|
||||
// If true, allow the bus to be kept open when there are no
|
||||
// outstanding requests. This is useful for any master that
|
||||
// might execute a read modify write cycle, such as an atomic
|
||||
// add.
|
||||
parameter [0:0] F_OPT_RMW_BUS_OPTION = 1,
|
||||
//
|
||||
//
|
||||
// If true, allow the bus to issue multiple discontinuous
|
||||
// requests.
|
||||
// Unlike F_OPT_RMW_BUS_OPTION, these requests may be issued
|
||||
// while other requests are outstanding
|
||||
parameter [0:0] F_OPT_DISCONTINUOUS = 1,
|
||||
//
|
||||
//
|
||||
// If true, insist that there be a minimum of a single clock
|
||||
// delay between request and response. This defaults to off
|
||||
// since the wishbone specification specifically doesn't
|
||||
// require this. However, some interfaces do, so we allow it
|
||||
// as an option here.
|
||||
parameter [0:0] F_OPT_MINCLOCK_DELAY = 0,
|
||||
//
|
||||
//
|
||||
//
|
||||
localparam [(F_LGDEPTH-1):0] MAX_OUTSTANDING
|
||||
= {(F_LGDEPTH){1'b1}},
|
||||
localparam MAX_DELAY = (F_MAX_STALL > F_MAX_ACK_DELAY)
|
||||
? F_MAX_STALL : F_MAX_ACK_DELAY,
|
||||
localparam DLYBITS= (MAX_DELAY < 4) ? 2
|
||||
: (MAX_DELAY >= 65536) ? 32
|
||||
: $clog2(MAX_DELAY+1)
|
||||
// }}}
|
||||
) (
|
||||
// {{{
|
||||
input wire i_clk, i_reset,
|
||||
// The Wishbone bus
|
||||
input wire i_wb_cyc, i_wb_stb, i_wb_we,
|
||||
input wire [(AW-1):0] i_wb_addr,
|
||||
input wire [(DW-1):0] i_wb_data,
|
||||
input wire [(DW/8-1):0] i_wb_sel,
|
||||
//
|
||||
input wire i_wb_ack,
|
||||
input wire i_wb_stall,
|
||||
input wire [(DW-1):0] i_wb_idata,
|
||||
input wire i_wb_err,
|
||||
// Some convenience output parameters
|
||||
output reg [(F_LGDEPTH-1):0] f_nreqs, f_nacks,
|
||||
output wire [(F_LGDEPTH-1):0] f_outstanding,
|
||||
output reg [(DLYBITS-1):0] f_ackwait_count,
|
||||
output reg [(DLYBITS-1):0] f_stall_count
|
||||
// }}}
|
||||
);
|
||||
|
||||
`define SLAVE_ASSUME assume
|
||||
`define SLAVE_ASSERT assert
|
||||
//
|
||||
// Let's just make sure our parameters are set up right
|
||||
// {{{
|
||||
initial assert(F_MAX_REQUESTS < {(F_LGDEPTH){1'b1}});
|
||||
// }}}
|
||||
|
||||
// f_request
|
||||
// {{{
|
||||
// Wrap the request line in a bundle. The top bit, named STB_BIT,
|
||||
// is the bit indicating whether the request described by this vector
|
||||
// is a valid request or not.
|
||||
//
|
||||
localparam STB_BIT = 2+AW+DW+DW/8-1;
|
||||
wire [STB_BIT:0] f_request;
|
||||
assign f_request = { i_wb_stb, i_wb_we, i_wb_addr, i_wb_data, i_wb_sel };
|
||||
// }}}
|
||||
|
||||
// f_past_valid and i_reset
|
||||
// {{{
|
||||
// A quick register to be used later to know if the $past() operator
|
||||
// will yield valid result
|
||||
reg f_past_valid;
|
||||
initial f_past_valid = 1'b0;
|
||||
always @(posedge i_clk)
|
||||
f_past_valid <= 1'b1;
|
||||
|
||||
always @(*)
|
||||
if (!f_past_valid)
|
||||
`SLAVE_ASSUME(i_reset);
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Assertions regarding the initial (and reset) state
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
// Assume we start from a reset condition
|
||||
initial assert(i_reset);
|
||||
initial `SLAVE_ASSUME(!i_wb_cyc);
|
||||
initial `SLAVE_ASSUME(!i_wb_stb);
|
||||
//
|
||||
initial `SLAVE_ASSERT(!i_wb_ack);
|
||||
initial `SLAVE_ASSERT(!i_wb_err);
|
||||
|
||||
`ifdef VERIFIC
|
||||
always @(*)
|
||||
if (!f_past_valid)
|
||||
begin
|
||||
`SLAVE_ASSUME(!i_wb_cyc);
|
||||
`SLAVE_ASSUME(!i_wb_stb);
|
||||
//
|
||||
`SLAVE_ASSERT(!i_wb_ack);
|
||||
`SLAVE_ASSERT(!i_wb_err);
|
||||
end
|
||||
`endif
|
||||
always @(posedge i_clk)
|
||||
if ((!f_past_valid)||($past(i_reset)))
|
||||
begin
|
||||
`SLAVE_ASSUME(!i_wb_cyc);
|
||||
`SLAVE_ASSUME(!i_wb_stb);
|
||||
//
|
||||
`SLAVE_ASSERT(!i_wb_ack);
|
||||
`SLAVE_ASSERT(!i_wb_err);
|
||||
end
|
||||
|
||||
always @(*)
|
||||
if (!f_past_valid)
|
||||
`SLAVE_ASSUME(!i_wb_cyc);
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Bus requests
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
// Following any bus error, the CYC line should be dropped to abort
|
||||
// the transaction
|
||||
always @(posedge i_clk)
|
||||
if (f_past_valid && OPT_BUS_ABORT && $past(i_wb_err)&& $past(i_wb_cyc)) //there is error so cyc should go high
|
||||
`SLAVE_ASSUME(!i_wb_cyc);
|
||||
|
||||
always @(*)
|
||||
if (!OPT_BUS_ABORT && !i_reset && (f_nreqs != f_nacks)) //not all requests has an ack YET so cyc should stay high (else request will be cancelled)
|
||||
`SLAVE_ASSUME(i_wb_cyc);
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (f_past_valid && !OPT_BUS_ABORT
|
||||
&& $past(!i_reset && i_wb_stb && i_wb_stall)) //a request is currently on the line so cyc shou;d stay high
|
||||
`SLAVE_ASSUME(i_wb_cyc);
|
||||
|
||||
// STB can only be true if CYC is also true
|
||||
always @(*)
|
||||
if (i_wb_stb) //stb will not go high unless cyc is high
|
||||
`SLAVE_ASSUME(i_wb_cyc);
|
||||
|
||||
// If a request was both outstanding and stalled on the last clock,
|
||||
// then nothing should change on this clock regarding it.
|
||||
always @(posedge i_clk)
|
||||
if ((f_past_valid)&&(!$past(i_reset))&&($past(i_wb_stb))
|
||||
&&($past(i_wb_stall))&&(i_wb_cyc))
|
||||
begin
|
||||
`SLAVE_ASSUME(i_wb_stb);
|
||||
`SLAVE_ASSUME(i_wb_we == $past(i_wb_we));
|
||||
`SLAVE_ASSUME(i_wb_addr == $past(i_wb_addr));
|
||||
`SLAVE_ASSUME(i_wb_sel == $past(i_wb_sel));
|
||||
if (i_wb_we)
|
||||
`SLAVE_ASSUME(i_wb_data == $past(i_wb_data));
|
||||
end
|
||||
|
||||
// Within any series of STB/requests, the direction of the request
|
||||
// may not change.
|
||||
// WHYYYYYYYYYYYY?????
|
||||
always @(posedge i_clk)
|
||||
if ((f_past_valid)&&($past(i_wb_stb))&&(i_wb_stb))
|
||||
`SLAVE_ASSUME(i_wb_we == $past(i_wb_we));
|
||||
|
||||
|
||||
// Within any given bus cycle, the direction may *only* change when
|
||||
// there are no further outstanding requests.
|
||||
always @(posedge i_clk)
|
||||
if ((f_past_valid)&&(f_outstanding > 0))
|
||||
`SLAVE_ASSUME(i_wb_we == $past(i_wb_we));
|
||||
|
||||
// Write requests must also set one (or more) of i_wb_sel
|
||||
//
|
||||
// This test has been removed since down-sizers (taking bus from width
|
||||
// DW to width dw < DW) might actually create empty requests that this
|
||||
// would prevent. Re-enabling it would also complicate AXI to WB
|
||||
// transfers, since AXI explicitly allows WSTRB == 0. Finally, this
|
||||
// criteria isn't found in the WB spec--so while it might be a good
|
||||
// idea to check, in hind sight there are too many exceptions to be
|
||||
// dogmatic about it.
|
||||
//
|
||||
// always @(*)
|
||||
// if ((i_wb_stb)&&(i_wb_we))
|
||||
// `SLAVE_ASSUME(|i_wb_sel);
|
||||
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Bus responses
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
// If CYC was low on the last clock, then both ACK and ERR should be
|
||||
// low on this clock.
|
||||
always @(posedge i_clk)
|
||||
if ((f_past_valid)&&(!$past(i_wb_cyc))&&(!i_wb_cyc))
|
||||
begin
|
||||
`SLAVE_ASSERT(!i_wb_ack);
|
||||
`SLAVE_ASSERT(!i_wb_err);
|
||||
// Stall may still be true--such as when we are not
|
||||
// selected at some arbiter between us and the slave
|
||||
end
|
||||
|
||||
//
|
||||
// Any time the CYC line drops, it is possible that there may be a
|
||||
// remaining (registered) ACK or ERR that hasn't yet been returned.
|
||||
// Restrict such out of band returns so that they are *only* returned
|
||||
// if there is an outstanding operation.
|
||||
//
|
||||
// Update: As per spec, WB-classic to WB-pipeline conversions require
|
||||
// that the ACK|ERR might come back on the same cycle that STB
|
||||
// is low, yet also be registered. Hence, if STB & STALL are true on
|
||||
// one cycle, then CYC is dropped, ACK|ERR might still be true on the
|
||||
// cycle when CYC is dropped
|
||||
always @(posedge i_clk)
|
||||
if ((f_past_valid)&&(!$past(i_reset))&&($past(i_wb_cyc))&&(!i_wb_cyc))
|
||||
begin
|
||||
// Note that, unlike f_outstanding, f_nreqs and f_nacks are both
|
||||
// registered. Hence, we can check here if a response is still
|
||||
// pending. If not, no response should be returned.
|
||||
if (f_nreqs == f_nacks)
|
||||
begin
|
||||
`SLAVE_ASSERT(!i_wb_ack);
|
||||
`SLAVE_ASSERT(!i_wb_err);
|
||||
end
|
||||
end
|
||||
|
||||
// ACK and ERR may never both be true at the same time
|
||||
always @(*)
|
||||
`SLAVE_ASSERT((!i_wb_ack)||(!i_wb_err));
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Stall checking
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
generate if (F_MAX_STALL > 0)
|
||||
begin : MXSTALL
|
||||
//
|
||||
// Assume the slave cannnot stall for more than F_MAX_STALL
|
||||
// counts. We'll count this forward any time STB and STALL
|
||||
// are both true.
|
||||
//
|
||||
|
||||
initial f_stall_count = 0;
|
||||
always @(posedge i_clk)
|
||||
if ((!i_reset)&&(i_wb_stb)&&(i_wb_stall))
|
||||
f_stall_count <= f_stall_count + 1'b1;
|
||||
else
|
||||
f_stall_count <= 0;
|
||||
|
||||
always @(*)
|
||||
if (i_wb_cyc)
|
||||
`SLAVE_ASSERT(f_stall_count < F_MAX_STALL);
|
||||
end endgenerate
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Maximum delay in any response
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
generate if (F_MAX_ACK_DELAY > 0)
|
||||
begin : MXWAIT
|
||||
//
|
||||
// Assume the slave will respond within F_MAX_ACK_DELAY cycles,
|
||||
// counted either from the end of the last request, or from the
|
||||
// last ACK received
|
||||
//
|
||||
|
||||
initial f_ackwait_count = 0;
|
||||
always @(posedge i_clk)
|
||||
if ((!i_reset)&&(i_wb_cyc)&&(!i_wb_stb)
|
||||
&&(!i_wb_ack)&&(!i_wb_err)
|
||||
&&(f_outstanding > 0))
|
||||
f_ackwait_count <= f_ackwait_count + 1'b1;
|
||||
else
|
||||
f_ackwait_count <= 0;
|
||||
|
||||
always @(*)
|
||||
if ((!i_reset)&&(i_wb_cyc)&&(!i_wb_stb)
|
||||
&&(!i_wb_ack)&&(!i_wb_err)
|
||||
&&(f_outstanding > 0))
|
||||
`SLAVE_ASSERT(f_ackwait_count < F_MAX_ACK_DELAY);
|
||||
end endgenerate
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Count outstanding requests vs acknowledgments
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
// Count the number of requests that have been received
|
||||
//
|
||||
initial f_nreqs = 0;
|
||||
always @(posedge i_clk)
|
||||
if ((i_reset)||(!i_wb_cyc))
|
||||
f_nreqs <= 0;
|
||||
else if ((i_wb_stb)&&(!i_wb_stall))
|
||||
f_nreqs <= f_nreqs + 1'b1;
|
||||
|
||||
|
||||
//
|
||||
// Count the number of acknowledgements that have been returned
|
||||
//
|
||||
initial f_nacks = 0;
|
||||
always @(posedge i_clk)
|
||||
if (i_reset)
|
||||
f_nacks <= 0;
|
||||
else if (!i_wb_cyc)
|
||||
f_nacks <= 0;
|
||||
else if ((i_wb_ack)||(i_wb_err))
|
||||
f_nacks <= f_nacks + 1'b1;
|
||||
|
||||
//
|
||||
// The number of outstanding requests is the difference between
|
||||
// the number of requests and the number of acknowledgements
|
||||
//
|
||||
assign f_outstanding = (i_wb_cyc) ? (f_nreqs - f_nacks):0;
|
||||
|
||||
always @(*)
|
||||
if ((i_wb_cyc)&&(F_MAX_REQUESTS > 0))
|
||||
begin
|
||||
if (i_wb_stb)
|
||||
begin
|
||||
`SLAVE_ASSUME(f_nreqs < F_MAX_REQUESTS);
|
||||
end else
|
||||
`SLAVE_ASSUME(f_nreqs <= F_MAX_REQUESTS);
|
||||
`SLAVE_ASSERT(f_nacks <= f_nreqs);
|
||||
assert(f_outstanding < (1<<F_LGDEPTH)-1);
|
||||
end else
|
||||
assume(f_outstanding < (1<<F_LGDEPTH)-1);
|
||||
|
||||
always @(*)
|
||||
if ((i_wb_cyc)&&(f_outstanding == 0))
|
||||
begin
|
||||
// If nothing is outstanding, then there should be
|
||||
// no acknowledgements ... however, an acknowledgement
|
||||
// *can* come back on the same clock as the stb is
|
||||
// going out.
|
||||
if (F_OPT_MINCLOCK_DELAY)
|
||||
begin
|
||||
`SLAVE_ASSERT(!i_wb_ack);
|
||||
`SLAVE_ASSERT(!i_wb_err);
|
||||
end else begin
|
||||
`SLAVE_ASSERT((!i_wb_ack)||((i_wb_stb)&&(!i_wb_stall)));
|
||||
// The same is true of errors. They may not be
|
||||
// created before the request gets through
|
||||
`SLAVE_ASSERT((!i_wb_err)||((i_wb_stb)&&(!i_wb_stall)));
|
||||
end
|
||||
end else if (!i_wb_cyc && f_nacks == f_nreqs)
|
||||
begin
|
||||
`SLAVE_ASSERT(!i_wb_ack);
|
||||
`SLAVE_ASSERT(!i_wb_err);
|
||||
end
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Bus direction
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
generate if (!F_OPT_RMW_BUS_OPTION)
|
||||
begin
|
||||
// If we aren't waiting for anything, and we aren't issuing
|
||||
// any requests, then then our transaction is over and we
|
||||
// should be dropping the CYC line.
|
||||
always @(*)
|
||||
if (f_outstanding == 0)
|
||||
`SLAVE_ASSUME((i_wb_stb)||(!i_wb_cyc));
|
||||
// Not all masters will abide by this restriction. Some
|
||||
// masters may wish to implement read-modify-write bus
|
||||
// interactions. These masters need to keep CYC high between
|
||||
// transactions, even though nothing is outstanding. For
|
||||
// these busses, turn F_OPT_RMW_BUS_OPTION on.
|
||||
end endgenerate
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Discontinuous request checking
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
generate if ((!F_OPT_DISCONTINUOUS)&&(!F_OPT_RMW_BUS_OPTION))
|
||||
begin : INSIST_ON_NO_DISCONTINUOUS_STBS
|
||||
// Within my own code, once a request begins it goes to
|
||||
// completion and the CYC line is dropped. The master
|
||||
// is not allowed to raise STB again after dropping it.
|
||||
// Doing so would be a *discontinuous* request.
|
||||
//
|
||||
// However, in any RMW scheme, discontinuous requests are
|
||||
// necessary, and the spec doesn't disallow them. Hence we
|
||||
// make this check optional.
|
||||
always @(posedge i_clk)
|
||||
if ((f_past_valid)&&($past(i_wb_cyc))&&(!$past(i_wb_stb)))
|
||||
`SLAVE_ASSUME(!i_wb_stb);
|
||||
end endgenerate
|
||||
// }}}
|
||||
endmodule
|
||||
`undef SLAVE_ASSUME
|
||||
`undef SLAVE_ASSERT
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Filename: fwb_slave.v
|
||||
// {{{
|
||||
// Project: WB2AXIPSP: bus bridges and other odds and ends
|
||||
//
|
||||
// Purpose: This file describes the rules of a wishbone interaction from the
|
||||
// perspective of a wishbone slave. These formal rules may be used
|
||||
// with yosys-smtbmc to *prove* that the slave properly handles outgoing
|
||||
// responses to (assumed correct) incoming requests.
|
||||
//
|
||||
// This module contains no functional logic. It is intended for formal
|
||||
// verification only. The outputs returned, the number of requests that
|
||||
// have been made, the number of acknowledgements received, and the number
|
||||
// of outstanding requests, are designed for further formal verification
|
||||
// purposes *only*.
|
||||
//
|
||||
// This file is different from a companion formal_master.v file in that
|
||||
// assumptions are made about the inputs to the slave: i_wb_cyc,
|
||||
// i_wb_stb, i_wb_we, i_wb_addr, i_wb_data, and i_wb_sel, while full
|
||||
// assertions are made about the outputs: o_wb_stall, o_wb_ack, o_wb_data,
|
||||
// o_wb_err. In the formal_master.v, assertions are made about the
|
||||
// master outputs (slave inputs)), and assumptions are made about the
|
||||
// master inputs (the slave outputs).
|
||||
//
|
||||
// In order to make it easier to compare the slave against the master,
|
||||
// assumptions with respect to the slave have been marked with the
|
||||
// `SLAVE_ASSUME macro. Similarly, assertions the slave would make have
|
||||
// been marked with `SLAVE_ASSERT. This allows the master to redefine
|
||||
// these two macros to be from his perspective, and therefore the
|
||||
// diffs between the two files actually show true differences, rather
|
||||
// than just these differences in perspective.
|
||||
//
|
||||
//
|
||||
// Creator: Dan Gisselquist, Ph.D.
|
||||
// Gisselquist Technology, LLC
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// }}}
|
||||
// Copyright (C) 2017-2022, Gisselquist Technology, LLC
|
||||
// {{{
|
||||
// This file is part of the WB2AXIP project.
|
||||
//
|
||||
// The WB2AXIP project contains free software and gateware, licensed under the
|
||||
// Apache License, Version 2.0 (the "License"). You may not use this project,
|
||||
// or this file, except in compliance with the License. You may obtain a copy
|
||||
// of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
`default_nettype none
|
||||
// }}}
|
||||
module fwb_slave #(
|
||||
// {{{
|
||||
parameter AW=32, DW=32,
|
||||
parameter F_MAX_STALL = 0,
|
||||
F_MAX_ACK_DELAY = 0,
|
||||
parameter F_LGDEPTH = 4,
|
||||
parameter [(F_LGDEPTH-1):0] F_MAX_REQUESTS = 0,
|
||||
// OPT_BUS_ABORT: If true, the master can drop CYC at any time
|
||||
// and must drop CYC following any bus error
|
||||
parameter [0:0] OPT_BUS_ABORT = 1'b1,
|
||||
//
|
||||
// If true, allow the bus to be kept open when there are no
|
||||
// outstanding requests. This is useful for any master that
|
||||
// might execute a read modify write cycle, such as an atomic
|
||||
// add.
|
||||
parameter [0:0] F_OPT_RMW_BUS_OPTION = 1,
|
||||
//
|
||||
//
|
||||
// If true, allow the bus to issue multiple discontinuous
|
||||
// requests.
|
||||
// Unlike F_OPT_RMW_BUS_OPTION, these requests may be issued
|
||||
// while other requests are outstanding
|
||||
parameter [0:0] F_OPT_DISCONTINUOUS = 1,
|
||||
//
|
||||
//
|
||||
// If true, insist that there be a minimum of a single clock
|
||||
// delay between request and response. This defaults to off
|
||||
// since the wishbone specification specifically doesn't
|
||||
// require this. However, some interfaces do, so we allow it
|
||||
// as an option here.
|
||||
parameter [0:0] F_OPT_MINCLOCK_DELAY = 0,
|
||||
//
|
||||
//
|
||||
//
|
||||
localparam [(F_LGDEPTH-1):0] MAX_OUTSTANDING
|
||||
= {(F_LGDEPTH){1'b1}},
|
||||
localparam MAX_DELAY = (F_MAX_STALL > F_MAX_ACK_DELAY)
|
||||
? F_MAX_STALL : F_MAX_ACK_DELAY,
|
||||
localparam DLYBITS= (MAX_DELAY < 4) ? 2
|
||||
: (MAX_DELAY >= 65536) ? 32
|
||||
: $clog2(MAX_DELAY+1)
|
||||
// }}}
|
||||
) (
|
||||
// {{{
|
||||
input wire i_clk, i_reset,
|
||||
// The Wishbone bus
|
||||
input wire i_wb_cyc, i_wb_stb, i_wb_we,
|
||||
input wire [(AW-1):0] i_wb_addr,
|
||||
input wire [(DW-1):0] i_wb_data,
|
||||
input wire [(DW/8-1):0] i_wb_sel,
|
||||
//
|
||||
input wire i_wb_ack,
|
||||
input wire i_wb_stall,
|
||||
input wire [(DW-1):0] i_wb_idata,
|
||||
input wire i_wb_err,
|
||||
// Some convenience output parameters
|
||||
output reg [(F_LGDEPTH-1):0] f_nreqs, f_nacks,
|
||||
output wire [(F_LGDEPTH-1):0] f_outstanding,
|
||||
output reg [(DLYBITS-1):0] f_ackwait_count,
|
||||
output reg [(DLYBITS-1):0] f_stall_count
|
||||
// }}}
|
||||
);
|
||||
|
||||
`define SLAVE_ASSUME assume
|
||||
`define SLAVE_ASSERT assert
|
||||
//
|
||||
// Let's just make sure our parameters are set up right
|
||||
// {{{
|
||||
initial assert(F_MAX_REQUESTS < {(F_LGDEPTH){1'b1}});
|
||||
// }}}
|
||||
|
||||
// f_request
|
||||
// {{{
|
||||
// Wrap the request line in a bundle. The top bit, named STB_BIT,
|
||||
// is the bit indicating whether the request described by this vector
|
||||
// is a valid request or not.
|
||||
//
|
||||
localparam STB_BIT = 2+AW+DW+DW/8-1;
|
||||
wire [STB_BIT:0] f_request;
|
||||
assign f_request = { i_wb_stb, i_wb_we, i_wb_addr, i_wb_data, i_wb_sel };
|
||||
// }}}
|
||||
|
||||
// f_past_valid and i_reset
|
||||
// {{{
|
||||
// A quick register to be used later to know if the $past() operator
|
||||
// will yield valid result
|
||||
reg f_past_valid;
|
||||
initial f_past_valid = 1'b0;
|
||||
always @(posedge i_clk)
|
||||
f_past_valid <= 1'b1;
|
||||
|
||||
always @(*)
|
||||
if (!f_past_valid)
|
||||
`SLAVE_ASSUME(i_reset);
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Assertions regarding the initial (and reset) state
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
// Assume we start from a reset condition
|
||||
initial assert(i_reset);
|
||||
initial `SLAVE_ASSUME(!i_wb_cyc);
|
||||
initial `SLAVE_ASSUME(!i_wb_stb);
|
||||
//
|
||||
initial `SLAVE_ASSERT(!i_wb_ack);
|
||||
initial `SLAVE_ASSERT(!i_wb_err);
|
||||
|
||||
`ifdef VERIFIC
|
||||
always @(*)
|
||||
if (!f_past_valid)
|
||||
begin
|
||||
`SLAVE_ASSUME(!i_wb_cyc);
|
||||
`SLAVE_ASSUME(!i_wb_stb);
|
||||
//
|
||||
`SLAVE_ASSERT(!i_wb_ack);
|
||||
`SLAVE_ASSERT(!i_wb_err);
|
||||
end
|
||||
`endif
|
||||
always @(posedge i_clk)
|
||||
if ((!f_past_valid)||($past(i_reset)))
|
||||
begin
|
||||
`SLAVE_ASSUME(!i_wb_cyc);
|
||||
`SLAVE_ASSUME(!i_wb_stb);
|
||||
//
|
||||
`SLAVE_ASSERT(!i_wb_ack);
|
||||
`SLAVE_ASSERT(!i_wb_err);
|
||||
end
|
||||
|
||||
always @(*)
|
||||
if (!f_past_valid)
|
||||
`SLAVE_ASSUME(!i_wb_cyc);
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Bus requests
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
// Following any bus error, the CYC line should be dropped to abort
|
||||
// the transaction
|
||||
always @(posedge i_clk)
|
||||
if (f_past_valid && OPT_BUS_ABORT && $past(i_wb_err)&& $past(i_wb_cyc)) //there is error so cyc should go high
|
||||
`SLAVE_ASSUME(!i_wb_cyc);
|
||||
|
||||
always @(*)
|
||||
if (!OPT_BUS_ABORT && !i_reset && (f_nreqs != f_nacks)) //not all requests has an ack YET so cyc should stay high (else request will be cancelled)
|
||||
`SLAVE_ASSUME(i_wb_cyc);
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (f_past_valid && !OPT_BUS_ABORT
|
||||
&& $past(!i_reset && i_wb_stb && i_wb_stall)) //a request is currently on the line so cyc shou;d stay high
|
||||
`SLAVE_ASSUME(i_wb_cyc);
|
||||
|
||||
// STB can only be true if CYC is also true
|
||||
always @(*)
|
||||
if (i_wb_stb) //stb will not go high unless cyc is high
|
||||
`SLAVE_ASSUME(i_wb_cyc);
|
||||
|
||||
// If a request was both outstanding and stalled on the last clock,
|
||||
// then nothing should change on this clock regarding it.
|
||||
always @(posedge i_clk)
|
||||
if ((f_past_valid)&&(!$past(i_reset))&&($past(i_wb_stb))
|
||||
&&($past(i_wb_stall))&&(i_wb_cyc))
|
||||
begin
|
||||
`SLAVE_ASSUME(i_wb_stb);
|
||||
`SLAVE_ASSUME(i_wb_we == $past(i_wb_we));
|
||||
`SLAVE_ASSUME(i_wb_addr == $past(i_wb_addr));
|
||||
`SLAVE_ASSUME(i_wb_sel == $past(i_wb_sel));
|
||||
if (i_wb_we)
|
||||
`SLAVE_ASSUME(i_wb_data == $past(i_wb_data));
|
||||
end
|
||||
|
||||
// Within any series of STB/requests, the direction of the request
|
||||
// may not change.
|
||||
// WHYYYYYYYYYYYY?????
|
||||
always @(posedge i_clk)
|
||||
if ((f_past_valid)&&($past(i_wb_stb))&&(i_wb_stb))
|
||||
`SLAVE_ASSUME(i_wb_we == $past(i_wb_we));
|
||||
|
||||
|
||||
// Within any given bus cycle, the direction may *only* change when
|
||||
// there are no further outstanding requests.
|
||||
always @(posedge i_clk)
|
||||
if ((f_past_valid)&&(f_outstanding > 0))
|
||||
`SLAVE_ASSUME(i_wb_we == $past(i_wb_we));
|
||||
|
||||
// Write requests must also set one (or more) of i_wb_sel
|
||||
//
|
||||
// This test has been removed since down-sizers (taking bus from width
|
||||
// DW to width dw < DW) might actually create empty requests that this
|
||||
// would prevent. Re-enabling it would also complicate AXI to WB
|
||||
// transfers, since AXI explicitly allows WSTRB == 0. Finally, this
|
||||
// criteria isn't found in the WB spec--so while it might be a good
|
||||
// idea to check, in hind sight there are too many exceptions to be
|
||||
// dogmatic about it.
|
||||
//
|
||||
// always @(*)
|
||||
// if ((i_wb_stb)&&(i_wb_we))
|
||||
// `SLAVE_ASSUME(|i_wb_sel);
|
||||
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Bus responses
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
// If CYC was low on the last clock, then both ACK and ERR should be
|
||||
// low on this clock.
|
||||
always @(posedge i_clk)
|
||||
if ((f_past_valid)&&(!$past(i_wb_cyc))&&(!i_wb_cyc))
|
||||
begin
|
||||
`SLAVE_ASSERT(!i_wb_ack);
|
||||
`SLAVE_ASSERT(!i_wb_err);
|
||||
// Stall may still be true--such as when we are not
|
||||
// selected at some arbiter between us and the slave
|
||||
end
|
||||
|
||||
//
|
||||
// Any time the CYC line drops, it is possible that there may be a
|
||||
// remaining (registered) ACK or ERR that hasn't yet been returned.
|
||||
// Restrict such out of band returns so that they are *only* returned
|
||||
// if there is an outstanding operation.
|
||||
//
|
||||
// Update: As per spec, WB-classic to WB-pipeline conversions require
|
||||
// that the ACK|ERR might come back on the same cycle that STB
|
||||
// is low, yet also be registered. Hence, if STB & STALL are true on
|
||||
// one cycle, then CYC is dropped, ACK|ERR might still be true on the
|
||||
// cycle when CYC is dropped
|
||||
always @(posedge i_clk)
|
||||
if ((f_past_valid)&&(!$past(i_reset))&&($past(i_wb_cyc))&&(!i_wb_cyc))
|
||||
begin
|
||||
// Note that, unlike f_outstanding, f_nreqs and f_nacks are both
|
||||
// registered. Hence, we can check here if a response is still
|
||||
// pending. If not, no response should be returned.
|
||||
if (f_nreqs == f_nacks)
|
||||
begin
|
||||
`SLAVE_ASSERT(!i_wb_ack);
|
||||
`SLAVE_ASSERT(!i_wb_err);
|
||||
end
|
||||
end
|
||||
|
||||
// ACK and ERR may never both be true at the same time
|
||||
always @(*)
|
||||
`SLAVE_ASSERT((!i_wb_ack)||(!i_wb_err));
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Stall checking
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
generate if (F_MAX_STALL > 0)
|
||||
begin : MXSTALL
|
||||
//
|
||||
// Assume the slave cannnot stall for more than F_MAX_STALL
|
||||
// counts. We'll count this forward any time STB and STALL
|
||||
// are both true.
|
||||
//
|
||||
|
||||
initial f_stall_count = 0;
|
||||
always @(posedge i_clk)
|
||||
if ((!i_reset)&&(i_wb_stb)&&(i_wb_stall))
|
||||
f_stall_count <= f_stall_count + 1'b1;
|
||||
else
|
||||
f_stall_count <= 0;
|
||||
|
||||
always @(*)
|
||||
if (i_wb_cyc)
|
||||
`SLAVE_ASSERT(f_stall_count < F_MAX_STALL);
|
||||
end endgenerate
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Maximum delay in any response
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
generate if (F_MAX_ACK_DELAY > 0)
|
||||
begin : MXWAIT
|
||||
//
|
||||
// Assume the slave will respond within F_MAX_ACK_DELAY cycles,
|
||||
// counted either from the end of the last request, or from the
|
||||
// last ACK received
|
||||
//
|
||||
|
||||
initial f_ackwait_count = 0;
|
||||
always @(posedge i_clk)
|
||||
if ((!i_reset)&&(i_wb_cyc)&&(!i_wb_stb)
|
||||
&&(!i_wb_ack)&&(!i_wb_err)
|
||||
&&(f_outstanding > 0))
|
||||
f_ackwait_count <= f_ackwait_count + 1'b1;
|
||||
else
|
||||
f_ackwait_count <= 0;
|
||||
|
||||
always @(*)
|
||||
if ((!i_reset)&&(i_wb_cyc)&&(!i_wb_stb)
|
||||
&&(!i_wb_ack)&&(!i_wb_err)
|
||||
&&(f_outstanding > 0))
|
||||
`SLAVE_ASSERT(f_ackwait_count < F_MAX_ACK_DELAY);
|
||||
end endgenerate
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Count outstanding requests vs acknowledgments
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
// Count the number of requests that have been received
|
||||
//
|
||||
initial f_nreqs = 0;
|
||||
always @(posedge i_clk)
|
||||
if ((i_reset)||(!i_wb_cyc))
|
||||
f_nreqs <= 0;
|
||||
else if ((i_wb_stb)&&(!i_wb_stall))
|
||||
f_nreqs <= f_nreqs + 1'b1;
|
||||
|
||||
|
||||
//
|
||||
// Count the number of acknowledgements that have been returned
|
||||
//
|
||||
initial f_nacks = 0;
|
||||
always @(posedge i_clk)
|
||||
if (i_reset)
|
||||
f_nacks <= 0;
|
||||
else if (!i_wb_cyc)
|
||||
f_nacks <= 0;
|
||||
else if ((i_wb_ack)||(i_wb_err))
|
||||
f_nacks <= f_nacks + 1'b1;
|
||||
|
||||
//
|
||||
// The number of outstanding requests is the difference between
|
||||
// the number of requests and the number of acknowledgements
|
||||
//
|
||||
assign f_outstanding = (i_wb_cyc) ? (f_nreqs - f_nacks):0;
|
||||
|
||||
always @(*)
|
||||
if ((i_wb_cyc)&&(F_MAX_REQUESTS > 0))
|
||||
begin
|
||||
if (i_wb_stb)
|
||||
begin
|
||||
`SLAVE_ASSUME(f_nreqs < F_MAX_REQUESTS);
|
||||
end else
|
||||
`SLAVE_ASSUME(f_nreqs <= F_MAX_REQUESTS);
|
||||
`SLAVE_ASSERT(f_nacks <= f_nreqs);
|
||||
assert(f_outstanding < (1<<F_LGDEPTH)-1);
|
||||
end else
|
||||
assume(f_outstanding < (1<<F_LGDEPTH)-1);
|
||||
|
||||
always @(*)
|
||||
if ((i_wb_cyc)&&(f_outstanding == 0))
|
||||
begin
|
||||
// If nothing is outstanding, then there should be
|
||||
// no acknowledgements ... however, an acknowledgement
|
||||
// *can* come back on the same clock as the stb is
|
||||
// going out.
|
||||
if (F_OPT_MINCLOCK_DELAY)
|
||||
begin
|
||||
`SLAVE_ASSERT(!i_wb_ack);
|
||||
`SLAVE_ASSERT(!i_wb_err);
|
||||
end else begin
|
||||
`SLAVE_ASSERT((!i_wb_ack)||((i_wb_stb)&&(!i_wb_stall)));
|
||||
// The same is true of errors. They may not be
|
||||
// created before the request gets through
|
||||
`SLAVE_ASSERT((!i_wb_err)||((i_wb_stb)&&(!i_wb_stall)));
|
||||
end
|
||||
end else if (!i_wb_cyc && f_nacks == f_nreqs)
|
||||
begin
|
||||
`SLAVE_ASSERT(!i_wb_ack);
|
||||
`SLAVE_ASSERT(!i_wb_err);
|
||||
end
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Bus direction
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
generate if (!F_OPT_RMW_BUS_OPTION)
|
||||
begin
|
||||
// If we aren't waiting for anything, and we aren't issuing
|
||||
// any requests, then then our transaction is over and we
|
||||
// should be dropping the CYC line.
|
||||
always @(*)
|
||||
if (f_outstanding == 0)
|
||||
`SLAVE_ASSUME((i_wb_stb)||(!i_wb_cyc));
|
||||
// Not all masters will abide by this restriction. Some
|
||||
// masters may wish to implement read-modify-write bus
|
||||
// interactions. These masters need to keep CYC high between
|
||||
// transactions, even though nothing is outstanding. For
|
||||
// these busses, turn F_OPT_RMW_BUS_OPTION on.
|
||||
end endgenerate
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Discontinuous request checking
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
generate if ((!F_OPT_DISCONTINUOUS)&&(!F_OPT_RMW_BUS_OPTION))
|
||||
begin : INSIST_ON_NO_DISCONTINUOUS_STBS
|
||||
// Within my own code, once a request begins it goes to
|
||||
// completion and the CYC line is dropped. The master
|
||||
// is not allowed to raise STB again after dropping it.
|
||||
// Doing so would be a *discontinuous* request.
|
||||
//
|
||||
// However, in any RMW scheme, discontinuous requests are
|
||||
// necessary, and the spec doesn't disallow them. Hence we
|
||||
// make this check optional.
|
||||
always @(posedge i_clk)
|
||||
if ((f_past_valid)&&($past(i_wb_cyc))&&(!$past(i_wb_stb)))
|
||||
`SLAVE_ASSUME(!i_wb_stb);
|
||||
end endgenerate
|
||||
// }}}
|
||||
endmodule
|
||||
`undef SLAVE_ASSUME
|
||||
`undef SLAVE_ASSERT
|
||||
|
|
|
|||
|
|
@ -1,235 +1,235 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Filename: axi_addr.v
|
||||
// {{{
|
||||
// Project: WB2AXIPSP: bus bridges and other odds and ends
|
||||
//
|
||||
// Purpose: The AXI (full) standard has some rather complicated addressing
|
||||
// modes, where the address can either be FIXED, INCRementing, or
|
||||
// even where it can WRAP around some boundary. When in either INCR or
|
||||
// WRAP modes, the next address must always be aligned. In WRAP mode,
|
||||
// the next address calculation needs to wrap around a given value, and
|
||||
// that value is dependent upon the burst size (i.e. bytes per beat) and
|
||||
// length (total numbers of beats). Since this calculation can be
|
||||
// non-trivial, and since it needs to be done multiple times, the logic
|
||||
// below captures it for every time it might be needed.
|
||||
//
|
||||
// 20200918 - modified to accommodate (potential) AXI3 burst lengths
|
||||
//
|
||||
// Creator: Dan Gisselquist, Ph.D.
|
||||
// Gisselquist Technology, LLC
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// }}}
|
||||
// Copyright (C) 2019-2024, Gisselquist Technology, LLC
|
||||
// {{{
|
||||
// This file is part of the WB2AXIP project.
|
||||
//
|
||||
// The WB2AXIP project contains free software and gateware, licensed under the
|
||||
// Apache License, Version 2.0 (the "License"). You may not use this project,
|
||||
// or this file, except in compliance with the License. You may obtain a copy
|
||||
// of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
`default_nettype none
|
||||
// }}}
|
||||
module axi_addr #(
|
||||
// {{{
|
||||
parameter AW = 32,
|
||||
DW = 32,
|
||||
// parameter [0:0] OPT_AXI3 = 1'b0,
|
||||
localparam LENB = 8
|
||||
// }}}
|
||||
) (
|
||||
// {{{
|
||||
input wire [AW-1:0] i_last_addr,
|
||||
input wire [2:0] i_size, // 1b, 2b, 4b, 8b, etc
|
||||
input wire [1:0] i_burst, // fixed, incr, wrap, reserved
|
||||
input wire [LENB-1:0] i_len,
|
||||
output wire [AW-1:0] o_next_addr
|
||||
// }}}
|
||||
);
|
||||
|
||||
// Parameter/register declarations
|
||||
// {{{
|
||||
localparam DSZ = $clog2(DW)-3;
|
||||
localparam [1:0] FIXED = 2'b00;
|
||||
// localparam [1:0] INCREMENT = 2'b01;
|
||||
// localparam [1:0] WRAP = 2'b10;
|
||||
localparam IN_AW = (AW >= 12) ? 12 : AW;
|
||||
localparam [IN_AW-1:0] ONE = 1;
|
||||
|
||||
reg [IN_AW-1:0] wrap_mask, increment;
|
||||
reg [IN_AW-1:0] crossblk_addr, aligned_addr, unaligned_addr;
|
||||
// }}}
|
||||
|
||||
// Address increment
|
||||
// {{{
|
||||
always @(*)
|
||||
if (DSZ == 0)
|
||||
increment = 1;
|
||||
else if (DSZ == 1)
|
||||
increment = (i_size[0]) ? 2 : 1;
|
||||
else if (DSZ == 2)
|
||||
increment = (i_size[1]) ? 4 : ((i_size[0]) ? 2 : 1);
|
||||
else if (DSZ == 3)
|
||||
case(i_size[1:0])
|
||||
2'b00: increment = 1;
|
||||
2'b01: increment = 2;
|
||||
2'b10: increment = 4;
|
||||
2'b11: increment = 8;
|
||||
endcase
|
||||
else
|
||||
increment = (1<<i_size);
|
||||
// }}}
|
||||
|
||||
// wrap_mask
|
||||
// {{{
|
||||
// The wrap_mask is used to determine which bits remain stable across
|
||||
// the burst, and which are allowed to change. It is only used during
|
||||
// wrapped addressing.
|
||||
always @(*)
|
||||
begin
|
||||
// Start with the default, minimum mask
|
||||
|
||||
/*
|
||||
// Here's the original code. It works, but it's
|
||||
// not economical (uses too many LUTs)
|
||||
//
|
||||
if (i_len[3:0] == 1)
|
||||
wrap_mask = (1<<(i_size+1));
|
||||
else if (i_len[3:0] == 3)
|
||||
wrap_mask = (1<<(i_size+2));
|
||||
else if (i_len[3:0] == 7)
|
||||
wrap_mask = (1<<(i_size+3));
|
||||
else if (i_len[3:0] == 15)
|
||||
wrap_mask = (1<<(i_size+4));
|
||||
wrap_mask = wrap_mask - 1;
|
||||
*/
|
||||
|
||||
// Here's what we *want*
|
||||
//
|
||||
// wrap_mask[i_size:0] = -1;
|
||||
//
|
||||
// On the other hand, since we're already guaranteed that our
|
||||
// addresses are aligned, do we really care about
|
||||
// wrap_mask[i_size-1:0] ?
|
||||
|
||||
// What we want:
|
||||
//
|
||||
// wrap_mask[i_size+3:i_size] |= i_len[3:0]
|
||||
//
|
||||
// We could simplify this to
|
||||
//
|
||||
// wrap_mask = wrap_mask | (i_len[3:0] << (i_size));
|
||||
// Verilator lint_off WIDTH
|
||||
if (DSZ < 2)
|
||||
wrap_mask = ONE | ({{(IN_AW-4){1'b0}},i_len[3:0]} << (i_size[0]));
|
||||
else if (DSZ < 4)
|
||||
wrap_mask = ONE | ({{(IN_AW-4){1'b0}},i_len[3:0]} << (i_size[1:0]));
|
||||
else
|
||||
wrap_mask = ONE | ({{(IN_AW-4){1'b0}},i_len[3:0]} << (i_size));
|
||||
// Verilator lint_on WIDTH
|
||||
end
|
||||
// }}}
|
||||
|
||||
// unaligned_addr
|
||||
always @(*)
|
||||
unaligned_addr = i_last_addr[IN_AW-1:0] + increment[IN_AW-1:0];
|
||||
|
||||
// aligned_addr
|
||||
// {{{
|
||||
always @(*)
|
||||
if (i_burst != FIXED)
|
||||
begin
|
||||
// Align subsequent beats in any burst
|
||||
// {{{
|
||||
aligned_addr = unaligned_addr;
|
||||
// We use the bus size here to simplify the logic
|
||||
// required in case the bus is smaller than the
|
||||
// maximum. This depends upon AxSIZE being less than
|
||||
// $clog2(DATA_WIDTH/8).
|
||||
if (DSZ < 2)
|
||||
begin
|
||||
// {{{
|
||||
// Align any subsequent address
|
||||
if (i_size[0])
|
||||
aligned_addr[0] = 0;
|
||||
// }}}
|
||||
end else if (DSZ < 4)
|
||||
begin
|
||||
// {{{
|
||||
// Align any subsequent address
|
||||
case(i_size[1:0])
|
||||
2'b00: aligned_addr = unaligned_addr;
|
||||
2'b01: aligned_addr[ 0] = 0;
|
||||
2'b10: aligned_addr[(AW-1>1) ? 1 : (AW-1):0]= 0;
|
||||
2'b11: aligned_addr[(AW-1>2) ? 2 : (AW-1):0]= 0;
|
||||
endcase
|
||||
// }}}
|
||||
end else begin
|
||||
// {{{
|
||||
// Align any subsequent address
|
||||
case(i_size)
|
||||
3'b001: aligned_addr[ 0] = 0;
|
||||
3'b010: aligned_addr[(AW-1>1) ? 1 : (AW-1):0]=0;
|
||||
3'b011: aligned_addr[(AW-1>2) ? 2 : (AW-1):0]=0;
|
||||
3'b100: aligned_addr[(AW-1>3) ? 3 : (AW-1):0]=0;
|
||||
3'b101: aligned_addr[(AW-1>4) ? 4 : (AW-1):0]=0;
|
||||
3'b110: aligned_addr[(AW-1>5) ? 5 : (AW-1):0]=0;
|
||||
3'b111: aligned_addr[(AW-1>6) ? 6 : (AW-1):0]=0;
|
||||
default: aligned_addr = unaligned_addr;
|
||||
endcase
|
||||
// }}}
|
||||
end
|
||||
// }}}
|
||||
end else
|
||||
aligned_addr = i_last_addr[IN_AW-1:0];
|
||||
// }}}
|
||||
|
||||
// crossblk_addr from aligned_addr, for WRAP addressing
|
||||
// {{{
|
||||
always @(*)
|
||||
if (i_burst[1])
|
||||
begin
|
||||
// WRAP!
|
||||
crossblk_addr[IN_AW-1:0] = (i_last_addr[IN_AW-1:0] & ~wrap_mask)
|
||||
| (aligned_addr & wrap_mask);
|
||||
end else
|
||||
crossblk_addr[IN_AW-1:0] = aligned_addr;
|
||||
// }}}
|
||||
|
||||
// o_next_addr: Guarantee only the bottom 12 bits change
|
||||
// {{{
|
||||
// This is really a logic simplification. AXI bursts aren't allowed
|
||||
// to cross 4kB boundaries. Given that's the case, we don't have to
|
||||
// suffer from the propagation across all AW bits, and can limit any
|
||||
// address propagation to just the lower 12 bits
|
||||
generate if (AW > 12)
|
||||
begin : WIDE_ADDRESS
|
||||
assign o_next_addr = { i_last_addr[AW-1:12],
|
||||
crossblk_addr[11:0] };
|
||||
end else begin : NARROW_ADDRESS
|
||||
assign o_next_addr = crossblk_addr[AW-1:0];
|
||||
end endgenerate
|
||||
// }}}
|
||||
|
||||
// Make Verilator happy
|
||||
// {{{
|
||||
// Verilator lint_off UNUSED
|
||||
wire unused;
|
||||
assign unused = (LENB <= 4) ? &{1'b0, i_len[0] }
|
||||
: &{ 1'b0, i_len[LENB-1:4], i_len[0] };
|
||||
// Verilator lint_on UNUSED
|
||||
// }}}
|
||||
endmodule
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Filename: axi_addr.v
|
||||
// {{{
|
||||
// Project: WB2AXIPSP: bus bridges and other odds and ends
|
||||
//
|
||||
// Purpose: The AXI (full) standard has some rather complicated addressing
|
||||
// modes, where the address can either be FIXED, INCRementing, or
|
||||
// even where it can WRAP around some boundary. When in either INCR or
|
||||
// WRAP modes, the next address must always be aligned. In WRAP mode,
|
||||
// the next address calculation needs to wrap around a given value, and
|
||||
// that value is dependent upon the burst size (i.e. bytes per beat) and
|
||||
// length (total numbers of beats). Since this calculation can be
|
||||
// non-trivial, and since it needs to be done multiple times, the logic
|
||||
// below captures it for every time it might be needed.
|
||||
//
|
||||
// 20200918 - modified to accommodate (potential) AXI3 burst lengths
|
||||
//
|
||||
// Creator: Dan Gisselquist, Ph.D.
|
||||
// Gisselquist Technology, LLC
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// }}}
|
||||
// Copyright (C) 2019-2024, Gisselquist Technology, LLC
|
||||
// {{{
|
||||
// This file is part of the WB2AXIP project.
|
||||
//
|
||||
// The WB2AXIP project contains free software and gateware, licensed under the
|
||||
// Apache License, Version 2.0 (the "License"). You may not use this project,
|
||||
// or this file, except in compliance with the License. You may obtain a copy
|
||||
// of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
`default_nettype none
|
||||
// }}}
|
||||
module axi_addr #(
|
||||
// {{{
|
||||
parameter AW = 32,
|
||||
DW = 32,
|
||||
// parameter [0:0] OPT_AXI3 = 1'b0,
|
||||
localparam LENB = 8
|
||||
// }}}
|
||||
) (
|
||||
// {{{
|
||||
input wire [AW-1:0] i_last_addr,
|
||||
input wire [2:0] i_size, // 1b, 2b, 4b, 8b, etc
|
||||
input wire [1:0] i_burst, // fixed, incr, wrap, reserved
|
||||
input wire [LENB-1:0] i_len,
|
||||
output wire [AW-1:0] o_next_addr
|
||||
// }}}
|
||||
);
|
||||
|
||||
// Parameter/register declarations
|
||||
// {{{
|
||||
localparam DSZ = $clog2(DW)-3;
|
||||
localparam [1:0] FIXED = 2'b00;
|
||||
// localparam [1:0] INCREMENT = 2'b01;
|
||||
// localparam [1:0] WRAP = 2'b10;
|
||||
localparam IN_AW = (AW >= 12) ? 12 : AW;
|
||||
localparam [IN_AW-1:0] ONE = 1;
|
||||
|
||||
reg [IN_AW-1:0] wrap_mask, increment;
|
||||
reg [IN_AW-1:0] crossblk_addr, aligned_addr, unaligned_addr;
|
||||
// }}}
|
||||
|
||||
// Address increment
|
||||
// {{{
|
||||
always @(*)
|
||||
if (DSZ == 0)
|
||||
increment = 1;
|
||||
else if (DSZ == 1)
|
||||
increment = (i_size[0]) ? 2 : 1;
|
||||
else if (DSZ == 2)
|
||||
increment = (i_size[1]) ? 4 : ((i_size[0]) ? 2 : 1);
|
||||
else if (DSZ == 3)
|
||||
case(i_size[1:0])
|
||||
2'b00: increment = 1;
|
||||
2'b01: increment = 2;
|
||||
2'b10: increment = 4;
|
||||
2'b11: increment = 8;
|
||||
endcase
|
||||
else
|
||||
increment = (1<<i_size);
|
||||
// }}}
|
||||
|
||||
// wrap_mask
|
||||
// {{{
|
||||
// The wrap_mask is used to determine which bits remain stable across
|
||||
// the burst, and which are allowed to change. It is only used during
|
||||
// wrapped addressing.
|
||||
always @(*)
|
||||
begin
|
||||
// Start with the default, minimum mask
|
||||
|
||||
/*
|
||||
// Here's the original code. It works, but it's
|
||||
// not economical (uses too many LUTs)
|
||||
//
|
||||
if (i_len[3:0] == 1)
|
||||
wrap_mask = (1<<(i_size+1));
|
||||
else if (i_len[3:0] == 3)
|
||||
wrap_mask = (1<<(i_size+2));
|
||||
else if (i_len[3:0] == 7)
|
||||
wrap_mask = (1<<(i_size+3));
|
||||
else if (i_len[3:0] == 15)
|
||||
wrap_mask = (1<<(i_size+4));
|
||||
wrap_mask = wrap_mask - 1;
|
||||
*/
|
||||
|
||||
// Here's what we *want*
|
||||
//
|
||||
// wrap_mask[i_size:0] = -1;
|
||||
//
|
||||
// On the other hand, since we're already guaranteed that our
|
||||
// addresses are aligned, do we really care about
|
||||
// wrap_mask[i_size-1:0] ?
|
||||
|
||||
// What we want:
|
||||
//
|
||||
// wrap_mask[i_size+3:i_size] |= i_len[3:0]
|
||||
//
|
||||
// We could simplify this to
|
||||
//
|
||||
// wrap_mask = wrap_mask | (i_len[3:0] << (i_size));
|
||||
// Verilator lint_off WIDTH
|
||||
if (DSZ < 2)
|
||||
wrap_mask = ONE | ({{(IN_AW-4){1'b0}},i_len[3:0]} << (i_size[0]));
|
||||
else if (DSZ < 4)
|
||||
wrap_mask = ONE | ({{(IN_AW-4){1'b0}},i_len[3:0]} << (i_size[1:0]));
|
||||
else
|
||||
wrap_mask = ONE | ({{(IN_AW-4){1'b0}},i_len[3:0]} << (i_size));
|
||||
// Verilator lint_on WIDTH
|
||||
end
|
||||
// }}}
|
||||
|
||||
// unaligned_addr
|
||||
always @(*)
|
||||
unaligned_addr = i_last_addr[IN_AW-1:0] + increment[IN_AW-1:0];
|
||||
|
||||
// aligned_addr
|
||||
// {{{
|
||||
always @(*)
|
||||
if (i_burst != FIXED)
|
||||
begin
|
||||
// Align subsequent beats in any burst
|
||||
// {{{
|
||||
aligned_addr = unaligned_addr;
|
||||
// We use the bus size here to simplify the logic
|
||||
// required in case the bus is smaller than the
|
||||
// maximum. This depends upon AxSIZE being less than
|
||||
// $clog2(DATA_WIDTH/8).
|
||||
if (DSZ < 2)
|
||||
begin
|
||||
// {{{
|
||||
// Align any subsequent address
|
||||
if (i_size[0])
|
||||
aligned_addr[0] = 0;
|
||||
// }}}
|
||||
end else if (DSZ < 4)
|
||||
begin
|
||||
// {{{
|
||||
// Align any subsequent address
|
||||
case(i_size[1:0])
|
||||
2'b00: aligned_addr = unaligned_addr;
|
||||
2'b01: aligned_addr[ 0] = 0;
|
||||
2'b10: aligned_addr[(AW-1>1) ? 1 : (AW-1):0]= 0;
|
||||
2'b11: aligned_addr[(AW-1>2) ? 2 : (AW-1):0]= 0;
|
||||
endcase
|
||||
// }}}
|
||||
end else begin
|
||||
// {{{
|
||||
// Align any subsequent address
|
||||
case(i_size)
|
||||
3'b001: aligned_addr[ 0] = 0;
|
||||
3'b010: aligned_addr[(AW-1>1) ? 1 : (AW-1):0]=0;
|
||||
3'b011: aligned_addr[(AW-1>2) ? 2 : (AW-1):0]=0;
|
||||
3'b100: aligned_addr[(AW-1>3) ? 3 : (AW-1):0]=0;
|
||||
3'b101: aligned_addr[(AW-1>4) ? 4 : (AW-1):0]=0;
|
||||
3'b110: aligned_addr[(AW-1>5) ? 5 : (AW-1):0]=0;
|
||||
3'b111: aligned_addr[(AW-1>6) ? 6 : (AW-1):0]=0;
|
||||
default: aligned_addr = unaligned_addr;
|
||||
endcase
|
||||
// }}}
|
||||
end
|
||||
// }}}
|
||||
end else
|
||||
aligned_addr = i_last_addr[IN_AW-1:0];
|
||||
// }}}
|
||||
|
||||
// crossblk_addr from aligned_addr, for WRAP addressing
|
||||
// {{{
|
||||
always @(*)
|
||||
if (i_burst[1])
|
||||
begin
|
||||
// WRAP!
|
||||
crossblk_addr[IN_AW-1:0] = (i_last_addr[IN_AW-1:0] & ~wrap_mask)
|
||||
| (aligned_addr & wrap_mask);
|
||||
end else
|
||||
crossblk_addr[IN_AW-1:0] = aligned_addr;
|
||||
// }}}
|
||||
|
||||
// o_next_addr: Guarantee only the bottom 12 bits change
|
||||
// {{{
|
||||
// This is really a logic simplification. AXI bursts aren't allowed
|
||||
// to cross 4kB boundaries. Given that's the case, we don't have to
|
||||
// suffer from the propagation across all AW bits, and can limit any
|
||||
// address propagation to just the lower 12 bits
|
||||
generate if (AW > 12)
|
||||
begin : WIDE_ADDRESS
|
||||
assign o_next_addr = { i_last_addr[AW-1:12],
|
||||
crossblk_addr[11:0] };
|
||||
end else begin : NARROW_ADDRESS
|
||||
assign o_next_addr = crossblk_addr[AW-1:0];
|
||||
end endgenerate
|
||||
// }}}
|
||||
|
||||
// Make Verilator happy
|
||||
// {{{
|
||||
// Verilator lint_off UNUSED
|
||||
wire unused;
|
||||
assign unused = (LENB <= 4) ? &{1'b0, i_len[0] }
|
||||
: &{ 1'b0, i_len[LENB-1:4], i_len[0] };
|
||||
// Verilator lint_on UNUSED
|
||||
// }}}
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,317 +1,317 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Filename: axim2wbsp.v
|
||||
// {{{
|
||||
// Project: WB2AXIPSP: bus bridges and other odds and ends
|
||||
//
|
||||
// Purpose: So ... this converter works in the other direction from
|
||||
// wbm2axisp. This converter takes AXI commands, and organizes
|
||||
// them into pipelined wishbone commands.
|
||||
//
|
||||
// This particular core treats AXI as two separate buses: one for writes,
|
||||
// and the other for reads. This particular core combines the two channels
|
||||
// into one. The designer should be aware that the two AXI buses turned
|
||||
// Wishbone buses can be kept separate as separate inputs to a WB crosssbar
|
||||
// for better performance in some circumstances.
|
||||
//
|
||||
// Creator: Dan Gisselquist, Ph.D.
|
||||
// Gisselquist Technology, LLC
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// }}}
|
||||
// Copyright (C) 2016-2024, Gisselquist Technology, LLC
|
||||
// {{{
|
||||
// This file is part of the WB2AXIP project.
|
||||
//
|
||||
// The WB2AXIP project contains free software and gateware, licensed under the
|
||||
// Apache License, Version 2.0 (the "License"). You may not use this project,
|
||||
// or this file, except in compliance with the License. You may obtain a copy
|
||||
// of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
`default_nettype none
|
||||
// }}}
|
||||
module axim2wbsp #(
|
||||
// {{{
|
||||
parameter C_AXI_ID_WIDTH = 2, // The AXI id width used for R&W
|
||||
// This is an int between 1-16
|
||||
parameter C_AXI_DATA_WIDTH = 32,// Width of the AXI R&W data
|
||||
parameter C_AXI_ADDR_WIDTH = 28, // AXI Address width
|
||||
localparam AXI_LSBS = $clog2(C_AXI_DATA_WIDTH)-3,
|
||||
localparam DW = C_AXI_DATA_WIDTH,
|
||||
localparam AW = C_AXI_ADDR_WIDTH - AXI_LSBS,
|
||||
parameter LGFIFO = 5,
|
||||
parameter [0:0] OPT_SWAP_ENDIANNESS = 1'b0,
|
||||
parameter [0:0] OPT_READONLY = 1'b0,
|
||||
parameter [0:0] OPT_WRITEONLY = 1'b0
|
||||
// }}}
|
||||
) (
|
||||
// {{{
|
||||
//
|
||||
input wire S_AXI_ACLK, // System clock
|
||||
input wire S_AXI_ARESETN,
|
||||
|
||||
// AXI write address channel signals
|
||||
// {{{
|
||||
input wire S_AXI_AWVALID,
|
||||
output wire S_AXI_AWREADY,
|
||||
input wire [C_AXI_ID_WIDTH-1:0] S_AXI_AWID,
|
||||
input wire [C_AXI_ADDR_WIDTH-1:0] S_AXI_AWADDR,
|
||||
input wire [7:0] S_AXI_AWLEN,
|
||||
input wire [2:0] S_AXI_AWSIZE,
|
||||
input wire [1:0] S_AXI_AWBURST,
|
||||
input wire [0:0] S_AXI_AWLOCK,
|
||||
input wire [3:0] S_AXI_AWCACHE,
|
||||
input wire [2:0] S_AXI_AWPROT,
|
||||
input wire [3:0] S_AXI_AWQOS,
|
||||
// }}}
|
||||
// AXI write data channel signals
|
||||
// {{{
|
||||
input wire S_AXI_WVALID,
|
||||
output wire S_AXI_WREADY,
|
||||
input wire [C_AXI_DATA_WIDTH-1:0] S_AXI_WDATA,
|
||||
input wire [C_AXI_DATA_WIDTH/8-1:0] S_AXI_WSTRB,
|
||||
input wire S_AXI_WLAST,
|
||||
// }}}
|
||||
// AXI write response channel signals
|
||||
// {{{
|
||||
output wire S_AXI_BVALID,
|
||||
input wire S_AXI_BREADY,
|
||||
output wire [C_AXI_ID_WIDTH-1:0] S_AXI_BID,
|
||||
output wire [1:0] S_AXI_BRESP,
|
||||
// }}}
|
||||
// AXI read address channel signals
|
||||
// {{{
|
||||
input wire S_AXI_ARVALID,
|
||||
output wire S_AXI_ARREADY,
|
||||
input wire [C_AXI_ID_WIDTH-1:0] S_AXI_ARID,
|
||||
input wire [C_AXI_ADDR_WIDTH-1:0] S_AXI_ARADDR,
|
||||
input wire [7:0] S_AXI_ARLEN,
|
||||
input wire [2:0] S_AXI_ARSIZE,
|
||||
input wire [1:0] S_AXI_ARBURST,
|
||||
input wire [0:0] S_AXI_ARLOCK,
|
||||
input wire [3:0] S_AXI_ARCACHE,
|
||||
input wire [2:0] S_AXI_ARPROT,
|
||||
input wire [3:0] S_AXI_ARQOS,
|
||||
// }}}
|
||||
// AXI read data channel signals
|
||||
// {{{
|
||||
output wire S_AXI_RVALID, // Rd rslt valid
|
||||
input wire S_AXI_RREADY, // Rd rslt ready
|
||||
output wire [C_AXI_ID_WIDTH-1:0] S_AXI_RID, // Response ID
|
||||
output wire [C_AXI_DATA_WIDTH-1:0] S_AXI_RDATA,// Read data
|
||||
output wire S_AXI_RLAST, // Read last
|
||||
output wire [1:0] S_AXI_RRESP, // Read response
|
||||
// }}}
|
||||
// We'll share the clock and the reset
|
||||
// {{{
|
||||
output wire o_reset,
|
||||
output wire o_wb_cyc,
|
||||
output wire o_wb_stb,
|
||||
output wire o_wb_we,
|
||||
output wire [(AW-1):0] o_wb_addr,
|
||||
output wire [(C_AXI_DATA_WIDTH-1):0] o_wb_data,
|
||||
output wire [(C_AXI_DATA_WIDTH/8-1):0] o_wb_sel,
|
||||
input wire i_wb_stall,
|
||||
input wire i_wb_ack,
|
||||
input wire [(C_AXI_DATA_WIDTH-1):0] i_wb_data,
|
||||
input wire i_wb_err
|
||||
// }}}
|
||||
// }}}
|
||||
);
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
wire [(AW-1):0] w_wb_addr, r_wb_addr;
|
||||
wire [(C_AXI_DATA_WIDTH-1):0] w_wb_data;
|
||||
wire [(C_AXI_DATA_WIDTH/8-1):0] w_wb_sel, r_wb_sel;
|
||||
wire r_wb_err, r_wb_cyc, r_wb_stb, r_wb_stall, r_wb_ack;
|
||||
wire w_wb_err, w_wb_cyc, w_wb_stb, w_wb_stall, w_wb_ack;
|
||||
wire r_wb_we, w_wb_we;
|
||||
|
||||
assign r_wb_we = 1'b0;
|
||||
assign w_wb_we = 1'b1;
|
||||
|
||||
generate if (!OPT_READONLY)
|
||||
begin : AXI_WR
|
||||
// {{{
|
||||
aximwr2wbsp #(
|
||||
// {{{
|
||||
.C_AXI_ID_WIDTH(C_AXI_ID_WIDTH),
|
||||
.C_AXI_DATA_WIDTH(C_AXI_DATA_WIDTH),
|
||||
.C_AXI_ADDR_WIDTH(C_AXI_ADDR_WIDTH),
|
||||
.OPT_SWAP_ENDIANNESS(OPT_SWAP_ENDIANNESS),
|
||||
.LGFIFO(LGFIFO)
|
||||
// }}}
|
||||
) axi_write_decoder(
|
||||
// {{{
|
||||
.S_AXI_ACLK(S_AXI_ACLK), .S_AXI_ARESETN(S_AXI_ARESETN),
|
||||
//
|
||||
.S_AXI_AWVALID(S_AXI_AWVALID),
|
||||
.S_AXI_AWREADY(S_AXI_AWREADY),
|
||||
.S_AXI_AWID( S_AXI_AWID),
|
||||
.S_AXI_AWADDR( S_AXI_AWADDR),
|
||||
.S_AXI_AWLEN( S_AXI_AWLEN),
|
||||
.S_AXI_AWSIZE( S_AXI_AWSIZE),
|
||||
.S_AXI_AWBURST(S_AXI_AWBURST),
|
||||
.S_AXI_AWLOCK( S_AXI_AWLOCK),
|
||||
.S_AXI_AWCACHE(S_AXI_AWCACHE),
|
||||
.S_AXI_AWPROT( S_AXI_AWPROT),
|
||||
.S_AXI_AWQOS( S_AXI_AWQOS),
|
||||
//
|
||||
.S_AXI_WVALID( S_AXI_WVALID),
|
||||
.S_AXI_WREADY( S_AXI_WREADY),
|
||||
.S_AXI_WDATA( S_AXI_WDATA),
|
||||
.S_AXI_WSTRB( S_AXI_WSTRB),
|
||||
.S_AXI_WLAST( S_AXI_WLAST),
|
||||
//
|
||||
.S_AXI_BVALID(S_AXI_BVALID),
|
||||
.S_AXI_BREADY(S_AXI_BREADY),
|
||||
.S_AXI_BID( S_AXI_BID),
|
||||
.S_AXI_BRESP( S_AXI_BRESP),
|
||||
//
|
||||
.o_wb_cyc( w_wb_cyc),
|
||||
.o_wb_stb( w_wb_stb),
|
||||
.o_wb_addr( w_wb_addr),
|
||||
.o_wb_data( w_wb_data),
|
||||
.o_wb_sel( w_wb_sel),
|
||||
.i_wb_ack( w_wb_ack),
|
||||
.i_wb_stall(w_wb_stall),
|
||||
.i_wb_err( w_wb_err)
|
||||
// }}}
|
||||
);
|
||||
// }}}
|
||||
end else begin : NO_WRITE_CHANNEL
|
||||
// {{{
|
||||
assign w_wb_cyc = 0;
|
||||
assign w_wb_stb = 0;
|
||||
assign w_wb_addr = 0;
|
||||
assign w_wb_data = 0;
|
||||
assign w_wb_sel = 0;
|
||||
assign S_AXI_AWREADY = 0;
|
||||
assign S_AXI_WREADY = 0;
|
||||
assign S_AXI_BVALID = 0;
|
||||
assign S_AXI_BRESP = 2'b11;
|
||||
assign S_AXI_BID = 0;
|
||||
// }}}
|
||||
end endgenerate
|
||||
|
||||
generate if (!OPT_WRITEONLY)
|
||||
begin : AXI_RD
|
||||
// {{{
|
||||
aximrd2wbsp #(
|
||||
// {{{
|
||||
.C_AXI_ID_WIDTH(C_AXI_ID_WIDTH),
|
||||
.C_AXI_DATA_WIDTH(C_AXI_DATA_WIDTH),
|
||||
.C_AXI_ADDR_WIDTH(C_AXI_ADDR_WIDTH),
|
||||
.OPT_SWAP_ENDIANNESS(OPT_SWAP_ENDIANNESS),
|
||||
.LGFIFO(LGFIFO)
|
||||
// }}}
|
||||
) axi_read_decoder(
|
||||
// {{{
|
||||
.S_AXI_ACLK(S_AXI_ACLK), .S_AXI_ARESETN(S_AXI_ARESETN),
|
||||
//
|
||||
.S_AXI_ARVALID(S_AXI_ARVALID),
|
||||
.S_AXI_ARREADY(S_AXI_ARREADY),
|
||||
.S_AXI_ARID( S_AXI_ARID),
|
||||
.S_AXI_ARADDR( S_AXI_ARADDR),
|
||||
.S_AXI_ARLEN( S_AXI_ARLEN),
|
||||
.S_AXI_ARSIZE( S_AXI_ARSIZE),
|
||||
.S_AXI_ARBURST(S_AXI_ARBURST),
|
||||
.S_AXI_ARLOCK( S_AXI_ARLOCK),
|
||||
.S_AXI_ARCACHE(S_AXI_ARCACHE),
|
||||
.S_AXI_ARPROT( S_AXI_ARPROT),
|
||||
.S_AXI_ARQOS( S_AXI_ARQOS),
|
||||
//
|
||||
.S_AXI_RVALID(S_AXI_RVALID),
|
||||
.S_AXI_RREADY(S_AXI_RREADY),
|
||||
.S_AXI_RID( S_AXI_RID),
|
||||
.S_AXI_RDATA( S_AXI_RDATA),
|
||||
.S_AXI_RLAST( S_AXI_RLAST),
|
||||
.S_AXI_RRESP( S_AXI_RRESP),
|
||||
//
|
||||
.o_wb_cyc( r_wb_cyc),
|
||||
.o_wb_stb( r_wb_stb),
|
||||
.o_wb_addr( r_wb_addr),
|
||||
.o_wb_sel( r_wb_sel),
|
||||
.i_wb_ack( r_wb_ack),
|
||||
.i_wb_stall(r_wb_stall),
|
||||
.i_wb_data( i_wb_data),
|
||||
.i_wb_err( r_wb_err)
|
||||
// }}}
|
||||
);
|
||||
// }}}
|
||||
end else begin : NO_READ_CHANNEL
|
||||
// {{{
|
||||
assign r_wb_cyc = 0;
|
||||
assign r_wb_stb = 0;
|
||||
assign r_wb_addr = 0;
|
||||
//
|
||||
assign S_AXI_ARREADY = 0;
|
||||
assign S_AXI_RVALID = 0;
|
||||
assign S_AXI_RID = 0;
|
||||
assign S_AXI_RDATA = 0;
|
||||
assign S_AXI_RLAST = 0;
|
||||
assign S_AXI_RRESP = 0;
|
||||
// }}}
|
||||
end endgenerate
|
||||
|
||||
generate if (OPT_READONLY)
|
||||
begin : ARB_RD
|
||||
// {{{
|
||||
assign o_wb_cyc = r_wb_cyc;
|
||||
assign o_wb_stb = r_wb_stb;
|
||||
assign o_wb_we = r_wb_we;
|
||||
assign o_wb_addr = r_wb_addr;
|
||||
assign o_wb_data = 0;
|
||||
assign o_wb_sel = r_wb_sel;
|
||||
assign r_wb_ack = i_wb_ack;
|
||||
assign r_wb_stall= i_wb_stall;
|
||||
assign r_wb_ack = i_wb_ack;
|
||||
assign r_wb_err = i_wb_err;
|
||||
// }}}
|
||||
end else if (OPT_WRITEONLY)
|
||||
begin : ARB_WR
|
||||
// {{{
|
||||
assign o_wb_cyc = w_wb_cyc;
|
||||
assign o_wb_stb = w_wb_stb;
|
||||
assign o_wb_we = w_wb_we;
|
||||
assign o_wb_addr = w_wb_addr;
|
||||
assign o_wb_data = w_wb_data;
|
||||
assign o_wb_sel = w_wb_sel;
|
||||
assign w_wb_ack = i_wb_ack;
|
||||
assign w_wb_stall= i_wb_stall;
|
||||
assign w_wb_ack = i_wb_ack;
|
||||
assign w_wb_err = i_wb_err;
|
||||
// }}}
|
||||
end else begin : ARB_WB
|
||||
// {{{
|
||||
wbarbiter #(.DW(DW), .AW(AW))
|
||||
readorwrite(S_AXI_ACLK, o_reset,
|
||||
r_wb_cyc, r_wb_stb, r_wb_we, r_wb_addr, w_wb_data, r_wb_sel,
|
||||
r_wb_ack, r_wb_stall, r_wb_err,
|
||||
w_wb_cyc, w_wb_stb, w_wb_we, w_wb_addr, w_wb_data, w_wb_sel,
|
||||
w_wb_ack, w_wb_stall, w_wb_err,
|
||||
o_wb_cyc, o_wb_stb, o_wb_we, o_wb_addr, o_wb_data, o_wb_sel,
|
||||
i_wb_ack, i_wb_stall, i_wb_err
|
||||
);
|
||||
// }}}
|
||||
end endgenerate
|
||||
|
||||
assign o_reset = (S_AXI_ARESETN == 1'b0);
|
||||
|
||||
`ifdef FORMAL
|
||||
`endif
|
||||
endmodule
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Filename: axim2wbsp.v
|
||||
// {{{
|
||||
// Project: WB2AXIPSP: bus bridges and other odds and ends
|
||||
//
|
||||
// Purpose: So ... this converter works in the other direction from
|
||||
// wbm2axisp. This converter takes AXI commands, and organizes
|
||||
// them into pipelined wishbone commands.
|
||||
//
|
||||
// This particular core treats AXI as two separate buses: one for writes,
|
||||
// and the other for reads. This particular core combines the two channels
|
||||
// into one. The designer should be aware that the two AXI buses turned
|
||||
// Wishbone buses can be kept separate as separate inputs to a WB crosssbar
|
||||
// for better performance in some circumstances.
|
||||
//
|
||||
// Creator: Dan Gisselquist, Ph.D.
|
||||
// Gisselquist Technology, LLC
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// }}}
|
||||
// Copyright (C) 2016-2024, Gisselquist Technology, LLC
|
||||
// {{{
|
||||
// This file is part of the WB2AXIP project.
|
||||
//
|
||||
// The WB2AXIP project contains free software and gateware, licensed under the
|
||||
// Apache License, Version 2.0 (the "License"). You may not use this project,
|
||||
// or this file, except in compliance with the License. You may obtain a copy
|
||||
// of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
`default_nettype none
|
||||
// }}}
|
||||
module axim2wbsp #(
|
||||
// {{{
|
||||
parameter C_AXI_ID_WIDTH = 2, // The AXI id width used for R&W
|
||||
// This is an int between 1-16
|
||||
parameter C_AXI_DATA_WIDTH = 32,// Width of the AXI R&W data
|
||||
parameter C_AXI_ADDR_WIDTH = 28, // AXI Address width
|
||||
localparam AXI_LSBS = $clog2(C_AXI_DATA_WIDTH)-3,
|
||||
localparam DW = C_AXI_DATA_WIDTH,
|
||||
localparam AW = C_AXI_ADDR_WIDTH - AXI_LSBS,
|
||||
parameter LGFIFO = 5,
|
||||
parameter [0:0] OPT_SWAP_ENDIANNESS = 1'b0,
|
||||
parameter [0:0] OPT_READONLY = 1'b0,
|
||||
parameter [0:0] OPT_WRITEONLY = 1'b0
|
||||
// }}}
|
||||
) (
|
||||
// {{{
|
||||
//
|
||||
input wire S_AXI_ACLK, // System clock
|
||||
input wire S_AXI_ARESETN,
|
||||
|
||||
// AXI write address channel signals
|
||||
// {{{
|
||||
input wire S_AXI_AWVALID,
|
||||
output wire S_AXI_AWREADY,
|
||||
input wire [C_AXI_ID_WIDTH-1:0] S_AXI_AWID,
|
||||
input wire [C_AXI_ADDR_WIDTH-1:0] S_AXI_AWADDR,
|
||||
input wire [7:0] S_AXI_AWLEN,
|
||||
input wire [2:0] S_AXI_AWSIZE,
|
||||
input wire [1:0] S_AXI_AWBURST,
|
||||
input wire [0:0] S_AXI_AWLOCK,
|
||||
input wire [3:0] S_AXI_AWCACHE,
|
||||
input wire [2:0] S_AXI_AWPROT,
|
||||
input wire [3:0] S_AXI_AWQOS,
|
||||
// }}}
|
||||
// AXI write data channel signals
|
||||
// {{{
|
||||
input wire S_AXI_WVALID,
|
||||
output wire S_AXI_WREADY,
|
||||
input wire [C_AXI_DATA_WIDTH-1:0] S_AXI_WDATA,
|
||||
input wire [C_AXI_DATA_WIDTH/8-1:0] S_AXI_WSTRB,
|
||||
input wire S_AXI_WLAST,
|
||||
// }}}
|
||||
// AXI write response channel signals
|
||||
// {{{
|
||||
output wire S_AXI_BVALID,
|
||||
input wire S_AXI_BREADY,
|
||||
output wire [C_AXI_ID_WIDTH-1:0] S_AXI_BID,
|
||||
output wire [1:0] S_AXI_BRESP,
|
||||
// }}}
|
||||
// AXI read address channel signals
|
||||
// {{{
|
||||
input wire S_AXI_ARVALID,
|
||||
output wire S_AXI_ARREADY,
|
||||
input wire [C_AXI_ID_WIDTH-1:0] S_AXI_ARID,
|
||||
input wire [C_AXI_ADDR_WIDTH-1:0] S_AXI_ARADDR,
|
||||
input wire [7:0] S_AXI_ARLEN,
|
||||
input wire [2:0] S_AXI_ARSIZE,
|
||||
input wire [1:0] S_AXI_ARBURST,
|
||||
input wire [0:0] S_AXI_ARLOCK,
|
||||
input wire [3:0] S_AXI_ARCACHE,
|
||||
input wire [2:0] S_AXI_ARPROT,
|
||||
input wire [3:0] S_AXI_ARQOS,
|
||||
// }}}
|
||||
// AXI read data channel signals
|
||||
// {{{
|
||||
output wire S_AXI_RVALID, // Rd rslt valid
|
||||
input wire S_AXI_RREADY, // Rd rslt ready
|
||||
output wire [C_AXI_ID_WIDTH-1:0] S_AXI_RID, // Response ID
|
||||
output wire [C_AXI_DATA_WIDTH-1:0] S_AXI_RDATA,// Read data
|
||||
output wire S_AXI_RLAST, // Read last
|
||||
output wire [1:0] S_AXI_RRESP, // Read response
|
||||
// }}}
|
||||
// We'll share the clock and the reset
|
||||
// {{{
|
||||
output wire o_reset,
|
||||
output wire o_wb_cyc,
|
||||
output wire o_wb_stb,
|
||||
output wire o_wb_we,
|
||||
output wire [(AW-1):0] o_wb_addr,
|
||||
output wire [(C_AXI_DATA_WIDTH-1):0] o_wb_data,
|
||||
output wire [(C_AXI_DATA_WIDTH/8-1):0] o_wb_sel,
|
||||
input wire i_wb_stall,
|
||||
input wire i_wb_ack,
|
||||
input wire [(C_AXI_DATA_WIDTH-1):0] i_wb_data,
|
||||
input wire i_wb_err
|
||||
// }}}
|
||||
// }}}
|
||||
);
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
wire [(AW-1):0] w_wb_addr, r_wb_addr;
|
||||
wire [(C_AXI_DATA_WIDTH-1):0] w_wb_data;
|
||||
wire [(C_AXI_DATA_WIDTH/8-1):0] w_wb_sel, r_wb_sel;
|
||||
wire r_wb_err, r_wb_cyc, r_wb_stb, r_wb_stall, r_wb_ack;
|
||||
wire w_wb_err, w_wb_cyc, w_wb_stb, w_wb_stall, w_wb_ack;
|
||||
wire r_wb_we, w_wb_we;
|
||||
|
||||
assign r_wb_we = 1'b0;
|
||||
assign w_wb_we = 1'b1;
|
||||
|
||||
generate if (!OPT_READONLY)
|
||||
begin : AXI_WR
|
||||
// {{{
|
||||
aximwr2wbsp #(
|
||||
// {{{
|
||||
.C_AXI_ID_WIDTH(C_AXI_ID_WIDTH),
|
||||
.C_AXI_DATA_WIDTH(C_AXI_DATA_WIDTH),
|
||||
.C_AXI_ADDR_WIDTH(C_AXI_ADDR_WIDTH),
|
||||
.OPT_SWAP_ENDIANNESS(OPT_SWAP_ENDIANNESS),
|
||||
.LGFIFO(LGFIFO)
|
||||
// }}}
|
||||
) axi_write_decoder(
|
||||
// {{{
|
||||
.S_AXI_ACLK(S_AXI_ACLK), .S_AXI_ARESETN(S_AXI_ARESETN),
|
||||
//
|
||||
.S_AXI_AWVALID(S_AXI_AWVALID),
|
||||
.S_AXI_AWREADY(S_AXI_AWREADY),
|
||||
.S_AXI_AWID( S_AXI_AWID),
|
||||
.S_AXI_AWADDR( S_AXI_AWADDR),
|
||||
.S_AXI_AWLEN( S_AXI_AWLEN),
|
||||
.S_AXI_AWSIZE( S_AXI_AWSIZE),
|
||||
.S_AXI_AWBURST(S_AXI_AWBURST),
|
||||
.S_AXI_AWLOCK( S_AXI_AWLOCK),
|
||||
.S_AXI_AWCACHE(S_AXI_AWCACHE),
|
||||
.S_AXI_AWPROT( S_AXI_AWPROT),
|
||||
.S_AXI_AWQOS( S_AXI_AWQOS),
|
||||
//
|
||||
.S_AXI_WVALID( S_AXI_WVALID),
|
||||
.S_AXI_WREADY( S_AXI_WREADY),
|
||||
.S_AXI_WDATA( S_AXI_WDATA),
|
||||
.S_AXI_WSTRB( S_AXI_WSTRB),
|
||||
.S_AXI_WLAST( S_AXI_WLAST),
|
||||
//
|
||||
.S_AXI_BVALID(S_AXI_BVALID),
|
||||
.S_AXI_BREADY(S_AXI_BREADY),
|
||||
.S_AXI_BID( S_AXI_BID),
|
||||
.S_AXI_BRESP( S_AXI_BRESP),
|
||||
//
|
||||
.o_wb_cyc( w_wb_cyc),
|
||||
.o_wb_stb( w_wb_stb),
|
||||
.o_wb_addr( w_wb_addr),
|
||||
.o_wb_data( w_wb_data),
|
||||
.o_wb_sel( w_wb_sel),
|
||||
.i_wb_ack( w_wb_ack),
|
||||
.i_wb_stall(w_wb_stall),
|
||||
.i_wb_err( w_wb_err)
|
||||
// }}}
|
||||
);
|
||||
// }}}
|
||||
end else begin : NO_WRITE_CHANNEL
|
||||
// {{{
|
||||
assign w_wb_cyc = 0;
|
||||
assign w_wb_stb = 0;
|
||||
assign w_wb_addr = 0;
|
||||
assign w_wb_data = 0;
|
||||
assign w_wb_sel = 0;
|
||||
assign S_AXI_AWREADY = 0;
|
||||
assign S_AXI_WREADY = 0;
|
||||
assign S_AXI_BVALID = 0;
|
||||
assign S_AXI_BRESP = 2'b11;
|
||||
assign S_AXI_BID = 0;
|
||||
// }}}
|
||||
end endgenerate
|
||||
|
||||
generate if (!OPT_WRITEONLY)
|
||||
begin : AXI_RD
|
||||
// {{{
|
||||
aximrd2wbsp #(
|
||||
// {{{
|
||||
.C_AXI_ID_WIDTH(C_AXI_ID_WIDTH),
|
||||
.C_AXI_DATA_WIDTH(C_AXI_DATA_WIDTH),
|
||||
.C_AXI_ADDR_WIDTH(C_AXI_ADDR_WIDTH),
|
||||
.OPT_SWAP_ENDIANNESS(OPT_SWAP_ENDIANNESS),
|
||||
.LGFIFO(LGFIFO)
|
||||
// }}}
|
||||
) axi_read_decoder(
|
||||
// {{{
|
||||
.S_AXI_ACLK(S_AXI_ACLK), .S_AXI_ARESETN(S_AXI_ARESETN),
|
||||
//
|
||||
.S_AXI_ARVALID(S_AXI_ARVALID),
|
||||
.S_AXI_ARREADY(S_AXI_ARREADY),
|
||||
.S_AXI_ARID( S_AXI_ARID),
|
||||
.S_AXI_ARADDR( S_AXI_ARADDR),
|
||||
.S_AXI_ARLEN( S_AXI_ARLEN),
|
||||
.S_AXI_ARSIZE( S_AXI_ARSIZE),
|
||||
.S_AXI_ARBURST(S_AXI_ARBURST),
|
||||
.S_AXI_ARLOCK( S_AXI_ARLOCK),
|
||||
.S_AXI_ARCACHE(S_AXI_ARCACHE),
|
||||
.S_AXI_ARPROT( S_AXI_ARPROT),
|
||||
.S_AXI_ARQOS( S_AXI_ARQOS),
|
||||
//
|
||||
.S_AXI_RVALID(S_AXI_RVALID),
|
||||
.S_AXI_RREADY(S_AXI_RREADY),
|
||||
.S_AXI_RID( S_AXI_RID),
|
||||
.S_AXI_RDATA( S_AXI_RDATA),
|
||||
.S_AXI_RLAST( S_AXI_RLAST),
|
||||
.S_AXI_RRESP( S_AXI_RRESP),
|
||||
//
|
||||
.o_wb_cyc( r_wb_cyc),
|
||||
.o_wb_stb( r_wb_stb),
|
||||
.o_wb_addr( r_wb_addr),
|
||||
.o_wb_sel( r_wb_sel),
|
||||
.i_wb_ack( r_wb_ack),
|
||||
.i_wb_stall(r_wb_stall),
|
||||
.i_wb_data( i_wb_data),
|
||||
.i_wb_err( r_wb_err)
|
||||
// }}}
|
||||
);
|
||||
// }}}
|
||||
end else begin : NO_READ_CHANNEL
|
||||
// {{{
|
||||
assign r_wb_cyc = 0;
|
||||
assign r_wb_stb = 0;
|
||||
assign r_wb_addr = 0;
|
||||
//
|
||||
assign S_AXI_ARREADY = 0;
|
||||
assign S_AXI_RVALID = 0;
|
||||
assign S_AXI_RID = 0;
|
||||
assign S_AXI_RDATA = 0;
|
||||
assign S_AXI_RLAST = 0;
|
||||
assign S_AXI_RRESP = 0;
|
||||
// }}}
|
||||
end endgenerate
|
||||
|
||||
generate if (OPT_READONLY)
|
||||
begin : ARB_RD
|
||||
// {{{
|
||||
assign o_wb_cyc = r_wb_cyc;
|
||||
assign o_wb_stb = r_wb_stb;
|
||||
assign o_wb_we = r_wb_we;
|
||||
assign o_wb_addr = r_wb_addr;
|
||||
assign o_wb_data = 0;
|
||||
assign o_wb_sel = r_wb_sel;
|
||||
assign r_wb_ack = i_wb_ack;
|
||||
assign r_wb_stall= i_wb_stall;
|
||||
assign r_wb_ack = i_wb_ack;
|
||||
assign r_wb_err = i_wb_err;
|
||||
// }}}
|
||||
end else if (OPT_WRITEONLY)
|
||||
begin : ARB_WR
|
||||
// {{{
|
||||
assign o_wb_cyc = w_wb_cyc;
|
||||
assign o_wb_stb = w_wb_stb;
|
||||
assign o_wb_we = w_wb_we;
|
||||
assign o_wb_addr = w_wb_addr;
|
||||
assign o_wb_data = w_wb_data;
|
||||
assign o_wb_sel = w_wb_sel;
|
||||
assign w_wb_ack = i_wb_ack;
|
||||
assign w_wb_stall= i_wb_stall;
|
||||
assign w_wb_ack = i_wb_ack;
|
||||
assign w_wb_err = i_wb_err;
|
||||
// }}}
|
||||
end else begin : ARB_WB
|
||||
// {{{
|
||||
wbarbiter #(.DW(DW), .AW(AW))
|
||||
readorwrite(S_AXI_ACLK, o_reset,
|
||||
r_wb_cyc, r_wb_stb, r_wb_we, r_wb_addr, w_wb_data, r_wb_sel,
|
||||
r_wb_ack, r_wb_stall, r_wb_err,
|
||||
w_wb_cyc, w_wb_stb, w_wb_we, w_wb_addr, w_wb_data, w_wb_sel,
|
||||
w_wb_ack, w_wb_stall, w_wb_err,
|
||||
o_wb_cyc, o_wb_stb, o_wb_we, o_wb_addr, o_wb_data, o_wb_sel,
|
||||
i_wb_ack, i_wb_stall, i_wb_err
|
||||
);
|
||||
// }}}
|
||||
end endgenerate
|
||||
|
||||
assign o_reset = (S_AXI_ARESETN == 1'b0);
|
||||
|
||||
`ifdef FORMAL
|
||||
`endif
|
||||
endmodule
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,303 +1,303 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Filename: ddr3_top_axi.v
|
||||
// Project: UberDDR3 - An Open Source DDR3 Controller
|
||||
//
|
||||
// Purpose: Top module which instantiates the ddr3_top and AXI to Wishbone bridge.
|
||||
// Use this as top module for instantiating UberDDR3 with AXI4 interface.
|
||||
//
|
||||
// Engineer: Angelo C. Jacobo
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2023-2024 Angelo Jacobo
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`default_nettype none
|
||||
`timescale 1ps / 1ps
|
||||
|
||||
module ddr3_top_axi #(
|
||||
parameter CONTROLLER_CLK_PERIOD = 12_000, //ps, clock period of the controller interface
|
||||
DDR3_CLK_PERIOD = 3_000, //ps, clock period of the DDR3 RAM device (must be 1/4 of the CONTROLLER_CLK_PERIOD)
|
||||
ROW_BITS = 14, //width of row address
|
||||
COL_BITS = 10, //width of column address
|
||||
BA_BITS = 3, //width of bank address
|
||||
BYTE_LANES = 2, //number of byte lanes of DDR3 RAM
|
||||
AXI_ID_WIDTH = 4, // The AXI id width used for R&W, an int between 1-16
|
||||
WB2_ADDR_BITS = 7, //width of 2nd wishbone address bus
|
||||
WB2_DATA_BITS = 32, //width of 2nd wishbone data bus
|
||||
/* verilator lint_off UNUSEDPARAM */
|
||||
parameter[0:0] MICRON_SIM = 0, //enable faster simulation for micron ddr3 model (shorten POWER_ON_RESET_HIGH and INITIAL_CKE_LOW)
|
||||
ODELAY_SUPPORTED = 0, //set to 1 when ODELAYE2 is supported
|
||||
SECOND_WISHBONE = 0, //set to 1 if 2nd wishbone for debugging is needed
|
||||
WB_ERROR = 0, // set to 1 to support Wishbone error (asserts at ECC double bit error)
|
||||
SKIP_INTERNAL_TEST = 0, // skip built-in self test (would require >2 seconds of internal test right after calibration)
|
||||
parameter[1:0] ECC_ENABLE = 0, // set to 1 or 2 to add ECC (1 = Side-band ECC per burst, 2 = Side-band ECC per 8 bursts , 3 = Inline ECC )
|
||||
parameter[1:0] DIC = 2'b00, //Output Driver Impedance Control (2'b00 = RZQ/6, 2'b01 = RZQ/7, RZQ = 240ohms) (only change when you know what you are doing)
|
||||
parameter[2:0] RTT_NOM = 3'b011, //RTT Nominal (3'b000 = disabled, 3'b001 = RZQ/4, 3'b010 = RZQ/2 , 3'b011 = RZQ/6, RZQ = 240ohms) (only change when you know what you are doing)
|
||||
parameter // The next parameters act more like a localparam (since user does not have to set this manually) but was added here to simplify port declaration
|
||||
DQ_BITS = 8, //device width (fixed to 8, if DDR3 is x16 then BYTE_LANES will be 2 while )
|
||||
serdes_ratio = 4, // this controller is fixed as a 4:1 memory controller (CONTROLLER_CLK_PERIOD/DDR3_CLK_PERIOD = 4)
|
||||
wb_addr_bits = ROW_BITS + COL_BITS + BA_BITS - $clog2(serdes_ratio*2),
|
||||
wb_data_bits = DQ_BITS*BYTE_LANES*serdes_ratio*2,
|
||||
wb_sel_bits = wb_data_bits / 8,
|
||||
wb2_sel_bits = WB2_DATA_BITS / 8,
|
||||
//4 is the width of a single ddr3 command {cs_n, ras_n, cas_n, we_n} plus 3 (ck_en, odt, reset_n) plus bank bits plus row bits
|
||||
cmd_len = 4 + 3 + BA_BITS + ROW_BITS,
|
||||
AXI_LSBS = $clog2(wb_data_bits)-3,
|
||||
AXI_ADDR_WIDTH = wb_addr_bits + AXI_LSBS,
|
||||
AXI_DATA_WIDTH = wb_data_bits
|
||||
)
|
||||
(
|
||||
input wire i_controller_clk, i_ddr3_clk, i_ref_clk, //i_controller_clk = CONTROLLER_CLK_PERIOD, i_ddr3_clk = DDR3_CLK_PERIOD, i_ref_clk = 200MHz
|
||||
input wire i_ddr3_clk_90, //required only when ODELAY_SUPPORTED is zero
|
||||
input wire i_rst_n,
|
||||
//
|
||||
// AXI Interface
|
||||
// AXI write address channel signals
|
||||
input wire s_axi_awvalid,
|
||||
output wire s_axi_awready,
|
||||
input wire [AXI_ID_WIDTH-1:0] s_axi_awid,
|
||||
input wire [AXI_ADDR_WIDTH-1:0] s_axi_awaddr,
|
||||
input wire [7:0] s_axi_awlen,
|
||||
input wire [2:0] s_axi_awsize,
|
||||
input wire [1:0] s_axi_awburst,
|
||||
input wire [0:0] s_axi_awlock,
|
||||
input wire [3:0] s_axi_awcache,
|
||||
input wire [2:0] s_axi_awprot,
|
||||
input wire [3:0] s_axi_awqos,
|
||||
// AXI write data channel signals
|
||||
input wire s_axi_wvalid,
|
||||
output wire s_axi_wready,
|
||||
input wire [AXI_DATA_WIDTH-1:0] s_axi_wdata,
|
||||
input wire [AXI_DATA_WIDTH/8-1:0] s_axi_wstrb,
|
||||
input wire s_axi_wlast,
|
||||
// AXI write response channel signals
|
||||
output wire s_axi_bvalid,
|
||||
input wire s_axi_bready,
|
||||
output wire [AXI_ID_WIDTH-1:0] s_axi_bid,
|
||||
output wire [1:0] s_axi_bresp,
|
||||
// AXI read address channel signals
|
||||
input wire s_axi_arvalid,
|
||||
output wire s_axi_arready,
|
||||
input wire [AXI_ID_WIDTH-1:0] s_axi_arid,
|
||||
input wire [AXI_ADDR_WIDTH-1:0] s_axi_araddr,
|
||||
input wire [7:0] s_axi_arlen,
|
||||
input wire [2:0] s_axi_arsize,
|
||||
input wire [1:0] s_axi_arburst,
|
||||
input wire [0:0] s_axi_arlock,
|
||||
input wire [3:0] s_axi_arcache,
|
||||
input wire [2:0] s_axi_arprot,
|
||||
input wire [3:0] s_axi_arqos,
|
||||
// AXI read data channel signals
|
||||
output wire s_axi_rvalid, // rd rslt valid
|
||||
input wire s_axi_rready, // rd rslt ready
|
||||
output wire [AXI_ID_WIDTH-1:0] s_axi_rid, // response id
|
||||
output wire [AXI_DATA_WIDTH-1:0] s_axi_rdata,// read data
|
||||
output wire s_axi_rlast, // read last
|
||||
output wire [1:0] s_axi_rresp, // read response
|
||||
//
|
||||
// DDR3 I/O Interface
|
||||
output wire o_ddr3_clk_p, o_ddr3_clk_n,
|
||||
output wire o_ddr3_reset_n,
|
||||
output wire o_ddr3_cke,
|
||||
output wire o_ddr3_cs_n,
|
||||
output wire o_ddr3_ras_n,
|
||||
output wire o_ddr3_cas_n,
|
||||
output wire o_ddr3_we_n,
|
||||
output wire[ROW_BITS-1:0] o_ddr3_addr,
|
||||
output wire[BA_BITS-1:0] o_ddr3_ba_addr,
|
||||
inout wire[(DQ_BITS*BYTE_LANES)-1:0] io_ddr3_dq,
|
||||
inout wire[BYTE_LANES-1:0] io_ddr3_dqs, io_ddr3_dqs_n,
|
||||
output wire[BYTE_LANES-1:0] o_ddr3_dm,
|
||||
output wire o_ddr3_odt,
|
||||
//
|
||||
// Done Calibration pin
|
||||
output wire o_calib_complete,
|
||||
//
|
||||
// Debug outputs
|
||||
output wire[31:0] o_debug1
|
||||
// output wire[31:0] o_debug2,
|
||||
// output wire[31:0] o_debug3,
|
||||
// output wire[(DQ_BITS*BYTE_LANES)/8-1:0] o_ddr3_debug_read_dqs_p,
|
||||
// output wire[(DQ_BITS*BYTE_LANES)/8-1:0] o_ddr3_debug_read_dqs_n
|
||||
);
|
||||
|
||||
wire wb_cyc;
|
||||
wire wb_stb;
|
||||
wire wb_we;
|
||||
wire[wb_addr_bits-1:0] wb_addr;
|
||||
wire[wb_data_bits-1:0] o_wb_data;
|
||||
wire[wb_sel_bits-1:0] wb_sel;
|
||||
wire wb_stall;
|
||||
wire wb_ack;
|
||||
wire[wb_data_bits-1:0] i_wb_data;
|
||||
|
||||
// DDR3 Controller
|
||||
ddr3_top #(
|
||||
.CONTROLLER_CLK_PERIOD(CONTROLLER_CLK_PERIOD), //ps, clock period of the controller interface
|
||||
.DDR3_CLK_PERIOD(DDR3_CLK_PERIOD), //ps, clock period of the DDR3 RAM device (must be 1/4 of the CONTROLLER_CLK_PERIOD)
|
||||
.ROW_BITS(ROW_BITS), //width of row address
|
||||
.COL_BITS(COL_BITS), //width of column address
|
||||
.BA_BITS(BA_BITS), //width of bank address
|
||||
.BYTE_LANES(BYTE_LANES), //number of byte lanes of DDR3 RAM
|
||||
.AUX_WIDTH(AXI_ID_WIDTH), //width of aux line (must be >= 4)
|
||||
.MICRON_SIM(MICRON_SIM), //enable faster simulation for micron ddr3 model (shorten POWER_ON_RESET_HIGH and INITIAL_CKE_LOW)
|
||||
.ODELAY_SUPPORTED(ODELAY_SUPPORTED), //set to 1 if ODELAYE2 is supported
|
||||
.SECOND_WISHBONE(SECOND_WISHBONE), //set to 1 if 2nd wishbone for debugging is needed
|
||||
.WB2_ADDR_BITS(WB2_ADDR_BITS), //width of 2nd wishbone address bus
|
||||
.WB2_DATA_BITS(WB2_DATA_BITS), //width of 2nd wishbone data bus
|
||||
.WB_ERROR(WB_ERROR), // set to 1 to support Wishbone error (asserts at ECC double bit error)
|
||||
.SKIP_INTERNAL_TEST(SKIP_INTERNAL_TEST), // skip built-in self test (would require >2 seconds of internal test right after calibration)
|
||||
.ECC_ENABLE(ECC_ENABLE), // set to 1 or 2 to add ECC (1 = Side-band ECC per burst, 2 = Side-band ECC per 8 bursts , 3 = Inline ECC )
|
||||
.DIC(DIC), // Output Driver Impedance Control (2'b00 = RZQ/6, 2'b01 = RZQ/7, RZQ = 240ohms) (only change when you know what you are doing)
|
||||
.RTT_NOM(RTT_NOM) //RTT Nominal (3'b000 = disabled, 3'b001 = RZQ/4, 3'b010 = RZQ/2 , 3'b011 = RZQ/6, RZQ = 240ohms) (only change when you know what you are doing)
|
||||
) ddr3_top_inst
|
||||
(
|
||||
//clock and reset
|
||||
.i_controller_clk(i_controller_clk),
|
||||
.i_ddr3_clk(i_ddr3_clk), //i_controller_clk has period of CONTROLLER_CLK_PERIOD, i_ddr3_clk has period of DDR3_CLK_PERIOD
|
||||
.i_ref_clk(i_ref_clk), // usually set to 200 MHz
|
||||
.i_ddr3_clk_90(i_ddr3_clk_90), //90 degree phase shifted version i_ddr3_clk (required only when ODELAY_SUPPORTED is zero)
|
||||
.i_rst_n(i_rst_n),
|
||||
//
|
||||
// Wishbone inputs
|
||||
.i_wb_cyc(wb_cyc), //bus cycle active (1 = normal operation, 0 = all ongoing transaction are to be cancelled)
|
||||
.i_wb_stb(wb_stb), //request a transfer
|
||||
.i_wb_we(wb_we), //write-enable (1 = write, 0 = read)
|
||||
.i_wb_addr(wb_addr), //burst-addressable {row,bank,col}
|
||||
.i_wb_data(o_wb_data), //write data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
.i_wb_sel(wb_sel), //byte strobe for write (1 = write the byte)
|
||||
.i_aux(0), //for AXI-interface compatibility (given upon strobe)
|
||||
// Wishbone outputs
|
||||
.o_wb_stall(wb_stall), //1 = busy, cannot accept requests
|
||||
.o_wb_ack(wb_ack), //1 = read/write request has completed
|
||||
.o_wb_data(i_wb_data), //read data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
.o_aux(),
|
||||
//
|
||||
// Wishbone 2 (PHY) inputs (WISHBONE 2 UNCONNECTED IN AXI MODE)
|
||||
.i_wb2_cyc(0), //bus cycle active (1 = normal operation, 0 = all ongoing transaction are to be cancelled)
|
||||
.i_wb2_stb(0), //request a transfer
|
||||
.i_wb2_we(0), //write-enable (1 = write, 0 = read)
|
||||
.i_wb2_addr(0), //burst-addressable {row,bank,col}
|
||||
.i_wb2_data(0), //write data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
.i_wb2_sel(0), //byte strobe for write (1 = write the byte)
|
||||
// Wishbone 2 (Controller) outputs
|
||||
.o_wb2_stall(), //1 = busy, cannot accept requests
|
||||
.o_wb2_ack(), //1 = read/write request has completed
|
||||
.o_wb2_data(), //read data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
//
|
||||
// DDR3 I/O Interface
|
||||
.o_ddr3_clk_p(o_ddr3_clk_p),
|
||||
.o_ddr3_clk_n(o_ddr3_clk_n),
|
||||
.o_ddr3_reset_n(o_ddr3_reset_n),
|
||||
.o_ddr3_cke(o_ddr3_cke),
|
||||
.o_ddr3_cs_n(o_ddr3_cs_n), // width = number of DDR3 ranks
|
||||
.o_ddr3_ras_n(o_ddr3_ras_n),
|
||||
.o_ddr3_cas_n(o_ddr3_cas_n),
|
||||
.o_ddr3_we_n(o_ddr3_we_n),
|
||||
.o_ddr3_addr(o_ddr3_addr), // width = ROW_BITS
|
||||
.o_ddr3_ba_addr(o_ddr3_ba_addr), // width = BA_BITS
|
||||
.io_ddr3_dq(io_ddr3_dq), // width = BYTE_LANES*8
|
||||
.io_ddr3_dqs(io_ddr3_dqs), // width = BYTE_LANES
|
||||
.io_ddr3_dqs_n(io_ddr3_dqs_n), // width = BYTE_LANES
|
||||
.o_ddr3_dm(o_ddr3_dm), // width = BYTE_LANES
|
||||
.o_ddr3_odt(o_ddr3_odt),
|
||||
//
|
||||
// Done Calibration pin
|
||||
.o_calib_complete(o_calib_complete),
|
||||
//
|
||||
// Debug outputs
|
||||
.o_debug1(o_debug1)
|
||||
// .o_debug2(o_debug2),
|
||||
// .o_debug3(o_debug3),
|
||||
// .o_ddr3_debug_read_dqs_p(o_ddr3_debug_read_dqs_p),
|
||||
// .o_ddr3_debug_read_dqs_n(o_ddr3_debug_read_dqs_n)
|
||||
////////////////////////////////////
|
||||
);
|
||||
|
||||
axim2wbsp #(
|
||||
.C_AXI_ID_WIDTH(AXI_ID_WIDTH), // The AXI id width used for R&W, an int between 1-16
|
||||
.C_AXI_DATA_WIDTH(AXI_DATA_WIDTH),// Width of the AXI R&W data
|
||||
.C_AXI_ADDR_WIDTH(AXI_ADDR_WIDTH), // AXI Address width
|
||||
.LGFIFO(5),
|
||||
.OPT_SWAP_ENDIANNESS(0),
|
||||
.OPT_READONLY(0),
|
||||
.OPT_WRITEONLY(0)
|
||||
) axim2wbsp_inst (
|
||||
.S_AXI_ACLK(i_controller_clk), // System clock
|
||||
.S_AXI_ARESETN(i_rst_n),
|
||||
// AXI write address channel signals
|
||||
.S_AXI_AWVALID(s_axi_awvalid),
|
||||
.S_AXI_AWREADY(s_axi_awready),
|
||||
.S_AXI_AWID(s_axi_awid),
|
||||
.S_AXI_AWADDR(s_axi_awaddr),
|
||||
.S_AXI_AWLEN(s_axi_awlen),
|
||||
.S_AXI_AWSIZE(s_axi_awsize),
|
||||
.S_AXI_AWBURST(s_axi_awburst),
|
||||
.S_AXI_AWLOCK(s_axi_awlock),
|
||||
.S_AXI_AWCACHE(s_axi_awcache),
|
||||
.S_AXI_AWPROT(s_axi_awprot),
|
||||
.S_AXI_AWQOS(s_axi_awqos),
|
||||
// AXI write data channel signals
|
||||
.S_AXI_WVALID(s_axi_wvalid),
|
||||
.S_AXI_WREADY(s_axi_wready),
|
||||
.S_AXI_WDATA(s_axi_wdata),
|
||||
.S_AXI_WSTRB(s_axi_wstrb),
|
||||
.S_AXI_WLAST(s_axi_wlast),
|
||||
// AXI write response channel signals
|
||||
.S_AXI_BVALID(s_axi_bvalid),
|
||||
.S_AXI_BREADY(s_axi_bready),
|
||||
.S_AXI_BID(s_axi_bid),
|
||||
.S_AXI_BRESP(s_axi_bresp),
|
||||
// AXI read address channel signals
|
||||
.S_AXI_ARVALID(s_axi_arvalid),
|
||||
.S_AXI_ARREADY(s_axi_arready),
|
||||
.S_AXI_ARID(s_axi_arid),
|
||||
.S_AXI_ARADDR(s_axi_araddr),
|
||||
.S_AXI_ARLEN(s_axi_arlen),
|
||||
.S_AXI_ARSIZE(s_axi_arsize),
|
||||
.S_AXI_ARBURST(s_axi_arburst),
|
||||
.S_AXI_ARLOCK(s_axi_arlock),
|
||||
.S_AXI_ARCACHE(s_axi_arcache),
|
||||
.S_AXI_ARPROT(s_axi_arprot),
|
||||
.S_AXI_ARQOS(s_axi_arqos),
|
||||
// AXI read data channel signals
|
||||
.S_AXI_RVALID(s_axi_rvalid), // Rd rslt valid
|
||||
.S_AXI_RREADY(s_axi_rready), // Rd rslt ready
|
||||
.S_AXI_RID(s_axi_rid), // Response ID
|
||||
.S_AXI_RDATA(s_axi_rdata),// Read data
|
||||
.S_AXI_RLAST(s_axi_rlast), // Read last
|
||||
.S_AXI_RRESP(s_axi_rresp), // Read response
|
||||
// We'll share the clock and the reset
|
||||
.o_reset(),
|
||||
.o_wb_cyc(wb_cyc),
|
||||
.o_wb_stb(wb_stb),
|
||||
.o_wb_we(wb_we),
|
||||
.o_wb_addr(wb_addr),
|
||||
.o_wb_data(o_wb_data),
|
||||
.o_wb_sel(wb_sel),
|
||||
.i_wb_stall(wb_stall),
|
||||
.i_wb_ack(wb_ack),
|
||||
.i_wb_data(i_wb_data),
|
||||
.i_wb_err(0)
|
||||
);
|
||||
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Filename: ddr3_top_axi.v
|
||||
// Project: UberDDR3 - An Open Source DDR3 Controller
|
||||
//
|
||||
// Purpose: Top module which instantiates the ddr3_top and AXI to Wishbone bridge.
|
||||
// Use this as top module for instantiating UberDDR3 with AXI4 interface.
|
||||
//
|
||||
// Engineer: Angelo C. Jacobo
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2023-2024 Angelo Jacobo
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`default_nettype none
|
||||
`timescale 1ps / 1ps
|
||||
|
||||
module ddr3_top_axi #(
|
||||
parameter CONTROLLER_CLK_PERIOD = 12_000, //ps, clock period of the controller interface
|
||||
DDR3_CLK_PERIOD = 3_000, //ps, clock period of the DDR3 RAM device (must be 1/4 of the CONTROLLER_CLK_PERIOD)
|
||||
ROW_BITS = 14, //width of row address
|
||||
COL_BITS = 10, //width of column address
|
||||
BA_BITS = 3, //width of bank address
|
||||
BYTE_LANES = 2, //number of byte lanes of DDR3 RAM
|
||||
AXI_ID_WIDTH = 4, // The AXI id width used for R&W, an int between 1-16
|
||||
WB2_ADDR_BITS = 7, //width of 2nd wishbone address bus
|
||||
WB2_DATA_BITS = 32, //width of 2nd wishbone data bus
|
||||
/* verilator lint_off UNUSEDPARAM */
|
||||
parameter[0:0] MICRON_SIM = 0, //enable faster simulation for micron ddr3 model (shorten POWER_ON_RESET_HIGH and INITIAL_CKE_LOW)
|
||||
ODELAY_SUPPORTED = 0, //set to 1 when ODELAYE2 is supported
|
||||
SECOND_WISHBONE = 0, //set to 1 if 2nd wishbone for debugging is needed
|
||||
WB_ERROR = 0, // set to 1 to support Wishbone error (asserts at ECC double bit error)
|
||||
SKIP_INTERNAL_TEST = 0, // skip built-in self test (would require >2 seconds of internal test right after calibration)
|
||||
parameter[1:0] ECC_ENABLE = 0, // set to 1 or 2 to add ECC (1 = Side-band ECC per burst, 2 = Side-band ECC per 8 bursts , 3 = Inline ECC )
|
||||
parameter[1:0] DIC = 2'b00, //Output Driver Impedance Control (2'b00 = RZQ/6, 2'b01 = RZQ/7, RZQ = 240ohms) (only change when you know what you are doing)
|
||||
parameter[2:0] RTT_NOM = 3'b011, //RTT Nominal (3'b000 = disabled, 3'b001 = RZQ/4, 3'b010 = RZQ/2 , 3'b011 = RZQ/6, RZQ = 240ohms) (only change when you know what you are doing)
|
||||
parameter // The next parameters act more like a localparam (since user does not have to set this manually) but was added here to simplify port declaration
|
||||
DQ_BITS = 8, //device width (fixed to 8, if DDR3 is x16 then BYTE_LANES will be 2 while )
|
||||
serdes_ratio = 4, // this controller is fixed as a 4:1 memory controller (CONTROLLER_CLK_PERIOD/DDR3_CLK_PERIOD = 4)
|
||||
wb_addr_bits = ROW_BITS + COL_BITS + BA_BITS - $clog2(serdes_ratio*2),
|
||||
wb_data_bits = DQ_BITS*BYTE_LANES*serdes_ratio*2,
|
||||
wb_sel_bits = wb_data_bits / 8,
|
||||
wb2_sel_bits = WB2_DATA_BITS / 8,
|
||||
//4 is the width of a single ddr3 command {cs_n, ras_n, cas_n, we_n} plus 3 (ck_en, odt, reset_n) plus bank bits plus row bits
|
||||
cmd_len = 4 + 3 + BA_BITS + ROW_BITS,
|
||||
AXI_LSBS = $clog2(wb_data_bits)-3,
|
||||
AXI_ADDR_WIDTH = wb_addr_bits + AXI_LSBS,
|
||||
AXI_DATA_WIDTH = wb_data_bits
|
||||
)
|
||||
(
|
||||
input wire i_controller_clk, i_ddr3_clk, i_ref_clk, //i_controller_clk = CONTROLLER_CLK_PERIOD, i_ddr3_clk = DDR3_CLK_PERIOD, i_ref_clk = 200MHz
|
||||
input wire i_ddr3_clk_90, //required only when ODELAY_SUPPORTED is zero
|
||||
input wire i_rst_n,
|
||||
//
|
||||
// AXI Interface
|
||||
// AXI write address channel signals
|
||||
input wire s_axi_awvalid,
|
||||
output wire s_axi_awready,
|
||||
input wire [AXI_ID_WIDTH-1:0] s_axi_awid,
|
||||
input wire [AXI_ADDR_WIDTH-1:0] s_axi_awaddr,
|
||||
input wire [7:0] s_axi_awlen,
|
||||
input wire [2:0] s_axi_awsize,
|
||||
input wire [1:0] s_axi_awburst,
|
||||
input wire [0:0] s_axi_awlock,
|
||||
input wire [3:0] s_axi_awcache,
|
||||
input wire [2:0] s_axi_awprot,
|
||||
input wire [3:0] s_axi_awqos,
|
||||
// AXI write data channel signals
|
||||
input wire s_axi_wvalid,
|
||||
output wire s_axi_wready,
|
||||
input wire [AXI_DATA_WIDTH-1:0] s_axi_wdata,
|
||||
input wire [AXI_DATA_WIDTH/8-1:0] s_axi_wstrb,
|
||||
input wire s_axi_wlast,
|
||||
// AXI write response channel signals
|
||||
output wire s_axi_bvalid,
|
||||
input wire s_axi_bready,
|
||||
output wire [AXI_ID_WIDTH-1:0] s_axi_bid,
|
||||
output wire [1:0] s_axi_bresp,
|
||||
// AXI read address channel signals
|
||||
input wire s_axi_arvalid,
|
||||
output wire s_axi_arready,
|
||||
input wire [AXI_ID_WIDTH-1:0] s_axi_arid,
|
||||
input wire [AXI_ADDR_WIDTH-1:0] s_axi_araddr,
|
||||
input wire [7:0] s_axi_arlen,
|
||||
input wire [2:0] s_axi_arsize,
|
||||
input wire [1:0] s_axi_arburst,
|
||||
input wire [0:0] s_axi_arlock,
|
||||
input wire [3:0] s_axi_arcache,
|
||||
input wire [2:0] s_axi_arprot,
|
||||
input wire [3:0] s_axi_arqos,
|
||||
// AXI read data channel signals
|
||||
output wire s_axi_rvalid, // rd rslt valid
|
||||
input wire s_axi_rready, // rd rslt ready
|
||||
output wire [AXI_ID_WIDTH-1:0] s_axi_rid, // response id
|
||||
output wire [AXI_DATA_WIDTH-1:0] s_axi_rdata,// read data
|
||||
output wire s_axi_rlast, // read last
|
||||
output wire [1:0] s_axi_rresp, // read response
|
||||
//
|
||||
// DDR3 I/O Interface
|
||||
output wire o_ddr3_clk_p, o_ddr3_clk_n,
|
||||
output wire o_ddr3_reset_n,
|
||||
output wire o_ddr3_cke,
|
||||
output wire o_ddr3_cs_n,
|
||||
output wire o_ddr3_ras_n,
|
||||
output wire o_ddr3_cas_n,
|
||||
output wire o_ddr3_we_n,
|
||||
output wire[ROW_BITS-1:0] o_ddr3_addr,
|
||||
output wire[BA_BITS-1:0] o_ddr3_ba_addr,
|
||||
inout wire[(DQ_BITS*BYTE_LANES)-1:0] io_ddr3_dq,
|
||||
inout wire[BYTE_LANES-1:0] io_ddr3_dqs, io_ddr3_dqs_n,
|
||||
output wire[BYTE_LANES-1:0] o_ddr3_dm,
|
||||
output wire o_ddr3_odt,
|
||||
//
|
||||
// Done Calibration pin
|
||||
output wire o_calib_complete,
|
||||
//
|
||||
// Debug outputs
|
||||
output wire[31:0] o_debug1
|
||||
// output wire[31:0] o_debug2,
|
||||
// output wire[31:0] o_debug3,
|
||||
// output wire[(DQ_BITS*BYTE_LANES)/8-1:0] o_ddr3_debug_read_dqs_p,
|
||||
// output wire[(DQ_BITS*BYTE_LANES)/8-1:0] o_ddr3_debug_read_dqs_n
|
||||
);
|
||||
|
||||
wire wb_cyc;
|
||||
wire wb_stb;
|
||||
wire wb_we;
|
||||
wire[wb_addr_bits-1:0] wb_addr;
|
||||
wire[wb_data_bits-1:0] o_wb_data;
|
||||
wire[wb_sel_bits-1:0] wb_sel;
|
||||
wire wb_stall;
|
||||
wire wb_ack;
|
||||
wire[wb_data_bits-1:0] i_wb_data;
|
||||
|
||||
// DDR3 Controller
|
||||
ddr3_top #(
|
||||
.CONTROLLER_CLK_PERIOD(CONTROLLER_CLK_PERIOD), //ps, clock period of the controller interface
|
||||
.DDR3_CLK_PERIOD(DDR3_CLK_PERIOD), //ps, clock period of the DDR3 RAM device (must be 1/4 of the CONTROLLER_CLK_PERIOD)
|
||||
.ROW_BITS(ROW_BITS), //width of row address
|
||||
.COL_BITS(COL_BITS), //width of column address
|
||||
.BA_BITS(BA_BITS), //width of bank address
|
||||
.BYTE_LANES(BYTE_LANES), //number of byte lanes of DDR3 RAM
|
||||
.AUX_WIDTH(AXI_ID_WIDTH), //width of aux line (must be >= 4)
|
||||
.MICRON_SIM(MICRON_SIM), //enable faster simulation for micron ddr3 model (shorten POWER_ON_RESET_HIGH and INITIAL_CKE_LOW)
|
||||
.ODELAY_SUPPORTED(ODELAY_SUPPORTED), //set to 1 if ODELAYE2 is supported
|
||||
.SECOND_WISHBONE(SECOND_WISHBONE), //set to 1 if 2nd wishbone for debugging is needed
|
||||
.WB2_ADDR_BITS(WB2_ADDR_BITS), //width of 2nd wishbone address bus
|
||||
.WB2_DATA_BITS(WB2_DATA_BITS), //width of 2nd wishbone data bus
|
||||
.WB_ERROR(WB_ERROR), // set to 1 to support Wishbone error (asserts at ECC double bit error)
|
||||
.SKIP_INTERNAL_TEST(SKIP_INTERNAL_TEST), // skip built-in self test (would require >2 seconds of internal test right after calibration)
|
||||
.ECC_ENABLE(ECC_ENABLE), // set to 1 or 2 to add ECC (1 = Side-band ECC per burst, 2 = Side-band ECC per 8 bursts , 3 = Inline ECC )
|
||||
.DIC(DIC), // Output Driver Impedance Control (2'b00 = RZQ/6, 2'b01 = RZQ/7, RZQ = 240ohms) (only change when you know what you are doing)
|
||||
.RTT_NOM(RTT_NOM) //RTT Nominal (3'b000 = disabled, 3'b001 = RZQ/4, 3'b010 = RZQ/2 , 3'b011 = RZQ/6, RZQ = 240ohms) (only change when you know what you are doing)
|
||||
) ddr3_top_inst
|
||||
(
|
||||
//clock and reset
|
||||
.i_controller_clk(i_controller_clk),
|
||||
.i_ddr3_clk(i_ddr3_clk), //i_controller_clk has period of CONTROLLER_CLK_PERIOD, i_ddr3_clk has period of DDR3_CLK_PERIOD
|
||||
.i_ref_clk(i_ref_clk), // usually set to 200 MHz
|
||||
.i_ddr3_clk_90(i_ddr3_clk_90), //90 degree phase shifted version i_ddr3_clk (required only when ODELAY_SUPPORTED is zero)
|
||||
.i_rst_n(i_rst_n),
|
||||
//
|
||||
// Wishbone inputs
|
||||
.i_wb_cyc(wb_cyc), //bus cycle active (1 = normal operation, 0 = all ongoing transaction are to be cancelled)
|
||||
.i_wb_stb(wb_stb), //request a transfer
|
||||
.i_wb_we(wb_we), //write-enable (1 = write, 0 = read)
|
||||
.i_wb_addr(wb_addr), //burst-addressable {row,bank,col}
|
||||
.i_wb_data(o_wb_data), //write data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
.i_wb_sel(wb_sel), //byte strobe for write (1 = write the byte)
|
||||
.i_aux(0), //for AXI-interface compatibility (given upon strobe)
|
||||
// Wishbone outputs
|
||||
.o_wb_stall(wb_stall), //1 = busy, cannot accept requests
|
||||
.o_wb_ack(wb_ack), //1 = read/write request has completed
|
||||
.o_wb_data(i_wb_data), //read data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
.o_aux(),
|
||||
//
|
||||
// Wishbone 2 (PHY) inputs (WISHBONE 2 UNCONNECTED IN AXI MODE)
|
||||
.i_wb2_cyc(0), //bus cycle active (1 = normal operation, 0 = all ongoing transaction are to be cancelled)
|
||||
.i_wb2_stb(0), //request a transfer
|
||||
.i_wb2_we(0), //write-enable (1 = write, 0 = read)
|
||||
.i_wb2_addr(0), //burst-addressable {row,bank,col}
|
||||
.i_wb2_data(0), //write data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
.i_wb2_sel(0), //byte strobe for write (1 = write the byte)
|
||||
// Wishbone 2 (Controller) outputs
|
||||
.o_wb2_stall(), //1 = busy, cannot accept requests
|
||||
.o_wb2_ack(), //1 = read/write request has completed
|
||||
.o_wb2_data(), //read data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
//
|
||||
// DDR3 I/O Interface
|
||||
.o_ddr3_clk_p(o_ddr3_clk_p),
|
||||
.o_ddr3_clk_n(o_ddr3_clk_n),
|
||||
.o_ddr3_reset_n(o_ddr3_reset_n),
|
||||
.o_ddr3_cke(o_ddr3_cke),
|
||||
.o_ddr3_cs_n(o_ddr3_cs_n), // width = number of DDR3 ranks
|
||||
.o_ddr3_ras_n(o_ddr3_ras_n),
|
||||
.o_ddr3_cas_n(o_ddr3_cas_n),
|
||||
.o_ddr3_we_n(o_ddr3_we_n),
|
||||
.o_ddr3_addr(o_ddr3_addr), // width = ROW_BITS
|
||||
.o_ddr3_ba_addr(o_ddr3_ba_addr), // width = BA_BITS
|
||||
.io_ddr3_dq(io_ddr3_dq), // width = BYTE_LANES*8
|
||||
.io_ddr3_dqs(io_ddr3_dqs), // width = BYTE_LANES
|
||||
.io_ddr3_dqs_n(io_ddr3_dqs_n), // width = BYTE_LANES
|
||||
.o_ddr3_dm(o_ddr3_dm), // width = BYTE_LANES
|
||||
.o_ddr3_odt(o_ddr3_odt),
|
||||
//
|
||||
// Done Calibration pin
|
||||
.o_calib_complete(o_calib_complete),
|
||||
//
|
||||
// Debug outputs
|
||||
.o_debug1(o_debug1)
|
||||
// .o_debug2(o_debug2),
|
||||
// .o_debug3(o_debug3),
|
||||
// .o_ddr3_debug_read_dqs_p(o_ddr3_debug_read_dqs_p),
|
||||
// .o_ddr3_debug_read_dqs_n(o_ddr3_debug_read_dqs_n)
|
||||
////////////////////////////////////
|
||||
);
|
||||
|
||||
axim2wbsp #(
|
||||
.C_AXI_ID_WIDTH(AXI_ID_WIDTH), // The AXI id width used for R&W, an int between 1-16
|
||||
.C_AXI_DATA_WIDTH(AXI_DATA_WIDTH),// Width of the AXI R&W data
|
||||
.C_AXI_ADDR_WIDTH(AXI_ADDR_WIDTH), // AXI Address width
|
||||
.LGFIFO(5),
|
||||
.OPT_SWAP_ENDIANNESS(0),
|
||||
.OPT_READONLY(0),
|
||||
.OPT_WRITEONLY(0)
|
||||
) axim2wbsp_inst (
|
||||
.S_AXI_ACLK(i_controller_clk), // System clock
|
||||
.S_AXI_ARESETN(i_rst_n),
|
||||
// AXI write address channel signals
|
||||
.S_AXI_AWVALID(s_axi_awvalid),
|
||||
.S_AXI_AWREADY(s_axi_awready),
|
||||
.S_AXI_AWID(s_axi_awid),
|
||||
.S_AXI_AWADDR(s_axi_awaddr),
|
||||
.S_AXI_AWLEN(s_axi_awlen),
|
||||
.S_AXI_AWSIZE(s_axi_awsize),
|
||||
.S_AXI_AWBURST(s_axi_awburst),
|
||||
.S_AXI_AWLOCK(s_axi_awlock),
|
||||
.S_AXI_AWCACHE(s_axi_awcache),
|
||||
.S_AXI_AWPROT(s_axi_awprot),
|
||||
.S_AXI_AWQOS(s_axi_awqos),
|
||||
// AXI write data channel signals
|
||||
.S_AXI_WVALID(s_axi_wvalid),
|
||||
.S_AXI_WREADY(s_axi_wready),
|
||||
.S_AXI_WDATA(s_axi_wdata),
|
||||
.S_AXI_WSTRB(s_axi_wstrb),
|
||||
.S_AXI_WLAST(s_axi_wlast),
|
||||
// AXI write response channel signals
|
||||
.S_AXI_BVALID(s_axi_bvalid),
|
||||
.S_AXI_BREADY(s_axi_bready),
|
||||
.S_AXI_BID(s_axi_bid),
|
||||
.S_AXI_BRESP(s_axi_bresp),
|
||||
// AXI read address channel signals
|
||||
.S_AXI_ARVALID(s_axi_arvalid),
|
||||
.S_AXI_ARREADY(s_axi_arready),
|
||||
.S_AXI_ARID(s_axi_arid),
|
||||
.S_AXI_ARADDR(s_axi_araddr),
|
||||
.S_AXI_ARLEN(s_axi_arlen),
|
||||
.S_AXI_ARSIZE(s_axi_arsize),
|
||||
.S_AXI_ARBURST(s_axi_arburst),
|
||||
.S_AXI_ARLOCK(s_axi_arlock),
|
||||
.S_AXI_ARCACHE(s_axi_arcache),
|
||||
.S_AXI_ARPROT(s_axi_arprot),
|
||||
.S_AXI_ARQOS(s_axi_arqos),
|
||||
// AXI read data channel signals
|
||||
.S_AXI_RVALID(s_axi_rvalid), // Rd rslt valid
|
||||
.S_AXI_RREADY(s_axi_rready), // Rd rslt ready
|
||||
.S_AXI_RID(s_axi_rid), // Response ID
|
||||
.S_AXI_RDATA(s_axi_rdata),// Read data
|
||||
.S_AXI_RLAST(s_axi_rlast), // Read last
|
||||
.S_AXI_RRESP(s_axi_rresp), // Read response
|
||||
// We'll share the clock and the reset
|
||||
.o_reset(),
|
||||
.o_wb_cyc(wb_cyc),
|
||||
.o_wb_stb(wb_stb),
|
||||
.o_wb_we(wb_we),
|
||||
.o_wb_addr(wb_addr),
|
||||
.o_wb_data(o_wb_data),
|
||||
.o_wb_sel(wb_sel),
|
||||
.i_wb_stall(wb_stall),
|
||||
.i_wb_ack(wb_ack),
|
||||
.i_wb_data(i_wb_data),
|
||||
.i_wb_err(0)
|
||||
);
|
||||
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
|
|||
964
rtl/axi/sfifo.v
964
rtl/axi/sfifo.v
|
|
@ -1,482 +1,482 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Filename: sfifo.v
|
||||
// {{{
|
||||
// Project: WB2AXIPSP: bus bridges and other odds and ends
|
||||
//
|
||||
// Purpose: A synchronous data FIFO.
|
||||
//
|
||||
// Creator: Dan Gisselquist, Ph.D.
|
||||
// Gisselquist Technology, LLC
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Written and distributed by Gisselquist Technology, LLC
|
||||
// }}}
|
||||
// This design is hereby granted to the public domain.
|
||||
// {{{
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
`default_nettype none
|
||||
// }}}
|
||||
module sfifo #(
|
||||
// {{{
|
||||
parameter BW=8, // Byte/data width
|
||||
parameter LGFLEN=4,
|
||||
parameter [0:0] OPT_ASYNC_READ = 1'b1,
|
||||
parameter [0:0] OPT_WRITE_ON_FULL = 1'b0,
|
||||
parameter [0:0] OPT_READ_ON_EMPTY = 1'b0
|
||||
// }}}
|
||||
) (
|
||||
// {{{
|
||||
input wire i_clk,
|
||||
input wire i_reset,
|
||||
//
|
||||
// Write interface
|
||||
input wire i_wr,
|
||||
input wire [(BW-1):0] i_data,
|
||||
output wire o_full,
|
||||
output reg [LGFLEN:0] o_fill,
|
||||
//
|
||||
// Read interface
|
||||
input wire i_rd,
|
||||
output reg [(BW-1):0] o_data,
|
||||
output wire o_empty // True if FIFO is empty
|
||||
`ifdef FORMAL
|
||||
`ifdef F_PEEK
|
||||
, output wire [LGFLEN:0] f_first_addr,
|
||||
output wire [LGFLEN:0] f_second_addr,
|
||||
output reg [BW-1:0] f_first_data, f_second_data,
|
||||
|
||||
output reg f_first_in_fifo,
|
||||
f_second_in_fifo,
|
||||
output reg [LGFLEN:0] f_distance_to_first,
|
||||
f_distance_to_second
|
||||
`endif
|
||||
`endif
|
||||
// }}}
|
||||
);
|
||||
|
||||
// Register/net declarations
|
||||
// {{{
|
||||
localparam FLEN=(1<<LGFLEN);
|
||||
reg r_full, r_empty;
|
||||
reg [(BW-1):0] mem[0:(FLEN-1)];
|
||||
reg [LGFLEN:0] wr_addr, rd_addr;
|
||||
|
||||
wire w_wr = (i_wr && !o_full);
|
||||
wire w_rd = (i_rd && !o_empty);
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Write half
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
// o_fill
|
||||
// {{{
|
||||
initial o_fill = 0;
|
||||
always @(posedge i_clk)
|
||||
if (i_reset)
|
||||
o_fill <= 0;
|
||||
else case({ w_wr, w_rd })
|
||||
2'b01: o_fill <= o_fill - 1;
|
||||
2'b10: o_fill <= o_fill + 1;
|
||||
default: o_fill <= wr_addr - rd_addr;
|
||||
endcase
|
||||
// }}}
|
||||
|
||||
// r_full, o_full
|
||||
// {{{
|
||||
initial r_full = 0;
|
||||
always @(posedge i_clk)
|
||||
if (i_reset)
|
||||
r_full <= 0;
|
||||
else case({ w_wr, w_rd})
|
||||
2'b01: r_full <= 1'b0;
|
||||
2'b10: r_full <= (o_fill == { 1'b0, {(LGFLEN){1'b1}} });
|
||||
default: r_full <= (o_fill == { 1'b1, {(LGFLEN){1'b0}} });
|
||||
endcase
|
||||
|
||||
assign o_full = (i_rd && OPT_WRITE_ON_FULL) ? 1'b0 : r_full;
|
||||
// }}}
|
||||
|
||||
// wr_addr, the write address pointer
|
||||
// {{{
|
||||
initial wr_addr = 0;
|
||||
always @(posedge i_clk)
|
||||
if (i_reset)
|
||||
wr_addr <= 0;
|
||||
else if (w_wr)
|
||||
wr_addr <= wr_addr + 1'b1;
|
||||
// }}}
|
||||
|
||||
// Write to memory
|
||||
// {{{
|
||||
always @(posedge i_clk)
|
||||
if (w_wr)
|
||||
mem[wr_addr[(LGFLEN-1):0]] <= i_data;
|
||||
// }}}
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Read half
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
// rd_addr, the read address pointer
|
||||
// {{{
|
||||
initial rd_addr = 0;
|
||||
always @(posedge i_clk)
|
||||
if (i_reset)
|
||||
rd_addr <= 0;
|
||||
else if (w_rd)
|
||||
rd_addr <= rd_addr + 1;
|
||||
// }}}
|
||||
|
||||
// r_empty, o_empty
|
||||
// {{{
|
||||
initial r_empty = 1'b1;
|
||||
always @(posedge i_clk)
|
||||
if (i_reset)
|
||||
r_empty <= 1'b1;
|
||||
else case ({ w_wr, w_rd })
|
||||
2'b01: r_empty <= (o_fill <= 1);
|
||||
2'b10: r_empty <= 1'b0;
|
||||
default: begin end
|
||||
endcase
|
||||
|
||||
assign o_empty = (OPT_READ_ON_EMPTY && i_wr) ? 1'b0 : r_empty;
|
||||
// }}}
|
||||
|
||||
// Read from the FIFO
|
||||
// {{{
|
||||
generate if (OPT_ASYNC_READ && OPT_READ_ON_EMPTY)
|
||||
begin : ASYNCHRONOUS_READ_ON_EMPTY
|
||||
// o_data
|
||||
// {{{
|
||||
always @(*)
|
||||
begin
|
||||
o_data = mem[rd_addr[LGFLEN-1:0]];
|
||||
if (r_empty)
|
||||
o_data = i_data;
|
||||
end
|
||||
// }}}
|
||||
end else if (OPT_ASYNC_READ)
|
||||
begin : ASYNCHRONOUS_READ
|
||||
// o_data
|
||||
// {{{
|
||||
always @(*)
|
||||
o_data = mem[rd_addr[LGFLEN-1:0]];
|
||||
// }}}
|
||||
end else begin : REGISTERED_READ
|
||||
// {{{
|
||||
reg bypass_valid;
|
||||
reg [BW-1:0] bypass_data, rd_data;
|
||||
reg [LGFLEN-1:0] rd_next;
|
||||
|
||||
always @(*)
|
||||
rd_next = rd_addr[LGFLEN-1:0] + 1;
|
||||
|
||||
// Memory read, bypassing it if we must
|
||||
// {{{
|
||||
initial bypass_valid = 0;
|
||||
always @(posedge i_clk)
|
||||
if (i_reset)
|
||||
bypass_valid <= 0;
|
||||
else if (r_empty || i_rd)
|
||||
begin
|
||||
if (!i_wr)
|
||||
bypass_valid <= 1'b0;
|
||||
else if (r_empty || (i_rd && (o_fill == 1)))
|
||||
bypass_valid <= 1'b1;
|
||||
else
|
||||
bypass_valid <= 1'b0;
|
||||
end
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (r_empty || i_rd)
|
||||
bypass_data <= i_data;
|
||||
|
||||
initial mem[0] = 0;
|
||||
initial rd_data = 0;
|
||||
always @(posedge i_clk)
|
||||
if (w_rd)
|
||||
rd_data <= mem[rd_next];
|
||||
|
||||
always @(*)
|
||||
if (OPT_READ_ON_EMPTY && r_empty)
|
||||
o_data = i_data;
|
||||
else if (bypass_valid)
|
||||
o_data = bypass_data;
|
||||
else
|
||||
o_data = rd_data;
|
||||
// }}}
|
||||
// }}}
|
||||
end endgenerate
|
||||
// }}}
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// FORMAL METHODS
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
`ifdef FORMAL
|
||||
|
||||
//
|
||||
// Assumptions about our input(s)
|
||||
//
|
||||
//
|
||||
`ifdef SFIFO
|
||||
`define ASSUME assume
|
||||
`else
|
||||
`define ASSUME assert
|
||||
`endif
|
||||
|
||||
reg f_past_valid;
|
||||
wire [LGFLEN:0] f_fill, f_next;
|
||||
wire f_empty;
|
||||
|
||||
initial f_past_valid = 1'b0;
|
||||
always @(posedge i_clk)
|
||||
f_past_valid <= 1'b1;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Assertions about our flags and counters
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
assign f_fill = wr_addr - rd_addr;
|
||||
assign f_empty = (wr_addr == rd_addr);
|
||||
assign f_next = rd_addr + 1'b1;
|
||||
|
||||
always @(*)
|
||||
begin
|
||||
assert(f_fill <= { 1'b1, {(LGFLEN){1'b0}} });
|
||||
assert(o_fill == f_fill);
|
||||
|
||||
assert(r_full == (f_fill == {1'b1, {(LGFLEN){1'b0}} }));
|
||||
assert(r_empty == (f_fill == 0));
|
||||
|
||||
if (!OPT_WRITE_ON_FULL)
|
||||
begin
|
||||
assert(o_full == r_full);
|
||||
end else begin
|
||||
assert(o_full == (r_full && !i_rd));
|
||||
end
|
||||
|
||||
if (!OPT_READ_ON_EMPTY)
|
||||
begin
|
||||
assert(o_empty == r_empty);
|
||||
end else begin
|
||||
assert(o_empty == (r_empty && !i_wr));
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (!OPT_ASYNC_READ && f_past_valid)
|
||||
begin
|
||||
if (f_fill == 0)
|
||||
begin
|
||||
assert(r_empty);
|
||||
assert(o_empty || (OPT_READ_ON_EMPTY && i_wr));
|
||||
end else if ($past(f_fill)>1)
|
||||
begin
|
||||
assert(!r_empty);
|
||||
end else if ($past(!i_rd && f_fill > 0))
|
||||
assert(!r_empty);
|
||||
end
|
||||
|
||||
always @(*)
|
||||
if (!r_empty)
|
||||
begin
|
||||
// This also applies for the registered read case
|
||||
assert(mem[rd_addr[LGFLEN-1:0]] == o_data);
|
||||
end else if (OPT_READ_ON_EMPTY)
|
||||
assert(o_data == i_data);
|
||||
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Formal contract: (Twin write test)
|
||||
// {{{
|
||||
// If you write two values in succession, you should be able to read
|
||||
// those same two values in succession some time later.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
// Verilator lint_off UNDRIVEN
|
||||
(* anyconst *) reg [LGFLEN:0] fw_first_addr;
|
||||
// Verilator lint_on UNDRIVEN
|
||||
`ifndef F_PEEK
|
||||
wire [LGFLEN:0] f_first_addr;
|
||||
wire [LGFLEN:0] f_second_addr;
|
||||
reg [BW-1:0] f_first_data, f_second_data;
|
||||
|
||||
reg f_first_in_fifo, f_second_in_fifo;
|
||||
reg [LGFLEN:0] f_distance_to_first, f_distance_to_second;
|
||||
`endif
|
||||
reg f_first_addr_in_fifo, f_second_addr_in_fifo;
|
||||
|
||||
assign f_first_addr = fw_first_addr;
|
||||
assign f_second_addr = f_first_addr + 1;
|
||||
|
||||
always @(*)
|
||||
begin
|
||||
f_distance_to_first = (f_first_addr - rd_addr);
|
||||
f_first_addr_in_fifo = 0;
|
||||
if ((f_fill != 0) && (f_distance_to_first < f_fill))
|
||||
f_first_addr_in_fifo = 1;
|
||||
end
|
||||
|
||||
always @(*)
|
||||
begin
|
||||
f_distance_to_second = (f_second_addr - rd_addr);
|
||||
f_second_addr_in_fifo = 0;
|
||||
if ((f_fill != 0) && (f_distance_to_second < f_fill))
|
||||
f_second_addr_in_fifo = 1;
|
||||
end
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (w_wr && wr_addr == f_first_addr)
|
||||
f_first_data <= i_data;
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (w_wr && wr_addr == f_second_addr)
|
||||
f_second_data <= i_data;
|
||||
|
||||
always @(*)
|
||||
if (f_first_addr_in_fifo)
|
||||
assert(mem[f_first_addr[LGFLEN-1:0]] == f_first_data);
|
||||
always @(*)
|
||||
f_first_in_fifo = (f_first_addr_in_fifo && (mem[f_first_addr[LGFLEN-1:0]] == f_first_data));
|
||||
|
||||
always @(*)
|
||||
if (f_second_addr_in_fifo)
|
||||
assert(mem[f_second_addr[LGFLEN-1:0]] == f_second_data);
|
||||
|
||||
always @(*)
|
||||
f_second_in_fifo = (f_second_addr_in_fifo && (mem[f_second_addr[LGFLEN-1:0]] == f_second_data));
|
||||
|
||||
always @(*)
|
||||
if (f_first_in_fifo && (o_fill == 1 || f_distance_to_first == 0))
|
||||
assert(o_data == f_first_data);
|
||||
|
||||
always @(*)
|
||||
if (f_second_in_fifo && (o_fill == 1 || f_distance_to_second == 0))
|
||||
assert(o_data == f_second_data);
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (f_past_valid && !$past(i_reset))
|
||||
begin
|
||||
case({$past(f_first_in_fifo), $past(f_second_in_fifo)})
|
||||
2'b00: begin
|
||||
if ($past(w_wr && (!w_rd || !r_empty))
|
||||
&&($past(wr_addr == f_first_addr)))
|
||||
begin
|
||||
assert(f_first_in_fifo);
|
||||
end else begin
|
||||
assert(!f_first_in_fifo);
|
||||
end
|
||||
//
|
||||
// The second could be in the FIFO, since
|
||||
// one might write other data than f_first_data
|
||||
//
|
||||
// assert(!f_second_in_fifo);
|
||||
end
|
||||
2'b01: begin
|
||||
assert(!f_first_in_fifo);
|
||||
if ($past(w_rd && (rd_addr==f_second_addr)))
|
||||
begin
|
||||
assert((o_empty&&!OPT_ASYNC_READ)||!f_second_in_fifo);
|
||||
end else begin
|
||||
assert(f_second_in_fifo);
|
||||
end
|
||||
end
|
||||
2'b10: begin
|
||||
if ($past(w_wr)
|
||||
&&($past(wr_addr == f_second_addr)))
|
||||
begin
|
||||
assert(f_second_in_fifo);
|
||||
end else begin
|
||||
assert(!f_second_in_fifo);
|
||||
end
|
||||
if ($past(!w_rd ||(rd_addr != f_first_addr)))
|
||||
assert(f_first_in_fifo);
|
||||
end
|
||||
2'b11: begin
|
||||
assert(f_second_in_fifo);
|
||||
if ($past(!w_rd ||(rd_addr != f_first_addr)))
|
||||
begin
|
||||
assert(f_first_in_fifo);
|
||||
if (rd_addr == f_first_addr)
|
||||
assert(o_data == f_first_data);
|
||||
end else begin
|
||||
assert(!f_first_in_fifo);
|
||||
assert(o_data == f_second_data);
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Cover properties
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
`ifdef SFIFO
|
||||
reg f_was_full;
|
||||
initial f_was_full = 0;
|
||||
always @(posedge i_clk)
|
||||
if (o_full)
|
||||
f_was_full <= 1;
|
||||
|
||||
always @(posedge i_clk)
|
||||
cover($fell(f_empty));
|
||||
|
||||
always @(posedge i_clk)
|
||||
cover($fell(o_empty));
|
||||
|
||||
always @(posedge i_clk)
|
||||
cover(f_was_full && f_empty);
|
||||
|
||||
always @(posedge i_clk)
|
||||
cover($past(o_full,2)&&(!$past(o_full))&&(o_full));
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (f_past_valid)
|
||||
cover($past(o_empty,2)&&(!$past(o_empty))&& o_empty);
|
||||
`endif
|
||||
// }}}
|
||||
|
||||
// Make Verilator happy
|
||||
// Verilator lint_off UNUSED
|
||||
wire unused_formal;
|
||||
assign unused_formal = &{ 1'b0, f_next[LGFLEN], f_empty };
|
||||
// Verilator lint_on UNUSED
|
||||
`endif // FORMAL
|
||||
// }}}
|
||||
endmodule
|
||||
`ifndef YOSYS
|
||||
`default_nettype wire
|
||||
`endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Filename: sfifo.v
|
||||
// {{{
|
||||
// Project: WB2AXIPSP: bus bridges and other odds and ends
|
||||
//
|
||||
// Purpose: A synchronous data FIFO.
|
||||
//
|
||||
// Creator: Dan Gisselquist, Ph.D.
|
||||
// Gisselquist Technology, LLC
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Written and distributed by Gisselquist Technology, LLC
|
||||
// }}}
|
||||
// This design is hereby granted to the public domain.
|
||||
// {{{
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
`default_nettype none
|
||||
// }}}
|
||||
module sfifo #(
|
||||
// {{{
|
||||
parameter BW=8, // Byte/data width
|
||||
parameter LGFLEN=4,
|
||||
parameter [0:0] OPT_ASYNC_READ = 1'b1,
|
||||
parameter [0:0] OPT_WRITE_ON_FULL = 1'b0,
|
||||
parameter [0:0] OPT_READ_ON_EMPTY = 1'b0
|
||||
// }}}
|
||||
) (
|
||||
// {{{
|
||||
input wire i_clk,
|
||||
input wire i_reset,
|
||||
//
|
||||
// Write interface
|
||||
input wire i_wr,
|
||||
input wire [(BW-1):0] i_data,
|
||||
output wire o_full,
|
||||
output reg [LGFLEN:0] o_fill,
|
||||
//
|
||||
// Read interface
|
||||
input wire i_rd,
|
||||
output reg [(BW-1):0] o_data,
|
||||
output wire o_empty // True if FIFO is empty
|
||||
`ifdef FORMAL
|
||||
`ifdef F_PEEK
|
||||
, output wire [LGFLEN:0] f_first_addr,
|
||||
output wire [LGFLEN:0] f_second_addr,
|
||||
output reg [BW-1:0] f_first_data, f_second_data,
|
||||
|
||||
output reg f_first_in_fifo,
|
||||
f_second_in_fifo,
|
||||
output reg [LGFLEN:0] f_distance_to_first,
|
||||
f_distance_to_second
|
||||
`endif
|
||||
`endif
|
||||
// }}}
|
||||
);
|
||||
|
||||
// Register/net declarations
|
||||
// {{{
|
||||
localparam FLEN=(1<<LGFLEN);
|
||||
reg r_full, r_empty;
|
||||
reg [(BW-1):0] mem[0:(FLEN-1)];
|
||||
reg [LGFLEN:0] wr_addr, rd_addr;
|
||||
|
||||
wire w_wr = (i_wr && !o_full);
|
||||
wire w_rd = (i_rd && !o_empty);
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Write half
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
// o_fill
|
||||
// {{{
|
||||
initial o_fill = 0;
|
||||
always @(posedge i_clk)
|
||||
if (i_reset)
|
||||
o_fill <= 0;
|
||||
else case({ w_wr, w_rd })
|
||||
2'b01: o_fill <= o_fill - 1;
|
||||
2'b10: o_fill <= o_fill + 1;
|
||||
default: o_fill <= wr_addr - rd_addr;
|
||||
endcase
|
||||
// }}}
|
||||
|
||||
// r_full, o_full
|
||||
// {{{
|
||||
initial r_full = 0;
|
||||
always @(posedge i_clk)
|
||||
if (i_reset)
|
||||
r_full <= 0;
|
||||
else case({ w_wr, w_rd})
|
||||
2'b01: r_full <= 1'b0;
|
||||
2'b10: r_full <= (o_fill == { 1'b0, {(LGFLEN){1'b1}} });
|
||||
default: r_full <= (o_fill == { 1'b1, {(LGFLEN){1'b0}} });
|
||||
endcase
|
||||
|
||||
assign o_full = (i_rd && OPT_WRITE_ON_FULL) ? 1'b0 : r_full;
|
||||
// }}}
|
||||
|
||||
// wr_addr, the write address pointer
|
||||
// {{{
|
||||
initial wr_addr = 0;
|
||||
always @(posedge i_clk)
|
||||
if (i_reset)
|
||||
wr_addr <= 0;
|
||||
else if (w_wr)
|
||||
wr_addr <= wr_addr + 1'b1;
|
||||
// }}}
|
||||
|
||||
// Write to memory
|
||||
// {{{
|
||||
always @(posedge i_clk)
|
||||
if (w_wr)
|
||||
mem[wr_addr[(LGFLEN-1):0]] <= i_data;
|
||||
// }}}
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Read half
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
// rd_addr, the read address pointer
|
||||
// {{{
|
||||
initial rd_addr = 0;
|
||||
always @(posedge i_clk)
|
||||
if (i_reset)
|
||||
rd_addr <= 0;
|
||||
else if (w_rd)
|
||||
rd_addr <= rd_addr + 1;
|
||||
// }}}
|
||||
|
||||
// r_empty, o_empty
|
||||
// {{{
|
||||
initial r_empty = 1'b1;
|
||||
always @(posedge i_clk)
|
||||
if (i_reset)
|
||||
r_empty <= 1'b1;
|
||||
else case ({ w_wr, w_rd })
|
||||
2'b01: r_empty <= (o_fill <= 1);
|
||||
2'b10: r_empty <= 1'b0;
|
||||
default: begin end
|
||||
endcase
|
||||
|
||||
assign o_empty = (OPT_READ_ON_EMPTY && i_wr) ? 1'b0 : r_empty;
|
||||
// }}}
|
||||
|
||||
// Read from the FIFO
|
||||
// {{{
|
||||
generate if (OPT_ASYNC_READ && OPT_READ_ON_EMPTY)
|
||||
begin : ASYNCHRONOUS_READ_ON_EMPTY
|
||||
// o_data
|
||||
// {{{
|
||||
always @(*)
|
||||
begin
|
||||
o_data = mem[rd_addr[LGFLEN-1:0]];
|
||||
if (r_empty)
|
||||
o_data = i_data;
|
||||
end
|
||||
// }}}
|
||||
end else if (OPT_ASYNC_READ)
|
||||
begin : ASYNCHRONOUS_READ
|
||||
// o_data
|
||||
// {{{
|
||||
always @(*)
|
||||
o_data = mem[rd_addr[LGFLEN-1:0]];
|
||||
// }}}
|
||||
end else begin : REGISTERED_READ
|
||||
// {{{
|
||||
reg bypass_valid;
|
||||
reg [BW-1:0] bypass_data, rd_data;
|
||||
reg [LGFLEN-1:0] rd_next;
|
||||
|
||||
always @(*)
|
||||
rd_next = rd_addr[LGFLEN-1:0] + 1;
|
||||
|
||||
// Memory read, bypassing it if we must
|
||||
// {{{
|
||||
initial bypass_valid = 0;
|
||||
always @(posedge i_clk)
|
||||
if (i_reset)
|
||||
bypass_valid <= 0;
|
||||
else if (r_empty || i_rd)
|
||||
begin
|
||||
if (!i_wr)
|
||||
bypass_valid <= 1'b0;
|
||||
else if (r_empty || (i_rd && (o_fill == 1)))
|
||||
bypass_valid <= 1'b1;
|
||||
else
|
||||
bypass_valid <= 1'b0;
|
||||
end
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (r_empty || i_rd)
|
||||
bypass_data <= i_data;
|
||||
|
||||
initial mem[0] = 0;
|
||||
initial rd_data = 0;
|
||||
always @(posedge i_clk)
|
||||
if (w_rd)
|
||||
rd_data <= mem[rd_next];
|
||||
|
||||
always @(*)
|
||||
if (OPT_READ_ON_EMPTY && r_empty)
|
||||
o_data = i_data;
|
||||
else if (bypass_valid)
|
||||
o_data = bypass_data;
|
||||
else
|
||||
o_data = rd_data;
|
||||
// }}}
|
||||
// }}}
|
||||
end endgenerate
|
||||
// }}}
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// FORMAL METHODS
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
`ifdef FORMAL
|
||||
|
||||
//
|
||||
// Assumptions about our input(s)
|
||||
//
|
||||
//
|
||||
`ifdef SFIFO
|
||||
`define ASSUME assume
|
||||
`else
|
||||
`define ASSUME assert
|
||||
`endif
|
||||
|
||||
reg f_past_valid;
|
||||
wire [LGFLEN:0] f_fill, f_next;
|
||||
wire f_empty;
|
||||
|
||||
initial f_past_valid = 1'b0;
|
||||
always @(posedge i_clk)
|
||||
f_past_valid <= 1'b1;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Assertions about our flags and counters
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
assign f_fill = wr_addr - rd_addr;
|
||||
assign f_empty = (wr_addr == rd_addr);
|
||||
assign f_next = rd_addr + 1'b1;
|
||||
|
||||
always @(*)
|
||||
begin
|
||||
assert(f_fill <= { 1'b1, {(LGFLEN){1'b0}} });
|
||||
assert(o_fill == f_fill);
|
||||
|
||||
assert(r_full == (f_fill == {1'b1, {(LGFLEN){1'b0}} }));
|
||||
assert(r_empty == (f_fill == 0));
|
||||
|
||||
if (!OPT_WRITE_ON_FULL)
|
||||
begin
|
||||
assert(o_full == r_full);
|
||||
end else begin
|
||||
assert(o_full == (r_full && !i_rd));
|
||||
end
|
||||
|
||||
if (!OPT_READ_ON_EMPTY)
|
||||
begin
|
||||
assert(o_empty == r_empty);
|
||||
end else begin
|
||||
assert(o_empty == (r_empty && !i_wr));
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (!OPT_ASYNC_READ && f_past_valid)
|
||||
begin
|
||||
if (f_fill == 0)
|
||||
begin
|
||||
assert(r_empty);
|
||||
assert(o_empty || (OPT_READ_ON_EMPTY && i_wr));
|
||||
end else if ($past(f_fill)>1)
|
||||
begin
|
||||
assert(!r_empty);
|
||||
end else if ($past(!i_rd && f_fill > 0))
|
||||
assert(!r_empty);
|
||||
end
|
||||
|
||||
always @(*)
|
||||
if (!r_empty)
|
||||
begin
|
||||
// This also applies for the registered read case
|
||||
assert(mem[rd_addr[LGFLEN-1:0]] == o_data);
|
||||
end else if (OPT_READ_ON_EMPTY)
|
||||
assert(o_data == i_data);
|
||||
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Formal contract: (Twin write test)
|
||||
// {{{
|
||||
// If you write two values in succession, you should be able to read
|
||||
// those same two values in succession some time later.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
// Verilator lint_off UNDRIVEN
|
||||
(* anyconst *) reg [LGFLEN:0] fw_first_addr;
|
||||
// Verilator lint_on UNDRIVEN
|
||||
`ifndef F_PEEK
|
||||
wire [LGFLEN:0] f_first_addr;
|
||||
wire [LGFLEN:0] f_second_addr;
|
||||
reg [BW-1:0] f_first_data, f_second_data;
|
||||
|
||||
reg f_first_in_fifo, f_second_in_fifo;
|
||||
reg [LGFLEN:0] f_distance_to_first, f_distance_to_second;
|
||||
`endif
|
||||
reg f_first_addr_in_fifo, f_second_addr_in_fifo;
|
||||
|
||||
assign f_first_addr = fw_first_addr;
|
||||
assign f_second_addr = f_first_addr + 1;
|
||||
|
||||
always @(*)
|
||||
begin
|
||||
f_distance_to_first = (f_first_addr - rd_addr);
|
||||
f_first_addr_in_fifo = 0;
|
||||
if ((f_fill != 0) && (f_distance_to_first < f_fill))
|
||||
f_first_addr_in_fifo = 1;
|
||||
end
|
||||
|
||||
always @(*)
|
||||
begin
|
||||
f_distance_to_second = (f_second_addr - rd_addr);
|
||||
f_second_addr_in_fifo = 0;
|
||||
if ((f_fill != 0) && (f_distance_to_second < f_fill))
|
||||
f_second_addr_in_fifo = 1;
|
||||
end
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (w_wr && wr_addr == f_first_addr)
|
||||
f_first_data <= i_data;
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (w_wr && wr_addr == f_second_addr)
|
||||
f_second_data <= i_data;
|
||||
|
||||
always @(*)
|
||||
if (f_first_addr_in_fifo)
|
||||
assert(mem[f_first_addr[LGFLEN-1:0]] == f_first_data);
|
||||
always @(*)
|
||||
f_first_in_fifo = (f_first_addr_in_fifo && (mem[f_first_addr[LGFLEN-1:0]] == f_first_data));
|
||||
|
||||
always @(*)
|
||||
if (f_second_addr_in_fifo)
|
||||
assert(mem[f_second_addr[LGFLEN-1:0]] == f_second_data);
|
||||
|
||||
always @(*)
|
||||
f_second_in_fifo = (f_second_addr_in_fifo && (mem[f_second_addr[LGFLEN-1:0]] == f_second_data));
|
||||
|
||||
always @(*)
|
||||
if (f_first_in_fifo && (o_fill == 1 || f_distance_to_first == 0))
|
||||
assert(o_data == f_first_data);
|
||||
|
||||
always @(*)
|
||||
if (f_second_in_fifo && (o_fill == 1 || f_distance_to_second == 0))
|
||||
assert(o_data == f_second_data);
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (f_past_valid && !$past(i_reset))
|
||||
begin
|
||||
case({$past(f_first_in_fifo), $past(f_second_in_fifo)})
|
||||
2'b00: begin
|
||||
if ($past(w_wr && (!w_rd || !r_empty))
|
||||
&&($past(wr_addr == f_first_addr)))
|
||||
begin
|
||||
assert(f_first_in_fifo);
|
||||
end else begin
|
||||
assert(!f_first_in_fifo);
|
||||
end
|
||||
//
|
||||
// The second could be in the FIFO, since
|
||||
// one might write other data than f_first_data
|
||||
//
|
||||
// assert(!f_second_in_fifo);
|
||||
end
|
||||
2'b01: begin
|
||||
assert(!f_first_in_fifo);
|
||||
if ($past(w_rd && (rd_addr==f_second_addr)))
|
||||
begin
|
||||
assert((o_empty&&!OPT_ASYNC_READ)||!f_second_in_fifo);
|
||||
end else begin
|
||||
assert(f_second_in_fifo);
|
||||
end
|
||||
end
|
||||
2'b10: begin
|
||||
if ($past(w_wr)
|
||||
&&($past(wr_addr == f_second_addr)))
|
||||
begin
|
||||
assert(f_second_in_fifo);
|
||||
end else begin
|
||||
assert(!f_second_in_fifo);
|
||||
end
|
||||
if ($past(!w_rd ||(rd_addr != f_first_addr)))
|
||||
assert(f_first_in_fifo);
|
||||
end
|
||||
2'b11: begin
|
||||
assert(f_second_in_fifo);
|
||||
if ($past(!w_rd ||(rd_addr != f_first_addr)))
|
||||
begin
|
||||
assert(f_first_in_fifo);
|
||||
if (rd_addr == f_first_addr)
|
||||
assert(o_data == f_first_data);
|
||||
end else begin
|
||||
assert(!f_first_in_fifo);
|
||||
assert(o_data == f_second_data);
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Cover properties
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
`ifdef SFIFO
|
||||
reg f_was_full;
|
||||
initial f_was_full = 0;
|
||||
always @(posedge i_clk)
|
||||
if (o_full)
|
||||
f_was_full <= 1;
|
||||
|
||||
always @(posedge i_clk)
|
||||
cover($fell(f_empty));
|
||||
|
||||
always @(posedge i_clk)
|
||||
cover($fell(o_empty));
|
||||
|
||||
always @(posedge i_clk)
|
||||
cover(f_was_full && f_empty);
|
||||
|
||||
always @(posedge i_clk)
|
||||
cover($past(o_full,2)&&(!$past(o_full))&&(o_full));
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (f_past_valid)
|
||||
cover($past(o_empty,2)&&(!$past(o_empty))&& o_empty);
|
||||
`endif
|
||||
// }}}
|
||||
|
||||
// Make Verilator happy
|
||||
// Verilator lint_off UNUSED
|
||||
wire unused_formal;
|
||||
assign unused_formal = &{ 1'b0, f_next[LGFLEN], f_empty };
|
||||
// Verilator lint_on UNUSED
|
||||
`endif // FORMAL
|
||||
// }}}
|
||||
endmodule
|
||||
`ifndef YOSYS
|
||||
`default_nettype wire
|
||||
`endif
|
||||
|
|
|
|||
|
|
@ -1,495 +1,495 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Filename: skidbuffer.v
|
||||
// {{{
|
||||
// Project: WB2AXIPSP: bus bridges and other odds and ends
|
||||
//
|
||||
// Purpose: A basic SKID buffer.
|
||||
// {{{
|
||||
// Skid buffers are required for high throughput AXI code, since the AXI
|
||||
// specification requires that all outputs be registered. This means
|
||||
// that, if there are any stall conditions calculated, it will take a clock
|
||||
// cycle before the stall can be propagated up stream. This means that
|
||||
// the data will need to be buffered for a cycle until the stall signal
|
||||
// can make it to the output.
|
||||
//
|
||||
// Handling that buffer is the purpose of this core.
|
||||
//
|
||||
// On one end of this core, you have the i_valid and i_data inputs to
|
||||
// connect to your bus interface. There's also a registered o_ready
|
||||
// signal to signal stalls for the bus interface.
|
||||
//
|
||||
// The other end of the core has the same basic interface, but it isn't
|
||||
// registered. This allows you to interact with the bus interfaces
|
||||
// as though they were combinatorial logic, by interacting with this half
|
||||
// of the core.
|
||||
//
|
||||
// If at any time the incoming !stall signal, i_ready, signals a stall,
|
||||
// the incoming data is placed into a buffer. Internally, that buffer
|
||||
// is held in r_data with the r_valid flag used to indicate that valid
|
||||
// data is within it.
|
||||
// }}}
|
||||
// Parameters:
|
||||
// {{{
|
||||
// DW or data width
|
||||
// In order to make this core generic, the width of the data in the
|
||||
// skid buffer is parameterized
|
||||
//
|
||||
// OPT_LOWPOWER
|
||||
// Forces both o_data and r_data to zero if the respective *VALID
|
||||
// signal is also low. While this costs extra logic, it can also
|
||||
// be used to guarantee that any unused values aren't toggling and
|
||||
// therefore unnecessarily using power.
|
||||
//
|
||||
// This excess toggling can be particularly problematic if the
|
||||
// bus signals have a high fanout rate, or a long signal path
|
||||
// across an FPGA.
|
||||
//
|
||||
// OPT_OUTREG
|
||||
// Causes the outputs to be registered
|
||||
//
|
||||
// OPT_PASSTHROUGH
|
||||
// Turns the skid buffer into a passthrough. Used for formal
|
||||
// verification only.
|
||||
// }}}
|
||||
// Creator: Dan Gisselquist, Ph.D.
|
||||
// Gisselquist Technology, LLC
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// }}}
|
||||
// Copyright (C) 2019-2024, Gisselquist Technology, LLC
|
||||
// {{{
|
||||
// This file is part of the WB2AXIP project.
|
||||
//
|
||||
// The WB2AXIP project contains free software and gateware, licensed under the
|
||||
// Apache License, Version 2.0 (the "License"). You may not use this project,
|
||||
// or this file, except in compliance with the License. You may obtain a copy
|
||||
// of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
`default_nettype none
|
||||
// }}}
|
||||
module skidbuffer #(
|
||||
// {{{
|
||||
parameter [0:0] OPT_LOWPOWER = 0,
|
||||
parameter [0:0] OPT_OUTREG = 1,
|
||||
//
|
||||
parameter [0:0] OPT_PASSTHROUGH = 0,
|
||||
parameter DW = 8,
|
||||
parameter [0:0] OPT_INITIAL = 1'b1
|
||||
// }}}
|
||||
) (
|
||||
// {{{
|
||||
input wire i_clk, i_reset,
|
||||
input wire i_valid,
|
||||
output wire o_ready,
|
||||
input wire [DW-1:0] i_data,
|
||||
output wire o_valid,
|
||||
input wire i_ready,
|
||||
output reg [DW-1:0] o_data
|
||||
// }}}
|
||||
);
|
||||
|
||||
wire [DW-1:0] w_data;
|
||||
|
||||
generate if (OPT_PASSTHROUGH)
|
||||
begin : PASSTHROUGH
|
||||
// {{{
|
||||
assign { o_valid, o_ready } = { i_valid, i_ready };
|
||||
|
||||
always @(*)
|
||||
if (!i_valid && OPT_LOWPOWER)
|
||||
o_data = 0;
|
||||
else
|
||||
o_data = i_data;
|
||||
|
||||
assign w_data = 0;
|
||||
|
||||
// Keep Verilator happy
|
||||
// Verilator lint_off UNUSED
|
||||
// {{{
|
||||
wire unused_passthrough;
|
||||
assign unused_passthrough = &{ 1'b0, i_clk, i_reset };
|
||||
// }}}
|
||||
// Verilator lint_on UNUSED
|
||||
// }}}
|
||||
end else begin : LOGIC
|
||||
// We'll start with skid buffer itself
|
||||
// {{{
|
||||
reg r_valid;
|
||||
reg [DW-1:0] r_data;
|
||||
|
||||
// r_valid
|
||||
// {{{
|
||||
initial if (OPT_INITIAL) r_valid = 0;
|
||||
always @(posedge i_clk)
|
||||
if (i_reset)
|
||||
r_valid <= 0;
|
||||
else if ((i_valid && o_ready) && (o_valid && !i_ready))
|
||||
// We have incoming data, but the output is stalled
|
||||
r_valid <= 1;
|
||||
else if (i_ready)
|
||||
r_valid <= 0;
|
||||
// }}}
|
||||
|
||||
// r_data
|
||||
// {{{
|
||||
initial if (OPT_INITIAL) r_data = 0;
|
||||
always @(posedge i_clk)
|
||||
if (OPT_LOWPOWER && i_reset)
|
||||
r_data <= 0;
|
||||
else if (OPT_LOWPOWER && (!o_valid || i_ready))
|
||||
r_data <= 0;
|
||||
else if ((!OPT_LOWPOWER || !OPT_OUTREG || i_valid) && o_ready)
|
||||
r_data <= i_data;
|
||||
|
||||
assign w_data = r_data;
|
||||
// }}}
|
||||
|
||||
// o_ready
|
||||
// {{{
|
||||
assign o_ready = !r_valid;
|
||||
// }}}
|
||||
|
||||
//
|
||||
// And then move on to the output port
|
||||
//
|
||||
if (!OPT_OUTREG)
|
||||
begin : NET_OUTPUT
|
||||
// Outputs are combinatorially determined from inputs
|
||||
// {{{
|
||||
// o_valid
|
||||
// {{{
|
||||
assign o_valid = !i_reset && (i_valid || r_valid);
|
||||
// }}}
|
||||
|
||||
// o_data
|
||||
// {{{
|
||||
always @(*)
|
||||
if (r_valid)
|
||||
o_data = r_data;
|
||||
else if (!OPT_LOWPOWER || i_valid)
|
||||
o_data = i_data;
|
||||
else
|
||||
o_data = 0;
|
||||
// }}}
|
||||
// }}}
|
||||
end else begin : REG_OUTPUT
|
||||
// Register our outputs
|
||||
// {{{
|
||||
// o_valid
|
||||
// {{{
|
||||
reg ro_valid;
|
||||
|
||||
initial if (OPT_INITIAL) ro_valid = 0;
|
||||
always @(posedge i_clk)
|
||||
if (i_reset)
|
||||
ro_valid <= 0;
|
||||
else if (!o_valid || i_ready)
|
||||
ro_valid <= (i_valid || r_valid);
|
||||
|
||||
assign o_valid = ro_valid;
|
||||
// }}}
|
||||
|
||||
// o_data
|
||||
// {{{
|
||||
initial if (OPT_INITIAL) o_data = 0;
|
||||
always @(posedge i_clk)
|
||||
if (OPT_LOWPOWER && i_reset)
|
||||
o_data <= 0;
|
||||
else if (!o_valid || i_ready)
|
||||
begin
|
||||
|
||||
if (r_valid)
|
||||
o_data <= r_data;
|
||||
else if (!OPT_LOWPOWER || i_valid)
|
||||
o_data <= i_data;
|
||||
else
|
||||
o_data <= 0;
|
||||
end
|
||||
// }}}
|
||||
|
||||
// }}}
|
||||
end
|
||||
// }}}
|
||||
end endgenerate
|
||||
|
||||
// Keep Verilator happy
|
||||
// {{{
|
||||
// Verilator lint_off UNUSED
|
||||
wire unused;
|
||||
assign unused = &{ 1'b0, w_data };
|
||||
// Verilator lint_on UNUSED
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Formal properties
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
`ifdef FORMAL
|
||||
`ifdef SKIDBUFFER
|
||||
`define ASSUME assume
|
||||
`else
|
||||
`define ASSUME assert
|
||||
`endif
|
||||
|
||||
reg f_past_valid;
|
||||
|
||||
initial f_past_valid = 0;
|
||||
always @(posedge i_clk)
|
||||
f_past_valid <= 1;
|
||||
|
||||
always @(*)
|
||||
if (!f_past_valid)
|
||||
assume(i_reset);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Incoming stream properties / assumptions
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
always @(posedge i_clk)
|
||||
if (!f_past_valid)
|
||||
begin
|
||||
`ASSUME(!i_valid || !OPT_INITIAL);
|
||||
end else if ($past(i_valid && !o_ready && !i_reset) && !i_reset)
|
||||
`ASSUME(i_valid && $stable(i_data));
|
||||
|
||||
`ifdef VERIFIC
|
||||
`define FORMAL_VERIFIC
|
||||
// Reset properties
|
||||
property RESET_CLEARS_IVALID;
|
||||
@(posedge i_clk) i_reset |=> !i_valid;
|
||||
endproperty
|
||||
|
||||
property IDATA_HELD_WHEN_NOT_READY;
|
||||
@(posedge i_clk) disable iff (i_reset)
|
||||
i_valid && !o_ready |=> i_valid && $stable(i_data);
|
||||
endproperty
|
||||
|
||||
`ifdef SKIDBUFFER
|
||||
assume property (IDATA_HELD_WHEN_NOT_READY);
|
||||
`else
|
||||
assert property (IDATA_HELD_WHEN_NOT_READY);
|
||||
`endif
|
||||
`endif
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Outgoing stream properties / assumptions
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
generate if (!OPT_PASSTHROUGH)
|
||||
begin
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (!f_past_valid) // || $past(i_reset))
|
||||
begin
|
||||
// Following any reset, valid must be deasserted
|
||||
assert(!o_valid || !OPT_INITIAL);
|
||||
end else if ($past(o_valid && !i_ready && !i_reset) && !i_reset)
|
||||
// Following any stall, valid must remain high and
|
||||
// data must be preserved
|
||||
assert(o_valid && $stable(o_data));
|
||||
|
||||
end endgenerate
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Other properties
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
generate if (!OPT_PASSTHROUGH)
|
||||
begin
|
||||
// Rule #1:
|
||||
// If registered, then following any reset we should be
|
||||
// ready for a new request
|
||||
// {{{
|
||||
always @(posedge i_clk)
|
||||
if (f_past_valid && $past(OPT_OUTREG && i_reset))
|
||||
assert(o_ready);
|
||||
// }}}
|
||||
|
||||
// Rule #2:
|
||||
// All incoming data must either go directly to the
|
||||
// output port, or into the skid buffer
|
||||
// {{{
|
||||
`ifndef VERIFIC
|
||||
always @(posedge i_clk)
|
||||
if (f_past_valid && !$past(i_reset) && $past(i_valid && o_ready
|
||||
&& (!OPT_OUTREG || o_valid) && !i_ready))
|
||||
assert(!o_ready && w_data == $past(i_data));
|
||||
`else
|
||||
assert property (@(posedge i_clk)
|
||||
disable iff (i_reset)
|
||||
(i_valid && o_ready
|
||||
&& (!OPT_OUTREG || o_valid) && !i_ready)
|
||||
|=> (!o_ready && w_data == $past(i_data)));
|
||||
`endif
|
||||
// }}}
|
||||
|
||||
// Rule #3:
|
||||
// After the last transaction, o_valid should become idle
|
||||
// {{{
|
||||
if (!OPT_OUTREG)
|
||||
begin
|
||||
// {{{
|
||||
always @(posedge i_clk)
|
||||
if (f_past_valid && !$past(i_reset) && !i_reset
|
||||
&& $past(i_ready))
|
||||
begin
|
||||
assert(o_valid == i_valid);
|
||||
assert(!i_valid || (o_data == i_data));
|
||||
end
|
||||
// }}}
|
||||
end else begin
|
||||
// {{{
|
||||
always @(posedge i_clk)
|
||||
if (f_past_valid && !$past(i_reset))
|
||||
begin
|
||||
if ($past(i_valid && o_ready))
|
||||
assert(o_valid);
|
||||
|
||||
if ($past(!i_valid && o_ready && i_ready))
|
||||
assert(!o_valid);
|
||||
end
|
||||
// }}}
|
||||
end
|
||||
// }}}
|
||||
|
||||
// Rule #4
|
||||
// Same thing, but this time for o_ready
|
||||
// {{{
|
||||
always @(posedge i_clk)
|
||||
if (f_past_valid && $past(!o_ready && i_ready))
|
||||
assert(o_ready);
|
||||
// }}}
|
||||
|
||||
// If OPT_LOWPOWER is set, o_data and w_data both need to be
|
||||
// zero any time !o_valid or !r_valid respectively
|
||||
// {{{
|
||||
if (OPT_LOWPOWER)
|
||||
begin
|
||||
always @(*)
|
||||
if ((OPT_OUTREG || !i_reset) && !o_valid)
|
||||
assert(o_data == 0);
|
||||
|
||||
always @(*)
|
||||
if (o_ready)
|
||||
assert(w_data == 0);
|
||||
|
||||
end
|
||||
// }}}
|
||||
end endgenerate
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Cover checks
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
`ifdef SKIDBUFFER
|
||||
generate if (!OPT_PASSTHROUGH)
|
||||
begin
|
||||
reg f_changed_data;
|
||||
|
||||
initial f_changed_data = 0;
|
||||
always @(posedge i_clk)
|
||||
if (i_reset)
|
||||
f_changed_data <= 1;
|
||||
else if (i_valid && $past(!i_valid || o_ready))
|
||||
begin
|
||||
if (i_data != $past(i_data + 1))
|
||||
f_changed_data <= 0;
|
||||
end else if (!i_valid && i_data != 0)
|
||||
f_changed_data <= 0;
|
||||
|
||||
|
||||
`ifndef VERIFIC
|
||||
reg [3:0] cvr_steps, cvr_hold;
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (i_reset)
|
||||
begin
|
||||
cvr_steps <= 0;
|
||||
cvr_hold <= 0;
|
||||
end else begin
|
||||
cvr_steps <= cvr_steps + 1;
|
||||
cvr_hold <= cvr_hold + 1;
|
||||
case(cvr_steps)
|
||||
0: if (o_valid || i_valid)
|
||||
cvr_steps <= 0;
|
||||
1: if (!i_valid || !i_ready)
|
||||
cvr_steps <= 0;
|
||||
2: if (!i_valid || !i_ready)
|
||||
cvr_steps <= 0;
|
||||
3: if (!i_valid || !i_ready)
|
||||
cvr_steps <= 0;
|
||||
4: if (!i_valid || i_ready)
|
||||
cvr_steps <= 0;
|
||||
5: if (!i_valid || !i_ready)
|
||||
cvr_steps <= 0;
|
||||
6: if (!i_valid || !i_ready)
|
||||
cvr_steps <= 0;
|
||||
7: if (!i_valid || i_ready)
|
||||
cvr_steps <= 0;
|
||||
8: if (!i_valid || i_ready)
|
||||
cvr_steps <= 0;
|
||||
9: if (!i_valid || !i_ready)
|
||||
cvr_steps <= 0;
|
||||
10: if (!i_valid || !i_ready)
|
||||
cvr_steps <= 0;
|
||||
11: if (!i_valid || !i_ready)
|
||||
cvr_steps <= 0;
|
||||
12: begin
|
||||
cvr_steps <= cvr_steps;
|
||||
cover(!o_valid && !i_valid && f_changed_data);
|
||||
if (!o_valid || !i_ready)
|
||||
cvr_steps <= 0;
|
||||
else
|
||||
cvr_hold <= cvr_hold + 1;
|
||||
end
|
||||
default: assert(0);
|
||||
endcase
|
||||
end
|
||||
|
||||
`else
|
||||
// Cover test
|
||||
cover property (@(posedge i_clk)
|
||||
disable iff (i_reset)
|
||||
(!o_valid && !i_valid)
|
||||
##1 i_valid && i_ready [*3]
|
||||
##1 i_valid && !i_ready
|
||||
##1 i_valid && i_ready [*2]
|
||||
##1 i_valid && !i_ready [*2]
|
||||
##1 i_valid && i_ready [*3]
|
||||
// Wait for the design to clear
|
||||
##1 o_valid && i_ready [*0:5]
|
||||
##1 (!o_valid && !i_valid && f_changed_data));
|
||||
`endif
|
||||
end endgenerate
|
||||
`endif // SKIDBUFFER
|
||||
// }}}
|
||||
`endif
|
||||
// }}}
|
||||
endmodule
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Filename: skidbuffer.v
|
||||
// {{{
|
||||
// Project: WB2AXIPSP: bus bridges and other odds and ends
|
||||
//
|
||||
// Purpose: A basic SKID buffer.
|
||||
// {{{
|
||||
// Skid buffers are required for high throughput AXI code, since the AXI
|
||||
// specification requires that all outputs be registered. This means
|
||||
// that, if there are any stall conditions calculated, it will take a clock
|
||||
// cycle before the stall can be propagated up stream. This means that
|
||||
// the data will need to be buffered for a cycle until the stall signal
|
||||
// can make it to the output.
|
||||
//
|
||||
// Handling that buffer is the purpose of this core.
|
||||
//
|
||||
// On one end of this core, you have the i_valid and i_data inputs to
|
||||
// connect to your bus interface. There's also a registered o_ready
|
||||
// signal to signal stalls for the bus interface.
|
||||
//
|
||||
// The other end of the core has the same basic interface, but it isn't
|
||||
// registered. This allows you to interact with the bus interfaces
|
||||
// as though they were combinatorial logic, by interacting with this half
|
||||
// of the core.
|
||||
//
|
||||
// If at any time the incoming !stall signal, i_ready, signals a stall,
|
||||
// the incoming data is placed into a buffer. Internally, that buffer
|
||||
// is held in r_data with the r_valid flag used to indicate that valid
|
||||
// data is within it.
|
||||
// }}}
|
||||
// Parameters:
|
||||
// {{{
|
||||
// DW or data width
|
||||
// In order to make this core generic, the width of the data in the
|
||||
// skid buffer is parameterized
|
||||
//
|
||||
// OPT_LOWPOWER
|
||||
// Forces both o_data and r_data to zero if the respective *VALID
|
||||
// signal is also low. While this costs extra logic, it can also
|
||||
// be used to guarantee that any unused values aren't toggling and
|
||||
// therefore unnecessarily using power.
|
||||
//
|
||||
// This excess toggling can be particularly problematic if the
|
||||
// bus signals have a high fanout rate, or a long signal path
|
||||
// across an FPGA.
|
||||
//
|
||||
// OPT_OUTREG
|
||||
// Causes the outputs to be registered
|
||||
//
|
||||
// OPT_PASSTHROUGH
|
||||
// Turns the skid buffer into a passthrough. Used for formal
|
||||
// verification only.
|
||||
// }}}
|
||||
// Creator: Dan Gisselquist, Ph.D.
|
||||
// Gisselquist Technology, LLC
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// }}}
|
||||
// Copyright (C) 2019-2024, Gisselquist Technology, LLC
|
||||
// {{{
|
||||
// This file is part of the WB2AXIP project.
|
||||
//
|
||||
// The WB2AXIP project contains free software and gateware, licensed under the
|
||||
// Apache License, Version 2.0 (the "License"). You may not use this project,
|
||||
// or this file, except in compliance with the License. You may obtain a copy
|
||||
// of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
`default_nettype none
|
||||
// }}}
|
||||
module skidbuffer #(
|
||||
// {{{
|
||||
parameter [0:0] OPT_LOWPOWER = 0,
|
||||
parameter [0:0] OPT_OUTREG = 1,
|
||||
//
|
||||
parameter [0:0] OPT_PASSTHROUGH = 0,
|
||||
parameter DW = 8,
|
||||
parameter [0:0] OPT_INITIAL = 1'b1
|
||||
// }}}
|
||||
) (
|
||||
// {{{
|
||||
input wire i_clk, i_reset,
|
||||
input wire i_valid,
|
||||
output wire o_ready,
|
||||
input wire [DW-1:0] i_data,
|
||||
output wire o_valid,
|
||||
input wire i_ready,
|
||||
output reg [DW-1:0] o_data
|
||||
// }}}
|
||||
);
|
||||
|
||||
wire [DW-1:0] w_data;
|
||||
|
||||
generate if (OPT_PASSTHROUGH)
|
||||
begin : PASSTHROUGH
|
||||
// {{{
|
||||
assign { o_valid, o_ready } = { i_valid, i_ready };
|
||||
|
||||
always @(*)
|
||||
if (!i_valid && OPT_LOWPOWER)
|
||||
o_data = 0;
|
||||
else
|
||||
o_data = i_data;
|
||||
|
||||
assign w_data = 0;
|
||||
|
||||
// Keep Verilator happy
|
||||
// Verilator lint_off UNUSED
|
||||
// {{{
|
||||
wire unused_passthrough;
|
||||
assign unused_passthrough = &{ 1'b0, i_clk, i_reset };
|
||||
// }}}
|
||||
// Verilator lint_on UNUSED
|
||||
// }}}
|
||||
end else begin : LOGIC
|
||||
// We'll start with skid buffer itself
|
||||
// {{{
|
||||
reg r_valid;
|
||||
reg [DW-1:0] r_data;
|
||||
|
||||
// r_valid
|
||||
// {{{
|
||||
initial if (OPT_INITIAL) r_valid = 0;
|
||||
always @(posedge i_clk)
|
||||
if (i_reset)
|
||||
r_valid <= 0;
|
||||
else if ((i_valid && o_ready) && (o_valid && !i_ready))
|
||||
// We have incoming data, but the output is stalled
|
||||
r_valid <= 1;
|
||||
else if (i_ready)
|
||||
r_valid <= 0;
|
||||
// }}}
|
||||
|
||||
// r_data
|
||||
// {{{
|
||||
initial if (OPT_INITIAL) r_data = 0;
|
||||
always @(posedge i_clk)
|
||||
if (OPT_LOWPOWER && i_reset)
|
||||
r_data <= 0;
|
||||
else if (OPT_LOWPOWER && (!o_valid || i_ready))
|
||||
r_data <= 0;
|
||||
else if ((!OPT_LOWPOWER || !OPT_OUTREG || i_valid) && o_ready)
|
||||
r_data <= i_data;
|
||||
|
||||
assign w_data = r_data;
|
||||
// }}}
|
||||
|
||||
// o_ready
|
||||
// {{{
|
||||
assign o_ready = !r_valid;
|
||||
// }}}
|
||||
|
||||
//
|
||||
// And then move on to the output port
|
||||
//
|
||||
if (!OPT_OUTREG)
|
||||
begin : NET_OUTPUT
|
||||
// Outputs are combinatorially determined from inputs
|
||||
// {{{
|
||||
// o_valid
|
||||
// {{{
|
||||
assign o_valid = !i_reset && (i_valid || r_valid);
|
||||
// }}}
|
||||
|
||||
// o_data
|
||||
// {{{
|
||||
always @(*)
|
||||
if (r_valid)
|
||||
o_data = r_data;
|
||||
else if (!OPT_LOWPOWER || i_valid)
|
||||
o_data = i_data;
|
||||
else
|
||||
o_data = 0;
|
||||
// }}}
|
||||
// }}}
|
||||
end else begin : REG_OUTPUT
|
||||
// Register our outputs
|
||||
// {{{
|
||||
// o_valid
|
||||
// {{{
|
||||
reg ro_valid;
|
||||
|
||||
initial if (OPT_INITIAL) ro_valid = 0;
|
||||
always @(posedge i_clk)
|
||||
if (i_reset)
|
||||
ro_valid <= 0;
|
||||
else if (!o_valid || i_ready)
|
||||
ro_valid <= (i_valid || r_valid);
|
||||
|
||||
assign o_valid = ro_valid;
|
||||
// }}}
|
||||
|
||||
// o_data
|
||||
// {{{
|
||||
initial if (OPT_INITIAL) o_data = 0;
|
||||
always @(posedge i_clk)
|
||||
if (OPT_LOWPOWER && i_reset)
|
||||
o_data <= 0;
|
||||
else if (!o_valid || i_ready)
|
||||
begin
|
||||
|
||||
if (r_valid)
|
||||
o_data <= r_data;
|
||||
else if (!OPT_LOWPOWER || i_valid)
|
||||
o_data <= i_data;
|
||||
else
|
||||
o_data <= 0;
|
||||
end
|
||||
// }}}
|
||||
|
||||
// }}}
|
||||
end
|
||||
// }}}
|
||||
end endgenerate
|
||||
|
||||
// Keep Verilator happy
|
||||
// {{{
|
||||
// Verilator lint_off UNUSED
|
||||
wire unused;
|
||||
assign unused = &{ 1'b0, w_data };
|
||||
// Verilator lint_on UNUSED
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Formal properties
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
`ifdef FORMAL
|
||||
`ifdef SKIDBUFFER
|
||||
`define ASSUME assume
|
||||
`else
|
||||
`define ASSUME assert
|
||||
`endif
|
||||
|
||||
reg f_past_valid;
|
||||
|
||||
initial f_past_valid = 0;
|
||||
always @(posedge i_clk)
|
||||
f_past_valid <= 1;
|
||||
|
||||
always @(*)
|
||||
if (!f_past_valid)
|
||||
assume(i_reset);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Incoming stream properties / assumptions
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
always @(posedge i_clk)
|
||||
if (!f_past_valid)
|
||||
begin
|
||||
`ASSUME(!i_valid || !OPT_INITIAL);
|
||||
end else if ($past(i_valid && !o_ready && !i_reset) && !i_reset)
|
||||
`ASSUME(i_valid && $stable(i_data));
|
||||
|
||||
`ifdef VERIFIC
|
||||
`define FORMAL_VERIFIC
|
||||
// Reset properties
|
||||
property RESET_CLEARS_IVALID;
|
||||
@(posedge i_clk) i_reset |=> !i_valid;
|
||||
endproperty
|
||||
|
||||
property IDATA_HELD_WHEN_NOT_READY;
|
||||
@(posedge i_clk) disable iff (i_reset)
|
||||
i_valid && !o_ready |=> i_valid && $stable(i_data);
|
||||
endproperty
|
||||
|
||||
`ifdef SKIDBUFFER
|
||||
assume property (IDATA_HELD_WHEN_NOT_READY);
|
||||
`else
|
||||
assert property (IDATA_HELD_WHEN_NOT_READY);
|
||||
`endif
|
||||
`endif
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Outgoing stream properties / assumptions
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
generate if (!OPT_PASSTHROUGH)
|
||||
begin
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (!f_past_valid) // || $past(i_reset))
|
||||
begin
|
||||
// Following any reset, valid must be deasserted
|
||||
assert(!o_valid || !OPT_INITIAL);
|
||||
end else if ($past(o_valid && !i_ready && !i_reset) && !i_reset)
|
||||
// Following any stall, valid must remain high and
|
||||
// data must be preserved
|
||||
assert(o_valid && $stable(o_data));
|
||||
|
||||
end endgenerate
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Other properties
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
generate if (!OPT_PASSTHROUGH)
|
||||
begin
|
||||
// Rule #1:
|
||||
// If registered, then following any reset we should be
|
||||
// ready for a new request
|
||||
// {{{
|
||||
always @(posedge i_clk)
|
||||
if (f_past_valid && $past(OPT_OUTREG && i_reset))
|
||||
assert(o_ready);
|
||||
// }}}
|
||||
|
||||
// Rule #2:
|
||||
// All incoming data must either go directly to the
|
||||
// output port, or into the skid buffer
|
||||
// {{{
|
||||
`ifndef VERIFIC
|
||||
always @(posedge i_clk)
|
||||
if (f_past_valid && !$past(i_reset) && $past(i_valid && o_ready
|
||||
&& (!OPT_OUTREG || o_valid) && !i_ready))
|
||||
assert(!o_ready && w_data == $past(i_data));
|
||||
`else
|
||||
assert property (@(posedge i_clk)
|
||||
disable iff (i_reset)
|
||||
(i_valid && o_ready
|
||||
&& (!OPT_OUTREG || o_valid) && !i_ready)
|
||||
|=> (!o_ready && w_data == $past(i_data)));
|
||||
`endif
|
||||
// }}}
|
||||
|
||||
// Rule #3:
|
||||
// After the last transaction, o_valid should become idle
|
||||
// {{{
|
||||
if (!OPT_OUTREG)
|
||||
begin
|
||||
// {{{
|
||||
always @(posedge i_clk)
|
||||
if (f_past_valid && !$past(i_reset) && !i_reset
|
||||
&& $past(i_ready))
|
||||
begin
|
||||
assert(o_valid == i_valid);
|
||||
assert(!i_valid || (o_data == i_data));
|
||||
end
|
||||
// }}}
|
||||
end else begin
|
||||
// {{{
|
||||
always @(posedge i_clk)
|
||||
if (f_past_valid && !$past(i_reset))
|
||||
begin
|
||||
if ($past(i_valid && o_ready))
|
||||
assert(o_valid);
|
||||
|
||||
if ($past(!i_valid && o_ready && i_ready))
|
||||
assert(!o_valid);
|
||||
end
|
||||
// }}}
|
||||
end
|
||||
// }}}
|
||||
|
||||
// Rule #4
|
||||
// Same thing, but this time for o_ready
|
||||
// {{{
|
||||
always @(posedge i_clk)
|
||||
if (f_past_valid && $past(!o_ready && i_ready))
|
||||
assert(o_ready);
|
||||
// }}}
|
||||
|
||||
// If OPT_LOWPOWER is set, o_data and w_data both need to be
|
||||
// zero any time !o_valid or !r_valid respectively
|
||||
// {{{
|
||||
if (OPT_LOWPOWER)
|
||||
begin
|
||||
always @(*)
|
||||
if ((OPT_OUTREG || !i_reset) && !o_valid)
|
||||
assert(o_data == 0);
|
||||
|
||||
always @(*)
|
||||
if (o_ready)
|
||||
assert(w_data == 0);
|
||||
|
||||
end
|
||||
// }}}
|
||||
end endgenerate
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Cover checks
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
`ifdef SKIDBUFFER
|
||||
generate if (!OPT_PASSTHROUGH)
|
||||
begin
|
||||
reg f_changed_data;
|
||||
|
||||
initial f_changed_data = 0;
|
||||
always @(posedge i_clk)
|
||||
if (i_reset)
|
||||
f_changed_data <= 1;
|
||||
else if (i_valid && $past(!i_valid || o_ready))
|
||||
begin
|
||||
if (i_data != $past(i_data + 1))
|
||||
f_changed_data <= 0;
|
||||
end else if (!i_valid && i_data != 0)
|
||||
f_changed_data <= 0;
|
||||
|
||||
|
||||
`ifndef VERIFIC
|
||||
reg [3:0] cvr_steps, cvr_hold;
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (i_reset)
|
||||
begin
|
||||
cvr_steps <= 0;
|
||||
cvr_hold <= 0;
|
||||
end else begin
|
||||
cvr_steps <= cvr_steps + 1;
|
||||
cvr_hold <= cvr_hold + 1;
|
||||
case(cvr_steps)
|
||||
0: if (o_valid || i_valid)
|
||||
cvr_steps <= 0;
|
||||
1: if (!i_valid || !i_ready)
|
||||
cvr_steps <= 0;
|
||||
2: if (!i_valid || !i_ready)
|
||||
cvr_steps <= 0;
|
||||
3: if (!i_valid || !i_ready)
|
||||
cvr_steps <= 0;
|
||||
4: if (!i_valid || i_ready)
|
||||
cvr_steps <= 0;
|
||||
5: if (!i_valid || !i_ready)
|
||||
cvr_steps <= 0;
|
||||
6: if (!i_valid || !i_ready)
|
||||
cvr_steps <= 0;
|
||||
7: if (!i_valid || i_ready)
|
||||
cvr_steps <= 0;
|
||||
8: if (!i_valid || i_ready)
|
||||
cvr_steps <= 0;
|
||||
9: if (!i_valid || !i_ready)
|
||||
cvr_steps <= 0;
|
||||
10: if (!i_valid || !i_ready)
|
||||
cvr_steps <= 0;
|
||||
11: if (!i_valid || !i_ready)
|
||||
cvr_steps <= 0;
|
||||
12: begin
|
||||
cvr_steps <= cvr_steps;
|
||||
cover(!o_valid && !i_valid && f_changed_data);
|
||||
if (!o_valid || !i_ready)
|
||||
cvr_steps <= 0;
|
||||
else
|
||||
cvr_hold <= cvr_hold + 1;
|
||||
end
|
||||
default: assert(0);
|
||||
endcase
|
||||
end
|
||||
|
||||
`else
|
||||
// Cover test
|
||||
cover property (@(posedge i_clk)
|
||||
disable iff (i_reset)
|
||||
(!o_valid && !i_valid)
|
||||
##1 i_valid && i_ready [*3]
|
||||
##1 i_valid && !i_ready
|
||||
##1 i_valid && i_ready [*2]
|
||||
##1 i_valid && !i_ready [*2]
|
||||
##1 i_valid && i_ready [*3]
|
||||
// Wait for the design to clear
|
||||
##1 o_valid && i_ready [*0:5]
|
||||
##1 (!o_valid && !i_valid && f_changed_data));
|
||||
`endif
|
||||
end endgenerate
|
||||
`endif // SKIDBUFFER
|
||||
// }}}
|
||||
`endif
|
||||
// }}}
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,404 +1,404 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Filename: wbarbiter.v
|
||||
// {{{
|
||||
// Project: WB2AXIPSP: bus bridges and other odds and ends
|
||||
//
|
||||
// Purpose: This is a priority bus arbiter. It allows two separate wishbone
|
||||
// masters to connect to the same bus, while also guaranteeing
|
||||
// that the last master can have the bus with no delay any time it is
|
||||
// idle. The goal is to minimize the combinatorial logic required in this
|
||||
// process, while still minimizing access time.
|
||||
//
|
||||
// The core logic works like this:
|
||||
//
|
||||
// 1. If 'A' or 'B' asserts the o_cyc line, a bus cycle will begin,
|
||||
// with acccess granted to whomever requested it.
|
||||
// 2. If both 'A' and 'B' assert o_cyc at the same time, only 'A'
|
||||
// will be granted the bus. (If the alternating parameter
|
||||
// is set, A and B will alternate who gets the bus in
|
||||
// this case.)
|
||||
// 3. The bus will remain owned by whomever the bus was granted to
|
||||
// until they deassert the o_cyc line.
|
||||
// 4. At the end of a bus cycle, o_cyc is guaranteed to be
|
||||
// deasserted (low) for one clock.
|
||||
// 5. On the next clock, bus arbitration takes place again. If
|
||||
// 'A' requests the bus, no matter how long 'B' was
|
||||
// waiting, 'A' will then be granted the bus. (Unless
|
||||
// again the alternating parameter is set, then the
|
||||
// access is guaranteed to switch to B.)
|
||||
//
|
||||
//
|
||||
// Creator: Dan Gisselquist, Ph.D.
|
||||
// Gisselquist Technology, LLC
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// }}}
|
||||
// Copyright (C) 2015-2024, Gisselquist Technology, LLC
|
||||
// {{{
|
||||
// This file is part of the WB2AXIP project.
|
||||
//
|
||||
// The WB2AXIP project contains free software and gateware, licensed under the
|
||||
// Apache License, Version 2.0 (the "License"). You may not use this project,
|
||||
// or this file, except in compliance with the License. You may obtain a copy
|
||||
// of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
`default_nettype none
|
||||
//
|
||||
`define WBA_ALTERNATING
|
||||
// }}}
|
||||
module wbarbiter #(
|
||||
// {{{
|
||||
parameter DW=32, AW=32,
|
||||
parameter SCHEME="ALTERNATING",
|
||||
parameter [0:0] OPT_ZERO_ON_IDLE = 1'b0,
|
||||
parameter [31:0] F_MAX_STALL = 3,
|
||||
parameter [31:0] F_MAX_ACK_DELAY = 3,
|
||||
parameter [31:0] F_LGDEPTH=3
|
||||
// }}}
|
||||
) (
|
||||
// {{{
|
||||
input wire i_clk, i_reset,
|
||||
// Bus A
|
||||
// {{{
|
||||
input wire i_a_cyc, i_a_stb, i_a_we,
|
||||
input wire [(AW-1):0] i_a_adr,
|
||||
input wire [(DW-1):0] i_a_dat,
|
||||
input wire [(DW/8-1):0] i_a_sel,
|
||||
output wire o_a_ack, o_a_stall, o_a_err,
|
||||
// }}}
|
||||
// Bus B
|
||||
// {{{
|
||||
input wire i_b_cyc, i_b_stb, i_b_we,
|
||||
input wire [(AW-1):0] i_b_adr,
|
||||
input wire [(DW-1):0] i_b_dat,
|
||||
input wire [(DW/8-1):0] i_b_sel,
|
||||
output wire o_b_ack, o_b_stall, o_b_err,
|
||||
// }}}
|
||||
// Combined/arbitrated bus
|
||||
// {{{
|
||||
output wire o_cyc, o_stb, o_we,
|
||||
output wire [(AW-1):0] o_adr,
|
||||
output wire [(DW-1):0] o_dat,
|
||||
output wire [(DW/8-1):0] o_sel,
|
||||
input wire i_ack, i_stall, i_err
|
||||
// }}}
|
||||
`ifdef FORMAL
|
||||
// {{{
|
||||
,
|
||||
output wire [(F_LGDEPTH-1):0]
|
||||
f_nreqs, f_nacks, f_outstanding,
|
||||
f_a_nreqs, f_a_nacks, f_a_outstanding,
|
||||
f_b_nreqs, f_b_nacks, f_b_outstanding
|
||||
// }}}
|
||||
`endif
|
||||
// }}}
|
||||
);
|
||||
//
|
||||
|
||||
// Go high immediately (new cycle) if ...
|
||||
// Previous cycle was low and *someone* is requesting a bus cycle
|
||||
// Go low immadiately if ...
|
||||
// We were just high and the owner no longer wants the bus
|
||||
// WISHBONE Spec recommends no logic between a FF and the o_cyc
|
||||
// This violates that spec. (Rec 3.15, p35)
|
||||
reg r_a_owner;
|
||||
|
||||
assign o_cyc = (r_a_owner) ? i_a_cyc : i_b_cyc;
|
||||
initial r_a_owner = 1'b1;
|
||||
|
||||
generate if (SCHEME == "PRIORITY")
|
||||
begin : PRI
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (!i_b_cyc)
|
||||
r_a_owner <= 1'b1;
|
||||
// Allow B to set its CYC line w/o activating this
|
||||
// interface
|
||||
else if ((i_b_stb)&&(!i_a_cyc))
|
||||
r_a_owner <= 1'b0;
|
||||
|
||||
end else if (SCHEME == "ALTERNATING")
|
||||
begin : ALT
|
||||
|
||||
reg last_owner;
|
||||
initial last_owner = 1'b0;
|
||||
always @(posedge i_clk)
|
||||
if ((i_a_cyc)&&(r_a_owner))
|
||||
last_owner <= 1'b1;
|
||||
else if ((i_b_cyc)&&(!r_a_owner))
|
||||
last_owner <= 1'b0;
|
||||
|
||||
always @(posedge i_clk)
|
||||
if ((!i_a_cyc)&&(!i_b_cyc))
|
||||
r_a_owner <= !last_owner;
|
||||
else if ((r_a_owner)&&(!i_a_cyc))
|
||||
begin
|
||||
|
||||
if (i_b_stb)
|
||||
r_a_owner <= 1'b0;
|
||||
|
||||
end else if ((!r_a_owner)&&(!i_b_cyc))
|
||||
begin
|
||||
|
||||
if (i_a_stb)
|
||||
r_a_owner <= 1'b1;
|
||||
|
||||
end
|
||||
|
||||
end else // if (SCHEME == "LAST")
|
||||
begin : LST
|
||||
always @(posedge i_clk)
|
||||
if ((!i_a_cyc)&&(i_b_stb))
|
||||
r_a_owner <= 1'b0;
|
||||
else if ((!i_b_cyc)&&(i_a_stb))
|
||||
r_a_owner <= 1'b1;
|
||||
end endgenerate
|
||||
|
||||
|
||||
// Realistically, if neither master owns the bus, the output is a
|
||||
// don't care. Thus we trigger off whether or not 'A' owns the bus.
|
||||
// If 'B' owns it all we care is that 'A' does not. Likewise, if
|
||||
// neither owns the bus than the values on the various lines are
|
||||
// irrelevant.
|
||||
assign o_we = (r_a_owner) ? i_a_we : i_b_we;
|
||||
|
||||
generate if (OPT_ZERO_ON_IDLE)
|
||||
begin : ZERO_IDLE
|
||||
// {{{
|
||||
//
|
||||
// OPT_ZERO_ON_IDLE will use up more logic and may even slow
|
||||
// down the master clock if set. However, it may also reduce
|
||||
// the power used by the FPGA by preventing things from toggling
|
||||
// when the bus isn't in use. The option is here because it
|
||||
// also makes it a lot easier to look for when things happen
|
||||
// on the bus via VERILATOR when timing and logic counts
|
||||
// don't matter.
|
||||
//
|
||||
assign o_stb = (o_cyc)? ((r_a_owner) ? i_a_stb : i_b_stb):0;
|
||||
assign o_adr = (o_stb)? ((r_a_owner) ? i_a_adr : i_b_adr):0;
|
||||
assign o_dat = (o_stb)? ((r_a_owner) ? i_a_dat : i_b_dat):0;
|
||||
assign o_sel = (o_stb)? ((r_a_owner) ? i_a_sel : i_b_sel):0;
|
||||
assign o_a_ack = (o_cyc)&&( r_a_owner) ? i_ack : 1'b0;
|
||||
assign o_b_ack = (o_cyc)&&(!r_a_owner) ? i_ack : 1'b0;
|
||||
assign o_a_stall = (o_cyc)&&( r_a_owner) ? i_stall : 1'b1;
|
||||
assign o_b_stall = (o_cyc)&&(!r_a_owner) ? i_stall : 1'b1;
|
||||
assign o_a_err = (o_cyc)&&( r_a_owner) ? i_err : 1'b0;
|
||||
assign o_b_err = (o_cyc)&&(!r_a_owner) ? i_err : 1'b0;
|
||||
// }}}
|
||||
end else begin : LOW_LOGIC
|
||||
// {{{
|
||||
assign o_stb = (r_a_owner) ? i_a_stb : i_b_stb;
|
||||
assign o_adr = (r_a_owner) ? i_a_adr : i_b_adr;
|
||||
assign o_dat = (r_a_owner) ? i_a_dat : i_b_dat;
|
||||
assign o_sel = (r_a_owner) ? i_a_sel : i_b_sel;
|
||||
|
||||
// We cannot allow the return acknowledgement to ever go high if
|
||||
// the master in question does not own the bus. Hence we force
|
||||
// it low if the particular master doesn't own the bus.
|
||||
assign o_a_ack = ( r_a_owner) ? i_ack : 1'b0;
|
||||
assign o_b_ack = (!r_a_owner) ? i_ack : 1'b0;
|
||||
|
||||
// Stall must be asserted on the same cycle the input master
|
||||
// asserts the bus, if the bus isn't granted to him.
|
||||
assign o_a_stall = ( r_a_owner) ? i_stall : 1'b1;
|
||||
assign o_b_stall = (!r_a_owner) ? i_stall : 1'b1;
|
||||
|
||||
//
|
||||
//
|
||||
assign o_a_err = ( r_a_owner) ? i_err : 1'b0;
|
||||
assign o_b_err = (!r_a_owner) ? i_err : 1'b0;
|
||||
// }}}
|
||||
end endgenerate
|
||||
|
||||
// Make Verilator happy
|
||||
// {{{
|
||||
// verilator lint_off UNUSED
|
||||
wire unused;
|
||||
assign unused = &{ 1'b0, i_reset, F_LGDEPTH, F_MAX_STALL,
|
||||
F_MAX_ACK_DELAY };
|
||||
// verilator lint_on UNUSED
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Formal properties
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
`ifdef FORMAL
|
||||
|
||||
`ifdef WBARBITER
|
||||
|
||||
`define ASSUME assume
|
||||
`else
|
||||
`define ASSUME assert
|
||||
`endif
|
||||
reg f_prior_a_ack, f_prior_b_ack;
|
||||
|
||||
|
||||
reg f_past_valid;
|
||||
initial f_past_valid = 1'b0;
|
||||
always @(posedge i_clk)
|
||||
f_past_valid <= 1'b1;
|
||||
|
||||
initial `ASSUME(!i_a_cyc);
|
||||
initial `ASSUME(!i_a_stb);
|
||||
|
||||
initial `ASSUME(!i_b_cyc);
|
||||
initial `ASSUME(!i_b_stb);
|
||||
|
||||
initial `ASSUME(!i_ack);
|
||||
initial `ASSUME(!i_err);
|
||||
|
||||
always @(*)
|
||||
if (!f_past_valid)
|
||||
`ASSUME(i_reset);
|
||||
|
||||
always @(posedge i_clk)
|
||||
begin
|
||||
if (o_cyc)
|
||||
assert((i_a_cyc)||(i_b_cyc));
|
||||
if ((f_past_valid)&&($past(o_cyc))&&(o_cyc))
|
||||
assert($past(r_a_owner) == r_a_owner);
|
||||
end
|
||||
|
||||
fwb_master #(
|
||||
// {{{
|
||||
.DW(DW), .AW(AW),
|
||||
.F_MAX_STALL(F_MAX_STALL),
|
||||
.F_LGDEPTH(F_LGDEPTH),
|
||||
.F_MAX_ACK_DELAY(F_MAX_ACK_DELAY),
|
||||
.F_OPT_RMW_BUS_OPTION(1),
|
||||
.F_OPT_DISCONTINUOUS(1)
|
||||
// }}}
|
||||
) f_wbm(
|
||||
// {{{
|
||||
i_clk, i_reset,
|
||||
o_cyc, o_stb, o_we, o_adr, o_dat, o_sel,
|
||||
i_ack, i_stall, 32'h0, i_err,
|
||||
f_nreqs, f_nacks, f_outstanding
|
||||
// }}}
|
||||
);
|
||||
|
||||
fwb_slave #(
|
||||
// {{{
|
||||
.DW(DW), .AW(AW),
|
||||
.F_MAX_STALL(0),
|
||||
.F_LGDEPTH(F_LGDEPTH),
|
||||
.F_MAX_ACK_DELAY(0),
|
||||
.F_OPT_RMW_BUS_OPTION(1),
|
||||
.F_OPT_DISCONTINUOUS(1)
|
||||
// }}}
|
||||
) f_wba(
|
||||
// {{{
|
||||
i_clk, i_reset,
|
||||
i_a_cyc, i_a_stb, i_a_we, i_a_adr, i_a_dat, i_a_sel,
|
||||
o_a_ack, o_a_stall, 32'h0, o_a_err,
|
||||
f_a_nreqs, f_a_nacks, f_a_outstanding
|
||||
// }}}
|
||||
);
|
||||
|
||||
fwb_slave #(
|
||||
// {{{
|
||||
.DW(DW), .AW(AW),
|
||||
.F_MAX_STALL(0),
|
||||
.F_LGDEPTH(F_LGDEPTH),
|
||||
.F_MAX_ACK_DELAY(0),
|
||||
.F_OPT_RMW_BUS_OPTION(1),
|
||||
.F_OPT_DISCONTINUOUS(1)
|
||||
// }}}
|
||||
) f_wbb(
|
||||
// {{{
|
||||
i_clk, i_reset,
|
||||
i_b_cyc, i_b_stb, i_b_we, i_b_adr, i_b_dat, i_b_sel,
|
||||
o_b_ack, o_b_stall, 32'h0, o_b_err,
|
||||
f_b_nreqs, f_b_nacks, f_b_outstanding
|
||||
// }}}
|
||||
);
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (r_a_owner)
|
||||
begin
|
||||
assert(f_b_nreqs == 0);
|
||||
assert(f_b_nacks == 0);
|
||||
assert(f_a_outstanding == f_outstanding);
|
||||
end else begin
|
||||
assert(f_a_nreqs == 0);
|
||||
assert(f_a_nacks == 0);
|
||||
assert(f_b_outstanding == f_outstanding);
|
||||
end
|
||||
|
||||
always @(posedge i_clk)
|
||||
if ((f_past_valid)&&(!$past(i_reset))
|
||||
&&($past(i_a_stb))&&(!$past(i_b_cyc)))
|
||||
assert(r_a_owner);
|
||||
|
||||
always @(posedge i_clk)
|
||||
if ((f_past_valid)&&(!$past(i_reset))
|
||||
&&(!$past(i_a_cyc))&&($past(i_b_stb)))
|
||||
assert(!r_a_owner);
|
||||
|
||||
always @(posedge i_clk)
|
||||
if ((f_past_valid)&&(r_a_owner != $past(r_a_owner)))
|
||||
assert(!$past(o_cyc));
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Cover checks
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
initial f_prior_a_ack = 1'b0;
|
||||
always @(posedge i_clk)
|
||||
if ((i_reset)||(o_a_err)||(o_b_err))
|
||||
f_prior_a_ack <= 1'b0;
|
||||
else if ((o_cyc)&&(o_a_ack))
|
||||
f_prior_a_ack <= 1'b1;
|
||||
|
||||
initial f_prior_b_ack = 1'b0;
|
||||
always @(posedge i_clk)
|
||||
if ((i_reset)||(o_a_err)||(o_b_err))
|
||||
f_prior_b_ack <= 1'b0;
|
||||
else if ((o_cyc)&&(o_b_ack))
|
||||
f_prior_b_ack <= 1'b1;
|
||||
|
||||
always @(posedge i_clk)
|
||||
begin
|
||||
cover(f_prior_b_ack && o_cyc && o_a_ack);
|
||||
|
||||
cover((o_cyc && o_a_ack)
|
||||
&&($past(o_cyc && o_a_ack))
|
||||
&&($past(o_cyc && o_a_ack,2)));
|
||||
|
||||
|
||||
cover(f_prior_a_ack && o_cyc && o_b_ack);
|
||||
|
||||
cover((o_cyc && o_b_ack)
|
||||
&&($past(o_cyc && o_b_ack))
|
||||
&&($past(o_cyc && o_b_ack,2)));
|
||||
end
|
||||
|
||||
always @(*)
|
||||
cover(o_cyc && o_b_ack);
|
||||
// }}}
|
||||
// }}}
|
||||
`endif
|
||||
endmodule
|
||||
`ifndef YOSYS
|
||||
`default_nettype wire
|
||||
`endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Filename: wbarbiter.v
|
||||
// {{{
|
||||
// Project: WB2AXIPSP: bus bridges and other odds and ends
|
||||
//
|
||||
// Purpose: This is a priority bus arbiter. It allows two separate wishbone
|
||||
// masters to connect to the same bus, while also guaranteeing
|
||||
// that the last master can have the bus with no delay any time it is
|
||||
// idle. The goal is to minimize the combinatorial logic required in this
|
||||
// process, while still minimizing access time.
|
||||
//
|
||||
// The core logic works like this:
|
||||
//
|
||||
// 1. If 'A' or 'B' asserts the o_cyc line, a bus cycle will begin,
|
||||
// with acccess granted to whomever requested it.
|
||||
// 2. If both 'A' and 'B' assert o_cyc at the same time, only 'A'
|
||||
// will be granted the bus. (If the alternating parameter
|
||||
// is set, A and B will alternate who gets the bus in
|
||||
// this case.)
|
||||
// 3. The bus will remain owned by whomever the bus was granted to
|
||||
// until they deassert the o_cyc line.
|
||||
// 4. At the end of a bus cycle, o_cyc is guaranteed to be
|
||||
// deasserted (low) for one clock.
|
||||
// 5. On the next clock, bus arbitration takes place again. If
|
||||
// 'A' requests the bus, no matter how long 'B' was
|
||||
// waiting, 'A' will then be granted the bus. (Unless
|
||||
// again the alternating parameter is set, then the
|
||||
// access is guaranteed to switch to B.)
|
||||
//
|
||||
//
|
||||
// Creator: Dan Gisselquist, Ph.D.
|
||||
// Gisselquist Technology, LLC
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// }}}
|
||||
// Copyright (C) 2015-2024, Gisselquist Technology, LLC
|
||||
// {{{
|
||||
// This file is part of the WB2AXIP project.
|
||||
//
|
||||
// The WB2AXIP project contains free software and gateware, licensed under the
|
||||
// Apache License, Version 2.0 (the "License"). You may not use this project,
|
||||
// or this file, except in compliance with the License. You may obtain a copy
|
||||
// of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
`default_nettype none
|
||||
//
|
||||
`define WBA_ALTERNATING
|
||||
// }}}
|
||||
module wbarbiter #(
|
||||
// {{{
|
||||
parameter DW=32, AW=32,
|
||||
parameter SCHEME="ALTERNATING",
|
||||
parameter [0:0] OPT_ZERO_ON_IDLE = 1'b0,
|
||||
parameter [31:0] F_MAX_STALL = 3,
|
||||
parameter [31:0] F_MAX_ACK_DELAY = 3,
|
||||
parameter [31:0] F_LGDEPTH=3
|
||||
// }}}
|
||||
) (
|
||||
// {{{
|
||||
input wire i_clk, i_reset,
|
||||
// Bus A
|
||||
// {{{
|
||||
input wire i_a_cyc, i_a_stb, i_a_we,
|
||||
input wire [(AW-1):0] i_a_adr,
|
||||
input wire [(DW-1):0] i_a_dat,
|
||||
input wire [(DW/8-1):0] i_a_sel,
|
||||
output wire o_a_ack, o_a_stall, o_a_err,
|
||||
// }}}
|
||||
// Bus B
|
||||
// {{{
|
||||
input wire i_b_cyc, i_b_stb, i_b_we,
|
||||
input wire [(AW-1):0] i_b_adr,
|
||||
input wire [(DW-1):0] i_b_dat,
|
||||
input wire [(DW/8-1):0] i_b_sel,
|
||||
output wire o_b_ack, o_b_stall, o_b_err,
|
||||
// }}}
|
||||
// Combined/arbitrated bus
|
||||
// {{{
|
||||
output wire o_cyc, o_stb, o_we,
|
||||
output wire [(AW-1):0] o_adr,
|
||||
output wire [(DW-1):0] o_dat,
|
||||
output wire [(DW/8-1):0] o_sel,
|
||||
input wire i_ack, i_stall, i_err
|
||||
// }}}
|
||||
`ifdef FORMAL
|
||||
// {{{
|
||||
,
|
||||
output wire [(F_LGDEPTH-1):0]
|
||||
f_nreqs, f_nacks, f_outstanding,
|
||||
f_a_nreqs, f_a_nacks, f_a_outstanding,
|
||||
f_b_nreqs, f_b_nacks, f_b_outstanding
|
||||
// }}}
|
||||
`endif
|
||||
// }}}
|
||||
);
|
||||
//
|
||||
|
||||
// Go high immediately (new cycle) if ...
|
||||
// Previous cycle was low and *someone* is requesting a bus cycle
|
||||
// Go low immadiately if ...
|
||||
// We were just high and the owner no longer wants the bus
|
||||
// WISHBONE Spec recommends no logic between a FF and the o_cyc
|
||||
// This violates that spec. (Rec 3.15, p35)
|
||||
reg r_a_owner;
|
||||
|
||||
assign o_cyc = (r_a_owner) ? i_a_cyc : i_b_cyc;
|
||||
initial r_a_owner = 1'b1;
|
||||
|
||||
generate if (SCHEME == "PRIORITY")
|
||||
begin : PRI
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (!i_b_cyc)
|
||||
r_a_owner <= 1'b1;
|
||||
// Allow B to set its CYC line w/o activating this
|
||||
// interface
|
||||
else if ((i_b_stb)&&(!i_a_cyc))
|
||||
r_a_owner <= 1'b0;
|
||||
|
||||
end else if (SCHEME == "ALTERNATING")
|
||||
begin : ALT
|
||||
|
||||
reg last_owner;
|
||||
initial last_owner = 1'b0;
|
||||
always @(posedge i_clk)
|
||||
if ((i_a_cyc)&&(r_a_owner))
|
||||
last_owner <= 1'b1;
|
||||
else if ((i_b_cyc)&&(!r_a_owner))
|
||||
last_owner <= 1'b0;
|
||||
|
||||
always @(posedge i_clk)
|
||||
if ((!i_a_cyc)&&(!i_b_cyc))
|
||||
r_a_owner <= !last_owner;
|
||||
else if ((r_a_owner)&&(!i_a_cyc))
|
||||
begin
|
||||
|
||||
if (i_b_stb)
|
||||
r_a_owner <= 1'b0;
|
||||
|
||||
end else if ((!r_a_owner)&&(!i_b_cyc))
|
||||
begin
|
||||
|
||||
if (i_a_stb)
|
||||
r_a_owner <= 1'b1;
|
||||
|
||||
end
|
||||
|
||||
end else // if (SCHEME == "LAST")
|
||||
begin : LST
|
||||
always @(posedge i_clk)
|
||||
if ((!i_a_cyc)&&(i_b_stb))
|
||||
r_a_owner <= 1'b0;
|
||||
else if ((!i_b_cyc)&&(i_a_stb))
|
||||
r_a_owner <= 1'b1;
|
||||
end endgenerate
|
||||
|
||||
|
||||
// Realistically, if neither master owns the bus, the output is a
|
||||
// don't care. Thus we trigger off whether or not 'A' owns the bus.
|
||||
// If 'B' owns it all we care is that 'A' does not. Likewise, if
|
||||
// neither owns the bus than the values on the various lines are
|
||||
// irrelevant.
|
||||
assign o_we = (r_a_owner) ? i_a_we : i_b_we;
|
||||
|
||||
generate if (OPT_ZERO_ON_IDLE)
|
||||
begin : ZERO_IDLE
|
||||
// {{{
|
||||
//
|
||||
// OPT_ZERO_ON_IDLE will use up more logic and may even slow
|
||||
// down the master clock if set. However, it may also reduce
|
||||
// the power used by the FPGA by preventing things from toggling
|
||||
// when the bus isn't in use. The option is here because it
|
||||
// also makes it a lot easier to look for when things happen
|
||||
// on the bus via VERILATOR when timing and logic counts
|
||||
// don't matter.
|
||||
//
|
||||
assign o_stb = (o_cyc)? ((r_a_owner) ? i_a_stb : i_b_stb):0;
|
||||
assign o_adr = (o_stb)? ((r_a_owner) ? i_a_adr : i_b_adr):0;
|
||||
assign o_dat = (o_stb)? ((r_a_owner) ? i_a_dat : i_b_dat):0;
|
||||
assign o_sel = (o_stb)? ((r_a_owner) ? i_a_sel : i_b_sel):0;
|
||||
assign o_a_ack = (o_cyc)&&( r_a_owner) ? i_ack : 1'b0;
|
||||
assign o_b_ack = (o_cyc)&&(!r_a_owner) ? i_ack : 1'b0;
|
||||
assign o_a_stall = (o_cyc)&&( r_a_owner) ? i_stall : 1'b1;
|
||||
assign o_b_stall = (o_cyc)&&(!r_a_owner) ? i_stall : 1'b1;
|
||||
assign o_a_err = (o_cyc)&&( r_a_owner) ? i_err : 1'b0;
|
||||
assign o_b_err = (o_cyc)&&(!r_a_owner) ? i_err : 1'b0;
|
||||
// }}}
|
||||
end else begin : LOW_LOGIC
|
||||
// {{{
|
||||
assign o_stb = (r_a_owner) ? i_a_stb : i_b_stb;
|
||||
assign o_adr = (r_a_owner) ? i_a_adr : i_b_adr;
|
||||
assign o_dat = (r_a_owner) ? i_a_dat : i_b_dat;
|
||||
assign o_sel = (r_a_owner) ? i_a_sel : i_b_sel;
|
||||
|
||||
// We cannot allow the return acknowledgement to ever go high if
|
||||
// the master in question does not own the bus. Hence we force
|
||||
// it low if the particular master doesn't own the bus.
|
||||
assign o_a_ack = ( r_a_owner) ? i_ack : 1'b0;
|
||||
assign o_b_ack = (!r_a_owner) ? i_ack : 1'b0;
|
||||
|
||||
// Stall must be asserted on the same cycle the input master
|
||||
// asserts the bus, if the bus isn't granted to him.
|
||||
assign o_a_stall = ( r_a_owner) ? i_stall : 1'b1;
|
||||
assign o_b_stall = (!r_a_owner) ? i_stall : 1'b1;
|
||||
|
||||
//
|
||||
//
|
||||
assign o_a_err = ( r_a_owner) ? i_err : 1'b0;
|
||||
assign o_b_err = (!r_a_owner) ? i_err : 1'b0;
|
||||
// }}}
|
||||
end endgenerate
|
||||
|
||||
// Make Verilator happy
|
||||
// {{{
|
||||
// verilator lint_off UNUSED
|
||||
wire unused;
|
||||
assign unused = &{ 1'b0, i_reset, F_LGDEPTH, F_MAX_STALL,
|
||||
F_MAX_ACK_DELAY };
|
||||
// verilator lint_on UNUSED
|
||||
// }}}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Formal properties
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
`ifdef FORMAL
|
||||
|
||||
`ifdef WBARBITER
|
||||
|
||||
`define ASSUME assume
|
||||
`else
|
||||
`define ASSUME assert
|
||||
`endif
|
||||
reg f_prior_a_ack, f_prior_b_ack;
|
||||
|
||||
|
||||
reg f_past_valid;
|
||||
initial f_past_valid = 1'b0;
|
||||
always @(posedge i_clk)
|
||||
f_past_valid <= 1'b1;
|
||||
|
||||
initial `ASSUME(!i_a_cyc);
|
||||
initial `ASSUME(!i_a_stb);
|
||||
|
||||
initial `ASSUME(!i_b_cyc);
|
||||
initial `ASSUME(!i_b_stb);
|
||||
|
||||
initial `ASSUME(!i_ack);
|
||||
initial `ASSUME(!i_err);
|
||||
|
||||
always @(*)
|
||||
if (!f_past_valid)
|
||||
`ASSUME(i_reset);
|
||||
|
||||
always @(posedge i_clk)
|
||||
begin
|
||||
if (o_cyc)
|
||||
assert((i_a_cyc)||(i_b_cyc));
|
||||
if ((f_past_valid)&&($past(o_cyc))&&(o_cyc))
|
||||
assert($past(r_a_owner) == r_a_owner);
|
||||
end
|
||||
|
||||
fwb_master #(
|
||||
// {{{
|
||||
.DW(DW), .AW(AW),
|
||||
.F_MAX_STALL(F_MAX_STALL),
|
||||
.F_LGDEPTH(F_LGDEPTH),
|
||||
.F_MAX_ACK_DELAY(F_MAX_ACK_DELAY),
|
||||
.F_OPT_RMW_BUS_OPTION(1),
|
||||
.F_OPT_DISCONTINUOUS(1)
|
||||
// }}}
|
||||
) f_wbm(
|
||||
// {{{
|
||||
i_clk, i_reset,
|
||||
o_cyc, o_stb, o_we, o_adr, o_dat, o_sel,
|
||||
i_ack, i_stall, 32'h0, i_err,
|
||||
f_nreqs, f_nacks, f_outstanding
|
||||
// }}}
|
||||
);
|
||||
|
||||
fwb_slave #(
|
||||
// {{{
|
||||
.DW(DW), .AW(AW),
|
||||
.F_MAX_STALL(0),
|
||||
.F_LGDEPTH(F_LGDEPTH),
|
||||
.F_MAX_ACK_DELAY(0),
|
||||
.F_OPT_RMW_BUS_OPTION(1),
|
||||
.F_OPT_DISCONTINUOUS(1)
|
||||
// }}}
|
||||
) f_wba(
|
||||
// {{{
|
||||
i_clk, i_reset,
|
||||
i_a_cyc, i_a_stb, i_a_we, i_a_adr, i_a_dat, i_a_sel,
|
||||
o_a_ack, o_a_stall, 32'h0, o_a_err,
|
||||
f_a_nreqs, f_a_nacks, f_a_outstanding
|
||||
// }}}
|
||||
);
|
||||
|
||||
fwb_slave #(
|
||||
// {{{
|
||||
.DW(DW), .AW(AW),
|
||||
.F_MAX_STALL(0),
|
||||
.F_LGDEPTH(F_LGDEPTH),
|
||||
.F_MAX_ACK_DELAY(0),
|
||||
.F_OPT_RMW_BUS_OPTION(1),
|
||||
.F_OPT_DISCONTINUOUS(1)
|
||||
// }}}
|
||||
) f_wbb(
|
||||
// {{{
|
||||
i_clk, i_reset,
|
||||
i_b_cyc, i_b_stb, i_b_we, i_b_adr, i_b_dat, i_b_sel,
|
||||
o_b_ack, o_b_stall, 32'h0, o_b_err,
|
||||
f_b_nreqs, f_b_nacks, f_b_outstanding
|
||||
// }}}
|
||||
);
|
||||
|
||||
always @(posedge i_clk)
|
||||
if (r_a_owner)
|
||||
begin
|
||||
assert(f_b_nreqs == 0);
|
||||
assert(f_b_nacks == 0);
|
||||
assert(f_a_outstanding == f_outstanding);
|
||||
end else begin
|
||||
assert(f_a_nreqs == 0);
|
||||
assert(f_a_nacks == 0);
|
||||
assert(f_b_outstanding == f_outstanding);
|
||||
end
|
||||
|
||||
always @(posedge i_clk)
|
||||
if ((f_past_valid)&&(!$past(i_reset))
|
||||
&&($past(i_a_stb))&&(!$past(i_b_cyc)))
|
||||
assert(r_a_owner);
|
||||
|
||||
always @(posedge i_clk)
|
||||
if ((f_past_valid)&&(!$past(i_reset))
|
||||
&&(!$past(i_a_cyc))&&($past(i_b_stb)))
|
||||
assert(!r_a_owner);
|
||||
|
||||
always @(posedge i_clk)
|
||||
if ((f_past_valid)&&(r_a_owner != $past(r_a_owner)))
|
||||
assert(!$past(o_cyc));
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Cover checks
|
||||
// {{{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
initial f_prior_a_ack = 1'b0;
|
||||
always @(posedge i_clk)
|
||||
if ((i_reset)||(o_a_err)||(o_b_err))
|
||||
f_prior_a_ack <= 1'b0;
|
||||
else if ((o_cyc)&&(o_a_ack))
|
||||
f_prior_a_ack <= 1'b1;
|
||||
|
||||
initial f_prior_b_ack = 1'b0;
|
||||
always @(posedge i_clk)
|
||||
if ((i_reset)||(o_a_err)||(o_b_err))
|
||||
f_prior_b_ack <= 1'b0;
|
||||
else if ((o_cyc)&&(o_b_ack))
|
||||
f_prior_b_ack <= 1'b1;
|
||||
|
||||
always @(posedge i_clk)
|
||||
begin
|
||||
cover(f_prior_b_ack && o_cyc && o_a_ack);
|
||||
|
||||
cover((o_cyc && o_a_ack)
|
||||
&&($past(o_cyc && o_a_ack))
|
||||
&&($past(o_cyc && o_a_ack,2)));
|
||||
|
||||
|
||||
cover(f_prior_a_ack && o_cyc && o_b_ack);
|
||||
|
||||
cover((o_cyc && o_b_ack)
|
||||
&&($past(o_cyc && o_b_ack))
|
||||
&&($past(o_cyc && o_b_ack,2)));
|
||||
end
|
||||
|
||||
always @(*)
|
||||
cover(o_cyc && o_b_ack);
|
||||
// }}}
|
||||
// }}}
|
||||
`endif
|
||||
endmodule
|
||||
`ifndef YOSYS
|
||||
`default_nettype wire
|
||||
`endif
|
||||
|
|
|
|||
10080
rtl/ddr3_controller.v
10080
rtl/ddr3_controller.v
File diff suppressed because it is too large
Load Diff
2430
rtl/ddr3_phy.v
2430
rtl/ddr3_phy.v
File diff suppressed because it is too large
Load Diff
727
rtl/ddr3_top.v
727
rtl/ddr3_top.v
|
|
@ -1,376 +1,351 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Filename: ddr3_top.v
|
||||
// Project: UberDDR3 - An Open Source DDR3 Controller
|
||||
//
|
||||
// Purpose: Top module which instantiates the ddr3_controller and ddr3_phy modules
|
||||
// Use this as top module for instantiating UberDDR3 with Wishbone Interface.
|
||||
//
|
||||
// Engineer: Angelo C. Jacobo
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2023-2024 Angelo Jacobo
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`default_nettype none
|
||||
`timescale 1ps / 1ps
|
||||
|
||||
module ddr3_top #(
|
||||
parameter CONTROLLER_CLK_PERIOD = 12_000, //ps, clock period of the controller interface
|
||||
DDR3_CLK_PERIOD = 3_000, //ps, clock period of the DDR3 RAM device (must be 1/4 of the CONTROLLER_CLK_PERIOD)
|
||||
ROW_BITS = 14, //width of row address
|
||||
COL_BITS = 10, //width of column address
|
||||
BA_BITS = 3, //width of bank address
|
||||
BYTE_LANES = 2, //number of byte lanes of DDR3 RAM
|
||||
AUX_WIDTH = 4, //width of aux line (must be >= 4)
|
||||
WB2_ADDR_BITS = 7, //width of 2nd wishbone address bus
|
||||
WB2_DATA_BITS = 32, //width of 2nd wishbone data bus
|
||||
parameter[0:0] MICRON_SIM = 0, //enable faster simulation for micron ddr3 model (shorten POWER_ON_RESET_HIGH and INITIAL_CKE_LOW)
|
||||
ODELAY_SUPPORTED = 0, //set to 1 when ODELAYE2 is supported
|
||||
SECOND_WISHBONE = 0, //set to 1 if 2nd wishbone for debugging is needed
|
||||
WB_ERROR = 0, // set to 1 to support Wishbone error (asserts at ECC double bit error)
|
||||
SKIP_INTERNAL_TEST = 0, // skip built-in self test (would require >2 seconds of internal test right after calibration)
|
||||
parameter[1:0] ECC_ENABLE = 0, // set to 1 or 2 to add ECC (1 = Side-band ECC per burst, 2 = Side-band ECC per 8 bursts , 3 = Inline ECC )
|
||||
parameter[1:0] DIC = 2'b00, //Output Driver Impedance Control (2'b00 = RZQ/6, 2'b01 = RZQ/7, RZQ = 240ohms) (only change when you know what you are doing)
|
||||
parameter[2:0] RTT_NOM = 3'b011, //RTT Nominal (3'b000 = disabled, 3'b001 = RZQ/4, 3'b010 = RZQ/2 , 3'b011 = RZQ/6, RZQ = 240ohms) (only change when you know what you are doing)
|
||||
parameter[1:0] SELF_REFRESH = 2'b00, // 0 = use i_user_self_refresh input, 1 = Self-refresh mode is enabled after 64 controller clock cycles of no requests, 2 = 128 cycles, 3 = 256 cycles
|
||||
parameter // The next parameters act more like a localparam (since user does not have to set this manually) but was added here to simplify port declaration
|
||||
DQ_BITS = 8, //device width (fixed to 8, if DDR3 is x16 then BYTE_LANES will be 2 while )
|
||||
serdes_ratio = 4, // this controller is fixed as a 4:1 memory controller (CONTROLLER_CLK_PERIOD/DDR3_CLK_PERIOD = 4)
|
||||
wb_addr_bits = ROW_BITS + COL_BITS + BA_BITS - $clog2(serdes_ratio*2),
|
||||
wb_data_bits = DQ_BITS*BYTE_LANES*serdes_ratio*2,
|
||||
wb_sel_bits = wb_data_bits / 8,
|
||||
wb2_sel_bits = WB2_DATA_BITS / 8,
|
||||
//4 is the width of a single ddr3 command {cs_n, ras_n, cas_n, we_n} plus 3 (ck_en, odt, reset_n) plus bank bits plus row bits
|
||||
cmd_len = 4 + 3 + BA_BITS + ROW_BITS
|
||||
)
|
||||
(
|
||||
input wire i_controller_clk, i_ddr3_clk, i_ref_clk, //i_controller_clk = CONTROLLER_CLK_PERIOD, i_ddr3_clk = DDR3_CLK_PERIOD, i_ref_clk = 200MHz
|
||||
input wire i_ddr3_clk_90, //required only when ODELAY_SUPPORTED is zero
|
||||
input wire i_rst_n,
|
||||
//
|
||||
// Wishbone inputs
|
||||
input wire i_wb_cyc, //bus cycle active (1 = normal operation, 0 = all ongoing transaction are to be cancelled)
|
||||
input wire i_wb_stb, //request a transfer
|
||||
input wire i_wb_we, //write-enable (1 = write, 0 = read)
|
||||
input wire[wb_addr_bits - 1:0] i_wb_addr, //burst-addressable {row,bank,col}
|
||||
input wire[wb_data_bits - 1:0] i_wb_data, //write data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
input wire[wb_sel_bits - 1:0] i_wb_sel, //byte strobe for write (1 = write the byte)
|
||||
input wire[AUX_WIDTH - 1:0] i_aux, //for AXI-interface compatibility (given upon strobe)
|
||||
// Wishbone outputs
|
||||
output wire o_wb_stall, //1 = busy, cannot accept requests
|
||||
output wire o_wb_ack, //1 = read/write request has completed
|
||||
output wire o_wb_err, //1 = Error due to ECC double bit error (fixed to 0 if WB_ERROR = 0)
|
||||
output wire[wb_data_bits - 1:0] o_wb_data, //read data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
output wire[AUX_WIDTH - 1:0] o_aux, //for AXI-interface compatibility (given upon strobe)
|
||||
//
|
||||
// Wishbone 2 (PHY) inputs
|
||||
input wire i_wb2_cyc, //bus cycle active (1 = normal operation, 0 = all ongoing transaction are to be cancelled)
|
||||
input wire i_wb2_stb, //request a transfer
|
||||
input wire i_wb2_we, //write-enable (1 = write, 0 = read)
|
||||
input wire[WB2_ADDR_BITS - 1:0] i_wb2_addr, // memory-mapped register to be accessed
|
||||
input wire[WB2_DATA_BITS - 1:0] i_wb2_data, //write data
|
||||
input wire[wb2_sel_bits - 1:0] i_wb2_sel, //byte strobe for write (1 = write the byte)
|
||||
// Wishbone 2 (Controller) outputs
|
||||
output wire o_wb2_stall, //1 = busy, cannot accept requests
|
||||
output wire o_wb2_ack, //1 = read/write request has completed
|
||||
output wire[WB2_DATA_BITS - 1:0] o_wb2_data, //read data
|
||||
//
|
||||
// DDR3 I/O Interface
|
||||
output wire o_ddr3_clk_p, o_ddr3_clk_n,
|
||||
output wire o_ddr3_reset_n,
|
||||
output wire o_ddr3_cke, // CKE
|
||||
output wire o_ddr3_cs_n, // chip select signal
|
||||
output wire o_ddr3_ras_n, // RAS#
|
||||
output wire o_ddr3_cas_n, // CAS#
|
||||
output wire o_ddr3_we_n, // WE#
|
||||
output wire[ROW_BITS-1:0] o_ddr3_addr,
|
||||
output wire[BA_BITS-1:0] o_ddr3_ba_addr,
|
||||
inout wire[(DQ_BITS*BYTE_LANES)-1:0] io_ddr3_dq,
|
||||
inout wire[BYTE_LANES-1:0] io_ddr3_dqs, io_ddr3_dqs_n,
|
||||
output wire[BYTE_LANES-1:0] o_ddr3_dm,
|
||||
output wire o_ddr3_odt, // on-die termination
|
||||
//
|
||||
// Done Calibration pin
|
||||
output wire o_calib_complete,
|
||||
// Debug outputs
|
||||
output wire[31:0] o_debug1,
|
||||
// output wire[31:0] o_debug2,
|
||||
// output wire[31:0] o_debug3,
|
||||
// output wire[(DQ_BITS*BYTE_LANES)/8-1:0] o_ddr3_debug_read_dqs_p,
|
||||
// output wire[(DQ_BITS*BYTE_LANES)/8-1:0] o_ddr3_debug_read_dqs_n
|
||||
//
|
||||
// User enabled self-refresh
|
||||
input wire i_user_self_refresh
|
||||
);
|
||||
|
||||
// Instantiation Template (DEFAULT VALUE IS FOR ARTY S7)
|
||||
/*
|
||||
// DDR3 Controller
|
||||
ddr3_top #(
|
||||
.CONTROLLER_CLK_PERIOD(12_000), //ps, clock period of the controller interface
|
||||
.DDR3_CLK_PERIOD(3_000), //ps, clock period of the DDR3 RAM device (must be 1/4 of the CONTROLLER_CLK_PERIOD)
|
||||
.ROW_BITS(14), //width of row address
|
||||
.COL_BITS(10), //width of column address
|
||||
.BA_BITS(3), //width of bank address
|
||||
.BYTE_LANES(2), //number of byte lanes of DDR3 RAM
|
||||
.AUX_WIDTH(4), //width of aux line (must be >= 4)
|
||||
.MICRON_SIM(0), //enable faster simulation for micron ddr3 model (shorten POWER_ON_RESET_HIGH and INITIAL_CKE_LOW)
|
||||
.ODELAY_SUPPORTED(0), //set to 1 if ODELAYE2 is supported
|
||||
.SECOND_WISHBONE(0), //set to 1 if 2nd wishbone for debugging is needed
|
||||
.ECC_ENABLE(0), // set to 1 or 2 to add ECC (1 = Side-band ECC per burst, 2 = Side-band ECC per 8 bursts , 3 = Inline ECC )
|
||||
.WB_ERROR(0), // set to 1 to support Wishbone error (asserts at ECC double bit error)
|
||||
) ddr3_top
|
||||
(
|
||||
//clock and reset
|
||||
.i_controller_clk(i_controller_clk),
|
||||
.i_ddr3_clk(i_ddr3_clk), //i_controller_clk has period of CONTROLLER_CLK_PERIOD, i_ddr3_clk has period of DDR3_CLK_PERIOD
|
||||
.i_ref_clk(i_ref_clk), // usually set to 200 MHz
|
||||
.i_ddr3_clk_90(i_ddr3_clk_90), //90 degree phase shifted version i_ddr3_clk (required only when ODELAY_SUPPORTED is zero)
|
||||
.i_rst_n(!i_rst && clk_locked),
|
||||
//
|
||||
// Wishbone inputs
|
||||
.i_wb_cyc(1), //bus cycle active (1 = normal operation, 0 = all ongoing transaction are to be cancelled)
|
||||
.i_wb_stb(i_wb_stb), //request a transfer
|
||||
.i_wb_we(i_wb_we), //write-enable (1 = write, 0 = read)
|
||||
.i_wb_addr(i_wb_addr), //burst-addressable {row,bank,col}
|
||||
.i_wb_data(i_wb_data), //write data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
.i_wb_sel(16'hffff), //byte strobe for write (1 = write the byte)
|
||||
.i_aux(i_wb_we), //for AXI-interface compatibility (given upon strobe)
|
||||
// Wishbone outputs
|
||||
.o_wb_stall(o_wb_stall), //1 = busy, cannot accept requests
|
||||
.o_wb_ack(o_wb_ack), //1 = read/write request has completed
|
||||
.o_wb_err(o_wb_err), //1 = Error due to ECC double bit error (fixed to 0 if WB_ERROR = 0)
|
||||
.o_wb_data(o_wb_data), //read data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
.o_aux(o_aux),
|
||||
//
|
||||
// Wishbone 2 (PHY) inputs
|
||||
.i_wb2_cyc(0), //bus cycle active (1 = normal operation, 0 = all ongoing transaction are to be cancelled)
|
||||
.i_wb2_stb(0), //request a transfer
|
||||
.i_wb2_we(0), //write-enable (1 = write, 0 = read)
|
||||
.i_wb2_addr(0), //burst-addressable {row,bank,col}
|
||||
.i_wb2_data(0), //write data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
.i_wb2_sel(0), //byte strobe for write (1 = write the byte)
|
||||
// Wishbone 2 (Controller) outputs
|
||||
.o_wb2_stall(), //1 = busy, cannot accept requests
|
||||
.o_wb2_ack(), //1 = read/write request has completed
|
||||
.o_wb2_data(), //read data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
//
|
||||
// DDR3 I/O Interface
|
||||
.o_ddr3_clk_p(ddr3_clk_p),
|
||||
.o_ddr3_clk_n(ddr3_clk_n),
|
||||
.o_ddr3_reset_n(ddr3_reset_n),
|
||||
.o_ddr3_cke(ddr3_cke),
|
||||
.o_ddr3_cs_n(ddr3_cs_n), // width = number of DDR3 ranks
|
||||
.o_ddr3_ras_n(ddr3_ras_n),
|
||||
.o_ddr3_cas_n(ddr3_cas_n),
|
||||
.o_ddr3_we_n(ddr3_we_n),
|
||||
.o_ddr3_addr(ddr3_addr), // width = ROW_BITS
|
||||
.o_ddr3_ba_addr(ddr3_ba), // width = BA_BITS
|
||||
.io_ddr3_dq(ddr3_dq), // width = BYTE_LANES*8
|
||||
.io_ddr3_dqs(ddr3_dqs_p), // width = BYTE_LANES
|
||||
.io_ddr3_dqs_n(ddr3_dqs_n), // width = BYTE_LANES
|
||||
.o_ddr3_dm(ddr3_dm), // width = BYTE_LANES
|
||||
.o_ddr3_odt(ddr3_odt),
|
||||
// Debug outputs
|
||||
.o_debug1(),
|
||||
////////////////////////////////////
|
||||
);
|
||||
*/
|
||||
|
||||
// Wire connections between controller and phy
|
||||
wire[cmd_len*serdes_ratio-1:0] cmd;
|
||||
wire dqs_tri_control, dq_tri_control;
|
||||
wire toggle_dqs;
|
||||
wire[wb_data_bits-1:0] data;
|
||||
wire[wb_sel_bits-1:0] dm;
|
||||
wire[BYTE_LANES-1:0] bitslip;
|
||||
wire[DQ_BITS*BYTE_LANES*8-1:0] iserdes_data;
|
||||
wire[BYTE_LANES*8-1:0] iserdes_dqs;
|
||||
wire[BYTE_LANES*8-1:0] iserdes_bitslip_reference;
|
||||
wire idelayctrl_rdy;
|
||||
wire[4:0] odelay_data_cntvaluein, odelay_dqs_cntvaluein;
|
||||
wire[4:0] idelay_data_cntvaluein, idelay_dqs_cntvaluein;
|
||||
wire[BYTE_LANES-1:0] odelay_data_ld, odelay_dqs_ld;
|
||||
wire[BYTE_LANES-1:0] idelay_data_ld, idelay_dqs_ld;
|
||||
wire write_leveling_calib;
|
||||
wire reset;
|
||||
|
||||
// logic for self-refresh
|
||||
reg[8:0] refresh_counter = 0;
|
||||
reg user_self_refresh;
|
||||
// refresh counter
|
||||
always @(posedge i_controller_clk) begin
|
||||
if(i_wb_stb && i_wb_cyc) begin // if there is Wishbone request, then reset counter
|
||||
refresh_counter <= 0;
|
||||
end
|
||||
else if(!o_wb_stall || user_self_refresh) begin // if no request (but not stalled) OR already on self-refresh, then increment counter
|
||||
refresh_counter <= refresh_counter + 1;
|
||||
end
|
||||
end
|
||||
// choose self-refresh options
|
||||
always @* begin
|
||||
case(SELF_REFRESH)
|
||||
2'b00: user_self_refresh = i_user_self_refresh; // use input i_user_self_refresh (high = enter self-refresh, low = exit self-refresh)
|
||||
2'b01: user_self_refresh = refresh_counter[6]; // Self-refresh mode is enabled after 64 controller clock cycles of no requests, then exit Self-refresh after another 64 controller clk cycles
|
||||
2'b10: user_self_refresh = refresh_counter[7]; // Self-refresh mode is enabled after 128 controller clock cycles of no requests, then exit Self-refresh after another 128 controller clk cycles
|
||||
2'b11: user_self_refresh = refresh_counter[8]; // Self-refresh mode is enabled after 256 controller clock cycles of no requests, then exit Self-refresh after another 256 controller clk cycles
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
|
||||
//module instantiations
|
||||
ddr3_controller #(
|
||||
.CONTROLLER_CLK_PERIOD(CONTROLLER_CLK_PERIOD), //ps, clock period of the controller interface
|
||||
.DDR3_CLK_PERIOD(DDR3_CLK_PERIOD), //ps, clock period of the DDR3 RAM device (must be 1/4 of the CONTROLLER_CLK_PERIOD)
|
||||
.ROW_BITS(ROW_BITS), //width of row address
|
||||
.COL_BITS(COL_BITS), //width of column address
|
||||
.BA_BITS(BA_BITS), //width of bank address
|
||||
.DQ_BITS(DQ_BITS), //width of DQ
|
||||
.LANES(BYTE_LANES), // byte lanes
|
||||
.AUX_WIDTH(AUX_WIDTH), //width of aux line (must be >= 4)
|
||||
.WB2_ADDR_BITS(WB2_ADDR_BITS), //width of 2nd wishbone address bus
|
||||
.WB2_DATA_BITS(WB2_DATA_BITS), //width of 2nd wishbone data bus
|
||||
.MICRON_SIM(MICRON_SIM), //simulation for micron ddr3 model (shorten POWER_ON_RESET_HIGH and INITIAL_CKE_LOW)
|
||||
.ODELAY_SUPPORTED(ODELAY_SUPPORTED), //set to 1 when ODELAYE2 is supported
|
||||
.SECOND_WISHBONE(SECOND_WISHBONE), //set to 1 if 2nd wishbone is needed
|
||||
.ECC_ENABLE(ECC_ENABLE), // set to 1 or 2 to add ECC (1 = Side-band ECC per burst, 2 = Side-band ECC per 8 bursts , 3 = Inline ECC )
|
||||
.WB_ERROR(WB_ERROR), // set to 1 to support Wishbone error (asserts at ECC double bit error)
|
||||
.SKIP_INTERNAL_TEST(SKIP_INTERNAL_TEST), // skip built-in self test (would require >2 seconds of internal test right after calibration)
|
||||
.DIC(DIC), //Output Driver Impedance Control (2'b00 = RZQ/6, 2'b01 = RZQ/7, RZQ = 240ohms)
|
||||
.RTT_NOM(RTT_NOM) //RTT Nominal (3'b000 = disabled, 3'b001 = RZQ/4, 3'b010 = RZQ/2 , 3'b011 = RZQ/6, RZQ = 240ohms)
|
||||
) ddr3_controller_inst (
|
||||
.i_controller_clk(i_controller_clk), //i_controller_clk has period of CONTROLLER_CLK_PERIOD
|
||||
.i_rst_n(i_rst_n), //200MHz input clock
|
||||
// Wishbone inputs
|
||||
.i_wb_cyc(i_wb_cyc), //bus cycle active (1 = normal operation, 0 = all ongoing transaction are to be cancelled)
|
||||
.i_wb_stb(i_wb_stb), //request a transfer
|
||||
.i_wb_we(i_wb_we), //write-enable (1 = write, 0 = read)
|
||||
.i_wb_addr(i_wb_addr), //burst-addressable {row,bank,col}
|
||||
.i_wb_data(i_wb_data), //write data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
.i_wb_sel(i_wb_sel), //byte strobe for write (1 = write the byte)
|
||||
.i_aux(i_aux), //for AXI-interface compatibility (given upon strobe)
|
||||
// Wishbone outputs
|
||||
.o_wb_stall(o_wb_stall), //1 = busy, cannot accept requests
|
||||
.o_wb_ack(o_wb_ack), //1 = read/write request has completed
|
||||
.o_wb_err(o_wb_err), //1 = Error due to ECC double bit error (fixed to 0 if WB_ERROR = 0)
|
||||
.o_wb_data(o_wb_data), //read data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
.o_aux(o_aux), //for AXI-interface compatibility (returned upon ack)
|
||||
// Wishbone 2 (PHY) inputs
|
||||
.i_wb2_cyc(i_wb2_cyc), //bus cycle active (1 = normal operation, 0 = all ongoing transaction are to be cancelled)
|
||||
.i_wb2_stb(i_wb2_stb), //request a transfer
|
||||
.i_wb2_we(i_wb2_we), //write-enable (1 = write, 0 = read)
|
||||
.i_wb2_addr(i_wb2_addr), // memory-mapped register to be accessed
|
||||
.i_wb2_data(i_wb2_data), //write data
|
||||
.i_wb2_sel(i_wb2_sel), //byte strobe for write (1 = write the byte)
|
||||
// Wishbone 2 (Controller) outputs
|
||||
.o_wb2_stall(o_wb2_stall), //1 = busy, cannot accept requests
|
||||
.o_wb2_ack(o_wb2_ack), //1 = read/write request has completed
|
||||
.o_wb2_data(o_wb2_data), //read data
|
||||
//
|
||||
// PHY interface
|
||||
.i_phy_iserdes_data(iserdes_data),
|
||||
.i_phy_iserdes_dqs(iserdes_dqs),
|
||||
.i_phy_iserdes_bitslip_reference(iserdes_bitslip_reference),
|
||||
.i_phy_idelayctrl_rdy(idelayctrl_rdy),
|
||||
.o_phy_cmd(cmd),
|
||||
.o_phy_dqs_tri_control(dqs_tri_control),
|
||||
.o_phy_dq_tri_control(dq_tri_control),
|
||||
.o_phy_toggle_dqs(toggle_dqs),
|
||||
.o_phy_data(data),
|
||||
.o_phy_dm(dm),
|
||||
.o_phy_odelay_data_cntvaluein(odelay_data_cntvaluein),
|
||||
.o_phy_odelay_dqs_cntvaluein(odelay_dqs_cntvaluein),
|
||||
.o_phy_idelay_data_cntvaluein(idelay_data_cntvaluein),
|
||||
.o_phy_idelay_dqs_cntvaluein(idelay_dqs_cntvaluein),
|
||||
.o_phy_odelay_data_ld(odelay_data_ld),
|
||||
.o_phy_odelay_dqs_ld(odelay_dqs_ld),
|
||||
.o_phy_idelay_data_ld(idelay_data_ld),
|
||||
.o_phy_idelay_dqs_ld(idelay_dqs_ld),
|
||||
.o_phy_bitslip(bitslip),
|
||||
.o_phy_write_leveling_calib(write_leveling_calib),
|
||||
.o_phy_reset(reset),
|
||||
// Done Calibration pin
|
||||
.o_calib_complete(o_calib_complete),
|
||||
// Debug outputs
|
||||
.o_debug1(o_debug1),
|
||||
// .o_debug2(o_debug2),
|
||||
// .o_debug3(o_debug3)
|
||||
// User enabled self-refresh
|
||||
.i_user_self_refresh(user_self_refresh)
|
||||
);
|
||||
|
||||
ddr3_phy #(
|
||||
.ROW_BITS(ROW_BITS), //width of row address
|
||||
.BA_BITS(BA_BITS), //width of bank address
|
||||
.DQ_BITS(DQ_BITS), //width of DQ
|
||||
.LANES(BYTE_LANES), //8 lanes of DQ
|
||||
.CONTROLLER_CLK_PERIOD(CONTROLLER_CLK_PERIOD), //ps, period of clock input to this DDR3 controller module
|
||||
.DDR3_CLK_PERIOD(DDR3_CLK_PERIOD), //ps, period of clock input to DDR3 RAM device
|
||||
.ODELAY_SUPPORTED(ODELAY_SUPPORTED)
|
||||
) ddr3_phy_inst (
|
||||
.i_controller_clk(i_controller_clk),
|
||||
.i_ddr3_clk(i_ddr3_clk),
|
||||
.i_ref_clk(i_ref_clk),
|
||||
.i_ddr3_clk_90(i_ddr3_clk_90),
|
||||
.i_rst_n(i_rst_n),
|
||||
// Controller Interface
|
||||
.i_controller_reset(reset),
|
||||
.i_controller_cmd(cmd),
|
||||
.i_controller_dqs_tri_control(dqs_tri_control),
|
||||
.i_controller_dq_tri_control(dq_tri_control),
|
||||
.i_controller_toggle_dqs(toggle_dqs),
|
||||
.i_controller_data(data),
|
||||
.i_controller_dm(dm),
|
||||
.i_controller_odelay_data_cntvaluein(odelay_data_cntvaluein),
|
||||
.i_controller_odelay_dqs_cntvaluein(odelay_dqs_cntvaluein),
|
||||
.i_controller_idelay_data_cntvaluein(idelay_data_cntvaluein),
|
||||
.i_controller_idelay_dqs_cntvaluein(idelay_dqs_cntvaluein),
|
||||
.i_controller_odelay_data_ld(odelay_data_ld),
|
||||
.i_controller_odelay_dqs_ld(odelay_dqs_ld),
|
||||
.i_controller_idelay_data_ld(idelay_data_ld),
|
||||
.i_controller_idelay_dqs_ld(idelay_dqs_ld),
|
||||
.i_controller_bitslip(bitslip),
|
||||
.i_controller_write_leveling_calib(write_leveling_calib),
|
||||
.o_controller_iserdes_data(iserdes_data),
|
||||
.o_controller_iserdes_dqs(iserdes_dqs),
|
||||
.o_controller_iserdes_bitslip_reference(iserdes_bitslip_reference),
|
||||
.o_controller_idelayctrl_rdy(idelayctrl_rdy),
|
||||
// DDR3 I/O Interface
|
||||
.o_ddr3_clk_p(o_ddr3_clk_p),
|
||||
.o_ddr3_clk_n(o_ddr3_clk_n),
|
||||
.o_ddr3_reset_n(o_ddr3_reset_n),
|
||||
.o_ddr3_cke(o_ddr3_cke), // CKE
|
||||
.o_ddr3_cs_n(o_ddr3_cs_n), // chip select signal
|
||||
.o_ddr3_ras_n(o_ddr3_ras_n), // RAS#
|
||||
.o_ddr3_cas_n(o_ddr3_cas_n), // CAS#
|
||||
.o_ddr3_we_n(o_ddr3_we_n), // WE#
|
||||
.o_ddr3_addr(o_ddr3_addr),
|
||||
.o_ddr3_ba_addr(o_ddr3_ba_addr),
|
||||
.io_ddr3_dq(io_ddr3_dq),
|
||||
.io_ddr3_dqs(io_ddr3_dqs),
|
||||
.io_ddr3_dqs_n(io_ddr3_dqs_n),
|
||||
.o_ddr3_dm(o_ddr3_dm),
|
||||
.o_ddr3_odt(o_ddr3_odt), // on-die termination
|
||||
.o_ddr3_debug_read_dqs_p(/*o_ddr3_debug_read_dqs_p*/),
|
||||
.o_ddr3_debug_read_dqs_n(/*o_ddr3_debug_read_dqs_n*/)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Filename: ddr3_top.v
|
||||
// Project: UberDDR3 - An Open Source DDR3 Controller
|
||||
//
|
||||
// Purpose: Top module which instantiates the ddr3_controller and ddr3_phy modules
|
||||
// Use this as top module for instantiating UberDDR3 with Wishbone Interface.
|
||||
//
|
||||
// Engineer: Angelo C. Jacobo
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2023-2024 Angelo Jacobo
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`default_nettype none
|
||||
`timescale 1ps / 1ps
|
||||
|
||||
module ddr3_top #(
|
||||
parameter CONTROLLER_CLK_PERIOD = 12_000, //ps, clock period of the controller interface
|
||||
DDR3_CLK_PERIOD = 3_000, //ps, clock period of the DDR3 RAM device (must be 1/4 of the CONTROLLER_CLK_PERIOD)
|
||||
ROW_BITS = 14, //width of row address
|
||||
COL_BITS = 10, //width of column address
|
||||
BA_BITS = 3, //width of bank address
|
||||
BYTE_LANES = 2, //number of byte lanes of DDR3 RAM
|
||||
AUX_WIDTH = 4, //width of aux line (must be >= 4)
|
||||
WB2_ADDR_BITS = 7, //width of 2nd wishbone address bus
|
||||
WB2_DATA_BITS = 32, //width of 2nd wishbone data bus
|
||||
parameter[0:0] MICRON_SIM = 0, //enable faster simulation for micron ddr3 model (shorten POWER_ON_RESET_HIGH and INITIAL_CKE_LOW)
|
||||
ODELAY_SUPPORTED = 0, //set to 1 when ODELAYE2 is supported
|
||||
SECOND_WISHBONE = 0, //set to 1 if 2nd wishbone for debugging is needed
|
||||
WB_ERROR = 0, // set to 1 to support Wishbone error (asserts at ECC double bit error)
|
||||
SKIP_INTERNAL_TEST = 0, // skip built-in self test (would require >2 seconds of internal test right after calibration)
|
||||
parameter[1:0] ECC_ENABLE = 0, // set to 1 or 2 to add ECC (1 = Side-band ECC per burst, 2 = Side-band ECC per 8 bursts , 3 = Inline ECC )
|
||||
parameter[1:0] DIC = 2'b00, //Output Driver Impedance Control (2'b00 = RZQ/6, 2'b01 = RZQ/7, RZQ = 240ohms) (only change when you know what you are doing)
|
||||
parameter[2:0] RTT_NOM = 3'b011, //RTT Nominal (3'b000 = disabled, 3'b001 = RZQ/4, 3'b010 = RZQ/2 , 3'b011 = RZQ/6, RZQ = 240ohms) (only change when you know what you are doing)
|
||||
parameter // The next parameters act more like a localparam (since user does not have to set this manually) but was added here to simplify port declaration
|
||||
DQ_BITS = 8, //device width (fixed to 8, if DDR3 is x16 then BYTE_LANES will be 2 while )
|
||||
serdes_ratio = 4, // this controller is fixed as a 4:1 memory controller (CONTROLLER_CLK_PERIOD/DDR3_CLK_PERIOD = 4)
|
||||
wb_addr_bits = ROW_BITS + COL_BITS + BA_BITS - $clog2(serdes_ratio*2),
|
||||
wb_data_bits = DQ_BITS*BYTE_LANES*serdes_ratio*2,
|
||||
wb_sel_bits = wb_data_bits / 8,
|
||||
wb2_sel_bits = WB2_DATA_BITS / 8,
|
||||
//4 is the width of a single ddr3 command {cs_n, ras_n, cas_n, we_n} plus 3 (ck_en, odt, reset_n) plus bank bits plus row bits
|
||||
cmd_len = 4 + 3 + BA_BITS + ROW_BITS
|
||||
)
|
||||
(
|
||||
input wire i_controller_clk, i_ddr3_clk, i_ref_clk, //i_controller_clk = CONTROLLER_CLK_PERIOD, i_ddr3_clk = DDR3_CLK_PERIOD, i_ref_clk = 200MHz
|
||||
input wire i_ddr3_clk_90, //required only when ODELAY_SUPPORTED is zero
|
||||
input wire i_rst_n,
|
||||
//
|
||||
// Wishbone inputs
|
||||
input wire i_wb_cyc, //bus cycle active (1 = normal operation, 0 = all ongoing transaction are to be cancelled)
|
||||
input wire i_wb_stb, //request a transfer
|
||||
input wire i_wb_we, //write-enable (1 = write, 0 = read)
|
||||
input wire[wb_addr_bits - 1:0] i_wb_addr, //burst-addressable {row,bank,col}
|
||||
input wire[wb_data_bits - 1:0] i_wb_data, //write data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
input wire[wb_sel_bits - 1:0] i_wb_sel, //byte strobe for write (1 = write the byte)
|
||||
input wire[AUX_WIDTH - 1:0] i_aux, //for AXI-interface compatibility (given upon strobe)
|
||||
// Wishbone outputs
|
||||
output wire o_wb_stall, //1 = busy, cannot accept requests
|
||||
output wire o_wb_ack, //1 = read/write request has completed
|
||||
output wire o_wb_err, //1 = Error due to ECC double bit error (fixed to 0 if WB_ERROR = 0)
|
||||
output wire[wb_data_bits - 1:0] o_wb_data, //read data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
output wire[AUX_WIDTH - 1:0] o_aux, //for AXI-interface compatibility (given upon strobe)
|
||||
//
|
||||
// Wishbone 2 (PHY) inputs
|
||||
input wire i_wb2_cyc, //bus cycle active (1 = normal operation, 0 = all ongoing transaction are to be cancelled)
|
||||
input wire i_wb2_stb, //request a transfer
|
||||
input wire i_wb2_we, //write-enable (1 = write, 0 = read)
|
||||
input wire[WB2_ADDR_BITS - 1:0] i_wb2_addr, // memory-mapped register to be accessed
|
||||
input wire[WB2_DATA_BITS - 1:0] i_wb2_data, //write data
|
||||
input wire[wb2_sel_bits - 1:0] i_wb2_sel, //byte strobe for write (1 = write the byte)
|
||||
// Wishbone 2 (Controller) outputs
|
||||
output wire o_wb2_stall, //1 = busy, cannot accept requests
|
||||
output wire o_wb2_ack, //1 = read/write request has completed
|
||||
output wire[WB2_DATA_BITS - 1:0] o_wb2_data, //read data
|
||||
//
|
||||
// DDR3 I/O Interface
|
||||
output wire o_ddr3_clk_p, o_ddr3_clk_n,
|
||||
output wire o_ddr3_reset_n,
|
||||
output wire o_ddr3_cke, // CKE
|
||||
output wire o_ddr3_cs_n, // chip select signal
|
||||
output wire o_ddr3_ras_n, // RAS#
|
||||
output wire o_ddr3_cas_n, // CAS#
|
||||
output wire o_ddr3_we_n, // WE#
|
||||
output wire[ROW_BITS-1:0] o_ddr3_addr,
|
||||
output wire[BA_BITS-1:0] o_ddr3_ba_addr,
|
||||
inout wire[(DQ_BITS*BYTE_LANES)-1:0] io_ddr3_dq,
|
||||
inout wire[BYTE_LANES-1:0] io_ddr3_dqs, io_ddr3_dqs_n,
|
||||
output wire[BYTE_LANES-1:0] o_ddr3_dm,
|
||||
output wire o_ddr3_odt, // on-die termination
|
||||
//
|
||||
// Done Calibration pin
|
||||
output wire o_calib_complete,
|
||||
// Debug outputs
|
||||
output wire[31:0] o_debug1,
|
||||
// output wire[31:0] o_debug2,
|
||||
// output wire[31:0] o_debug3,
|
||||
// output wire[(DQ_BITS*BYTE_LANES)/8-1:0] o_ddr3_debug_read_dqs_p,
|
||||
// output wire[(DQ_BITS*BYTE_LANES)/8-1:0] o_ddr3_debug_read_dqs_n
|
||||
//
|
||||
// User enabled self-refresh
|
||||
input wire i_user_self_refresh
|
||||
);
|
||||
|
||||
// Instantiation Template (DEFAULT VALUE IS FOR ARTY S7)
|
||||
/*
|
||||
// DDR3 Controller
|
||||
ddr3_top #(
|
||||
.CONTROLLER_CLK_PERIOD(12_000), //ps, clock period of the controller interface
|
||||
.DDR3_CLK_PERIOD(3_000), //ps, clock period of the DDR3 RAM device (must be 1/4 of the CONTROLLER_CLK_PERIOD)
|
||||
.ROW_BITS(14), //width of row address
|
||||
.COL_BITS(10), //width of column address
|
||||
.BA_BITS(3), //width of bank address
|
||||
.BYTE_LANES(2), //number of byte lanes of DDR3 RAM
|
||||
.AUX_WIDTH(4), //width of aux line (must be >= 4)
|
||||
.MICRON_SIM(0), //enable faster simulation for micron ddr3 model (shorten POWER_ON_RESET_HIGH and INITIAL_CKE_LOW)
|
||||
.ODELAY_SUPPORTED(0), //set to 1 if ODELAYE2 is supported
|
||||
.SECOND_WISHBONE(0), //set to 1 if 2nd wishbone for debugging is needed
|
||||
.ECC_ENABLE(0), // set to 1 or 2 to add ECC (1 = Side-band ECC per burst, 2 = Side-band ECC per 8 bursts , 3 = Inline ECC )
|
||||
.WB_ERROR(0), // set to 1 to support Wishbone error (asserts at ECC double bit error)
|
||||
) ddr3_top
|
||||
(
|
||||
//clock and reset
|
||||
.i_controller_clk(i_controller_clk),
|
||||
.i_ddr3_clk(i_ddr3_clk), //i_controller_clk has period of CONTROLLER_CLK_PERIOD, i_ddr3_clk has period of DDR3_CLK_PERIOD
|
||||
.i_ref_clk(i_ref_clk), // usually set to 200 MHz
|
||||
.i_ddr3_clk_90(i_ddr3_clk_90), //90 degree phase shifted version i_ddr3_clk (required only when ODELAY_SUPPORTED is zero)
|
||||
.i_rst_n(!i_rst && clk_locked),
|
||||
//
|
||||
// Wishbone inputs
|
||||
.i_wb_cyc(1), //bus cycle active (1 = normal operation, 0 = all ongoing transaction are to be cancelled)
|
||||
.i_wb_stb(i_wb_stb), //request a transfer
|
||||
.i_wb_we(i_wb_we), //write-enable (1 = write, 0 = read)
|
||||
.i_wb_addr(i_wb_addr), //burst-addressable {row,bank,col}
|
||||
.i_wb_data(i_wb_data), //write data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
.i_wb_sel(16'hffff), //byte strobe for write (1 = write the byte)
|
||||
.i_aux(i_wb_we), //for AXI-interface compatibility (given upon strobe)
|
||||
// Wishbone outputs
|
||||
.o_wb_stall(o_wb_stall), //1 = busy, cannot accept requests
|
||||
.o_wb_ack(o_wb_ack), //1 = read/write request has completed
|
||||
.o_wb_err(o_wb_err), //1 = Error due to ECC double bit error (fixed to 0 if WB_ERROR = 0)
|
||||
.o_wb_data(o_wb_data), //read data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
.o_aux(o_aux),
|
||||
//
|
||||
// Wishbone 2 (PHY) inputs
|
||||
.i_wb2_cyc(0), //bus cycle active (1 = normal operation, 0 = all ongoing transaction are to be cancelled)
|
||||
.i_wb2_stb(0), //request a transfer
|
||||
.i_wb2_we(0), //write-enable (1 = write, 0 = read)
|
||||
.i_wb2_addr(0), //burst-addressable {row,bank,col}
|
||||
.i_wb2_data(0), //write data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
.i_wb2_sel(0), //byte strobe for write (1 = write the byte)
|
||||
// Wishbone 2 (Controller) outputs
|
||||
.o_wb2_stall(), //1 = busy, cannot accept requests
|
||||
.o_wb2_ack(), //1 = read/write request has completed
|
||||
.o_wb2_data(), //read data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
//
|
||||
// DDR3 I/O Interface
|
||||
.o_ddr3_clk_p(ddr3_clk_p),
|
||||
.o_ddr3_clk_n(ddr3_clk_n),
|
||||
.o_ddr3_reset_n(ddr3_reset_n),
|
||||
.o_ddr3_cke(ddr3_cke),
|
||||
.o_ddr3_cs_n(ddr3_cs_n), // width = number of DDR3 ranks
|
||||
.o_ddr3_ras_n(ddr3_ras_n),
|
||||
.o_ddr3_cas_n(ddr3_cas_n),
|
||||
.o_ddr3_we_n(ddr3_we_n),
|
||||
.o_ddr3_addr(ddr3_addr), // width = ROW_BITS
|
||||
.o_ddr3_ba_addr(ddr3_ba), // width = BA_BITS
|
||||
.io_ddr3_dq(ddr3_dq), // width = BYTE_LANES*8
|
||||
.io_ddr3_dqs(ddr3_dqs_p), // width = BYTE_LANES
|
||||
.io_ddr3_dqs_n(ddr3_dqs_n), // width = BYTE_LANES
|
||||
.o_ddr3_dm(ddr3_dm), // width = BYTE_LANES
|
||||
.o_ddr3_odt(ddr3_odt),
|
||||
// Debug outputs
|
||||
.o_debug1(),
|
||||
////////////////////////////////////
|
||||
);
|
||||
*/
|
||||
|
||||
// Wire connections between controller and phy
|
||||
wire[cmd_len*serdes_ratio-1:0] cmd;
|
||||
wire dqs_tri_control, dq_tri_control;
|
||||
wire toggle_dqs;
|
||||
wire[wb_data_bits-1:0] data;
|
||||
wire[wb_sel_bits-1:0] dm;
|
||||
wire[BYTE_LANES-1:0] bitslip;
|
||||
wire[DQ_BITS*BYTE_LANES*8-1:0] iserdes_data;
|
||||
wire[BYTE_LANES*8-1:0] iserdes_dqs;
|
||||
wire[BYTE_LANES*8-1:0] iserdes_bitslip_reference;
|
||||
wire idelayctrl_rdy;
|
||||
wire[4:0] odelay_data_cntvaluein, odelay_dqs_cntvaluein;
|
||||
wire[4:0] idelay_data_cntvaluein, idelay_dqs_cntvaluein;
|
||||
wire[BYTE_LANES-1:0] odelay_data_ld, odelay_dqs_ld;
|
||||
wire[BYTE_LANES-1:0] idelay_data_ld, idelay_dqs_ld;
|
||||
wire write_leveling_calib;
|
||||
wire reset;
|
||||
|
||||
//module instantiations
|
||||
ddr3_controller #(
|
||||
.CONTROLLER_CLK_PERIOD(CONTROLLER_CLK_PERIOD), //ps, clock period of the controller interface
|
||||
.DDR3_CLK_PERIOD(DDR3_CLK_PERIOD), //ps, clock period of the DDR3 RAM device (must be 1/4 of the CONTROLLER_CLK_PERIOD)
|
||||
.ROW_BITS(ROW_BITS), //width of row address
|
||||
.COL_BITS(COL_BITS), //width of column address
|
||||
.BA_BITS(BA_BITS), //width of bank address
|
||||
.DQ_BITS(DQ_BITS), //width of DQ
|
||||
.LANES(BYTE_LANES), // byte lanes
|
||||
.AUX_WIDTH(AUX_WIDTH), //width of aux line (must be >= 4)
|
||||
.WB2_ADDR_BITS(WB2_ADDR_BITS), //width of 2nd wishbone address bus
|
||||
.WB2_DATA_BITS(WB2_DATA_BITS), //width of 2nd wishbone data bus
|
||||
.MICRON_SIM(MICRON_SIM), //simulation for micron ddr3 model (shorten POWER_ON_RESET_HIGH and INITIAL_CKE_LOW)
|
||||
.ODELAY_SUPPORTED(ODELAY_SUPPORTED), //set to 1 when ODELAYE2 is supported
|
||||
.SECOND_WISHBONE(SECOND_WISHBONE), //set to 1 if 2nd wishbone is needed
|
||||
.ECC_ENABLE(ECC_ENABLE), // set to 1 or 2 to add ECC (1 = Side-band ECC per burst, 2 = Side-band ECC per 8 bursts , 3 = Inline ECC )
|
||||
.WB_ERROR(WB_ERROR), // set to 1 to support Wishbone error (asserts at ECC double bit error)
|
||||
.SKIP_INTERNAL_TEST(SKIP_INTERNAL_TEST), // skip built-in self test (would require >2 seconds of internal test right after calibration)
|
||||
.DIC(DIC), //Output Driver Impedance Control (2'b00 = RZQ/6, 2'b01 = RZQ/7, RZQ = 240ohms)
|
||||
.RTT_NOM(RTT_NOM) //RTT Nominal (3'b000 = disabled, 3'b001 = RZQ/4, 3'b010 = RZQ/2 , 3'b011 = RZQ/6, RZQ = 240ohms)
|
||||
) ddr3_controller_inst (
|
||||
.i_controller_clk(i_controller_clk), //i_controller_clk has period of CONTROLLER_CLK_PERIOD
|
||||
.i_rst_n(i_rst_n), //200MHz input clock
|
||||
// Wishbone inputs
|
||||
.i_wb_cyc(i_wb_cyc), //bus cycle active (1 = normal operation, 0 = all ongoing transaction are to be cancelled)
|
||||
.i_wb_stb(i_wb_stb), //request a transfer
|
||||
.i_wb_we(i_wb_we), //write-enable (1 = write, 0 = read)
|
||||
.i_wb_addr(i_wb_addr), //burst-addressable {row,bank,col}
|
||||
.i_wb_data(i_wb_data), //write data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
.i_wb_sel(i_wb_sel), //byte strobe for write (1 = write the byte)
|
||||
.i_aux(i_aux), //for AXI-interface compatibility (given upon strobe)
|
||||
// Wishbone outputs
|
||||
.o_wb_stall(o_wb_stall), //1 = busy, cannot accept requests
|
||||
.o_wb_ack(o_wb_ack), //1 = read/write request has completed
|
||||
.o_wb_err(o_wb_err), //1 = Error due to ECC double bit error (fixed to 0 if WB_ERROR = 0)
|
||||
.o_wb_data(o_wb_data), //read data, for a 4:1 controller data width is 8 times the number of pins on the device
|
||||
.o_aux(o_aux), //for AXI-interface compatibility (returned upon ack)
|
||||
// Wishbone 2 (PHY) inputs
|
||||
.i_wb2_cyc(i_wb2_cyc), //bus cycle active (1 = normal operation, 0 = all ongoing transaction are to be cancelled)
|
||||
.i_wb2_stb(i_wb2_stb), //request a transfer
|
||||
.i_wb2_we(i_wb2_we), //write-enable (1 = write, 0 = read)
|
||||
.i_wb2_addr(i_wb2_addr), // memory-mapped register to be accessed
|
||||
.i_wb2_data(i_wb2_data), //write data
|
||||
.i_wb2_sel(i_wb2_sel), //byte strobe for write (1 = write the byte)
|
||||
// Wishbone 2 (Controller) outputs
|
||||
.o_wb2_stall(o_wb2_stall), //1 = busy, cannot accept requests
|
||||
.o_wb2_ack(o_wb2_ack), //1 = read/write request has completed
|
||||
.o_wb2_data(o_wb2_data), //read data
|
||||
//
|
||||
// PHY interface
|
||||
.i_phy_iserdes_data(iserdes_data),
|
||||
.i_phy_iserdes_dqs(iserdes_dqs),
|
||||
.i_phy_iserdes_bitslip_reference(iserdes_bitslip_reference),
|
||||
.i_phy_idelayctrl_rdy(idelayctrl_rdy),
|
||||
.o_phy_cmd(cmd),
|
||||
.o_phy_dqs_tri_control(dqs_tri_control),
|
||||
.o_phy_dq_tri_control(dq_tri_control),
|
||||
.o_phy_toggle_dqs(toggle_dqs),
|
||||
.o_phy_data(data),
|
||||
.o_phy_dm(dm),
|
||||
.o_phy_odelay_data_cntvaluein(odelay_data_cntvaluein),
|
||||
.o_phy_odelay_dqs_cntvaluein(odelay_dqs_cntvaluein),
|
||||
.o_phy_idelay_data_cntvaluein(idelay_data_cntvaluein),
|
||||
.o_phy_idelay_dqs_cntvaluein(idelay_dqs_cntvaluein),
|
||||
.o_phy_odelay_data_ld(odelay_data_ld),
|
||||
.o_phy_odelay_dqs_ld(odelay_dqs_ld),
|
||||
.o_phy_idelay_data_ld(idelay_data_ld),
|
||||
.o_phy_idelay_dqs_ld(idelay_dqs_ld),
|
||||
.o_phy_bitslip(bitslip),
|
||||
.o_phy_write_leveling_calib(write_leveling_calib),
|
||||
.o_phy_reset(reset),
|
||||
// Done Calibration pin
|
||||
.o_calib_complete(o_calib_complete),
|
||||
// Debug outputs
|
||||
.o_debug1(o_debug1),
|
||||
// .o_debug2(o_debug2),
|
||||
// .o_debug3(o_debug3)
|
||||
// User enabled self-refresh
|
||||
.i_user_self_refresh(i_user_self_refresh)
|
||||
);
|
||||
|
||||
ddr3_phy #(
|
||||
.ROW_BITS(ROW_BITS), //width of row address
|
||||
.BA_BITS(BA_BITS), //width of bank address
|
||||
.DQ_BITS(DQ_BITS), //width of DQ
|
||||
.LANES(BYTE_LANES), //8 lanes of DQ
|
||||
.CONTROLLER_CLK_PERIOD(CONTROLLER_CLK_PERIOD), //ps, period of clock input to this DDR3 controller module
|
||||
.DDR3_CLK_PERIOD(DDR3_CLK_PERIOD), //ps, period of clock input to DDR3 RAM device
|
||||
.ODELAY_SUPPORTED(ODELAY_SUPPORTED)
|
||||
) ddr3_phy_inst (
|
||||
.i_controller_clk(i_controller_clk),
|
||||
.i_ddr3_clk(i_ddr3_clk),
|
||||
.i_ref_clk(i_ref_clk),
|
||||
.i_ddr3_clk_90(i_ddr3_clk_90),
|
||||
.i_rst_n(i_rst_n),
|
||||
// Controller Interface
|
||||
.i_controller_reset(reset),
|
||||
.i_controller_cmd(cmd),
|
||||
.i_controller_dqs_tri_control(dqs_tri_control),
|
||||
.i_controller_dq_tri_control(dq_tri_control),
|
||||
.i_controller_toggle_dqs(toggle_dqs),
|
||||
.i_controller_data(data),
|
||||
.i_controller_dm(dm),
|
||||
.i_controller_odelay_data_cntvaluein(odelay_data_cntvaluein),
|
||||
.i_controller_odelay_dqs_cntvaluein(odelay_dqs_cntvaluein),
|
||||
.i_controller_idelay_data_cntvaluein(idelay_data_cntvaluein),
|
||||
.i_controller_idelay_dqs_cntvaluein(idelay_dqs_cntvaluein),
|
||||
.i_controller_odelay_data_ld(odelay_data_ld),
|
||||
.i_controller_odelay_dqs_ld(odelay_dqs_ld),
|
||||
.i_controller_idelay_data_ld(idelay_data_ld),
|
||||
.i_controller_idelay_dqs_ld(idelay_dqs_ld),
|
||||
.i_controller_bitslip(bitslip),
|
||||
.i_controller_write_leveling_calib(write_leveling_calib),
|
||||
.o_controller_iserdes_data(iserdes_data),
|
||||
.o_controller_iserdes_dqs(iserdes_dqs),
|
||||
.o_controller_iserdes_bitslip_reference(iserdes_bitslip_reference),
|
||||
.o_controller_idelayctrl_rdy(idelayctrl_rdy),
|
||||
// DDR3 I/O Interface
|
||||
.o_ddr3_clk_p(o_ddr3_clk_p),
|
||||
.o_ddr3_clk_n(o_ddr3_clk_n),
|
||||
.o_ddr3_reset_n(o_ddr3_reset_n),
|
||||
.o_ddr3_cke(o_ddr3_cke), // CKE
|
||||
.o_ddr3_cs_n(o_ddr3_cs_n), // chip select signal
|
||||
.o_ddr3_ras_n(o_ddr3_ras_n), // RAS#
|
||||
.o_ddr3_cas_n(o_ddr3_cas_n), // CAS#
|
||||
.o_ddr3_we_n(o_ddr3_we_n), // WE#
|
||||
.o_ddr3_addr(o_ddr3_addr),
|
||||
.o_ddr3_ba_addr(o_ddr3_ba_addr),
|
||||
.io_ddr3_dq(io_ddr3_dq),
|
||||
.io_ddr3_dqs(io_ddr3_dqs),
|
||||
.io_ddr3_dqs_n(io_ddr3_dqs_n),
|
||||
.o_ddr3_dm(o_ddr3_dm),
|
||||
.o_ddr3_odt(o_ddr3_odt), // on-die termination
|
||||
.o_ddr3_debug_read_dqs_p(/*o_ddr3_debug_read_dqs_p*/),
|
||||
.o_ddr3_debug_read_dqs_n(/*o_ddr3_debug_read_dqs_n*/)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
|
|||
|
|
@ -1,317 +1,317 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
// ,------. ,--. ,--. //
|
||||
// | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. //
|
||||
// | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' //
|
||||
// | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. //
|
||||
// `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' //
|
||||
// `---' //
|
||||
// Error Correction and Detection Decoder //
|
||||
// Parameterized Extended Hamming Code Decoder //
|
||||
// //
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Copyright (C) 2017 ROA Logic BV //
|
||||
// www.roalogic.com //
|
||||
// //
|
||||
// This source file may be used and distributed without //
|
||||
// restriction provided that this copyright statement is not //
|
||||
// removed from the file and that any derivative work contains //
|
||||
// the original copyright notice and the associated disclaimer. //
|
||||
// //
|
||||
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //
|
||||
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //
|
||||
// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR OR //
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, //
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT //
|
||||
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; //
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) //
|
||||
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN //
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR //
|
||||
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS //
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //
|
||||
// //
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// +FHDR - Semiconductor Reuse Standard File Header Section -------
|
||||
// FILE NAME : ecc_dec.sv
|
||||
// DEPARTMENT :
|
||||
// AUTHOR : rherveille
|
||||
// AUTHOR'S EMAIL :
|
||||
// ------------------------------------------------------------------
|
||||
// RELEASE HISTORY
|
||||
// VERSION DATE AUTHOR DESCRIPTION
|
||||
// 1.0 2017-04-07 rherveille initial release
|
||||
// ------------------------------------------------------------------
|
||||
// KEYWORDS : HAMMING ERROR CORRECTION DECODER
|
||||
// ------------------------------------------------------------------
|
||||
// PURPOSE : Decodes Data and ECC bits from incoming data
|
||||
// Detects and corrects bit errors
|
||||
// ------------------------------------------------------------------
|
||||
// PARAMETERS
|
||||
// PARAM NAME RANGE DESCRIPTION DEFAULT UNITS
|
||||
// K 1+ Information vector size 8
|
||||
// LATENCY 0,1,2 0: No latency 0
|
||||
// 1: Registered outputs
|
||||
// 2: Registered inputs/outputs
|
||||
// P0_LSB 0,1 0: p0 located at MSB 1
|
||||
// 1: p0 located at LSB
|
||||
// ------------------------------------------------------------------
|
||||
// REUSE ISSUES
|
||||
// Reset Strategy : external asynchronous active low; rst_ni
|
||||
// Clock Domains : 1, clk_i, rising edge
|
||||
// Critical Timing :
|
||||
// Test Features : na
|
||||
// Asynchronous I/F : no
|
||||
// Scan Methodology : na
|
||||
// Instantiations : none
|
||||
// Synthesizable (y/n) : Yes
|
||||
// Other :
|
||||
// -FHDR-------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Hamming codes can detect and correct a single bit error.
|
||||
// An extended Hamming code allows detection of double bit errors and
|
||||
// correction of single bit errors.
|
||||
// This is called SECDED; Single Error Correction, Double Error Detection
|
||||
//
|
||||
// Number of bits required by a Hamming code: n = m + k
|
||||
// n = code length
|
||||
// m = number of check bits
|
||||
// k = number of information bits
|
||||
//
|
||||
// Information, parity, and syndrome expressed as vectors:
|
||||
// u = Information bit vector
|
||||
// p = Parity check bit vector
|
||||
// s = Syndrome vector
|
||||
//
|
||||
// The parity vector is encoded in 'n'.
|
||||
// The information bit vector is part of 'p'
|
||||
// The syndrome vector needs to be calculated.
|
||||
//
|
||||
// Bits required:
|
||||
// p ranges from 0 to m+k; or p_range=m+k+1
|
||||
// As a result 2^m >= m+k+1
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
module ecc_dec #(
|
||||
parameter K = 8, //Information bit vector size
|
||||
parameter LATENCY = 0, //0: no latency (combinatorial design)
|
||||
//1: registered outputs
|
||||
//2: registered inputs+outputs
|
||||
parameter P0_LSB = 1, //0: p0 is located at MSB
|
||||
//1: p0 is located at LSB
|
||||
|
||||
//These should be localparams
|
||||
parameter m = calculate_m(K),
|
||||
parameter n = m + K
|
||||
)
|
||||
(
|
||||
/* verilator lint_off UNUSEDSIGNAL */
|
||||
//clock/reset ports (if LATENCY > 0)
|
||||
input rst_ni, //asynchronous reset
|
||||
input clk_i, //clock input
|
||||
input clkena_i, //clock enable input
|
||||
/* verilator lint_on UNUSEDSIGNAL */
|
||||
|
||||
//data ports
|
||||
input [n :0] d_i, //encoded code word input
|
||||
output reg [K-1:0] q_o, //information bit vector output
|
||||
output reg [m :0] syndrome_o, //syndrome vector output
|
||||
|
||||
//flags
|
||||
output reg sb_err_o, //single bit error detected
|
||||
output reg db_err_o, //double bit error detected
|
||||
output reg sb_fix_o //repaired error in the information bits
|
||||
);
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Functions
|
||||
//---------------------------------------------------------
|
||||
function integer calculate_m(input integer k);
|
||||
integer m_local;
|
||||
begin
|
||||
m_local=1;
|
||||
while (2**m_local < m_local+k+1) m_local++;
|
||||
|
||||
calculate_m = m_local;
|
||||
end
|
||||
endfunction //calculate_m
|
||||
|
||||
|
||||
function [m:1] calculate_syndrome(input [n:0] cw);
|
||||
integer p_idx, cw_idx;
|
||||
begin
|
||||
//clear syndrome
|
||||
calculate_syndrome = 0;
|
||||
|
||||
for (p_idx =1; p_idx <=m; p_idx++) //parity vector index
|
||||
for (cw_idx=1; cw_idx<=n; cw_idx++) //code-word index
|
||||
if (|(2**(p_idx-1) & cw_idx)) calculate_syndrome[p_idx] = calculate_syndrome[p_idx] ^ cw[cw_idx];
|
||||
end
|
||||
endfunction //calculate_syndrome
|
||||
|
||||
|
||||
function [n:0] correct_codeword(input [n:0] cw, input [m:1] syndrome);
|
||||
/*
|
||||
Correct all bits, including parity bits and extended parity bit.
|
||||
This simplifies this section and keeps the logic simple.
|
||||
|
||||
The parity-bits are not used when extracting the information bits vector.
|
||||
Dead-logic-removal gets rid of the generated logic for the parity bits.
|
||||
*/
|
||||
|
||||
//assign code word
|
||||
correct_codeword = cw;
|
||||
|
||||
//then invert bit indicated by syndrome
|
||||
correct_codeword[syndrome] = ~correct_codeword[syndrome];
|
||||
endfunction //correct_codeword
|
||||
|
||||
|
||||
function [K-1:0] extract_q(input [n:0] cw);
|
||||
integer bit_idx, cw_idx;
|
||||
begin
|
||||
//This function extracts the information bits vector from the codeword
|
||||
//information bits are stored in non-power-of-2 locations
|
||||
|
||||
bit_idx=0; //information bit vector index
|
||||
for (cw_idx=1; cw_idx<=n; cw_idx++) //codeword index
|
||||
if (2**$clog2(cw_idx) != cw_idx)
|
||||
/* verilator lint_off UNUSEDSIGNAL */
|
||||
extract_q[bit_idx++] = cw[cw_idx];
|
||||
/* verilator lint_on UNUSEDSIGNAL */
|
||||
end
|
||||
endfunction //extract_q
|
||||
|
||||
|
||||
function is_power_of_2(input [m:1] n_local);
|
||||
is_power_of_2 = (n_local & (n_local-1)) == 0;
|
||||
endfunction
|
||||
|
||||
|
||||
function information_error(input [m:1] syndrome);
|
||||
begin
|
||||
//This function checks if an error was detected/corrected in the information bits
|
||||
information_error = |syndrome & !is_power_of_2(syndrome);
|
||||
end
|
||||
endfunction //information_error
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Variables
|
||||
//---------------------------------------------------------
|
||||
wire parity; //full codeword parity check
|
||||
logic parity_reg;
|
||||
wire [m :1] syndrome; //bit error indication/location
|
||||
logic [m :1] syndrome_reg;
|
||||
wire [n :0] cw_fixed; //corrected code word
|
||||
|
||||
wire [n :0] d;
|
||||
logic [n :0] d_reg;
|
||||
wire [K-1:0] q;
|
||||
wire sb_err;
|
||||
wire db_err;
|
||||
wire sb_fix;
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Module Body
|
||||
//---------------------------------------------------------
|
||||
|
||||
/*
|
||||
Below diagram indicates the locations of the parity and data bits
|
||||
in the final 'p' vector.
|
||||
It also shows what databits each parity bit operates on
|
||||
|
||||
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
p1 p2 d1 p4 d2 d3 d4 p8 d5 d6 d7 d8 d9 d10 d11
|
||||
p1 x x x x x x x x
|
||||
p2 x x x x x x x x
|
||||
p4 x x x x x x x x
|
||||
p8 x x x x x x x x
|
||||
*/
|
||||
|
||||
//Step 1: Locate Parity bit
|
||||
assign d = P0_LSB ? d_i : {d_i[n-1:0],d_i[n]};
|
||||
|
||||
//Step 2: Calculate code word parity
|
||||
assign parity = ^d;
|
||||
|
||||
//Step 3: Calculate syndrome
|
||||
assign syndrome = calculate_syndrome(d);
|
||||
|
||||
//Step 4: Generate intermediate registers (if any)
|
||||
generate
|
||||
if (LATENCY > 1)
|
||||
begin : gen_inter_reg_latency_g1
|
||||
always @(posedge clk_i or negedge rst_ni)
|
||||
if (!rst_ni)
|
||||
begin
|
||||
d_reg <= {n+1{1'b0}};
|
||||
parity_reg <= 1'b0;
|
||||
syndrome_reg <= {m{1'b0}};
|
||||
end
|
||||
else if (clkena_i)
|
||||
begin
|
||||
d_reg <= d;
|
||||
parity_reg <= parity;
|
||||
syndrome_reg <= syndrome;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin : gen_inter_reg_latency_0
|
||||
assign d_reg = d;
|
||||
assign parity_reg = parity;
|
||||
assign syndrome_reg = syndrome;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
//Step 5: Correct erroneous bit (if any)
|
||||
assign cw_fixed = correct_codeword(d_reg, syndrome_reg);
|
||||
|
||||
//Step 6: Extract information bits vector
|
||||
assign q = extract_q(cw_fixed);
|
||||
|
||||
//Step 7: Generate status flags
|
||||
assign sb_err = (parity_reg & |syndrome_reg);
|
||||
assign db_err = ~parity_reg & |syndrome_reg;
|
||||
assign sb_fix = parity_reg & |information_error(syndrome_reg);
|
||||
|
||||
//Step 8: Generate output registers (if required)
|
||||
generate
|
||||
if (LATENCY > 0)
|
||||
begin : gen_output_reg_latency_g0 //Generate output registers
|
||||
always @(posedge clk_i or negedge rst_ni)
|
||||
if (!rst_ni)
|
||||
begin
|
||||
q_o <= {K{1'b0}};
|
||||
syndrome_o <= {m+1{1'b0}};
|
||||
sb_err_o <= 1'b0;
|
||||
db_err_o <= 1'b0;
|
||||
sb_fix_o <= 1'b0;
|
||||
end
|
||||
else if (clkena_i)
|
||||
begin
|
||||
q_o <= q;
|
||||
syndrome_o <= P0_LSB ? {syndrome_reg, parity_reg} : {parity_reg, syndrome_reg};
|
||||
sb_err_o <= sb_err;
|
||||
db_err_o <= db_err;
|
||||
sb_fix_o <= sb_fix;
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
begin : gen_output_reg_latency_0//No output registers
|
||||
always_comb
|
||||
begin
|
||||
q_o = q;
|
||||
syndrome_o = P0_LSB ? {syndrome_reg, parity_reg} : {parity_reg, syndrome_reg};
|
||||
sb_err_o = sb_err;
|
||||
db_err_o = db_err;
|
||||
sb_fix_o = sb_fix;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// ,------. ,--. ,--. //
|
||||
// | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. //
|
||||
// | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' //
|
||||
// | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. //
|
||||
// `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' //
|
||||
// `---' //
|
||||
// Error Correction and Detection Decoder //
|
||||
// Parameterized Extended Hamming Code Decoder //
|
||||
// //
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Copyright (C) 2017 ROA Logic BV //
|
||||
// www.roalogic.com //
|
||||
// //
|
||||
// This source file may be used and distributed without //
|
||||
// restriction provided that this copyright statement is not //
|
||||
// removed from the file and that any derivative work contains //
|
||||
// the original copyright notice and the associated disclaimer. //
|
||||
// //
|
||||
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //
|
||||
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //
|
||||
// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR OR //
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, //
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT //
|
||||
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; //
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) //
|
||||
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN //
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR //
|
||||
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS //
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //
|
||||
// //
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// +FHDR - Semiconductor Reuse Standard File Header Section -------
|
||||
// FILE NAME : ecc_dec.sv
|
||||
// DEPARTMENT :
|
||||
// AUTHOR : rherveille
|
||||
// AUTHOR'S EMAIL :
|
||||
// ------------------------------------------------------------------
|
||||
// RELEASE HISTORY
|
||||
// VERSION DATE AUTHOR DESCRIPTION
|
||||
// 1.0 2017-04-07 rherveille initial release
|
||||
// ------------------------------------------------------------------
|
||||
// KEYWORDS : HAMMING ERROR CORRECTION DECODER
|
||||
// ------------------------------------------------------------------
|
||||
// PURPOSE : Decodes Data and ECC bits from incoming data
|
||||
// Detects and corrects bit errors
|
||||
// ------------------------------------------------------------------
|
||||
// PARAMETERS
|
||||
// PARAM NAME RANGE DESCRIPTION DEFAULT UNITS
|
||||
// K 1+ Information vector size 8
|
||||
// LATENCY 0,1,2 0: No latency 0
|
||||
// 1: Registered outputs
|
||||
// 2: Registered inputs/outputs
|
||||
// P0_LSB 0,1 0: p0 located at MSB 1
|
||||
// 1: p0 located at LSB
|
||||
// ------------------------------------------------------------------
|
||||
// REUSE ISSUES
|
||||
// Reset Strategy : external asynchronous active low; rst_ni
|
||||
// Clock Domains : 1, clk_i, rising edge
|
||||
// Critical Timing :
|
||||
// Test Features : na
|
||||
// Asynchronous I/F : no
|
||||
// Scan Methodology : na
|
||||
// Instantiations : none
|
||||
// Synthesizable (y/n) : Yes
|
||||
// Other :
|
||||
// -FHDR-------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Hamming codes can detect and correct a single bit error.
|
||||
// An extended Hamming code allows detection of double bit errors and
|
||||
// correction of single bit errors.
|
||||
// This is called SECDED; Single Error Correction, Double Error Detection
|
||||
//
|
||||
// Number of bits required by a Hamming code: n = m + k
|
||||
// n = code length
|
||||
// m = number of check bits
|
||||
// k = number of information bits
|
||||
//
|
||||
// Information, parity, and syndrome expressed as vectors:
|
||||
// u = Information bit vector
|
||||
// p = Parity check bit vector
|
||||
// s = Syndrome vector
|
||||
//
|
||||
// The parity vector is encoded in 'n'.
|
||||
// The information bit vector is part of 'p'
|
||||
// The syndrome vector needs to be calculated.
|
||||
//
|
||||
// Bits required:
|
||||
// p ranges from 0 to m+k; or p_range=m+k+1
|
||||
// As a result 2^m >= m+k+1
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
module ecc_dec #(
|
||||
parameter K = 8, //Information bit vector size
|
||||
parameter LATENCY = 0, //0: no latency (combinatorial design)
|
||||
//1: registered outputs
|
||||
//2: registered inputs+outputs
|
||||
parameter P0_LSB = 1, //0: p0 is located at MSB
|
||||
//1: p0 is located at LSB
|
||||
|
||||
//These should be localparams
|
||||
parameter m = calculate_m(K),
|
||||
parameter n = m + K
|
||||
)
|
||||
(
|
||||
/* verilator lint_off UNUSEDSIGNAL */
|
||||
//clock/reset ports (if LATENCY > 0)
|
||||
input rst_ni, //asynchronous reset
|
||||
input clk_i, //clock input
|
||||
input clkena_i, //clock enable input
|
||||
/* verilator lint_on UNUSEDSIGNAL */
|
||||
|
||||
//data ports
|
||||
input [n :0] d_i, //encoded code word input
|
||||
output reg [K-1:0] q_o, //information bit vector output
|
||||
output reg [m :0] syndrome_o, //syndrome vector output
|
||||
|
||||
//flags
|
||||
output reg sb_err_o, //single bit error detected
|
||||
output reg db_err_o, //double bit error detected
|
||||
output reg sb_fix_o //repaired error in the information bits
|
||||
);
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Functions
|
||||
//---------------------------------------------------------
|
||||
function integer calculate_m(input integer k);
|
||||
integer m_local;
|
||||
begin
|
||||
m_local=1;
|
||||
while (2**m_local < m_local+k+1) m_local++;
|
||||
|
||||
calculate_m = m_local;
|
||||
end
|
||||
endfunction //calculate_m
|
||||
|
||||
|
||||
function [m:1] calculate_syndrome(input [n:0] cw);
|
||||
integer p_idx, cw_idx;
|
||||
begin
|
||||
//clear syndrome
|
||||
calculate_syndrome = 0;
|
||||
|
||||
for (p_idx =1; p_idx <=m; p_idx++) //parity vector index
|
||||
for (cw_idx=1; cw_idx<=n; cw_idx++) //code-word index
|
||||
if (|(2**(p_idx-1) & cw_idx)) calculate_syndrome[p_idx] = calculate_syndrome[p_idx] ^ cw[cw_idx];
|
||||
end
|
||||
endfunction //calculate_syndrome
|
||||
|
||||
|
||||
function [n:0] correct_codeword(input [n:0] cw, input [m:1] syndrome);
|
||||
/*
|
||||
Correct all bits, including parity bits and extended parity bit.
|
||||
This simplifies this section and keeps the logic simple.
|
||||
|
||||
The parity-bits are not used when extracting the information bits vector.
|
||||
Dead-logic-removal gets rid of the generated logic for the parity bits.
|
||||
*/
|
||||
|
||||
//assign code word
|
||||
correct_codeword = cw;
|
||||
|
||||
//then invert bit indicated by syndrome
|
||||
correct_codeword[syndrome] = ~correct_codeword[syndrome];
|
||||
endfunction //correct_codeword
|
||||
|
||||
|
||||
function [K-1:0] extract_q(input [n:0] cw);
|
||||
integer bit_idx, cw_idx;
|
||||
begin
|
||||
//This function extracts the information bits vector from the codeword
|
||||
//information bits are stored in non-power-of-2 locations
|
||||
|
||||
bit_idx=0; //information bit vector index
|
||||
for (cw_idx=1; cw_idx<=n; cw_idx++) //codeword index
|
||||
if (2**$clog2(cw_idx) != cw_idx)
|
||||
/* verilator lint_off UNUSEDSIGNAL */
|
||||
extract_q[bit_idx++] = cw[cw_idx];
|
||||
/* verilator lint_on UNUSEDSIGNAL */
|
||||
end
|
||||
endfunction //extract_q
|
||||
|
||||
|
||||
function is_power_of_2(input [m:1] n_local);
|
||||
is_power_of_2 = (n_local & (n_local-1)) == 0;
|
||||
endfunction
|
||||
|
||||
|
||||
function information_error(input [m:1] syndrome);
|
||||
begin
|
||||
//This function checks if an error was detected/corrected in the information bits
|
||||
information_error = |syndrome & !is_power_of_2(syndrome);
|
||||
end
|
||||
endfunction //information_error
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Variables
|
||||
//---------------------------------------------------------
|
||||
wire parity; //full codeword parity check
|
||||
logic parity_reg;
|
||||
wire [m :1] syndrome; //bit error indication/location
|
||||
logic [m :1] syndrome_reg;
|
||||
wire [n :0] cw_fixed; //corrected code word
|
||||
|
||||
wire [n :0] d;
|
||||
logic [n :0] d_reg;
|
||||
wire [K-1:0] q;
|
||||
wire sb_err;
|
||||
wire db_err;
|
||||
wire sb_fix;
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Module Body
|
||||
//---------------------------------------------------------
|
||||
|
||||
/*
|
||||
Below diagram indicates the locations of the parity and data bits
|
||||
in the final 'p' vector.
|
||||
It also shows what databits each parity bit operates on
|
||||
|
||||
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
p1 p2 d1 p4 d2 d3 d4 p8 d5 d6 d7 d8 d9 d10 d11
|
||||
p1 x x x x x x x x
|
||||
p2 x x x x x x x x
|
||||
p4 x x x x x x x x
|
||||
p8 x x x x x x x x
|
||||
*/
|
||||
|
||||
//Step 1: Locate Parity bit
|
||||
assign d = P0_LSB ? d_i : {d_i[n-1:0],d_i[n]};
|
||||
|
||||
//Step 2: Calculate code word parity
|
||||
assign parity = ^d;
|
||||
|
||||
//Step 3: Calculate syndrome
|
||||
assign syndrome = calculate_syndrome(d);
|
||||
|
||||
//Step 4: Generate intermediate registers (if any)
|
||||
generate
|
||||
if (LATENCY > 1)
|
||||
begin : gen_inter_reg_latency_g1
|
||||
always @(posedge clk_i or negedge rst_ni)
|
||||
if (!rst_ni)
|
||||
begin
|
||||
d_reg <= {n+1{1'b0}};
|
||||
parity_reg <= 1'b0;
|
||||
syndrome_reg <= {m{1'b0}};
|
||||
end
|
||||
else if (clkena_i)
|
||||
begin
|
||||
d_reg <= d;
|
||||
parity_reg <= parity;
|
||||
syndrome_reg <= syndrome;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin : gen_inter_reg_latency_0
|
||||
assign d_reg = d;
|
||||
assign parity_reg = parity;
|
||||
assign syndrome_reg = syndrome;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
//Step 5: Correct erroneous bit (if any)
|
||||
assign cw_fixed = correct_codeword(d_reg, syndrome_reg);
|
||||
|
||||
//Step 6: Extract information bits vector
|
||||
assign q = extract_q(cw_fixed);
|
||||
|
||||
//Step 7: Generate status flags
|
||||
assign sb_err = (parity_reg & |syndrome_reg);
|
||||
assign db_err = ~parity_reg & |syndrome_reg;
|
||||
assign sb_fix = parity_reg & |information_error(syndrome_reg);
|
||||
|
||||
//Step 8: Generate output registers (if required)
|
||||
generate
|
||||
if (LATENCY > 0)
|
||||
begin : gen_output_reg_latency_g0 //Generate output registers
|
||||
always @(posedge clk_i or negedge rst_ni)
|
||||
if (!rst_ni)
|
||||
begin
|
||||
q_o <= {K{1'b0}};
|
||||
syndrome_o <= {m+1{1'b0}};
|
||||
sb_err_o <= 1'b0;
|
||||
db_err_o <= 1'b0;
|
||||
sb_fix_o <= 1'b0;
|
||||
end
|
||||
else if (clkena_i)
|
||||
begin
|
||||
q_o <= q;
|
||||
syndrome_o <= P0_LSB ? {syndrome_reg, parity_reg} : {parity_reg, syndrome_reg};
|
||||
sb_err_o <= sb_err;
|
||||
db_err_o <= db_err;
|
||||
sb_fix_o <= sb_fix;
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
begin : gen_output_reg_latency_0//No output registers
|
||||
always_comb
|
||||
begin
|
||||
q_o = q;
|
||||
syndrome_o = P0_LSB ? {syndrome_reg, parity_reg} : {parity_reg, syndrome_reg};
|
||||
sb_err_o = sb_err;
|
||||
db_err_o = db_err;
|
||||
sb_fix_o = sb_fix;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,219 +1,219 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
// ,------. ,--. ,--. //
|
||||
// | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. //
|
||||
// | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' //
|
||||
// | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. //
|
||||
// `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' //
|
||||
// `---' //
|
||||
// Error Correction and Detection Encoder //
|
||||
// Parameterized Extended Hamming Code Encoder //
|
||||
// //
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Copyright (C) 2017 ROA Logic BV //
|
||||
// www.roalogic.com //
|
||||
// //
|
||||
// This source file may be used and distributed without //
|
||||
// restriction provided that this copyright statement is not //
|
||||
// removed from the file and that any derivative work contains //
|
||||
// the original copyright notice and the associated disclaimer. //
|
||||
// //
|
||||
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //
|
||||
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //
|
||||
// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR OR //
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, //
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT //
|
||||
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; //
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) //
|
||||
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN //
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR //
|
||||
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS //
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //
|
||||
// //
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// +FHDR - Semiconductor Reuse Standard File Header Section -------
|
||||
// FILE NAME : ecc_enc.sv
|
||||
// DEPARTMENT :
|
||||
// AUTHOR : rherveille
|
||||
// AUTHOR'S EMAIL :
|
||||
// ------------------------------------------------------------------
|
||||
// RELEASE HISTORY
|
||||
// VERSION DATE AUTHOR DESCRIPTION
|
||||
// 1.0 2017-04-07 rherveille initial release
|
||||
// ------------------------------------------------------------------
|
||||
// KEYWORDS : HAMMING ERROR CORRECTION ENCODER
|
||||
// ------------------------------------------------------------------
|
||||
// PURPOSE : Adds ECC bits to incoming data
|
||||
// ------------------------------------------------------------------
|
||||
// PARAMETERS
|
||||
// PARAM NAME RANGE DESCRIPTION DEFAULT UNITS
|
||||
// K 1+ Information vector size 8
|
||||
// P0_LSB 0,1 0: p0 located at MSB 1
|
||||
// 1: p0 located at LSB
|
||||
// ------------------------------------------------------------------
|
||||
// REUSE ISSUES
|
||||
// Reset Strategy : none
|
||||
// Clock Domains : none
|
||||
// Critical Timing :
|
||||
// Test Features : na
|
||||
// Asynchronous I/F : yes
|
||||
// Scan Methodology : na
|
||||
// Instantiations : none
|
||||
// Synthesizable (y/n) : Yes
|
||||
// Other :
|
||||
// -FHDR-------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Hamming codes can detect and correct a single bit error.
|
||||
// An extended Hamming code allows detection of double bit errors and
|
||||
// correction of single bit errors.
|
||||
// This is called SECDED; Single Error Correction, Double Error Detection
|
||||
//
|
||||
// Number of bits required by a Hamming code: n = m + k
|
||||
// n = code length
|
||||
// m = number of check bits
|
||||
// k = number of information bits
|
||||
//
|
||||
// Information, parity, and syndrome expressed as vectors:
|
||||
// u = Information bit vector
|
||||
// p = Parity check bit vector
|
||||
// s = Syndrome vector
|
||||
//
|
||||
// The parity vector is encoded in 'n'.
|
||||
// The information bit vector is part of 'p'
|
||||
// The syndrome vector needs to be calculated.
|
||||
//
|
||||
// Bits required:
|
||||
// p ranges from 0 to m+k; or p_range=m+k+1
|
||||
// As a result 2^m >= m+k+1
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
module ecc_enc #(
|
||||
parameter K = 8, //Information bit vector size
|
||||
parameter P0_LSB = 1, //0: p0 is located at MSB
|
||||
//1: p0 is located at LSB
|
||||
|
||||
//these should be localparams
|
||||
parameter m = calculate_m(K),
|
||||
parameter n = m + K
|
||||
)
|
||||
(
|
||||
input [K-1:0] d_i, //information bit vector input
|
||||
output [n :0] q_o, //encoded data word output
|
||||
|
||||
output [m :1] p_o, //parity vector output
|
||||
output p0_o //extended parity bit
|
||||
);
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Functions
|
||||
//---------------------------------------------------------
|
||||
function integer calculate_m;
|
||||
input integer k;
|
||||
|
||||
integer m_local;
|
||||
begin
|
||||
m_local=1;
|
||||
while (2**m_local < m_local+k+1) m_local++;
|
||||
|
||||
calculate_m = m_local;
|
||||
end
|
||||
endfunction //calculate_m
|
||||
|
||||
|
||||
function [n:1] store_dbits_in_codeword;
|
||||
input [K-1:0] d;
|
||||
|
||||
integer bit_idx, cw_idx;
|
||||
begin
|
||||
//This function puts the information bits vector in the correct location
|
||||
//Information bits are stored in non-power-of-2 locations
|
||||
|
||||
//clear all bits
|
||||
store_dbits_in_codeword = 0;
|
||||
|
||||
bit_idx=0; //information vector bit index
|
||||
for (cw_idx=1; cw_idx<=n; cw_idx++)
|
||||
if (2**$clog2(cw_idx) != cw_idx)
|
||||
/* verilator lint_off UNUSEDSIGNAL */
|
||||
store_dbits_in_codeword[cw_idx] = d[bit_idx++];
|
||||
/* verilator lint_on UNUSEDSIGNAL */
|
||||
end
|
||||
endfunction //store_dbits_in_codeword
|
||||
|
||||
|
||||
function [m:1] calculate_p;
|
||||
input [n:1] cw;
|
||||
|
||||
integer p_idx, cw_idx;
|
||||
begin
|
||||
//clear p
|
||||
calculate_p = 0;
|
||||
|
||||
for (p_idx =1; p_idx <=m; p_idx++) //parity-index
|
||||
for (cw_idx=1; cw_idx<=n; cw_idx++) //codeword-index
|
||||
if (|(2**(p_idx-1) & cw_idx)) calculate_p[p_idx] = calculate_p[p_idx] ^ cw[cw_idx];
|
||||
end
|
||||
endfunction //calculate_p
|
||||
|
||||
|
||||
function [n:1] store_p_in_codeword;
|
||||
input [n:1] cw;
|
||||
input [m:1] p;
|
||||
|
||||
integer i;
|
||||
begin
|
||||
//databits don't change ... copy into codeword
|
||||
store_p_in_codeword = cw;
|
||||
|
||||
//put parity vector at power-of-2 locations
|
||||
for (i=1; i<=m; i=i+1)
|
||||
store_p_in_codeword[2**(i-1)] = p[i];
|
||||
end
|
||||
endfunction //store_p_in_codeword
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Variables
|
||||
//---------------------------------------------------------
|
||||
logic [n:1] cw_w_dbits; //codeword with loaded data bits
|
||||
logic [n:1] cw; //codeword with information + parity bits
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Module Body
|
||||
//---------------------------------------------------------
|
||||
|
||||
/*
|
||||
Below diagram indicates the locations of the parity and data bits
|
||||
in the final 'p' vector.
|
||||
It also shows what databits each parity bit operates on
|
||||
|
||||
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
p1 p2 d1 p4 d2 d3 d4 p8 d5 d6 d7 d8 d9 d10 d11
|
||||
p1 x x x x x x x x
|
||||
p2 x x x x x x x x
|
||||
p4 x x x x x x x x
|
||||
p8 x x x x x x x x
|
||||
*/
|
||||
|
||||
//Step 1: Load all databits in codeword
|
||||
assign cw_w_dbits = store_dbits_in_codeword(d_i);
|
||||
|
||||
//Step 2: Calculate p-vector
|
||||
assign p_o = calculate_p(cw_w_dbits);
|
||||
|
||||
//Step 3: Store p-vector in codeword
|
||||
assign cw = store_p_in_codeword(cw_w_dbits, p_o);
|
||||
|
||||
//Step 4: Calculate p0 (extended parity bit)
|
||||
// and store it in the codeword
|
||||
assign p0_o = ^cw;
|
||||
assign q_o = P0_LSB ? {cw,p0_o} : {p0_o,cw};
|
||||
|
||||
endmodule
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// ,------. ,--. ,--. //
|
||||
// | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. //
|
||||
// | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' //
|
||||
// | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. //
|
||||
// `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' //
|
||||
// `---' //
|
||||
// Error Correction and Detection Encoder //
|
||||
// Parameterized Extended Hamming Code Encoder //
|
||||
// //
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Copyright (C) 2017 ROA Logic BV //
|
||||
// www.roalogic.com //
|
||||
// //
|
||||
// This source file may be used and distributed without //
|
||||
// restriction provided that this copyright statement is not //
|
||||
// removed from the file and that any derivative work contains //
|
||||
// the original copyright notice and the associated disclaimer. //
|
||||
// //
|
||||
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //
|
||||
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //
|
||||
// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR OR //
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, //
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT //
|
||||
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; //
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) //
|
||||
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN //
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR //
|
||||
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS //
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //
|
||||
// //
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// +FHDR - Semiconductor Reuse Standard File Header Section -------
|
||||
// FILE NAME : ecc_enc.sv
|
||||
// DEPARTMENT :
|
||||
// AUTHOR : rherveille
|
||||
// AUTHOR'S EMAIL :
|
||||
// ------------------------------------------------------------------
|
||||
// RELEASE HISTORY
|
||||
// VERSION DATE AUTHOR DESCRIPTION
|
||||
// 1.0 2017-04-07 rherveille initial release
|
||||
// ------------------------------------------------------------------
|
||||
// KEYWORDS : HAMMING ERROR CORRECTION ENCODER
|
||||
// ------------------------------------------------------------------
|
||||
// PURPOSE : Adds ECC bits to incoming data
|
||||
// ------------------------------------------------------------------
|
||||
// PARAMETERS
|
||||
// PARAM NAME RANGE DESCRIPTION DEFAULT UNITS
|
||||
// K 1+ Information vector size 8
|
||||
// P0_LSB 0,1 0: p0 located at MSB 1
|
||||
// 1: p0 located at LSB
|
||||
// ------------------------------------------------------------------
|
||||
// REUSE ISSUES
|
||||
// Reset Strategy : none
|
||||
// Clock Domains : none
|
||||
// Critical Timing :
|
||||
// Test Features : na
|
||||
// Asynchronous I/F : yes
|
||||
// Scan Methodology : na
|
||||
// Instantiations : none
|
||||
// Synthesizable (y/n) : Yes
|
||||
// Other :
|
||||
// -FHDR-------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Hamming codes can detect and correct a single bit error.
|
||||
// An extended Hamming code allows detection of double bit errors and
|
||||
// correction of single bit errors.
|
||||
// This is called SECDED; Single Error Correction, Double Error Detection
|
||||
//
|
||||
// Number of bits required by a Hamming code: n = m + k
|
||||
// n = code length
|
||||
// m = number of check bits
|
||||
// k = number of information bits
|
||||
//
|
||||
// Information, parity, and syndrome expressed as vectors:
|
||||
// u = Information bit vector
|
||||
// p = Parity check bit vector
|
||||
// s = Syndrome vector
|
||||
//
|
||||
// The parity vector is encoded in 'n'.
|
||||
// The information bit vector is part of 'p'
|
||||
// The syndrome vector needs to be calculated.
|
||||
//
|
||||
// Bits required:
|
||||
// p ranges from 0 to m+k; or p_range=m+k+1
|
||||
// As a result 2^m >= m+k+1
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
module ecc_enc #(
|
||||
parameter K = 8, //Information bit vector size
|
||||
parameter P0_LSB = 1, //0: p0 is located at MSB
|
||||
//1: p0 is located at LSB
|
||||
|
||||
//these should be localparams
|
||||
parameter m = calculate_m(K),
|
||||
parameter n = m + K
|
||||
)
|
||||
(
|
||||
input [K-1:0] d_i, //information bit vector input
|
||||
output [n :0] q_o, //encoded data word output
|
||||
|
||||
output [m :1] p_o, //parity vector output
|
||||
output p0_o //extended parity bit
|
||||
);
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Functions
|
||||
//---------------------------------------------------------
|
||||
function integer calculate_m;
|
||||
input integer k;
|
||||
|
||||
integer m_local;
|
||||
begin
|
||||
m_local=1;
|
||||
while (2**m_local < m_local+k+1) m_local++;
|
||||
|
||||
calculate_m = m_local;
|
||||
end
|
||||
endfunction //calculate_m
|
||||
|
||||
|
||||
function [n:1] store_dbits_in_codeword;
|
||||
input [K-1:0] d;
|
||||
|
||||
integer bit_idx, cw_idx;
|
||||
begin
|
||||
//This function puts the information bits vector in the correct location
|
||||
//Information bits are stored in non-power-of-2 locations
|
||||
|
||||
//clear all bits
|
||||
store_dbits_in_codeword = 0;
|
||||
|
||||
bit_idx=0; //information vector bit index
|
||||
for (cw_idx=1; cw_idx<=n; cw_idx++)
|
||||
if (2**$clog2(cw_idx) != cw_idx)
|
||||
/* verilator lint_off UNUSEDSIGNAL */
|
||||
store_dbits_in_codeword[cw_idx] = d[bit_idx++];
|
||||
/* verilator lint_on UNUSEDSIGNAL */
|
||||
end
|
||||
endfunction //store_dbits_in_codeword
|
||||
|
||||
|
||||
function [m:1] calculate_p;
|
||||
input [n:1] cw;
|
||||
|
||||
integer p_idx, cw_idx;
|
||||
begin
|
||||
//clear p
|
||||
calculate_p = 0;
|
||||
|
||||
for (p_idx =1; p_idx <=m; p_idx++) //parity-index
|
||||
for (cw_idx=1; cw_idx<=n; cw_idx++) //codeword-index
|
||||
if (|(2**(p_idx-1) & cw_idx)) calculate_p[p_idx] = calculate_p[p_idx] ^ cw[cw_idx];
|
||||
end
|
||||
endfunction //calculate_p
|
||||
|
||||
|
||||
function [n:1] store_p_in_codeword;
|
||||
input [n:1] cw;
|
||||
input [m:1] p;
|
||||
|
||||
integer i;
|
||||
begin
|
||||
//databits don't change ... copy into codeword
|
||||
store_p_in_codeword = cw;
|
||||
|
||||
//put parity vector at power-of-2 locations
|
||||
for (i=1; i<=m; i=i+1)
|
||||
store_p_in_codeword[2**(i-1)] = p[i];
|
||||
end
|
||||
endfunction //store_p_in_codeword
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Variables
|
||||
//---------------------------------------------------------
|
||||
logic [n:1] cw_w_dbits; //codeword with loaded data bits
|
||||
logic [n:1] cw; //codeword with information + parity bits
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Module Body
|
||||
//---------------------------------------------------------
|
||||
|
||||
/*
|
||||
Below diagram indicates the locations of the parity and data bits
|
||||
in the final 'p' vector.
|
||||
It also shows what databits each parity bit operates on
|
||||
|
||||
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
p1 p2 d1 p4 d2 d3 d4 p8 d5 d6 d7 d8 d9 d10 d11
|
||||
p1 x x x x x x x x
|
||||
p2 x x x x x x x x
|
||||
p4 x x x x x x x x
|
||||
p8 x x x x x x x x
|
||||
*/
|
||||
|
||||
//Step 1: Load all databits in codeword
|
||||
assign cw_w_dbits = store_dbits_in_codeword(d_i);
|
||||
|
||||
//Step 2: Calculate p-vector
|
||||
assign p_o = calculate_p(cw_w_dbits);
|
||||
|
||||
//Step 3: Store p-vector in codeword
|
||||
assign cw = store_p_in_codeword(cw_w_dbits, p_o);
|
||||
|
||||
//Step 4: Calculate p0 (extended parity bit)
|
||||
// and store it in the codeword
|
||||
assign p0_o = ^cw;
|
||||
assign q_o = P0_LSB ? {cw,p0_o} : {p0_o,cw};
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
160
run_compile.sh
160
run_compile.sh
|
|
@ -1,80 +1,80 @@
|
|||
# Clean files
|
||||
rm -rf formal/ddr3*prf*
|
||||
rm -rf formal/ddr3_singleconfig
|
||||
|
||||
# run verilator lint
|
||||
echo -e "\e[32mRun Verilator Lint:\e[0m"
|
||||
verilator --lint-only rtl/ddr3_controller.v rtl/ecc/ecc_dec.sv rtl/ecc/ecc_enc.sv
|
||||
echo "DONE!"
|
||||
|
||||
|
||||
# run yosys compile
|
||||
echo ""
|
||||
echo ""
|
||||
echo -e "\e[32mRun Yosys Compile:\e[0m"
|
||||
yosys -q -p "
|
||||
read_verilog -sv ./rtl/ddr3_controller.v rtl/ecc/ecc_dec.sv rtl/ecc/ecc_enc.sv;
|
||||
synth -top ddr3_controller"
|
||||
|
||||
# run iverilog compile
|
||||
echo ""
|
||||
echo ""
|
||||
echo -e "\e[32mRun IVerilog Compile:\e[0m"
|
||||
iverilog rtl/ddr3_controller.v -o out
|
||||
vvp out
|
||||
rm out
|
||||
echo
|
||||
|
||||
# run symbiyosys
|
||||
echo ""
|
||||
echo -e "\e[32mRun Symbiyosys Formal Verification: ECC\e[0m"
|
||||
echo "---------------------------------------"
|
||||
sby -f formal/ecc.sby
|
||||
|
||||
echo ""
|
||||
echo -e "\e[32mRun Symbiyosys Formal Verification: Single Configuration\e[0m"
|
||||
echo "---------------------------------------"
|
||||
sby -f formal/ddr3_singleconfig.sby
|
||||
|
||||
echo ""
|
||||
echo -e "\e[32mRun Symbiyosys Formal Verification: Multiple Configurations (DEFAULT)\e[0m"
|
||||
echo "---------------------------------------"
|
||||
sby -f formal/ddr3_multiconfig_default.sby
|
||||
|
||||
echo ""
|
||||
echo -e "\e[32mRun Symbiyosys Formal Verification: Multiple Configurations (ECC)\e[0m"
|
||||
echo "---------------------------------------"
|
||||
sby -f formal/ddr3_multiconfig_ecc.sby
|
||||
|
||||
|
||||
# ANSI color codes
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
echo "Summary:"
|
||||
# Iterate over folders starting with 'ddr3*'
|
||||
for folder in formal/ddr3*/ ; do
|
||||
# Check if the 'PASS' file exists in the folder
|
||||
if [[ -e "${folder}PASS" ]]; then
|
||||
# Print the folder name and 'PASS' in green
|
||||
echo -e "${folder}: ${GREEN}PASS${NC}"
|
||||
else
|
||||
# Print the folder name and 'FAIL' in red
|
||||
echo -e "${folder}: ${RED}FAIL${NC}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Iterate over folders inside 'ecc/'
|
||||
for folder in formal/ecc/ ; do
|
||||
# Check if the 'PASS' file exists in the folder
|
||||
if [[ -e "${folder}PASS" ]]; then
|
||||
# Print the folder name and 'PASS' in green
|
||||
echo -e "${folder}: ${GREEN}PASS${NC}"
|
||||
else
|
||||
# Print the folder name and 'FAIL' in red
|
||||
echo -e "${folder}: ${RED}FAIL${NC}"
|
||||
fi
|
||||
done
|
||||
# Clean files
|
||||
rm -rf formal/ddr3*prf*
|
||||
rm -rf formal/ddr3_singleconfig
|
||||
|
||||
# run verilator lint
|
||||
echo -e "\e[32mRun Verilator Lint:\e[0m"
|
||||
verilator --lint-only rtl/ddr3_controller.v rtl/ecc/ecc_dec.sv rtl/ecc/ecc_enc.sv -Irtl/ -Wall
|
||||
echo "DONE!"
|
||||
|
||||
|
||||
# run yosys compile
|
||||
echo ""
|
||||
echo ""
|
||||
echo -e "\e[32mRun Yosys Compile:\e[0m"
|
||||
yosys -q -p "
|
||||
read_verilog -sv ./rtl/ddr3_controller.v rtl/ecc/ecc_dec.sv rtl/ecc/ecc_enc.sv;
|
||||
synth -top ddr3_controller"
|
||||
|
||||
# run iverilog compile
|
||||
echo ""
|
||||
echo ""
|
||||
echo -e "\e[32mRun IVerilog Compile:\e[0m"
|
||||
iverilog rtl/ddr3_controller.v -o out
|
||||
vvp out
|
||||
rm out
|
||||
echo
|
||||
|
||||
# run symbiyosys
|
||||
echo ""
|
||||
echo -e "\e[32mRun Symbiyosys Formal Verification: ECC\e[0m"
|
||||
echo "---------------------------------------"
|
||||
sby -f formal/ecc.sby
|
||||
|
||||
echo ""
|
||||
echo -e "\e[32mRun Symbiyosys Formal Verification: Single Configuration\e[0m"
|
||||
echo "---------------------------------------"
|
||||
sby -f formal/ddr3_singleconfig.sby
|
||||
|
||||
echo ""
|
||||
echo -e "\e[32mRun Symbiyosys Formal Verification: Multiple Configurations (DEFAULT)\e[0m"
|
||||
echo "---------------------------------------"
|
||||
sby -f formal/ddr3_multiconfig_default.sby
|
||||
|
||||
echo ""
|
||||
echo -e "\e[32mRun Symbiyosys Formal Verification: Multiple Configurations (ECC)\e[0m"
|
||||
echo "---------------------------------------"
|
||||
sby -f formal/ddr3_multiconfig_ecc.sby
|
||||
|
||||
|
||||
# ANSI color codes
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
echo "Summary:"
|
||||
# Iterate over folders starting with 'ddr3*'
|
||||
for folder in formal/ddr3*/ ; do
|
||||
# Check if the 'PASS' file exists in the folder
|
||||
if [[ -e "${folder}PASS" ]]; then
|
||||
# Print the folder name and 'PASS' in green
|
||||
echo -e "${folder}: ${GREEN}PASS${NC}"
|
||||
else
|
||||
# Print the folder name and 'FAIL' in red
|
||||
echo -e "${folder}: ${RED}FAIL${NC}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Iterate over folders inside 'ecc/'
|
||||
for folder in formal/ecc/ ; do
|
||||
# Check if the 'PASS' file exists in the folder
|
||||
if [[ -e "${folder}PASS" ]]; then
|
||||
# Print the folder name and 'PASS' in green
|
||||
echo -e "${folder}: ${GREEN}PASS${NC}"
|
||||
else
|
||||
# Print the folder name and 'FAIL' in red
|
||||
echo -e "${folder}: ${RED}FAIL${NC}"
|
||||
fi
|
||||
done
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,258 +1,258 @@
|
|||
memory_initialization_radix = 16;
|
||||
memory_initialization_vector =
|
||||
00000000
|
||||
00000000
|
||||
00000010
|
||||
00000010
|
||||
00000020
|
||||
00000020
|
||||
00000030
|
||||
00000030
|
||||
00000040
|
||||
00000040
|
||||
00000050
|
||||
00000050
|
||||
00000060
|
||||
00000060
|
||||
00000070
|
||||
00000070
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
ffffffff
|
||||
;
|
||||
memory_initialization_radix = 16;
|
||||
memory_initialization_vector =
|
||||
00000000
|
||||
00000000
|
||||
00000010
|
||||
00000010
|
||||
00000020
|
||||
00000020
|
||||
00000030
|
||||
00000030
|
||||
00000040
|
||||
00000040
|
||||
00000050
|
||||
00000050
|
||||
00000060
|
||||
00000060
|
||||
00000070
|
||||
00000070
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
ffffffff
|
||||
;
|
||||
|
|
|
|||
|
|
@ -1,258 +1,258 @@
|
|||
memory_initialization_radix = 16;
|
||||
memory_initialization_vector =
|
||||
00030100
|
||||
00020201
|
||||
00030302
|
||||
00020403
|
||||
00030504
|
||||
00020605
|
||||
00030706
|
||||
00020807
|
||||
00030908
|
||||
00020a09
|
||||
00030b0a
|
||||
00020c0b
|
||||
00030d0c
|
||||
00020e0d
|
||||
00030f0e
|
||||
0002100f
|
||||
00031110
|
||||
00031211
|
||||
00031312
|
||||
00031413
|
||||
00031514
|
||||
00031615
|
||||
00031716
|
||||
00031817
|
||||
00031918
|
||||
00031a19
|
||||
00031b1a
|
||||
00031c1b
|
||||
00031d1c
|
||||
00031e1d
|
||||
00031f1e
|
||||
0003201f
|
||||
00032120
|
||||
00032221
|
||||
00032322
|
||||
00032423
|
||||
00032524
|
||||
00032625
|
||||
00032726
|
||||
00032827
|
||||
00032928
|
||||
00032a29
|
||||
00032b2a
|
||||
00032c2b
|
||||
00032d2c
|
||||
00032e2d
|
||||
00032f2e
|
||||
0003302f
|
||||
00033130
|
||||
00033231
|
||||
00033332
|
||||
00033433
|
||||
00033534
|
||||
00033635
|
||||
00033736
|
||||
00033837
|
||||
00033938
|
||||
00033a39
|
||||
00033b3a
|
||||
00033c3b
|
||||
00033d3c
|
||||
00033e3d
|
||||
00033f3e
|
||||
0003403f
|
||||
00034140
|
||||
00034241
|
||||
00034342
|
||||
00034443
|
||||
00034544
|
||||
00034645
|
||||
00034746
|
||||
00034847
|
||||
00034948
|
||||
00034a49
|
||||
00034b4a
|
||||
00034c4b
|
||||
00034d4c
|
||||
00034e4d
|
||||
00034f4e
|
||||
0003504f
|
||||
00035150
|
||||
00035251
|
||||
00035352
|
||||
00035453
|
||||
00035554
|
||||
00035655
|
||||
00035756
|
||||
00035857
|
||||
00035958
|
||||
00035a59
|
||||
00035b5a
|
||||
00035c5b
|
||||
00035d5c
|
||||
00035e5d
|
||||
00035f5e
|
||||
0003605f
|
||||
00036160
|
||||
00036261
|
||||
00036362
|
||||
00036463
|
||||
00036564
|
||||
00036665
|
||||
00036766
|
||||
00036867
|
||||
00036968
|
||||
00036a69
|
||||
00036b6a
|
||||
00036c6b
|
||||
00036d6c
|
||||
00036e6d
|
||||
00036f6e
|
||||
0003706f
|
||||
00037170
|
||||
00037271
|
||||
00037372
|
||||
00037473
|
||||
00037574
|
||||
00037675
|
||||
00037776
|
||||
00037877
|
||||
00037978
|
||||
00037a79
|
||||
00037b7a
|
||||
00037c7b
|
||||
00037d7c
|
||||
00037e7d
|
||||
00037f7e
|
||||
0003807f
|
||||
00038180
|
||||
00038281
|
||||
00038382
|
||||
00038483
|
||||
00038584
|
||||
00038685
|
||||
00038786
|
||||
00038887
|
||||
00038988
|
||||
00038a89
|
||||
00038b8a
|
||||
00038c8b
|
||||
00038d8c
|
||||
00038e8d
|
||||
00038f8e
|
||||
0003908f
|
||||
00039190
|
||||
00039291
|
||||
00039392
|
||||
00039493
|
||||
00039594
|
||||
00039695
|
||||
00039796
|
||||
00039897
|
||||
00039998
|
||||
00039a99
|
||||
00039b9a
|
||||
00039c9b
|
||||
00039d9c
|
||||
00039e9d
|
||||
00039f9e
|
||||
0003a09f
|
||||
0003a1a0
|
||||
0003a2a1
|
||||
0003a3a2
|
||||
0003a4a3
|
||||
0003a5a4
|
||||
0003a6a5
|
||||
0003a7a6
|
||||
0003a8a7
|
||||
0003a9a8
|
||||
0003aaa9
|
||||
0003abaa
|
||||
0003acab
|
||||
0003adac
|
||||
0003aead
|
||||
0003afae
|
||||
0003b0af
|
||||
0003b1b0
|
||||
0003b2b1
|
||||
0003b3b2
|
||||
0003b4b3
|
||||
0003b5b4
|
||||
0003b6b5
|
||||
0003b7b6
|
||||
0003b8b7
|
||||
0003b9b8
|
||||
0003bab9
|
||||
0003bbba
|
||||
0003bcbb
|
||||
0003bdbc
|
||||
0003bebd
|
||||
0003bfbe
|
||||
0003c0bf
|
||||
0003c1c0
|
||||
0003c2c1
|
||||
0003c3c2
|
||||
0003c4c3
|
||||
0003c5c4
|
||||
0003c6c5
|
||||
0003c7c6
|
||||
0003c8c7
|
||||
0003c9c8
|
||||
0003cac9
|
||||
0003cbca
|
||||
0003cccb
|
||||
0003cdcc
|
||||
0003cecd
|
||||
0003cfce
|
||||
0003d0cf
|
||||
0003d1d0
|
||||
0003d2d1
|
||||
0003d3d2
|
||||
0003d4d3
|
||||
0003d5d4
|
||||
0003d6d5
|
||||
0003d7d6
|
||||
0003d8d7
|
||||
0003d9d8
|
||||
0003dad9
|
||||
0003dbda
|
||||
0003dcdb
|
||||
0003dddc
|
||||
0003dedd
|
||||
0003dfde
|
||||
0003e0df
|
||||
0003e1e0
|
||||
0003e2e1
|
||||
0003e3e2
|
||||
0003e4e3
|
||||
0003e5e4
|
||||
0003e6e5
|
||||
0003e7e6
|
||||
0003e8e7
|
||||
0003e9e8
|
||||
0003eae9
|
||||
0003ebea
|
||||
0003eceb
|
||||
0003edec
|
||||
0003eeed
|
||||
0003efee
|
||||
0003f0ef
|
||||
0003f1f0
|
||||
0003f2f1
|
||||
0003f3f2
|
||||
0003f4f3
|
||||
0003f5f4
|
||||
0003f6f5
|
||||
0003f7f6
|
||||
0003f8f7
|
||||
0003f9f8
|
||||
0003faf9
|
||||
0003fbfa
|
||||
0003fcfb
|
||||
0003fdfc
|
||||
0003fefd
|
||||
0003fffe
|
||||
;
|
||||
memory_initialization_radix = 16;
|
||||
memory_initialization_vector =
|
||||
00030100
|
||||
00020201
|
||||
00030302
|
||||
00020403
|
||||
00030504
|
||||
00020605
|
||||
00030706
|
||||
00020807
|
||||
00030908
|
||||
00020a09
|
||||
00030b0a
|
||||
00020c0b
|
||||
00030d0c
|
||||
00020e0d
|
||||
00030f0e
|
||||
0002100f
|
||||
00031110
|
||||
00031211
|
||||
00031312
|
||||
00031413
|
||||
00031514
|
||||
00031615
|
||||
00031716
|
||||
00031817
|
||||
00031918
|
||||
00031a19
|
||||
00031b1a
|
||||
00031c1b
|
||||
00031d1c
|
||||
00031e1d
|
||||
00031f1e
|
||||
0003201f
|
||||
00032120
|
||||
00032221
|
||||
00032322
|
||||
00032423
|
||||
00032524
|
||||
00032625
|
||||
00032726
|
||||
00032827
|
||||
00032928
|
||||
00032a29
|
||||
00032b2a
|
||||
00032c2b
|
||||
00032d2c
|
||||
00032e2d
|
||||
00032f2e
|
||||
0003302f
|
||||
00033130
|
||||
00033231
|
||||
00033332
|
||||
00033433
|
||||
00033534
|
||||
00033635
|
||||
00033736
|
||||
00033837
|
||||
00033938
|
||||
00033a39
|
||||
00033b3a
|
||||
00033c3b
|
||||
00033d3c
|
||||
00033e3d
|
||||
00033f3e
|
||||
0003403f
|
||||
00034140
|
||||
00034241
|
||||
00034342
|
||||
00034443
|
||||
00034544
|
||||
00034645
|
||||
00034746
|
||||
00034847
|
||||
00034948
|
||||
00034a49
|
||||
00034b4a
|
||||
00034c4b
|
||||
00034d4c
|
||||
00034e4d
|
||||
00034f4e
|
||||
0003504f
|
||||
00035150
|
||||
00035251
|
||||
00035352
|
||||
00035453
|
||||
00035554
|
||||
00035655
|
||||
00035756
|
||||
00035857
|
||||
00035958
|
||||
00035a59
|
||||
00035b5a
|
||||
00035c5b
|
||||
00035d5c
|
||||
00035e5d
|
||||
00035f5e
|
||||
0003605f
|
||||
00036160
|
||||
00036261
|
||||
00036362
|
||||
00036463
|
||||
00036564
|
||||
00036665
|
||||
00036766
|
||||
00036867
|
||||
00036968
|
||||
00036a69
|
||||
00036b6a
|
||||
00036c6b
|
||||
00036d6c
|
||||
00036e6d
|
||||
00036f6e
|
||||
0003706f
|
||||
00037170
|
||||
00037271
|
||||
00037372
|
||||
00037473
|
||||
00037574
|
||||
00037675
|
||||
00037776
|
||||
00037877
|
||||
00037978
|
||||
00037a79
|
||||
00037b7a
|
||||
00037c7b
|
||||
00037d7c
|
||||
00037e7d
|
||||
00037f7e
|
||||
0003807f
|
||||
00038180
|
||||
00038281
|
||||
00038382
|
||||
00038483
|
||||
00038584
|
||||
00038685
|
||||
00038786
|
||||
00038887
|
||||
00038988
|
||||
00038a89
|
||||
00038b8a
|
||||
00038c8b
|
||||
00038d8c
|
||||
00038e8d
|
||||
00038f8e
|
||||
0003908f
|
||||
00039190
|
||||
00039291
|
||||
00039392
|
||||
00039493
|
||||
00039594
|
||||
00039695
|
||||
00039796
|
||||
00039897
|
||||
00039998
|
||||
00039a99
|
||||
00039b9a
|
||||
00039c9b
|
||||
00039d9c
|
||||
00039e9d
|
||||
00039f9e
|
||||
0003a09f
|
||||
0003a1a0
|
||||
0003a2a1
|
||||
0003a3a2
|
||||
0003a4a3
|
||||
0003a5a4
|
||||
0003a6a5
|
||||
0003a7a6
|
||||
0003a8a7
|
||||
0003a9a8
|
||||
0003aaa9
|
||||
0003abaa
|
||||
0003acab
|
||||
0003adac
|
||||
0003aead
|
||||
0003afae
|
||||
0003b0af
|
||||
0003b1b0
|
||||
0003b2b1
|
||||
0003b3b2
|
||||
0003b4b3
|
||||
0003b5b4
|
||||
0003b6b5
|
||||
0003b7b6
|
||||
0003b8b7
|
||||
0003b9b8
|
||||
0003bab9
|
||||
0003bbba
|
||||
0003bcbb
|
||||
0003bdbc
|
||||
0003bebd
|
||||
0003bfbe
|
||||
0003c0bf
|
||||
0003c1c0
|
||||
0003c2c1
|
||||
0003c3c2
|
||||
0003c4c3
|
||||
0003c5c4
|
||||
0003c6c5
|
||||
0003c7c6
|
||||
0003c8c7
|
||||
0003c9c8
|
||||
0003cac9
|
||||
0003cbca
|
||||
0003cccb
|
||||
0003cdcc
|
||||
0003cecd
|
||||
0003cfce
|
||||
0003d0cf
|
||||
0003d1d0
|
||||
0003d2d1
|
||||
0003d3d2
|
||||
0003d4d3
|
||||
0003d5d4
|
||||
0003d6d5
|
||||
0003d7d6
|
||||
0003d8d7
|
||||
0003d9d8
|
||||
0003dad9
|
||||
0003dbda
|
||||
0003dcdb
|
||||
0003dddc
|
||||
0003dedd
|
||||
0003dfde
|
||||
0003e0df
|
||||
0003e1e0
|
||||
0003e2e1
|
||||
0003e3e2
|
||||
0003e4e3
|
||||
0003e5e4
|
||||
0003e6e5
|
||||
0003e7e6
|
||||
0003e8e7
|
||||
0003e9e8
|
||||
0003eae9
|
||||
0003ebea
|
||||
0003eceb
|
||||
0003edec
|
||||
0003eeed
|
||||
0003efee
|
||||
0003f0ef
|
||||
0003f1f0
|
||||
0003f2f1
|
||||
0003f3f2
|
||||
0003f4f3
|
||||
0003f5f4
|
||||
0003f6f5
|
||||
0003f7f6
|
||||
0003f8f7
|
||||
0003f9f8
|
||||
0003faf9
|
||||
0003fbfa
|
||||
0003fcfb
|
||||
0003fdfc
|
||||
0003fefd
|
||||
0003fffe
|
||||
;
|
||||
|
|
|
|||
|
|
@ -1,258 +1,258 @@
|
|||
memory_initialization_radix = 16;
|
||||
memory_initialization_vector =
|
||||
01234567
|
||||
00000000
|
||||
89abcdef
|
||||
00000000
|
||||
19283746
|
||||
00000000
|
||||
afdec70a
|
||||
00000000
|
||||
12121212
|
||||
00000000
|
||||
34343434
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
ffffffff
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
;
|
||||
memory_initialization_radix = 16;
|
||||
memory_initialization_vector =
|
||||
01234567
|
||||
00000000
|
||||
89abcdef
|
||||
00000000
|
||||
19283746
|
||||
00000000
|
||||
afdec70a
|
||||
00000000
|
||||
12121212
|
||||
00000000
|
||||
34343434
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
ffffffff
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
;
|
||||
|
|
|
|||
|
|
@ -1,205 +1,205 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<wave_config>
|
||||
<wave_state>
|
||||
</wave_state>
|
||||
<db_ref_list>
|
||||
<db_ref path="ddr3_axi_traffic_gen_behav.wdb" id="1">
|
||||
<top_modules>
|
||||
<top_module name="ddr3_axi_traffic_gen_tb" />
|
||||
<top_module name="glbl" />
|
||||
</top_modules>
|
||||
</db_ref>
|
||||
</db_ref_list>
|
||||
<zoom_setting>
|
||||
<ZoomStartTime time="56,185.259 ns"></ZoomStartTime>
|
||||
<ZoomEndTime time="56,341.826 ns"></ZoomEndTime>
|
||||
<Cursor1Time time="56,242.459 ns"></Cursor1Time>
|
||||
</zoom_setting>
|
||||
<column_width_setting>
|
||||
<NameColumnWidth column_width="276"></NameColumnWidth>
|
||||
<ValueColumnWidth column_width="84"></ValueColumnWidth>
|
||||
</column_width_setting>
|
||||
<WVObjectSize size="45" />
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/i_controller_clk">
|
||||
<obj_property name="ElementShortName">i_controller_clk</obj_property>
|
||||
<obj_property name="ObjectShortName">i_controller_clk</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/i_ddr3_clk">
|
||||
<obj_property name="ElementShortName">i_ddr3_clk</obj_property>
|
||||
<obj_property name="ObjectShortName">i_ddr3_clk</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/i_ref_clk">
|
||||
<obj_property name="ElementShortName">i_ref_clk</obj_property>
|
||||
<obj_property name="ObjectShortName">i_ref_clk</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/i_ddr3_clk_90">
|
||||
<obj_property name="ElementShortName">i_ddr3_clk_90</obj_property>
|
||||
<obj_property name="ObjectShortName">i_ddr3_clk_90</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/i_rst_n">
|
||||
<obj_property name="ElementShortName">i_rst_n</obj_property>
|
||||
<obj_property name="ObjectShortName">i_rst_n</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="divider622" type="divider">
|
||||
<obj_property name="label">AXI Lite (Traffic Generator)</obj_property>
|
||||
<obj_property name="DisplayName">label</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/s_axi_aclk">
|
||||
<obj_property name="ElementShortName">s_axi_aclk</obj_property>
|
||||
<obj_property name="ObjectShortName">s_axi_aclk</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/s_axi_aresetn">
|
||||
<obj_property name="ElementShortName">s_axi_aresetn</obj_property>
|
||||
<obj_property name="ObjectShortName">s_axi_aresetn</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/m_axi_lite_ch1_awaddr">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_awaddr[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_awaddr[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/m_axi_lite_ch1_awprot">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_awprot[2:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_awprot[2:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/m_axi_lite_ch1_awvalid">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_awvalid</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_awvalid</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/m_axi_lite_ch1_awready">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_awready</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_awready</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/m_axi_lite_ch1_wdata">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_wdata[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_wdata[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/m_axi_lite_ch1_wstrb">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_wstrb[3:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_wstrb[3:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/m_axi_lite_ch1_wvalid">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_wvalid</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_wvalid</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/m_axi_lite_ch1_wready">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_wready</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_wready</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/m_axi_lite_ch1_bresp">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_bresp[1:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_bresp[1:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/m_axi_lite_ch1_bvalid">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_bvalid</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_bvalid</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/m_axi_lite_ch1_bready">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_bready</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_bready</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/m_axi_lite_ch1_araddr">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_araddr[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_araddr[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/m_axi_lite_ch1_arvalid">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_arvalid</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_arvalid</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/m_axi_lite_ch1_arready">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_arready</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_arready</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/m_axi_lite_ch1_rdata">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_rdata[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_rdata[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/m_axi_lite_ch1_rvalid">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_rvalid</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_rvalid</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/m_axi_lite_ch1_rresp">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_rresp[1:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_rresp[1:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/m_axi_lite_ch1_rready">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_rready</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_rready</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/done">
|
||||
<obj_property name="ElementShortName">done</obj_property>
|
||||
<obj_property name="ObjectShortName">done</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/status">
|
||||
<obj_property name="ElementShortName">status[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">status[31:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/dut/s_axi_wdata">
|
||||
<obj_property name="ElementShortName">s_axi_wdata[127:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">s_axi_wdata[127:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/dut/s_axi_wstrb">
|
||||
<obj_property name="ElementShortName">s_axi_wstrb[15:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">s_axi_wstrb[15:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="divider621" type="divider">
|
||||
<obj_property name="label">Controller</obj_property>
|
||||
<obj_property name="DisplayName">label</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/ddr3_controller_inst/instruction_address">
|
||||
<obj_property name="ElementShortName">instruction_address[4:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">instruction_address[4:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/ddr3_controller_inst/state_calibrate">
|
||||
<obj_property name="ElementShortName">state_calibrate[5:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">state_calibrate[5:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/ddr3_controller_inst/lane">
|
||||
<obj_property name="ElementShortName">lane[0:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">lane[0:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/ddr3_controller_inst/correct_read_data">
|
||||
<obj_property name="ElementShortName">correct_read_data[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">correct_read_data[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/ddr3_controller_inst/wrong_read_data">
|
||||
<obj_property name="ElementShortName">wrong_read_data[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">wrong_read_data[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/i_wb_cyc">
|
||||
<obj_property name="ElementShortName">i_wb_cyc</obj_property>
|
||||
<obj_property name="ObjectShortName">i_wb_cyc</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/i_wb_stb">
|
||||
<obj_property name="ElementShortName">i_wb_stb</obj_property>
|
||||
<obj_property name="ObjectShortName">i_wb_stb</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/i_wb_we">
|
||||
<obj_property name="ElementShortName">i_wb_we</obj_property>
|
||||
<obj_property name="ObjectShortName">i_wb_we</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/i_wb_addr">
|
||||
<obj_property name="ElementShortName">i_wb_addr[23:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">i_wb_addr[23:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/i_wb_data">
|
||||
<obj_property name="ElementShortName">i_wb_data[127:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">i_wb_data[127:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/i_wb_sel">
|
||||
<obj_property name="ElementShortName">i_wb_sel[15:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">i_wb_sel[15:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/o_wb_stall">
|
||||
<obj_property name="ElementShortName">o_wb_stall</obj_property>
|
||||
<obj_property name="ObjectShortName">o_wb_stall</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/o_wb_ack">
|
||||
<obj_property name="ElementShortName">o_wb_ack</obj_property>
|
||||
<obj_property name="ObjectShortName">o_wb_ack</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/o_wb_data">
|
||||
<obj_property name="ElementShortName">o_wb_data[127:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">o_wb_data[127:0]</obj_property>
|
||||
</wvobject>
|
||||
</wave_config>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<wave_config>
|
||||
<wave_state>
|
||||
</wave_state>
|
||||
<db_ref_list>
|
||||
<db_ref path="ddr3_axi_traffic_gen_behav.wdb" id="1">
|
||||
<top_modules>
|
||||
<top_module name="ddr3_axi_traffic_gen_tb" />
|
||||
<top_module name="glbl" />
|
||||
</top_modules>
|
||||
</db_ref>
|
||||
</db_ref_list>
|
||||
<zoom_setting>
|
||||
<ZoomStartTime time="56,185.259 ns"></ZoomStartTime>
|
||||
<ZoomEndTime time="56,341.826 ns"></ZoomEndTime>
|
||||
<Cursor1Time time="56,242.459 ns"></Cursor1Time>
|
||||
</zoom_setting>
|
||||
<column_width_setting>
|
||||
<NameColumnWidth column_width="276"></NameColumnWidth>
|
||||
<ValueColumnWidth column_width="84"></ValueColumnWidth>
|
||||
</column_width_setting>
|
||||
<WVObjectSize size="45" />
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/i_controller_clk">
|
||||
<obj_property name="ElementShortName">i_controller_clk</obj_property>
|
||||
<obj_property name="ObjectShortName">i_controller_clk</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/i_ddr3_clk">
|
||||
<obj_property name="ElementShortName">i_ddr3_clk</obj_property>
|
||||
<obj_property name="ObjectShortName">i_ddr3_clk</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/i_ref_clk">
|
||||
<obj_property name="ElementShortName">i_ref_clk</obj_property>
|
||||
<obj_property name="ObjectShortName">i_ref_clk</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/i_ddr3_clk_90">
|
||||
<obj_property name="ElementShortName">i_ddr3_clk_90</obj_property>
|
||||
<obj_property name="ObjectShortName">i_ddr3_clk_90</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/i_rst_n">
|
||||
<obj_property name="ElementShortName">i_rst_n</obj_property>
|
||||
<obj_property name="ObjectShortName">i_rst_n</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="divider622" type="divider">
|
||||
<obj_property name="label">AXI Lite (Traffic Generator)</obj_property>
|
||||
<obj_property name="DisplayName">label</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/s_axi_aclk">
|
||||
<obj_property name="ElementShortName">s_axi_aclk</obj_property>
|
||||
<obj_property name="ObjectShortName">s_axi_aclk</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/s_axi_aresetn">
|
||||
<obj_property name="ElementShortName">s_axi_aresetn</obj_property>
|
||||
<obj_property name="ObjectShortName">s_axi_aresetn</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/m_axi_lite_ch1_awaddr">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_awaddr[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_awaddr[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/m_axi_lite_ch1_awprot">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_awprot[2:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_awprot[2:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/m_axi_lite_ch1_awvalid">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_awvalid</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_awvalid</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/m_axi_lite_ch1_awready">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_awready</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_awready</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/m_axi_lite_ch1_wdata">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_wdata[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_wdata[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/m_axi_lite_ch1_wstrb">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_wstrb[3:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_wstrb[3:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/m_axi_lite_ch1_wvalid">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_wvalid</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_wvalid</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/m_axi_lite_ch1_wready">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_wready</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_wready</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/m_axi_lite_ch1_bresp">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_bresp[1:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_bresp[1:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/m_axi_lite_ch1_bvalid">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_bvalid</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_bvalid</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/m_axi_lite_ch1_bready">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_bready</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_bready</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/m_axi_lite_ch1_araddr">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_araddr[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_araddr[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/m_axi_lite_ch1_arvalid">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_arvalid</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_arvalid</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/m_axi_lite_ch1_arready">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_arready</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_arready</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/m_axi_lite_ch1_rdata">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_rdata[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_rdata[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/m_axi_lite_ch1_rvalid">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_rvalid</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_rvalid</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/m_axi_lite_ch1_rresp">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_rresp[1:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_rresp[1:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/m_axi_lite_ch1_rready">
|
||||
<obj_property name="ElementShortName">m_axi_lite_ch1_rready</obj_property>
|
||||
<obj_property name="ObjectShortName">m_axi_lite_ch1_rready</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/done">
|
||||
<obj_property name="ElementShortName">done</obj_property>
|
||||
<obj_property name="ObjectShortName">done</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/axi_traffic_gen_inst/status">
|
||||
<obj_property name="ElementShortName">status[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">status[31:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/dut/s_axi_wdata">
|
||||
<obj_property name="ElementShortName">s_axi_wdata[127:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">s_axi_wdata[127:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/dut/s_axi_wstrb">
|
||||
<obj_property name="ElementShortName">s_axi_wstrb[15:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">s_axi_wstrb[15:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="divider621" type="divider">
|
||||
<obj_property name="label">Controller</obj_property>
|
||||
<obj_property name="DisplayName">label</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/ddr3_controller_inst/instruction_address">
|
||||
<obj_property name="ElementShortName">instruction_address[4:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">instruction_address[4:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/ddr3_controller_inst/state_calibrate">
|
||||
<obj_property name="ElementShortName">state_calibrate[5:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">state_calibrate[5:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/ddr3_controller_inst/lane">
|
||||
<obj_property name="ElementShortName">lane[0:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">lane[0:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/ddr3_controller_inst/correct_read_data">
|
||||
<obj_property name="ElementShortName">correct_read_data[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">correct_read_data[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/ddr3_controller_inst/wrong_read_data">
|
||||
<obj_property name="ElementShortName">wrong_read_data[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">wrong_read_data[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/i_wb_cyc">
|
||||
<obj_property name="ElementShortName">i_wb_cyc</obj_property>
|
||||
<obj_property name="ObjectShortName">i_wb_cyc</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/i_wb_stb">
|
||||
<obj_property name="ElementShortName">i_wb_stb</obj_property>
|
||||
<obj_property name="ObjectShortName">i_wb_stb</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/i_wb_we">
|
||||
<obj_property name="ElementShortName">i_wb_we</obj_property>
|
||||
<obj_property name="ObjectShortName">i_wb_we</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/i_wb_addr">
|
||||
<obj_property name="ElementShortName">i_wb_addr[23:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">i_wb_addr[23:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/i_wb_data">
|
||||
<obj_property name="ElementShortName">i_wb_data[127:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">i_wb_data[127:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/i_wb_sel">
|
||||
<obj_property name="ElementShortName">i_wb_sel[15:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">i_wb_sel[15:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/o_wb_stall">
|
||||
<obj_property name="ElementShortName">o_wb_stall</obj_property>
|
||||
<obj_property name="ObjectShortName">o_wb_stall</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/o_wb_ack">
|
||||
<obj_property name="ElementShortName">o_wb_ack</obj_property>
|
||||
<obj_property name="ObjectShortName">o_wb_ack</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_axi_traffic_gen_tb/dut/ddr3_top_inst/o_wb_data">
|
||||
<obj_property name="ElementShortName">o_wb_data[127:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">o_wb_data[127:0]</obj_property>
|
||||
</wvobject>
|
||||
</wave_config>
|
||||
|
|
|
|||
|
|
@ -1,202 +1,202 @@
|
|||
module ddr3_axi_traffic_gen_tb;
|
||||
|
||||
reg i_controller_clk, i_ddr3_clk, i_ref_clk, i_ddr3_clk_90;
|
||||
reg i_rst_n;
|
||||
|
||||
// DDR3 Pins
|
||||
wire o_ddr3_clk_p;
|
||||
wire o_ddr3_clk_n;
|
||||
wire o_ddr3_reset_n;
|
||||
wire o_ddr3_cke;
|
||||
wire o_ddr3_cs_n;
|
||||
wire o_ddr3_ras_n;
|
||||
wire o_ddr3_cas_n;
|
||||
wire o_ddr3_we_n;
|
||||
wire[dut.ROW_BITS-1:0] o_ddr3_addr;
|
||||
wire[dut.BA_BITS-1:0] o_ddr3_ba_addr;
|
||||
wire[(dut.DQ_BITS*dut.BYTE_LANES)-1:0] io_ddr3_dq;
|
||||
wire[dut.BYTE_LANES-1:0] io_ddr3_dqs, io_ddr3_dqs_n;
|
||||
wire[dut.BYTE_LANES-1:0] o_ddr3_dm;
|
||||
wire o_ddr3_odt;
|
||||
|
||||
localparam CONTROLLER_CLK_PERIOD = 10_000, //ps, period of clock input to this DDR3 controller module
|
||||
DDR3_CLK_PERIOD = 2500; //ps, period of clock input to DDR3 RAM device
|
||||
|
||||
|
||||
// Clocks and reset
|
||||
always #(CONTROLLER_CLK_PERIOD/2) i_controller_clk = !i_controller_clk;
|
||||
always #(DDR3_CLK_PERIOD/2) i_ddr3_clk = !i_ddr3_clk;
|
||||
always #2500 i_ref_clk = !i_ref_clk;
|
||||
initial begin //90 degree phase shifted ddr3_clk
|
||||
#(DDR3_CLK_PERIOD/4);
|
||||
while(1) begin
|
||||
#(DDR3_CLK_PERIOD/2) i_ddr3_clk_90 = !i_ddr3_clk_90;
|
||||
end
|
||||
end
|
||||
initial begin
|
||||
i_controller_clk = 1;
|
||||
i_ddr3_clk = 1;
|
||||
i_ref_clk = 1;
|
||||
i_ddr3_clk_90 = 1;
|
||||
i_rst_n = 0;
|
||||
#1_000_000;
|
||||
i_rst_n = 1;
|
||||
wait(done);
|
||||
#1_000_000;
|
||||
$finish;
|
||||
end
|
||||
|
||||
wire [31 : 0] m_axi_lite_ch1_awaddr;
|
||||
wire [2 : 0] m_axi_lite_ch1_awprot;
|
||||
wire m_axi_lite_ch1_awvalid;
|
||||
wire m_axi_lite_ch1_awready;
|
||||
wire [31 : 0] m_axi_lite_ch1_wdata;
|
||||
wire [3 : 0] m_axi_lite_ch1_wstrb;
|
||||
wire m_axi_lite_ch1_wvalid;
|
||||
wire m_axi_lite_ch1_wready;
|
||||
wire [1 : 0] m_axi_lite_ch1_bresp;
|
||||
wire m_axi_lite_ch1_bvalid;
|
||||
wire m_axi_lite_ch1_bready;
|
||||
wire [31 : 0] m_axi_lite_ch1_araddr;
|
||||
wire m_axi_lite_ch1_arvalid;
|
||||
wire m_axi_lite_ch1_arready;
|
||||
wire [31 : 0] m_axi_lite_ch1_rdata;
|
||||
wire m_axi_lite_ch1_rvalid;
|
||||
wire [1 : 0] m_axi_lite_ch1_rresp;
|
||||
wire m_axi_lite_ch1_rready;
|
||||
|
||||
wire done;
|
||||
wire [31 : 0] status;
|
||||
|
||||
axi_traffic_gen_0 axi_traffic_gen_inst(
|
||||
.s_axi_aclk(i_controller_clk),
|
||||
.s_axi_aresetn(i_rst_n && (dut.ddr3_top_inst.ddr3_controller_inst.state_calibrate == 23)), //stay reset until calibration is done
|
||||
.m_axi_lite_ch1_awaddr(m_axi_lite_ch1_awaddr),
|
||||
.m_axi_lite_ch1_awprot(m_axi_lite_ch1_awprot),
|
||||
.m_axi_lite_ch1_awvalid(m_axi_lite_ch1_awvalid),
|
||||
.m_axi_lite_ch1_awready(m_axi_lite_ch1_awready),
|
||||
.m_axi_lite_ch1_wdata(m_axi_lite_ch1_wdata),
|
||||
.m_axi_lite_ch1_wstrb(m_axi_lite_ch1_wstrb), // assuming full byte enable for simplicity
|
||||
.m_axi_lite_ch1_wvalid(m_axi_lite_ch1_wvalid),
|
||||
.m_axi_lite_ch1_wready(m_axi_lite_ch1_wready),
|
||||
.m_axi_lite_ch1_bresp(m_axi_lite_ch1_bresp),
|
||||
.m_axi_lite_ch1_bvalid(m_axi_lite_ch1_bvalid),
|
||||
.m_axi_lite_ch1_bready(m_axi_lite_ch1_bready),
|
||||
.m_axi_lite_ch1_araddr(m_axi_lite_ch1_araddr),
|
||||
.m_axi_lite_ch1_arvalid(m_axi_lite_ch1_arvalid),
|
||||
.m_axi_lite_ch1_arready(m_axi_lite_ch1_arready),
|
||||
.m_axi_lite_ch1_rdata(m_axi_lite_ch1_rdata),
|
||||
.m_axi_lite_ch1_rvalid(m_axi_lite_ch1_rvalid),
|
||||
.m_axi_lite_ch1_rresp(m_axi_lite_ch1_rresp),
|
||||
.m_axi_lite_ch1_rready(m_axi_lite_ch1_rready),
|
||||
.done(done),
|
||||
.status(status)
|
||||
);
|
||||
|
||||
ddr3_top_axi #(
|
||||
.CONTROLLER_CLK_PERIOD(10_000), //ps, clock period of the controller interface
|
||||
.DDR3_CLK_PERIOD(2_500), //ps, clock period of the DDR3 RAM device (must be 1/4 of the CONTROLLER_CLK_PERIOD)
|
||||
.ROW_BITS(14), //width of row address
|
||||
.COL_BITS(10), //width of column address
|
||||
.BA_BITS(3), //width of bank address
|
||||
.BYTE_LANES(2), //number of byte lanes of DDR3 RAM
|
||||
.AXI_ID_WIDTH(4), // The AXI id width used for R&W, an int between 1-16
|
||||
.MICRON_SIM(1), //enable faster simulation for micron ddr3 model (shorten POWER_ON_RESET_HIGH and INITIAL_CKE_LOW)
|
||||
.ODELAY_SUPPORTED(0), //set to 1 when ODELAYE2 is supported
|
||||
.SECOND_WISHBONE(0) //set to 1 if 2nd wishbone for debugging is needed
|
||||
) dut (
|
||||
.i_controller_clk(i_controller_clk),
|
||||
.i_ddr3_clk(i_ddr3_clk),
|
||||
.i_ref_clk(i_ref_clk), //i_controller_clk = CONTROLLER_CLK_PERIOD, i_ddr3_clk = DDR3_CLK_PERIOD, i_ref_clk = 200MHz
|
||||
.i_ddr3_clk_90(i_ddr3_clk_90), //required only when ODELAY_SUPPORTED is zero
|
||||
.i_rst_n(i_rst_n),
|
||||
|
||||
// AXI Interface
|
||||
// AXI write address channel signals
|
||||
.s_axi_awvalid(m_axi_lite_ch1_awvalid),
|
||||
.s_axi_awready(m_axi_lite_ch1_awready),
|
||||
.s_axi_awid(4'b0000), // AXI-Lite doesn't have ID, so set to 0
|
||||
.s_axi_awaddr(m_axi_lite_ch1_awaddr),
|
||||
.s_axi_awlen(8'b00000000), // AXI-Lite doesn't use burst length
|
||||
.s_axi_awsize(3'b010), // Assuming 32-bit size
|
||||
.s_axi_awburst(2'b01), // AXI-Lite doesn't use burst, set to incrementing
|
||||
.s_axi_awlock(1'b0), // AXI-Lite doesn't use lock, set to 0
|
||||
.s_axi_awcache(4'b0000), // Assuming normal non-cacheable memory
|
||||
.s_axi_awprot(m_axi_lite_ch1_awprot ), // Set to normal, non-secure, data access
|
||||
.s_axi_awqos(4'b0000), // Quality of Service, set to 0
|
||||
|
||||
// AXI write data channel signals
|
||||
.s_axi_wvalid(m_axi_lite_ch1_wvalid),
|
||||
.s_axi_wready(m_axi_lite_ch1_wready),
|
||||
.s_axi_wdata({128'd0,m_axi_lite_ch1_wdata}),
|
||||
.s_axi_wstrb({0,m_axi_lite_ch1_wstrb}), // Assuming full byte enable
|
||||
.s_axi_wlast(m_axi_lite_ch1_wvalid), // AXI-Lite only has single beat transfers
|
||||
|
||||
// AXI write response channel signals
|
||||
.s_axi_bvalid(m_axi_lite_ch1_bvalid),
|
||||
.s_axi_bready(m_axi_lite_ch1_bready),
|
||||
.s_axi_bid(), // AXI-Lite doesn't have ID, so set to 0
|
||||
.s_axi_bresp(m_axi_lite_ch1_bresp),
|
||||
|
||||
// AXI read address channel signals
|
||||
.s_axi_arvalid(m_axi_lite_ch1_arvalid), // No read transactions in this example
|
||||
.s_axi_arready(m_axi_lite_ch1_arready),
|
||||
.s_axi_arid(4'b0000),
|
||||
.s_axi_araddr(m_axi_lite_ch1_araddr),
|
||||
.s_axi_arlen(8'b00000000),
|
||||
.s_axi_arsize(3'b010),
|
||||
.s_axi_arburst(2'b01),
|
||||
.s_axi_arlock(1'b0),
|
||||
.s_axi_arcache(4'b0000),
|
||||
.s_axi_arprot(3'b000),
|
||||
.s_axi_arqos(4'b0000),
|
||||
|
||||
// AXI read data channel signals
|
||||
.s_axi_rvalid(m_axi_lite_ch1_rvalid),
|
||||
.s_axi_rready(m_axi_lite_ch1_rready), // No read transactions in this example
|
||||
.s_axi_rid(),
|
||||
.s_axi_rdata(m_axi_lite_ch1_rdata),
|
||||
.s_axi_rlast(),
|
||||
.s_axi_rresp(m_axi_lite_ch1_rresp),
|
||||
|
||||
// DDR3 I/O Interface
|
||||
.o_ddr3_clk_p(o_ddr3_clk_p),
|
||||
.o_ddr3_clk_n(o_ddr3_clk_n),
|
||||
.o_ddr3_reset_n(o_ddr3_reset_n),
|
||||
.o_ddr3_cke(o_ddr3_cke),
|
||||
.o_ddr3_cs_n(o_ddr3_cs_n),
|
||||
.o_ddr3_ras_n(o_ddr3_ras_n),
|
||||
.o_ddr3_cas_n(o_ddr3_cas_n),
|
||||
.o_ddr3_we_n(o_ddr3_we_n),
|
||||
.o_ddr3_addr(o_ddr3_addr),
|
||||
.o_ddr3_ba_addr(o_ddr3_ba_addr),
|
||||
.io_ddr3_dq(io_ddr3_dq),
|
||||
.io_ddr3_dqs(io_ddr3_dqs),
|
||||
.io_ddr3_dqs_n(io_ddr3_dqs_n),
|
||||
.o_ddr3_dm(o_ddr3_dm),
|
||||
.o_ddr3_odt(o_ddr3_odt)
|
||||
);
|
||||
|
||||
|
||||
ddr3 ddr3_0(
|
||||
.rst_n(o_ddr3_reset_n),
|
||||
.ck(o_ddr3_clk_p),
|
||||
.ck_n(o_ddr3_clk_n),
|
||||
.cke(o_ddr3_cke),
|
||||
.cs_n(o_ddr3_cs_n),
|
||||
.ras_n(o_ddr3_ras_n),
|
||||
.cas_n(o_ddr3_cas_n),
|
||||
.we_n(o_ddr3_we_n),
|
||||
.dm_tdqs(o_ddr3_dm),
|
||||
.ba(o_ddr3_ba_addr),
|
||||
.addr({0,o_ddr3_addr}),
|
||||
.dq(io_ddr3_dq),
|
||||
.dqs(io_ddr3_dqs),
|
||||
.dqs_n(io_ddr3_dqs_n),
|
||||
.tdqs_n(),
|
||||
.odt(o_ddr3_odt)
|
||||
);
|
||||
|
||||
|
||||
|
||||
module ddr3_axi_traffic_gen_tb;
|
||||
|
||||
reg i_controller_clk, i_ddr3_clk, i_ref_clk, i_ddr3_clk_90;
|
||||
reg i_rst_n;
|
||||
|
||||
// DDR3 Pins
|
||||
wire o_ddr3_clk_p;
|
||||
wire o_ddr3_clk_n;
|
||||
wire o_ddr3_reset_n;
|
||||
wire o_ddr3_cke;
|
||||
wire o_ddr3_cs_n;
|
||||
wire o_ddr3_ras_n;
|
||||
wire o_ddr3_cas_n;
|
||||
wire o_ddr3_we_n;
|
||||
wire[dut.ROW_BITS-1:0] o_ddr3_addr;
|
||||
wire[dut.BA_BITS-1:0] o_ddr3_ba_addr;
|
||||
wire[(dut.DQ_BITS*dut.BYTE_LANES)-1:0] io_ddr3_dq;
|
||||
wire[dut.BYTE_LANES-1:0] io_ddr3_dqs, io_ddr3_dqs_n;
|
||||
wire[dut.BYTE_LANES-1:0] o_ddr3_dm;
|
||||
wire o_ddr3_odt;
|
||||
|
||||
localparam CONTROLLER_CLK_PERIOD = 10_000, //ps, period of clock input to this DDR3 controller module
|
||||
DDR3_CLK_PERIOD = 2500; //ps, period of clock input to DDR3 RAM device
|
||||
|
||||
|
||||
// Clocks and reset
|
||||
always #(CONTROLLER_CLK_PERIOD/2) i_controller_clk = !i_controller_clk;
|
||||
always #(DDR3_CLK_PERIOD/2) i_ddr3_clk = !i_ddr3_clk;
|
||||
always #2500 i_ref_clk = !i_ref_clk;
|
||||
initial begin //90 degree phase shifted ddr3_clk
|
||||
#(DDR3_CLK_PERIOD/4);
|
||||
while(1) begin
|
||||
#(DDR3_CLK_PERIOD/2) i_ddr3_clk_90 = !i_ddr3_clk_90;
|
||||
end
|
||||
end
|
||||
initial begin
|
||||
i_controller_clk = 1;
|
||||
i_ddr3_clk = 1;
|
||||
i_ref_clk = 1;
|
||||
i_ddr3_clk_90 = 1;
|
||||
i_rst_n = 0;
|
||||
#1_000_000;
|
||||
i_rst_n = 1;
|
||||
wait(done);
|
||||
#1_000_000;
|
||||
$finish;
|
||||
end
|
||||
|
||||
wire [31 : 0] m_axi_lite_ch1_awaddr;
|
||||
wire [2 : 0] m_axi_lite_ch1_awprot;
|
||||
wire m_axi_lite_ch1_awvalid;
|
||||
wire m_axi_lite_ch1_awready;
|
||||
wire [31 : 0] m_axi_lite_ch1_wdata;
|
||||
wire [3 : 0] m_axi_lite_ch1_wstrb;
|
||||
wire m_axi_lite_ch1_wvalid;
|
||||
wire m_axi_lite_ch1_wready;
|
||||
wire [1 : 0] m_axi_lite_ch1_bresp;
|
||||
wire m_axi_lite_ch1_bvalid;
|
||||
wire m_axi_lite_ch1_bready;
|
||||
wire [31 : 0] m_axi_lite_ch1_araddr;
|
||||
wire m_axi_lite_ch1_arvalid;
|
||||
wire m_axi_lite_ch1_arready;
|
||||
wire [31 : 0] m_axi_lite_ch1_rdata;
|
||||
wire m_axi_lite_ch1_rvalid;
|
||||
wire [1 : 0] m_axi_lite_ch1_rresp;
|
||||
wire m_axi_lite_ch1_rready;
|
||||
|
||||
wire done;
|
||||
wire [31 : 0] status;
|
||||
|
||||
axi_traffic_gen_0 axi_traffic_gen_inst(
|
||||
.s_axi_aclk(i_controller_clk),
|
||||
.s_axi_aresetn(i_rst_n && (dut.ddr3_top_inst.ddr3_controller_inst.state_calibrate == 23)), //stay reset until calibration is done
|
||||
.m_axi_lite_ch1_awaddr(m_axi_lite_ch1_awaddr),
|
||||
.m_axi_lite_ch1_awprot(m_axi_lite_ch1_awprot),
|
||||
.m_axi_lite_ch1_awvalid(m_axi_lite_ch1_awvalid),
|
||||
.m_axi_lite_ch1_awready(m_axi_lite_ch1_awready),
|
||||
.m_axi_lite_ch1_wdata(m_axi_lite_ch1_wdata),
|
||||
.m_axi_lite_ch1_wstrb(m_axi_lite_ch1_wstrb), // assuming full byte enable for simplicity
|
||||
.m_axi_lite_ch1_wvalid(m_axi_lite_ch1_wvalid),
|
||||
.m_axi_lite_ch1_wready(m_axi_lite_ch1_wready),
|
||||
.m_axi_lite_ch1_bresp(m_axi_lite_ch1_bresp),
|
||||
.m_axi_lite_ch1_bvalid(m_axi_lite_ch1_bvalid),
|
||||
.m_axi_lite_ch1_bready(m_axi_lite_ch1_bready),
|
||||
.m_axi_lite_ch1_araddr(m_axi_lite_ch1_araddr),
|
||||
.m_axi_lite_ch1_arvalid(m_axi_lite_ch1_arvalid),
|
||||
.m_axi_lite_ch1_arready(m_axi_lite_ch1_arready),
|
||||
.m_axi_lite_ch1_rdata(m_axi_lite_ch1_rdata),
|
||||
.m_axi_lite_ch1_rvalid(m_axi_lite_ch1_rvalid),
|
||||
.m_axi_lite_ch1_rresp(m_axi_lite_ch1_rresp),
|
||||
.m_axi_lite_ch1_rready(m_axi_lite_ch1_rready),
|
||||
.done(done),
|
||||
.status(status)
|
||||
);
|
||||
|
||||
ddr3_top_axi #(
|
||||
.CONTROLLER_CLK_PERIOD(10_000), //ps, clock period of the controller interface
|
||||
.DDR3_CLK_PERIOD(2_500), //ps, clock period of the DDR3 RAM device (must be 1/4 of the CONTROLLER_CLK_PERIOD)
|
||||
.ROW_BITS(14), //width of row address
|
||||
.COL_BITS(10), //width of column address
|
||||
.BA_BITS(3), //width of bank address
|
||||
.BYTE_LANES(2), //number of byte lanes of DDR3 RAM
|
||||
.AXI_ID_WIDTH(4), // The AXI id width used for R&W, an int between 1-16
|
||||
.MICRON_SIM(1), //enable faster simulation for micron ddr3 model (shorten POWER_ON_RESET_HIGH and INITIAL_CKE_LOW)
|
||||
.ODELAY_SUPPORTED(0), //set to 1 when ODELAYE2 is supported
|
||||
.SECOND_WISHBONE(0) //set to 1 if 2nd wishbone for debugging is needed
|
||||
) dut (
|
||||
.i_controller_clk(i_controller_clk),
|
||||
.i_ddr3_clk(i_ddr3_clk),
|
||||
.i_ref_clk(i_ref_clk), //i_controller_clk = CONTROLLER_CLK_PERIOD, i_ddr3_clk = DDR3_CLK_PERIOD, i_ref_clk = 200MHz
|
||||
.i_ddr3_clk_90(i_ddr3_clk_90), //required only when ODELAY_SUPPORTED is zero
|
||||
.i_rst_n(i_rst_n),
|
||||
|
||||
// AXI Interface
|
||||
// AXI write address channel signals
|
||||
.s_axi_awvalid(m_axi_lite_ch1_awvalid),
|
||||
.s_axi_awready(m_axi_lite_ch1_awready),
|
||||
.s_axi_awid(4'b0000), // AXI-Lite doesn't have ID, so set to 0
|
||||
.s_axi_awaddr(m_axi_lite_ch1_awaddr),
|
||||
.s_axi_awlen(8'b00000000), // AXI-Lite doesn't use burst length
|
||||
.s_axi_awsize(3'b010), // Assuming 32-bit size
|
||||
.s_axi_awburst(2'b01), // AXI-Lite doesn't use burst, set to incrementing
|
||||
.s_axi_awlock(1'b0), // AXI-Lite doesn't use lock, set to 0
|
||||
.s_axi_awcache(4'b0000), // Assuming normal non-cacheable memory
|
||||
.s_axi_awprot(m_axi_lite_ch1_awprot ), // Set to normal, non-secure, data access
|
||||
.s_axi_awqos(4'b0000), // Quality of Service, set to 0
|
||||
|
||||
// AXI write data channel signals
|
||||
.s_axi_wvalid(m_axi_lite_ch1_wvalid),
|
||||
.s_axi_wready(m_axi_lite_ch1_wready),
|
||||
.s_axi_wdata({128'd0,m_axi_lite_ch1_wdata}),
|
||||
.s_axi_wstrb({0,m_axi_lite_ch1_wstrb}), // Assuming full byte enable
|
||||
.s_axi_wlast(m_axi_lite_ch1_wvalid), // AXI-Lite only has single beat transfers
|
||||
|
||||
// AXI write response channel signals
|
||||
.s_axi_bvalid(m_axi_lite_ch1_bvalid),
|
||||
.s_axi_bready(m_axi_lite_ch1_bready),
|
||||
.s_axi_bid(), // AXI-Lite doesn't have ID, so set to 0
|
||||
.s_axi_bresp(m_axi_lite_ch1_bresp),
|
||||
|
||||
// AXI read address channel signals
|
||||
.s_axi_arvalid(m_axi_lite_ch1_arvalid), // No read transactions in this example
|
||||
.s_axi_arready(m_axi_lite_ch1_arready),
|
||||
.s_axi_arid(4'b0000),
|
||||
.s_axi_araddr(m_axi_lite_ch1_araddr),
|
||||
.s_axi_arlen(8'b00000000),
|
||||
.s_axi_arsize(3'b010),
|
||||
.s_axi_arburst(2'b01),
|
||||
.s_axi_arlock(1'b0),
|
||||
.s_axi_arcache(4'b0000),
|
||||
.s_axi_arprot(3'b000),
|
||||
.s_axi_arqos(4'b0000),
|
||||
|
||||
// AXI read data channel signals
|
||||
.s_axi_rvalid(m_axi_lite_ch1_rvalid),
|
||||
.s_axi_rready(m_axi_lite_ch1_rready), // No read transactions in this example
|
||||
.s_axi_rid(),
|
||||
.s_axi_rdata(m_axi_lite_ch1_rdata),
|
||||
.s_axi_rlast(),
|
||||
.s_axi_rresp(m_axi_lite_ch1_rresp),
|
||||
|
||||
// DDR3 I/O Interface
|
||||
.o_ddr3_clk_p(o_ddr3_clk_p),
|
||||
.o_ddr3_clk_n(o_ddr3_clk_n),
|
||||
.o_ddr3_reset_n(o_ddr3_reset_n),
|
||||
.o_ddr3_cke(o_ddr3_cke),
|
||||
.o_ddr3_cs_n(o_ddr3_cs_n),
|
||||
.o_ddr3_ras_n(o_ddr3_ras_n),
|
||||
.o_ddr3_cas_n(o_ddr3_cas_n),
|
||||
.o_ddr3_we_n(o_ddr3_we_n),
|
||||
.o_ddr3_addr(o_ddr3_addr),
|
||||
.o_ddr3_ba_addr(o_ddr3_ba_addr),
|
||||
.io_ddr3_dq(io_ddr3_dq),
|
||||
.io_ddr3_dqs(io_ddr3_dqs),
|
||||
.io_ddr3_dqs_n(io_ddr3_dqs_n),
|
||||
.o_ddr3_dm(o_ddr3_dm),
|
||||
.o_ddr3_odt(o_ddr3_odt)
|
||||
);
|
||||
|
||||
|
||||
ddr3 ddr3_0(
|
||||
.rst_n(o_ddr3_reset_n),
|
||||
.ck(o_ddr3_clk_p),
|
||||
.ck_n(o_ddr3_clk_n),
|
||||
.cke(o_ddr3_cke),
|
||||
.cs_n(o_ddr3_cs_n),
|
||||
.ras_n(o_ddr3_ras_n),
|
||||
.cas_n(o_ddr3_cas_n),
|
||||
.we_n(o_ddr3_we_n),
|
||||
.dm_tdqs(o_ddr3_dm),
|
||||
.ba(o_ddr3_ba_addr),
|
||||
.addr({0,o_ddr3_addr}),
|
||||
.dq(io_ddr3_dq),
|
||||
.dqs(io_ddr3_dqs),
|
||||
.dqs_n(io_ddr3_dqs_n),
|
||||
.tdqs_n(),
|
||||
.odt(o_ddr3_odt)
|
||||
);
|
||||
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
@ -1,258 +1,258 @@
|
|||
memory_initialization_radix = 16;
|
||||
memory_initialization_vector =
|
||||
ffffffff
|
||||
00000000
|
||||
ffffffff
|
||||
00000000
|
||||
ffffffff
|
||||
00000000
|
||||
ffffffff
|
||||
00000000
|
||||
ffffffff
|
||||
00000000
|
||||
ffffffff
|
||||
00000000
|
||||
ffffffff
|
||||
00000000
|
||||
ffffffff
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
;
|
||||
memory_initialization_radix = 16;
|
||||
memory_initialization_vector =
|
||||
ffffffff
|
||||
00000000
|
||||
ffffffff
|
||||
00000000
|
||||
ffffffff
|
||||
00000000
|
||||
ffffffff
|
||||
00000000
|
||||
ffffffff
|
||||
00000000
|
||||
ffffffff
|
||||
00000000
|
||||
ffffffff
|
||||
00000000
|
||||
ffffffff
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
;
|
||||
|
|
|
|||
5974
testbench/ddr3.sv
5974
testbench/ddr3.sv
File diff suppressed because it is too large
Load Diff
|
|
@ -1,248 +1,248 @@
|
|||
/****************************************************************************************
|
||||
*
|
||||
* File Name: ddr3_dimm.v
|
||||
*
|
||||
* Description: Micron SDRAM DDR3 (Double Data Rate 3) 240 pin dual in-line memory module (DIMM)
|
||||
*
|
||||
* Limitation: - SPD (Serial Presence-Detect) is not modeled
|
||||
*
|
||||
* Disclaimer This software code and all associated documentation, comments or other
|
||||
* of Warranty: information (collectively "Software") is provided "AS IS" without
|
||||
* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
|
||||
* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
|
||||
* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
|
||||
* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
|
||||
* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
|
||||
* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
|
||||
* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
|
||||
* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
|
||||
* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
|
||||
* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
|
||||
* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
|
||||
* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGES. Because some jurisdictions prohibit the exclusion or
|
||||
* limitation of liability for consequential or incidental damages, the
|
||||
* above limitation may not apply to you.
|
||||
*
|
||||
* Copyright 2003 Micron Technology, Inc. All rights reserved.
|
||||
*
|
||||
****************************************************************************************/
|
||||
`timescale 1ps / 1ps
|
||||
`define den8192Mb
|
||||
`define sg125
|
||||
`define x8
|
||||
|
||||
module ddr3_dimm (
|
||||
reset_n,
|
||||
ck ,
|
||||
ck_n ,
|
||||
cke ,
|
||||
s_n ,
|
||||
ras_n ,
|
||||
cas_n ,
|
||||
we_n ,
|
||||
ba ,
|
||||
addr ,
|
||||
odt ,
|
||||
dqs ,
|
||||
dqs_n ,
|
||||
dq ,
|
||||
cb ,
|
||||
scl ,
|
||||
sa ,
|
||||
sda
|
||||
);
|
||||
//added delay for each lane (in referenced to the DQ line) due to the fly-by configuration
|
||||
|
||||
`ifdef den1024Mb
|
||||
`include "1024Mb_ddr3_parameters.vh"
|
||||
`elsif den2048Mb
|
||||
`include "2048Mb_ddr3_parameters.vh"
|
||||
`elsif den4096Mb
|
||||
`include "4096Mb_ddr3_parameters.vh"
|
||||
`elsif den8192Mb
|
||||
`include "8192Mb_ddr3_parameters.vh"
|
||||
`else
|
||||
// NOTE: Intentionally cause a compile fail here to force the users
|
||||
// to select the correct component density before continuing
|
||||
ERROR: You must specify component density with +define+den____Mb.
|
||||
`endif
|
||||
|
||||
input reset_n;
|
||||
input [1:0] ck ;
|
||||
input [1:0] ck_n ;
|
||||
input [1:0] cke ;
|
||||
input [1:0] s_n ;
|
||||
input ras_n ;
|
||||
input cas_n ;
|
||||
input we_n ;
|
||||
input [2:0] ba ;
|
||||
input [15:0] addr ;
|
||||
input [1:0] odt ;
|
||||
inout [17:0] dqs ;
|
||||
inout [17:0] dqs_n ;
|
||||
inout [63:0] dq ;
|
||||
inout [7:0] cb ;
|
||||
input scl ; // no connect
|
||||
input [2:0] sa ; // no connect
|
||||
inout sda ; // no connect
|
||||
`ifdef DUAL_RANK
|
||||
initial if (DEBUG) $display("%m: Dual Rank");
|
||||
`else
|
||||
initial if (DEBUG) $display("%m: Single Rank");
|
||||
`endif
|
||||
`ifdef ECC
|
||||
initial if (DEBUG) $display("%m: ECC");
|
||||
`else
|
||||
initial if (DEBUG) $display("%m: non ECC");
|
||||
`endif
|
||||
`ifdef RDIMM
|
||||
initial if (DEBUG) $display("%m: Registered DIMM");
|
||||
wire [1:0] rck = {2{ck[0]}};
|
||||
wire [1:0] rck_n = {2{ck_n[0]}};
|
||||
reg [1:0] rcke ;
|
||||
reg [1:0] rs_n ;
|
||||
reg rras_n ;
|
||||
reg rcas_n ;
|
||||
reg rwe_n ;
|
||||
reg [2:0] rba ;
|
||||
reg [15:0] raddr ;
|
||||
reg [1:0] rodt ;
|
||||
|
||||
always @(negedge reset_n or posedge ck[0]) begin
|
||||
if (!reset_n) begin
|
||||
rcke <= #(500) 0;
|
||||
rs_n <= #(500) 0;
|
||||
rras_n <= #(500) 0;
|
||||
rcas_n <= #(500) 0;
|
||||
rwe_n <= #(500) 0;
|
||||
rba <= #(500) 0;
|
||||
raddr <= #(500) 0;
|
||||
rodt <= #(500) 0;
|
||||
end else begin
|
||||
rcke <= #(500) cke ;
|
||||
rs_n <= #(500) s_n ;
|
||||
rras_n <= #(500) ras_n;
|
||||
rcas_n <= #(500) cas_n;
|
||||
rwe_n <= #(500) we_n ;
|
||||
rba <= #(500) ba ;
|
||||
raddr <= #(500) addr ;
|
||||
rodt <= #(500) odt ;
|
||||
end
|
||||
end
|
||||
`else
|
||||
initial if (DEBUG) $display("%m: Unbuffered DIMM");
|
||||
wire [1:0] rck = ck ;
|
||||
wire [1:0] rck_n = ck_n ;
|
||||
wire [1:0] rs_n = s_n ;
|
||||
wire [2:0] rba = ba ;
|
||||
wire [15:0] raddr = addr ;
|
||||
wire [1:0] rcke = cke ;
|
||||
wire rras_n = ras_n;
|
||||
wire rcas_n = cas_n;
|
||||
wire rwe_n = we_n ;
|
||||
wire [1:0] rodt = odt ;
|
||||
`endif
|
||||
|
||||
wire zero = 1'b0;
|
||||
wire one = 1'b1;
|
||||
|
||||
//ddr3 (rst_n , ck , ck_n , cke , cs_n , ras_n , cas_n , we_n , dm_tdqs , ba , addr , dq , dqs , dqs_n , tdqs_n , odt );
|
||||
`ifdef x4
|
||||
initial if (DEBUG) $display("%m: Component Width = x4");
|
||||
ddr3 U1 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[ 3: 0], dqs[ 0], dqs_n[ 0], , rodt[0]);
|
||||
ddr3 U2 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[11: 8], dqs[ 1], dqs_n[ 1], , rodt[0]);
|
||||
ddr3 U3 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[19:16], dqs[ 2], dqs_n[ 2], , rodt[0]);
|
||||
ddr3 U4 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[27:24], dqs[ 3], dqs_n[ 3], , rodt[0]);
|
||||
ddr3 U6 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[35:32], dqs[ 4], dqs_n[ 4], , rodt[0]);
|
||||
ddr3 U7 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[43:40], dqs[ 5], dqs_n[ 5], , rodt[0]);
|
||||
ddr3 U8 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[51:48], dqs[ 6], dqs_n[ 6], , rodt[0]);
|
||||
ddr3 U9 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[59:56], dqs[ 7], dqs_n[ 7], , rodt[0]);
|
||||
`ifdef ECC
|
||||
ddr3 U5 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], cb[ 3: 0], dqs[ 8], dqs_n[ 8], , rodt[0]);
|
||||
`endif
|
||||
ddr3 U18 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[ 7: 4], dqs[ 9], dqs_n[ 9], , rodt[0]);
|
||||
ddr3 U17 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[15:12], dqs[ 10], dqs_n[ 10], , rodt[0]);
|
||||
ddr3 U16 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[23:20], dqs[ 11], dqs_n[ 11], , rodt[0]);
|
||||
ddr3 U15 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[31:28], dqs[ 12], dqs_n[ 12], , rodt[0]);
|
||||
ddr3 U13 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[39:36], dqs[ 13], dqs_n[ 13], , rodt[0]);
|
||||
ddr3 U12 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[47:44], dqs[ 14], dqs_n[ 14], , rodt[0]);
|
||||
ddr3 U11 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[55:52], dqs[ 15], dqs_n[ 15], , rodt[0]);
|
||||
ddr3 U10 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[63:60], dqs[ 16], dqs_n[ 16], , rodt[0]);
|
||||
`ifdef ECC
|
||||
ddr3 U14 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], cb[ 7: 4], dqs[ 17], dqs_n[ 17], , rodt[0]);
|
||||
`endif
|
||||
`ifdef DUAL_RANK
|
||||
ddr3 U1t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[ 3: 0], dqs[ 0], dqs_n[ 0], , rodt[1]);
|
||||
ddr3 U2t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[11: 8], dqs[ 1], dqs_n[ 1], , rodt[1]);
|
||||
ddr3 U3t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[19:16], dqs[ 2], dqs_n[ 2], , rodt[1]);
|
||||
ddr3 U4t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[27:24], dqs[ 3], dqs_n[ 3], , rodt[1]);
|
||||
ddr3 U6t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[35:32], dqs[ 4], dqs_n[ 4], , rodt[1]);
|
||||
ddr3 U7t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[43:40], dqs[ 5], dqs_n[ 5], , rodt[1]);
|
||||
ddr3 U8t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[51:48], dqs[ 6], dqs_n[ 6], , rodt[1]);
|
||||
ddr3 U9t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[59:56], dqs[ 7], dqs_n[ 7], , rodt[1]);
|
||||
`ifdef ECC
|
||||
ddr3 U5t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], cb[ 3: 0], dqs[ 8], dqs_n[ 8], , rodt[1]);
|
||||
`endif
|
||||
ddr3 U18t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[ 7: 4], dqs[ 9], dqs_n[ 9], , rodt[1]);
|
||||
ddr3 U17t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[15:12], dqs[ 10], dqs_n[ 10], , rodt[1]);
|
||||
ddr3 U16t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[23:20], dqs[ 11], dqs_n[ 11], , rodt[1]);
|
||||
ddr3 U15t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[31:28], dqs[ 12], dqs_n[ 12], , rodt[1]);
|
||||
ddr3 U13t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[39:36], dqs[ 13], dqs_n[ 13], , rodt[1]);
|
||||
ddr3 U12t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[47:44], dqs[ 14], dqs_n[ 14], , rodt[1]);
|
||||
ddr3 U11t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[55:52], dqs[ 15], dqs_n[ 15], , rodt[1]);
|
||||
ddr3 U10t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[63:60], dqs[ 16], dqs_n[ 16], , rodt[1]);
|
||||
`ifdef ECC
|
||||
ddr3 U14t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], cb[ 7: 4], dqs[ 17], dqs_n[ 17], , rodt[1]);
|
||||
`endif
|
||||
`endif
|
||||
`else `ifdef x8
|
||||
initial if (DEBUG) $display("%m: Component Width = x8");
|
||||
ddr3 #(.FLY_BY_DELAY(FLY_BY_DELAY_LANE_0)) U1 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[ 9] , rba, raddr[ADDR_BITS-1:0], dq[ 7: 0], dqs[ 0], dqs_n[ 0], dqs_n[ 9], rodt[0]);
|
||||
ddr3 #(.FLY_BY_DELAY(FLY_BY_DELAY_LANE_1)) U2 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[10] , rba, raddr[ADDR_BITS-1:0], dq[15: 8], dqs[ 1], dqs_n[ 1], dqs_n[10], rodt[0]);
|
||||
ddr3 #(.FLY_BY_DELAY(FLY_BY_DELAY_LANE_2)) U3 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[11] , rba, raddr[ADDR_BITS-1:0], dq[23:16], dqs[ 2], dqs_n[ 2], dqs_n[11], rodt[0]);
|
||||
ddr3 #(.FLY_BY_DELAY(FLY_BY_DELAY_LANE_3)) U4 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[12] , rba, raddr[ADDR_BITS-1:0], dq[31:24], dqs[ 3], dqs_n[ 3], dqs_n[12], rodt[0]);
|
||||
ddr3 #(.FLY_BY_DELAY(FLY_BY_DELAY_LANE_4)) U6 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[13] , rba, raddr[ADDR_BITS-1:0], dq[39:32], dqs[ 4], dqs_n[ 4], dqs_n[13], rodt[0]);
|
||||
ddr3 #(.FLY_BY_DELAY(FLY_BY_DELAY_LANE_5)) U7 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[14] , rba, raddr[ADDR_BITS-1:0], dq[47:40], dqs[ 5], dqs_n[ 5], dqs_n[14], rodt[0]);
|
||||
ddr3 #(.FLY_BY_DELAY(FLY_BY_DELAY_LANE_6)) U8 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[15] , rba, raddr[ADDR_BITS-1:0], dq[55:48], dqs[ 6], dqs_n[ 6], dqs_n[15], rodt[0]);
|
||||
ddr3 #(.FLY_BY_DELAY(FLY_BY_DELAY_LANE_7)) U9 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[16] , rba, raddr[ADDR_BITS-1:0], dq[63:56], dqs[ 7], dqs_n[ 7], dqs_n[16], rodt[0]);
|
||||
`ifdef ECC
|
||||
ddr3 U5 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[17] , rba, raddr[ADDR_BITS-1:0], cb[ 7: 0], dqs[ 8], dqs_n[ 8], dqs_n[17], rodt[0]);
|
||||
`endif
|
||||
`ifdef DUAL_RANK
|
||||
ddr3 U18 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[ 9] , rba, raddr[ADDR_BITS-1:0], dq[ 7: 0], dqs[ 0], dqs_n[ 0], dqs_n[ 9], rodt[1]);
|
||||
ddr3 U17 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[10] , rba, raddr[ADDR_BITS-1:0], dq[15: 8], dqs[ 1], dqs_n[ 1], dqs_n[10], rodt[1]);
|
||||
ddr3 U16 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[11] , rba, raddr[ADDR_BITS-1:0], dq[23:16], dqs[ 2], dqs_n[ 2], dqs_n[11], rodt[1]);
|
||||
ddr3 U15 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[12] , rba, raddr[ADDR_BITS-1:0], dq[31:24], dqs[ 3], dqs_n[ 3], dqs_n[12], rodt[1]);
|
||||
ddr3 U13 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[13] , rba, raddr[ADDR_BITS-1:0], dq[39:32], dqs[ 4], dqs_n[ 4], dqs_n[13], rodt[1]);
|
||||
ddr3 U12 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[14] , rba, raddr[ADDR_BITS-1:0], dq[47:40], dqs[ 5], dqs_n[ 5], dqs_n[14], rodt[1]);
|
||||
ddr3 U11 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[15] , rba, raddr[ADDR_BITS-1:0], dq[55:48], dqs[ 6], dqs_n[ 6], dqs_n[15], rodt[1]);
|
||||
ddr3 U10 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[16] , rba, raddr[ADDR_BITS-1:0], dq[63:56], dqs[ 7], dqs_n[ 7], dqs_n[16], rodt[1]);
|
||||
`ifdef ECC
|
||||
ddr3 U14 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[17] , rba, raddr[ADDR_BITS-1:0], cb[ 7: 0], dqs[ 8], dqs_n[ 8], dqs_n[17], rodt[1]);
|
||||
`endif
|
||||
`endif
|
||||
`else `ifdef x16
|
||||
initial if (DEBUG) $display("%m: Component Width = x16");
|
||||
ddr3 U1 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[10: 9], rba, raddr[ADDR_BITS-1:0], dq[15: 0], dqs[1:0], dqs_n[1:0], , rodt[0]);
|
||||
ddr3 U2 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[12:11], rba, raddr[ADDR_BITS-1:0], dq[31:16], dqs[3:2], dqs_n[3:2], , rodt[0]);
|
||||
ddr3 U4 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[14:13], rba, raddr[ADDR_BITS-1:0], dq[47:32], dqs[5:4], dqs_n[5:4], , rodt[0]);
|
||||
ddr3 U5 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[16:15], rba, raddr[ADDR_BITS-1:0], dq[63:48], dqs[7:6], dqs_n[7:6], , rodt[0]);
|
||||
`ifdef ECC
|
||||
ddr3 U3 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, {one, dqs[17]}, rba, raddr[ADDR_BITS-1:0], {{8{zero}}, cb}, {zero, dqs[8]}, {one, dqs_n[8]},, rodt[0]);
|
||||
`endif
|
||||
`ifdef DUAL_RANK
|
||||
ddr3 U10 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[10: 9], rba, raddr[ADDR_BITS-1:0], dq[15: 0], dqs[1:0], dqs_n[1:0], , rodt[1]);
|
||||
ddr3 U9 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[12:11], rba, raddr[ADDR_BITS-1:0], dq[31:16], dqs[3:2], dqs_n[3:2], , rodt[1]);
|
||||
ddr3 U7 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[14:13], rba, raddr[ADDR_BITS-1:0], dq[47:32], dqs[5:4], dqs_n[5:4], , rodt[1]);
|
||||
ddr3 U6 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[16:15], rba, raddr[ADDR_BITS-1:0], dq[63:48], dqs[7:6], dqs_n[7:6], , rodt[1]);
|
||||
`ifdef ECC
|
||||
ddr3 U8 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, {one, dqs[17]}, rba, raddr[ADDR_BITS-1:0], {{8{zero}}, cb}, {zero, dqs[8]}, {one, dqs_n[8]},, rodt[1]);
|
||||
`endif
|
||||
`endif
|
||||
`endif `endif `endif
|
||||
|
||||
endmodule
|
||||
/****************************************************************************************
|
||||
*
|
||||
* File Name: ddr3_dimm.v
|
||||
*
|
||||
* Description: Micron SDRAM DDR3 (Double Data Rate 3) 240 pin dual in-line memory module (DIMM)
|
||||
*
|
||||
* Limitation: - SPD (Serial Presence-Detect) is not modeled
|
||||
*
|
||||
* Disclaimer This software code and all associated documentation, comments or other
|
||||
* of Warranty: information (collectively "Software") is provided "AS IS" without
|
||||
* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
|
||||
* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
|
||||
* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
|
||||
* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
|
||||
* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
|
||||
* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
|
||||
* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
|
||||
* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
|
||||
* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
|
||||
* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
|
||||
* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
|
||||
* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGES. Because some jurisdictions prohibit the exclusion or
|
||||
* limitation of liability for consequential or incidental damages, the
|
||||
* above limitation may not apply to you.
|
||||
*
|
||||
* Copyright 2003 Micron Technology, Inc. All rights reserved.
|
||||
*
|
||||
****************************************************************************************/
|
||||
`timescale 1ps / 1ps
|
||||
`define den8192Mb
|
||||
`define sg125
|
||||
`define x8
|
||||
|
||||
module ddr3_dimm (
|
||||
reset_n,
|
||||
ck ,
|
||||
ck_n ,
|
||||
cke ,
|
||||
s_n ,
|
||||
ras_n ,
|
||||
cas_n ,
|
||||
we_n ,
|
||||
ba ,
|
||||
addr ,
|
||||
odt ,
|
||||
dqs ,
|
||||
dqs_n ,
|
||||
dq ,
|
||||
cb ,
|
||||
scl ,
|
||||
sa ,
|
||||
sda
|
||||
);
|
||||
//added delay for each lane (in referenced to the DQ line) due to the fly-by configuration
|
||||
|
||||
`ifdef den1024Mb
|
||||
`include "1024Mb_ddr3_parameters.vh"
|
||||
`elsif den2048Mb
|
||||
`include "2048Mb_ddr3_parameters.vh"
|
||||
`elsif den4096Mb
|
||||
`include "4096Mb_ddr3_parameters.vh"
|
||||
`elsif den8192Mb
|
||||
`include "8192Mb_ddr3_parameters.vh"
|
||||
`else
|
||||
// NOTE: Intentionally cause a compile fail here to force the users
|
||||
// to select the correct component density before continuing
|
||||
ERROR: You must specify component density with +define+den____Mb.
|
||||
`endif
|
||||
|
||||
input reset_n;
|
||||
input [1:0] ck ;
|
||||
input [1:0] ck_n ;
|
||||
input [1:0] cke ;
|
||||
input [1:0] s_n ;
|
||||
input ras_n ;
|
||||
input cas_n ;
|
||||
input we_n ;
|
||||
input [2:0] ba ;
|
||||
input [15:0] addr ;
|
||||
input [1:0] odt ;
|
||||
inout [17:0] dqs ;
|
||||
inout [17:0] dqs_n ;
|
||||
inout [63:0] dq ;
|
||||
inout [7:0] cb ;
|
||||
input scl ; // no connect
|
||||
input [2:0] sa ; // no connect
|
||||
inout sda ; // no connect
|
||||
`ifdef DUAL_RANK
|
||||
initial if (DEBUG) $display("%m: Dual Rank");
|
||||
`else
|
||||
initial if (DEBUG) $display("%m: Single Rank");
|
||||
`endif
|
||||
`ifdef ECC
|
||||
initial if (DEBUG) $display("%m: ECC");
|
||||
`else
|
||||
initial if (DEBUG) $display("%m: non ECC");
|
||||
`endif
|
||||
`ifdef RDIMM
|
||||
initial if (DEBUG) $display("%m: Registered DIMM");
|
||||
wire [1:0] rck = {2{ck[0]}};
|
||||
wire [1:0] rck_n = {2{ck_n[0]}};
|
||||
reg [1:0] rcke ;
|
||||
reg [1:0] rs_n ;
|
||||
reg rras_n ;
|
||||
reg rcas_n ;
|
||||
reg rwe_n ;
|
||||
reg [2:0] rba ;
|
||||
reg [15:0] raddr ;
|
||||
reg [1:0] rodt ;
|
||||
|
||||
always @(negedge reset_n or posedge ck[0]) begin
|
||||
if (!reset_n) begin
|
||||
rcke <= #(500) 0;
|
||||
rs_n <= #(500) 0;
|
||||
rras_n <= #(500) 0;
|
||||
rcas_n <= #(500) 0;
|
||||
rwe_n <= #(500) 0;
|
||||
rba <= #(500) 0;
|
||||
raddr <= #(500) 0;
|
||||
rodt <= #(500) 0;
|
||||
end else begin
|
||||
rcke <= #(500) cke ;
|
||||
rs_n <= #(500) s_n ;
|
||||
rras_n <= #(500) ras_n;
|
||||
rcas_n <= #(500) cas_n;
|
||||
rwe_n <= #(500) we_n ;
|
||||
rba <= #(500) ba ;
|
||||
raddr <= #(500) addr ;
|
||||
rodt <= #(500) odt ;
|
||||
end
|
||||
end
|
||||
`else
|
||||
initial if (DEBUG) $display("%m: Unbuffered DIMM");
|
||||
wire [1:0] rck = ck ;
|
||||
wire [1:0] rck_n = ck_n ;
|
||||
wire [1:0] rs_n = s_n ;
|
||||
wire [2:0] rba = ba ;
|
||||
wire [15:0] raddr = addr ;
|
||||
wire [1:0] rcke = cke ;
|
||||
wire rras_n = ras_n;
|
||||
wire rcas_n = cas_n;
|
||||
wire rwe_n = we_n ;
|
||||
wire [1:0] rodt = odt ;
|
||||
`endif
|
||||
|
||||
wire zero = 1'b0;
|
||||
wire one = 1'b1;
|
||||
|
||||
//ddr3 (rst_n , ck , ck_n , cke , cs_n , ras_n , cas_n , we_n , dm_tdqs , ba , addr , dq , dqs , dqs_n , tdqs_n , odt );
|
||||
`ifdef x4
|
||||
initial if (DEBUG) $display("%m: Component Width = x4");
|
||||
ddr3 U1 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[ 3: 0], dqs[ 0], dqs_n[ 0], , rodt[0]);
|
||||
ddr3 U2 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[11: 8], dqs[ 1], dqs_n[ 1], , rodt[0]);
|
||||
ddr3 U3 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[19:16], dqs[ 2], dqs_n[ 2], , rodt[0]);
|
||||
ddr3 U4 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[27:24], dqs[ 3], dqs_n[ 3], , rodt[0]);
|
||||
ddr3 U6 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[35:32], dqs[ 4], dqs_n[ 4], , rodt[0]);
|
||||
ddr3 U7 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[43:40], dqs[ 5], dqs_n[ 5], , rodt[0]);
|
||||
ddr3 U8 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[51:48], dqs[ 6], dqs_n[ 6], , rodt[0]);
|
||||
ddr3 U9 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[59:56], dqs[ 7], dqs_n[ 7], , rodt[0]);
|
||||
`ifdef ECC
|
||||
ddr3 U5 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], cb[ 3: 0], dqs[ 8], dqs_n[ 8], , rodt[0]);
|
||||
`endif
|
||||
ddr3 U18 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[ 7: 4], dqs[ 9], dqs_n[ 9], , rodt[0]);
|
||||
ddr3 U17 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[15:12], dqs[ 10], dqs_n[ 10], , rodt[0]);
|
||||
ddr3 U16 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[23:20], dqs[ 11], dqs_n[ 11], , rodt[0]);
|
||||
ddr3 U15 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[31:28], dqs[ 12], dqs_n[ 12], , rodt[0]);
|
||||
ddr3 U13 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[39:36], dqs[ 13], dqs_n[ 13], , rodt[0]);
|
||||
ddr3 U12 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[47:44], dqs[ 14], dqs_n[ 14], , rodt[0]);
|
||||
ddr3 U11 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[55:52], dqs[ 15], dqs_n[ 15], , rodt[0]);
|
||||
ddr3 U10 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[63:60], dqs[ 16], dqs_n[ 16], , rodt[0]);
|
||||
`ifdef ECC
|
||||
ddr3 U14 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], cb[ 7: 4], dqs[ 17], dqs_n[ 17], , rodt[0]);
|
||||
`endif
|
||||
`ifdef DUAL_RANK
|
||||
ddr3 U1t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[ 3: 0], dqs[ 0], dqs_n[ 0], , rodt[1]);
|
||||
ddr3 U2t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[11: 8], dqs[ 1], dqs_n[ 1], , rodt[1]);
|
||||
ddr3 U3t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[19:16], dqs[ 2], dqs_n[ 2], , rodt[1]);
|
||||
ddr3 U4t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[27:24], dqs[ 3], dqs_n[ 3], , rodt[1]);
|
||||
ddr3 U6t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[35:32], dqs[ 4], dqs_n[ 4], , rodt[1]);
|
||||
ddr3 U7t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[43:40], dqs[ 5], dqs_n[ 5], , rodt[1]);
|
||||
ddr3 U8t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[51:48], dqs[ 6], dqs_n[ 6], , rodt[1]);
|
||||
ddr3 U9t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[59:56], dqs[ 7], dqs_n[ 7], , rodt[1]);
|
||||
`ifdef ECC
|
||||
ddr3 U5t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], cb[ 3: 0], dqs[ 8], dqs_n[ 8], , rodt[1]);
|
||||
`endif
|
||||
ddr3 U18t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[ 7: 4], dqs[ 9], dqs_n[ 9], , rodt[1]);
|
||||
ddr3 U17t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[15:12], dqs[ 10], dqs_n[ 10], , rodt[1]);
|
||||
ddr3 U16t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[23:20], dqs[ 11], dqs_n[ 11], , rodt[1]);
|
||||
ddr3 U15t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[31:28], dqs[ 12], dqs_n[ 12], , rodt[1]);
|
||||
ddr3 U13t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[39:36], dqs[ 13], dqs_n[ 13], , rodt[1]);
|
||||
ddr3 U12t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[47:44], dqs[ 14], dqs_n[ 14], , rodt[1]);
|
||||
ddr3 U11t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[55:52], dqs[ 15], dqs_n[ 15], , rodt[1]);
|
||||
ddr3 U10t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq[63:60], dqs[ 16], dqs_n[ 16], , rodt[1]);
|
||||
`ifdef ECC
|
||||
ddr3 U14t (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], cb[ 7: 4], dqs[ 17], dqs_n[ 17], , rodt[1]);
|
||||
`endif
|
||||
`endif
|
||||
`else `ifdef x8
|
||||
initial if (DEBUG) $display("%m: Component Width = x8");
|
||||
ddr3 #(.FLY_BY_DELAY(FLY_BY_DELAY_LANE_0)) U1 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[ 9] , rba, raddr[ADDR_BITS-1:0], dq[ 7: 0], dqs[ 0], dqs_n[ 0], dqs_n[ 9], rodt[0]);
|
||||
ddr3 #(.FLY_BY_DELAY(FLY_BY_DELAY_LANE_1)) U2 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[10] , rba, raddr[ADDR_BITS-1:0], dq[15: 8], dqs[ 1], dqs_n[ 1], dqs_n[10], rodt[0]);
|
||||
ddr3 #(.FLY_BY_DELAY(FLY_BY_DELAY_LANE_2)) U3 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[11] , rba, raddr[ADDR_BITS-1:0], dq[23:16], dqs[ 2], dqs_n[ 2], dqs_n[11], rodt[0]);
|
||||
ddr3 #(.FLY_BY_DELAY(FLY_BY_DELAY_LANE_3)) U4 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[12] , rba, raddr[ADDR_BITS-1:0], dq[31:24], dqs[ 3], dqs_n[ 3], dqs_n[12], rodt[0]);
|
||||
ddr3 #(.FLY_BY_DELAY(FLY_BY_DELAY_LANE_4)) U6 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[13] , rba, raddr[ADDR_BITS-1:0], dq[39:32], dqs[ 4], dqs_n[ 4], dqs_n[13], rodt[0]);
|
||||
ddr3 #(.FLY_BY_DELAY(FLY_BY_DELAY_LANE_5)) U7 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[14] , rba, raddr[ADDR_BITS-1:0], dq[47:40], dqs[ 5], dqs_n[ 5], dqs_n[14], rodt[0]);
|
||||
ddr3 #(.FLY_BY_DELAY(FLY_BY_DELAY_LANE_6)) U8 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[15] , rba, raddr[ADDR_BITS-1:0], dq[55:48], dqs[ 6], dqs_n[ 6], dqs_n[15], rodt[0]);
|
||||
ddr3 #(.FLY_BY_DELAY(FLY_BY_DELAY_LANE_7)) U9 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[16] , rba, raddr[ADDR_BITS-1:0], dq[63:56], dqs[ 7], dqs_n[ 7], dqs_n[16], rodt[0]);
|
||||
`ifdef ECC
|
||||
ddr3 U5 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[17] , rba, raddr[ADDR_BITS-1:0], cb[ 7: 0], dqs[ 8], dqs_n[ 8], dqs_n[17], rodt[0]);
|
||||
`endif
|
||||
`ifdef DUAL_RANK
|
||||
ddr3 U18 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[ 9] , rba, raddr[ADDR_BITS-1:0], dq[ 7: 0], dqs[ 0], dqs_n[ 0], dqs_n[ 9], rodt[1]);
|
||||
ddr3 U17 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[10] , rba, raddr[ADDR_BITS-1:0], dq[15: 8], dqs[ 1], dqs_n[ 1], dqs_n[10], rodt[1]);
|
||||
ddr3 U16 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[11] , rba, raddr[ADDR_BITS-1:0], dq[23:16], dqs[ 2], dqs_n[ 2], dqs_n[11], rodt[1]);
|
||||
ddr3 U15 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[12] , rba, raddr[ADDR_BITS-1:0], dq[31:24], dqs[ 3], dqs_n[ 3], dqs_n[12], rodt[1]);
|
||||
ddr3 U13 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[13] , rba, raddr[ADDR_BITS-1:0], dq[39:32], dqs[ 4], dqs_n[ 4], dqs_n[13], rodt[1]);
|
||||
ddr3 U12 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[14] , rba, raddr[ADDR_BITS-1:0], dq[47:40], dqs[ 5], dqs_n[ 5], dqs_n[14], rodt[1]);
|
||||
ddr3 U11 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[15] , rba, raddr[ADDR_BITS-1:0], dq[55:48], dqs[ 6], dqs_n[ 6], dqs_n[15], rodt[1]);
|
||||
ddr3 U10 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[16] , rba, raddr[ADDR_BITS-1:0], dq[63:56], dqs[ 7], dqs_n[ 7], dqs_n[16], rodt[1]);
|
||||
`ifdef ECC
|
||||
ddr3 U14 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[17] , rba, raddr[ADDR_BITS-1:0], cb[ 7: 0], dqs[ 8], dqs_n[ 8], dqs_n[17], rodt[1]);
|
||||
`endif
|
||||
`endif
|
||||
`else `ifdef x16
|
||||
initial if (DEBUG) $display("%m: Component Width = x16");
|
||||
ddr3 U1 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[10: 9], rba, raddr[ADDR_BITS-1:0], dq[15: 0], dqs[1:0], dqs_n[1:0], , rodt[0]);
|
||||
ddr3 U2 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[12:11], rba, raddr[ADDR_BITS-1:0], dq[31:16], dqs[3:2], dqs_n[3:2], , rodt[0]);
|
||||
ddr3 U4 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[14:13], rba, raddr[ADDR_BITS-1:0], dq[47:32], dqs[5:4], dqs_n[5:4], , rodt[0]);
|
||||
ddr3 U5 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[16:15], rba, raddr[ADDR_BITS-1:0], dq[63:48], dqs[7:6], dqs_n[7:6], , rodt[0]);
|
||||
`ifdef ECC
|
||||
ddr3 U3 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, {one, dqs[17]}, rba, raddr[ADDR_BITS-1:0], {{8{zero}}, cb}, {zero, dqs[8]}, {one, dqs_n[8]},, rodt[0]);
|
||||
`endif
|
||||
`ifdef DUAL_RANK
|
||||
ddr3 U10 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[10: 9], rba, raddr[ADDR_BITS-1:0], dq[15: 0], dqs[1:0], dqs_n[1:0], , rodt[1]);
|
||||
ddr3 U9 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[12:11], rba, raddr[ADDR_BITS-1:0], dq[31:16], dqs[3:2], dqs_n[3:2], , rodt[1]);
|
||||
ddr3 U7 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[14:13], rba, raddr[ADDR_BITS-1:0], dq[47:32], dqs[5:4], dqs_n[5:4], , rodt[1]);
|
||||
ddr3 U6 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[16:15], rba, raddr[ADDR_BITS-1:0], dq[63:48], dqs[7:6], dqs_n[7:6], , rodt[1]);
|
||||
`ifdef ECC
|
||||
ddr3 U8 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, {one, dqs[17]}, rba, raddr[ADDR_BITS-1:0], {{8{zero}}, cb}, {zero, dqs[8]}, {one, dqs_n[8]},, rodt[1]);
|
||||
`endif
|
||||
`endif
|
||||
`endif `endif `endif
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -11,24 +11,15 @@
|
|||
</db_ref>
|
||||
</db_ref_list>
|
||||
<zoom_setting>
|
||||
<ZoomStartTime time="0.000000 us"></ZoomStartTime>
|
||||
<ZoomEndTime time="119.000001 us"></ZoomEndTime>
|
||||
<Cursor1Time time="1.000000 us"></Cursor1Time>
|
||||
<ZoomStartTime time="749.583 ns"></ZoomStartTime>
|
||||
<ZoomEndTime time="6,229.584 ns"></ZoomEndTime>
|
||||
<Cursor1Time time="1,130.000 ns"></Cursor1Time>
|
||||
</zoom_setting>
|
||||
<column_width_setting>
|
||||
<NameColumnWidth column_width="267"></NameColumnWidth>
|
||||
<ValueColumnWidth column_width="112"></ValueColumnWidth>
|
||||
<NameColumnWidth column_width="272"></NameColumnWidth>
|
||||
<ValueColumnWidth column_width="129"></ValueColumnWidth>
|
||||
</column_width_setting>
|
||||
<WVObjectSize size="65" />
|
||||
<wave_markers>
|
||||
<marker label="" time="211751250" />
|
||||
<marker label="" time="320531250" />
|
||||
<marker label="" time="480281250" />
|
||||
<marker label="" time="61533750" />
|
||||
<marker label="" time="102971250" />
|
||||
<marker label="" time="102493750" />
|
||||
<marker label="" time="99448750" />
|
||||
</wave_markers>
|
||||
<WVObjectSize size="47" />
|
||||
<wvobject fp_name="divider869" type="divider">
|
||||
<obj_property name="label">Clocks and Reset</obj_property>
|
||||
<obj_property name="DisplayName">label</obj_property>
|
||||
|
|
@ -37,6 +28,10 @@
|
|||
<obj_property name="ElementShortName">i_rst_n</obj_property>
|
||||
<obj_property name="ObjectShortName">i_rst_n</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/i_controller_clk">
|
||||
<obj_property name="ElementShortName">i_controller_clk</obj_property>
|
||||
<obj_property name="ObjectShortName">i_controller_clk</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/i_ddr3_clk">
|
||||
<obj_property name="ElementShortName">i_ddr3_clk</obj_property>
|
||||
<obj_property name="ObjectShortName">i_ddr3_clk</obj_property>
|
||||
|
|
@ -53,6 +48,14 @@
|
|||
<obj_property name="label">Calibration</obj_property>
|
||||
<obj_property name="DisplayName">label</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/ddr3_controller_inst/\sideband_ECC_per_8_bursts.ecc_dec_inst /sb_err">
|
||||
<obj_property name="ElementShortName">sb_err</obj_property>
|
||||
<obj_property name="ObjectShortName">sb_err</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/ddr3_controller_inst/\sideband_ECC_per_8_bursts.ecc_dec_inst /db_err">
|
||||
<obj_property name="ElementShortName">db_err</obj_property>
|
||||
<obj_property name="ObjectShortName">db_err</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/ddr3_controller_inst/initial_calibration_done">
|
||||
<obj_property name="ElementShortName">initial_calibration_done</obj_property>
|
||||
<obj_property name="ObjectShortName">initial_calibration_done</obj_property>
|
||||
|
|
@ -94,30 +97,6 @@
|
|||
<obj_property name="ElementShortName">instruction_address[4:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">instruction_address[4:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/ddr3_controller_inst/user_self_refresh_q">
|
||||
<obj_property name="ElementShortName">user_self_refresh_q</obj_property>
|
||||
<obj_property name="ObjectShortName">user_self_refresh_q</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/o_wb_stall">
|
||||
<obj_property name="ElementShortName">o_wb_stall</obj_property>
|
||||
<obj_property name="ObjectShortName">o_wb_stall</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/i_controller_clk">
|
||||
<obj_property name="ElementShortName">i_controller_clk</obj_property>
|
||||
<obj_property name="ObjectShortName">i_controller_clk</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_dimm_micron_sim/ddr3_top/ddr3_controller_inst/delay_counter">
|
||||
<obj_property name="ElementShortName">delay_counter[15:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">delay_counter[15:0]</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FF00FF</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_dimm_micron_sim/ddr3_top/ddr3_controller_inst/read_test_address_counter">
|
||||
<obj_property name="ElementShortName">read_test_address_counter[25:0]</obj_property>
|
||||
|
|
@ -143,10 +122,6 @@
|
|||
<obj_property name="label">WIshbone Interface</obj_property>
|
||||
<obj_property name="DisplayName">label</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_dimm_micron_sim/ddr3_top/ddr3_controller_inst/state_calibrate">
|
||||
<obj_property name="ElementShortName">state_calibrate[4:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">state_calibrate[4:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/i_controller_clk">
|
||||
<obj_property name="ElementShortName">i_controller_clk</obj_property>
|
||||
<obj_property name="ObjectShortName">i_controller_clk</obj_property>
|
||||
|
|
@ -196,13 +171,6 @@
|
|||
<obj_property name="label">DDR3 Interface</obj_property>
|
||||
<obj_property name="DisplayName">label</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_dimm_micron_sim/command_used">
|
||||
<obj_property name="ElementShortName">command_used[23:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">command_used[23:0]</obj_property>
|
||||
<obj_property name="Radix">ASCIIRADIX</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FFD700</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/o_ddr3_cke">
|
||||
<obj_property name="ElementShortName">o_ddr3_cke</obj_property>
|
||||
<obj_property name="ObjectShortName">o_ddr3_cke</obj_property>
|
||||
|
|
@ -250,80 +218,5 @@
|
|||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/o_ddr3_odt">
|
||||
<obj_property name="ElementShortName">o_ddr3_odt</obj_property>
|
||||
<obj_property name="ObjectShortName">o_ddr3_odt</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FF00FF</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_dimm_micron_sim/calibration_state">
|
||||
<obj_property name="ElementShortName">calibration_state[319:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">calibration_state[319:0]</obj_property>
|
||||
<obj_property name="Radix">ASCIIRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/ddr3_controller_inst/i_user_self_refresh">
|
||||
<obj_property name="ElementShortName">i_user_self_refresh</obj_property>
|
||||
<obj_property name="ObjectShortName">i_user_self_refresh</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/ddr3_controller_inst/user_self_refresh_q">
|
||||
<obj_property name="ElementShortName">user_self_refresh_q</obj_property>
|
||||
<obj_property name="ObjectShortName">user_self_refresh_q</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FF00FF</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_dimm_micron_sim/ddr3_top/refresh_counter">
|
||||
<obj_property name="ElementShortName">refresh_counter[8:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">refresh_counter[8:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FF00FF</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/i_wb_stb">
|
||||
<obj_property name="ElementShortName">i_wb_stb</obj_property>
|
||||
<obj_property name="ObjectShortName">i_wb_stb</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FF00FF</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/o_wb_stall">
|
||||
<obj_property name="ElementShortName">o_wb_stall</obj_property>
|
||||
<obj_property name="ObjectShortName">o_wb_stall</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FF00FF</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/i_wb_cyc">
|
||||
<obj_property name="ElementShortName">i_wb_cyc</obj_property>
|
||||
<obj_property name="ObjectShortName">i_wb_cyc</obj_property>
|
||||
<obj_property name="CustomSignalColor">#FF00FF</obj_property>
|
||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/o_ddr3_cke">
|
||||
<obj_property name="ElementShortName">o_ddr3_cke</obj_property>
|
||||
<obj_property name="ObjectShortName">o_ddr3_cke</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/i_user_self_refresh">
|
||||
<obj_property name="ElementShortName">i_user_self_refresh</obj_property>
|
||||
<obj_property name="ObjectShortName">i_user_self_refresh</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_dimm_micron_sim/ddr3_top/ddr3_controller_inst/instruction_address">
|
||||
<obj_property name="ElementShortName">instruction_address[4:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">instruction_address[4:0]</obj_property>
|
||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/ddr3_controller_inst/o_wb_stall_d">
|
||||
<obj_property name="ElementShortName">o_wb_stall_d</obj_property>
|
||||
<obj_property name="ObjectShortName">o_wb_stall_d</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/ddr3_controller_inst/pause_counter">
|
||||
<obj_property name="ElementShortName">pause_counter</obj_property>
|
||||
<obj_property name="ObjectShortName">pause_counter</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_dimm_micron_sim/ddr3_top/ddr3_controller_inst/tCKESR">
|
||||
<obj_property name="ElementShortName">tCKESR[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">tCKESR[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/ddr3_dimm_micron_sim/ddr3_top/ddr3_controller_inst/delay_counter">
|
||||
<obj_property name="ElementShortName">delay_counter[15:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">delay_counter[15:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/ddr3_dimm_micron_sim/ddr3_top/user_self_refresh">
|
||||
<obj_property name="ElementShortName">user_self_refresh</obj_property>
|
||||
<obj_property name="ObjectShortName">user_self_refresh</obj_property>
|
||||
</wvobject>
|
||||
</wave_config>
|
||||
|
|
|
|||
|
|
@ -1,49 +1,49 @@
|
|||
################################################################################
|
||||
# Vivado (TM) v2022.1 (64-bit)
|
||||
#
|
||||
# README.txt: Please read the sections below to understand the steps required to
|
||||
# run the exported script and information about the source files.
|
||||
#
|
||||
# Generated by export_simulation on Sat Jul 27 15:51:00 PST 2024
|
||||
#
|
||||
################################################################################
|
||||
|
||||
1. How to run the generated simulation script:-
|
||||
|
||||
From the shell prompt in the current directory, issue the following command:-
|
||||
|
||||
./ddr3_dimm_micron_sim.sh
|
||||
|
||||
This command will launch the 'compile', 'elaborate' and 'simulate' functions
|
||||
implemented in the script file for the 3-step flow. These functions are called
|
||||
from the main 'run' function in the script file.
|
||||
|
||||
The 'run' function first executes the 'setup' function, the purpose of which is to
|
||||
create simulator specific setup files, create design library mappings and library
|
||||
directories and copy 'glbl.v' from the Vivado software install location into the
|
||||
current directory.
|
||||
|
||||
The 'setup' function is also used for removing the simulator generated data in
|
||||
order to reset the current directory to the original state when export_simulation
|
||||
was launched from Vivado. This generated data can be removed by specifying the
|
||||
'-reset_run' switch to the './ddr3_dimm_micron_sim.sh' script.
|
||||
|
||||
./ddr3_dimm_micron_sim.sh -reset_run
|
||||
|
||||
To keep the generated data from the previous run but regenerate the setup files and
|
||||
library directories, use the '-noclean_files' switch.
|
||||
|
||||
./ddr3_dimm_micron_sim.sh -noclean_files
|
||||
|
||||
For more information on the script, please type './ddr3_dimm_micron_sim.sh -help'.
|
||||
|
||||
2. Additional design information files:-
|
||||
|
||||
export_simulation generates following additional file that can be used for fetching
|
||||
the design files information or for integrating with external custom scripts.
|
||||
|
||||
Name : file_info.txt
|
||||
Purpose: This file contains detail design file information based on the compile order
|
||||
when export_simulation was executed from Vivado. The file contains information
|
||||
about the file type, name, whether it is part of the IP, associated library
|
||||
and the file path information.
|
||||
################################################################################
|
||||
# Vivado (TM) v2022.1 (64-bit)
|
||||
#
|
||||
# README.txt: Please read the sections below to understand the steps required to
|
||||
# run the exported script and information about the source files.
|
||||
#
|
||||
# Generated by export_simulation on Sat Jul 27 15:51:00 PST 2024
|
||||
#
|
||||
################################################################################
|
||||
|
||||
1. How to run the generated simulation script:-
|
||||
|
||||
From the shell prompt in the current directory, issue the following command:-
|
||||
|
||||
./ddr3_dimm_micron_sim.sh
|
||||
|
||||
This command will launch the 'compile', 'elaborate' and 'simulate' functions
|
||||
implemented in the script file for the 3-step flow. These functions are called
|
||||
from the main 'run' function in the script file.
|
||||
|
||||
The 'run' function first executes the 'setup' function, the purpose of which is to
|
||||
create simulator specific setup files, create design library mappings and library
|
||||
directories and copy 'glbl.v' from the Vivado software install location into the
|
||||
current directory.
|
||||
|
||||
The 'setup' function is also used for removing the simulator generated data in
|
||||
order to reset the current directory to the original state when export_simulation
|
||||
was launched from Vivado. This generated data can be removed by specifying the
|
||||
'-reset_run' switch to the './ddr3_dimm_micron_sim.sh' script.
|
||||
|
||||
./ddr3_dimm_micron_sim.sh -reset_run
|
||||
|
||||
To keep the generated data from the previous run but regenerate the setup files and
|
||||
library directories, use the '-noclean_files' switch.
|
||||
|
||||
./ddr3_dimm_micron_sim.sh -noclean_files
|
||||
|
||||
For more information on the script, please type './ddr3_dimm_micron_sim.sh -help'.
|
||||
|
||||
2. Additional design information files:-
|
||||
|
||||
export_simulation generates following additional file that can be used for fetching
|
||||
the design files information or for integrating with external custom scripts.
|
||||
|
||||
Name : file_info.txt
|
||||
Purpose: This file contains detail design file information based on the compile order
|
||||
when export_simulation was executed from Vivado. The file contains information
|
||||
about the file type, name, whether it is part of the IP, associated library
|
||||
and the file path information.
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
set curr_wave [current_wave_config]
|
||||
if { [string length $curr_wave] == 0 } {
|
||||
if { [llength [get_objects]] > 0} {
|
||||
add_wave /
|
||||
set_property needs_save false [current_wave_config]
|
||||
} else {
|
||||
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."
|
||||
}
|
||||
}
|
||||
|
||||
run -all
|
||||
quit
|
||||
set curr_wave [current_wave_config]
|
||||
if { [string length $curr_wave] == 0 } {
|
||||
if { [llength [get_objects]] > 0} {
|
||||
add_wave /
|
||||
set_property needs_save false [current_wave_config]
|
||||
} else {
|
||||
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."
|
||||
}
|
||||
}
|
||||
|
||||
run -all
|
||||
quit
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
ddr3_controller.v,verilog,xil_defaultlib,../Desktop/UberDDR3/rtl/ddr3_controller.v,incdir="../"
|
||||
ddr3_phy.v,verilog,xil_defaultlib,../Desktop/UberDDR3/rtl/ddr3_phy.v,incdir="../"
|
||||
ddr3_top.v,verilog,xil_defaultlib,../Desktop/UberDDR3/rtl/ddr3_top.v,incdir="../"
|
||||
ddr3.sv,systemverilog,xil_defaultlib,../Desktop/UberDDR3/testbench/ddr3.sv,incdir="../"
|
||||
ddr3.sv,systemverilog,xil_defaultlib,../Desktop/UberDDR3/testbench/ddr3_module.sv,incdir="../"
|
||||
ecc_dec.sv,systemverilog,xil_defaultlib,../Desktop/UberDDR3/rtl/ecc/ecc_dec.sv,incdir="../"
|
||||
ecc_enc.sv,systemverilog,xil_defaultlib,../Desktop/UberDDR3/rtl/ecc/ecc_enc.sv,incdir="../"
|
||||
ddr3_dimm_micron_sim.sv,systemverilog,xil_defaultlib,../Desktop/UberDDR3/testbench/ddr3_dimm_micron_sim.sv,incdir="../"
|
||||
glbl.v,Verilog,xil_defaultlib,glbl.v
|
||||
ddr3_controller.v,verilog,xil_defaultlib,../Desktop/UberDDR3/rtl/ddr3_controller.v,incdir="../"
|
||||
ddr3_phy.v,verilog,xil_defaultlib,../Desktop/UberDDR3/rtl/ddr3_phy.v,incdir="../"
|
||||
ddr3_top.v,verilog,xil_defaultlib,../Desktop/UberDDR3/rtl/ddr3_top.v,incdir="../"
|
||||
ddr3.sv,systemverilog,xil_defaultlib,../Desktop/UberDDR3/testbench/ddr3.sv,incdir="../"
|
||||
ddr3.sv,systemverilog,xil_defaultlib,../Desktop/UberDDR3/testbench/ddr3_module.sv,incdir="../"
|
||||
ecc_dec.sv,systemverilog,xil_defaultlib,../Desktop/UberDDR3/rtl/ecc/ecc_dec.sv,incdir="../"
|
||||
ecc_enc.sv,systemverilog,xil_defaultlib,../Desktop/UberDDR3/rtl/ecc/ecc_enc.sv,incdir="../"
|
||||
ddr3_dimm_micron_sim.sv,systemverilog,xil_defaultlib,../Desktop/UberDDR3/testbench/ddr3_dimm_micron_sim.sv,incdir="../"
|
||||
glbl.v,Verilog,xil_defaultlib,glbl.v
|
||||
|
|
|
|||
|
|
@ -1,84 +1,84 @@
|
|||
// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/glbl.v,v 1.14 2010/10/28 20:44:00 fphillip Exp $
|
||||
`ifndef GLBL
|
||||
`define GLBL
|
||||
`timescale 1 ps / 1 ps
|
||||
|
||||
module glbl ();
|
||||
|
||||
parameter ROC_WIDTH = 100000;
|
||||
parameter TOC_WIDTH = 0;
|
||||
parameter GRES_WIDTH = 10000;
|
||||
parameter GRES_START = 10000;
|
||||
|
||||
//-------- STARTUP Globals --------------
|
||||
wire GSR;
|
||||
wire GTS;
|
||||
wire GWE;
|
||||
wire PRLD;
|
||||
wire GRESTORE;
|
||||
tri1 p_up_tmp;
|
||||
tri (weak1, strong0) PLL_LOCKG = p_up_tmp;
|
||||
|
||||
wire PROGB_GLBL;
|
||||
wire CCLKO_GLBL;
|
||||
wire FCSBO_GLBL;
|
||||
wire [3:0] DO_GLBL;
|
||||
wire [3:0] DI_GLBL;
|
||||
|
||||
reg GSR_int;
|
||||
reg GTS_int;
|
||||
reg PRLD_int;
|
||||
reg GRESTORE_int;
|
||||
|
||||
//-------- JTAG Globals --------------
|
||||
wire JTAG_TDO_GLBL;
|
||||
wire JTAG_TCK_GLBL;
|
||||
wire JTAG_TDI_GLBL;
|
||||
wire JTAG_TMS_GLBL;
|
||||
wire JTAG_TRST_GLBL;
|
||||
|
||||
reg JTAG_CAPTURE_GLBL;
|
||||
reg JTAG_RESET_GLBL;
|
||||
reg JTAG_SHIFT_GLBL;
|
||||
reg JTAG_UPDATE_GLBL;
|
||||
reg JTAG_RUNTEST_GLBL;
|
||||
|
||||
reg JTAG_SEL1_GLBL = 0;
|
||||
reg JTAG_SEL2_GLBL = 0 ;
|
||||
reg JTAG_SEL3_GLBL = 0;
|
||||
reg JTAG_SEL4_GLBL = 0;
|
||||
|
||||
reg JTAG_USER_TDO1_GLBL = 1'bz;
|
||||
reg JTAG_USER_TDO2_GLBL = 1'bz;
|
||||
reg JTAG_USER_TDO3_GLBL = 1'bz;
|
||||
reg JTAG_USER_TDO4_GLBL = 1'bz;
|
||||
|
||||
assign (strong1, weak0) GSR = GSR_int;
|
||||
assign (strong1, weak0) GTS = GTS_int;
|
||||
assign (weak1, weak0) PRLD = PRLD_int;
|
||||
assign (strong1, weak0) GRESTORE = GRESTORE_int;
|
||||
|
||||
initial begin
|
||||
GSR_int = 1'b1;
|
||||
PRLD_int = 1'b1;
|
||||
#(ROC_WIDTH)
|
||||
GSR_int = 1'b0;
|
||||
PRLD_int = 1'b0;
|
||||
end
|
||||
|
||||
initial begin
|
||||
GTS_int = 1'b1;
|
||||
#(TOC_WIDTH)
|
||||
GTS_int = 1'b0;
|
||||
end
|
||||
|
||||
initial begin
|
||||
GRESTORE_int = 1'b0;
|
||||
#(GRES_START);
|
||||
GRESTORE_int = 1'b1;
|
||||
#(GRES_WIDTH);
|
||||
GRESTORE_int = 1'b0;
|
||||
end
|
||||
|
||||
endmodule
|
||||
`endif
|
||||
// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/glbl.v,v 1.14 2010/10/28 20:44:00 fphillip Exp $
|
||||
`ifndef GLBL
|
||||
`define GLBL
|
||||
`timescale 1 ps / 1 ps
|
||||
|
||||
module glbl ();
|
||||
|
||||
parameter ROC_WIDTH = 100000;
|
||||
parameter TOC_WIDTH = 0;
|
||||
parameter GRES_WIDTH = 10000;
|
||||
parameter GRES_START = 10000;
|
||||
|
||||
//-------- STARTUP Globals --------------
|
||||
wire GSR;
|
||||
wire GTS;
|
||||
wire GWE;
|
||||
wire PRLD;
|
||||
wire GRESTORE;
|
||||
tri1 p_up_tmp;
|
||||
tri (weak1, strong0) PLL_LOCKG = p_up_tmp;
|
||||
|
||||
wire PROGB_GLBL;
|
||||
wire CCLKO_GLBL;
|
||||
wire FCSBO_GLBL;
|
||||
wire [3:0] DO_GLBL;
|
||||
wire [3:0] DI_GLBL;
|
||||
|
||||
reg GSR_int;
|
||||
reg GTS_int;
|
||||
reg PRLD_int;
|
||||
reg GRESTORE_int;
|
||||
|
||||
//-------- JTAG Globals --------------
|
||||
wire JTAG_TDO_GLBL;
|
||||
wire JTAG_TCK_GLBL;
|
||||
wire JTAG_TDI_GLBL;
|
||||
wire JTAG_TMS_GLBL;
|
||||
wire JTAG_TRST_GLBL;
|
||||
|
||||
reg JTAG_CAPTURE_GLBL;
|
||||
reg JTAG_RESET_GLBL;
|
||||
reg JTAG_SHIFT_GLBL;
|
||||
reg JTAG_UPDATE_GLBL;
|
||||
reg JTAG_RUNTEST_GLBL;
|
||||
|
||||
reg JTAG_SEL1_GLBL = 0;
|
||||
reg JTAG_SEL2_GLBL = 0 ;
|
||||
reg JTAG_SEL3_GLBL = 0;
|
||||
reg JTAG_SEL4_GLBL = 0;
|
||||
|
||||
reg JTAG_USER_TDO1_GLBL = 1'bz;
|
||||
reg JTAG_USER_TDO2_GLBL = 1'bz;
|
||||
reg JTAG_USER_TDO3_GLBL = 1'bz;
|
||||
reg JTAG_USER_TDO4_GLBL = 1'bz;
|
||||
|
||||
assign (strong1, weak0) GSR = GSR_int;
|
||||
assign (strong1, weak0) GTS = GTS_int;
|
||||
assign (weak1, weak0) PRLD = PRLD_int;
|
||||
assign (strong1, weak0) GRESTORE = GRESTORE_int;
|
||||
|
||||
initial begin
|
||||
GSR_int = 1'b1;
|
||||
PRLD_int = 1'b1;
|
||||
#(ROC_WIDTH)
|
||||
GSR_int = 1'b0;
|
||||
PRLD_int = 1'b0;
|
||||
end
|
||||
|
||||
initial begin
|
||||
GTS_int = 1'b1;
|
||||
#(TOC_WIDTH)
|
||||
GTS_int = 1'b0;
|
||||
end
|
||||
|
||||
initial begin
|
||||
GRESTORE_int = 1'b0;
|
||||
#(GRES_START);
|
||||
GRESTORE_int = 1'b1;
|
||||
#(GRES_WIDTH);
|
||||
GRESTORE_int = 1'b0;
|
||||
end
|
||||
|
||||
endmodule
|
||||
`endif
|
||||
|
|
|
|||
|
|
@ -1,26 +1,26 @@
|
|||
rm -rf *backup*
|
||||
rm -rf *test_ecc*.log*
|
||||
echo -e "\e[32mRun test: test_ecc_0 \e[0m"
|
||||
./test_ecc_0.sh -reset_run
|
||||
./test_ecc_0.sh >> ./test_ecc_0.log
|
||||
./test_ecc_0.sh -reset_run
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
echo -e "\e[32mRun test: test_ecc_1 \e[0m"
|
||||
./test_ecc_1.sh >> ./test_ecc_1.log
|
||||
./test_ecc_1.sh -reset_run
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
echo -e "\e[32mRun test: test_ecc_2 \e[0m"
|
||||
./test_ecc_2.sh >> ./test_ecc_2.log
|
||||
./test_ecc_2.sh -reset_run
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
echo -e "\e[32mRun test: test_ecc_3 \e[0m"
|
||||
./test_ecc_3.sh >> ./test_ecc_3.log
|
||||
./test_ecc_3.sh -reset_run
|
||||
|
||||
rm -rf *backup*
|
||||
rm -rf *backup*
|
||||
rm -rf *test_ecc*.log*
|
||||
echo -e "\e[32mRun test: test_ecc_0 \e[0m"
|
||||
./test_ecc_0.sh -reset_run
|
||||
./test_ecc_0.sh >> ./test_ecc_0.log
|
||||
./test_ecc_0.sh -reset_run
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
echo -e "\e[32mRun test: test_ecc_1 \e[0m"
|
||||
./test_ecc_1.sh >> ./test_ecc_1.log
|
||||
./test_ecc_1.sh -reset_run
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
echo -e "\e[32mRun test: test_ecc_2 \e[0m"
|
||||
./test_ecc_2.sh >> ./test_ecc_2.log
|
||||
./test_ecc_2.sh -reset_run
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
echo -e "\e[32mRun test: test_ecc_3 \e[0m"
|
||||
./test_ecc_3.sh >> ./test_ecc_3.log
|
||||
./test_ecc_3.sh -reset_run
|
||||
|
||||
rm -rf *backup*
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,129 +1,129 @@
|
|||
#!/bin/bash -f
|
||||
#*********************************************************************************************************
|
||||
# Vivado (TM) v2022.1 (64-bit)
|
||||
#
|
||||
# Filename : ddr3_dimm_micron_sim.sh
|
||||
# Simulator : Xilinx Vivado Simulator
|
||||
# Description : Simulation script for compiling, elaborating and verifying the project source files.
|
||||
# The script will automatically create the design libraries sub-directories in the run
|
||||
# directory, add the library logical mappings in the simulator setup file, create default
|
||||
# 'do/prj' file, execute compilation, elaboration and simulation steps.
|
||||
#
|
||||
# Generated by Vivado on Sat Jul 27 15:51:00 PST 2024
|
||||
# SW Build 3526262 on Mon Apr 18 15:47:01 MDT 2022
|
||||
#
|
||||
# Tool Version Limit: 2022.04
|
||||
#
|
||||
# usage: ddr3_dimm_micron_sim.sh [-help]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-lib_map_path]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-noclean_files]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-reset_run]
|
||||
#
|
||||
#*********************************************************************************************************
|
||||
|
||||
# Set xvlog options
|
||||
xvlog_opts="--incr --relax -L uvm"
|
||||
|
||||
# Script info
|
||||
echo -e "ddr3_dimm_micron_sim.sh - Script generated by export_simulation (Vivado v2022.1 (64-bit)-id)\n"
|
||||
|
||||
# Main steps
|
||||
run()
|
||||
{
|
||||
check_args $# $1
|
||||
setup $1 $2
|
||||
compile
|
||||
elaborate
|
||||
simulate
|
||||
}
|
||||
|
||||
# RUN_STEP: <compile>
|
||||
compile()
|
||||
{
|
||||
xvlog $xvlog_opts -prj vlog.prj 2>&1 | tee compile.log
|
||||
}
|
||||
|
||||
# RUN_STEP: <elaborate>
|
||||
elaborate()
|
||||
{
|
||||
xelab -generic_top "ECC_ENABLE=0" --incr --debug typical --relax --mt auto -L xil_defaultlib -L uvm -L unisims_ver -L unimacro_ver -L secureip --snapshot ddr3_dimm_micron_sim xil_defaultlib.ddr3_dimm_micron_sim xil_defaultlib.glbl -log elaborate.log
|
||||
}
|
||||
|
||||
# RUN_STEP: <simulate>
|
||||
simulate()
|
||||
{
|
||||
xsim ddr3_dimm_micron_sim -key {Behavioral:sim_1:Functional:ddr3_dimm_micron_sim} -tclbatch cmd.tcl -log simulate.log
|
||||
}
|
||||
|
||||
# STEP: setup
|
||||
setup()
|
||||
{
|
||||
case $1 in
|
||||
"-lib_map_path" )
|
||||
if [[ ($2 == "") ]]; then
|
||||
echo -e "ERROR: Simulation library directory path not specified (type \"./ddr3_dimm_micron_sim.sh -help\" for more information)\n"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
"-reset_run" )
|
||||
reset_run
|
||||
echo -e "INFO: Simulation run files deleted.\n"
|
||||
exit 0
|
||||
;;
|
||||
"-noclean_files" )
|
||||
# do not remove previous data
|
||||
;;
|
||||
* )
|
||||
esac
|
||||
|
||||
# Add any setup/initialization commands here:-
|
||||
|
||||
# <user specific commands>
|
||||
|
||||
}
|
||||
|
||||
# Delete generated data from the previous run
|
||||
reset_run()
|
||||
{
|
||||
files_to_remove=(xelab.pb xsim.jou xvhdl.log xvlog.log compile.log elaborate.log simulate.log xelab.log xsim.log run.log xvhdl.pb xvlog.pb ddr3_dimm_micron_sim.wdb xsim.dir)
|
||||
for (( i=0; i<${#files_to_remove[*]}; i++ )); do
|
||||
file="${files_to_remove[i]}"
|
||||
if [[ -e $file ]]; then
|
||||
rm -rf $file
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Check command line arguments
|
||||
check_args()
|
||||
{
|
||||
if [[ ($1 == 1 ) && ($2 != "-lib_map_path" && $2 != "-noclean_files" && $2 != "-reset_run" && $2 != "-help" && $2 != "-h") ]]; then
|
||||
echo -e "ERROR: Unknown option specified '$2' (type \"./ddr3_dimm_micron_sim.sh -help\" for more information)\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ($2 == "-help" || $2 == "-h") ]]; then
|
||||
usage
|
||||
fi
|
||||
}
|
||||
|
||||
# Script usage
|
||||
usage()
|
||||
{
|
||||
msg="Usage: ddr3_dimm_micron_sim.sh [-help]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-lib_map_path]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-reset_run]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-noclean_files]\n\n\
|
||||
[-help] -- Print help information for this script\n\n\
|
||||
[-lib_map_path <path>] -- Compiled simulation library directory path. The simulation library is compiled\n\
|
||||
using the compile_simlib tcl command. Please see 'compile_simlib -help' for more information.\n\n\
|
||||
[-reset_run] -- Recreate simulator setup files and library mappings for a clean run. The generated files\n\
|
||||
from the previous run will be removed. If you don't want to remove the simulator generated files, use the\n\
|
||||
-noclean_files switch.\n\n\
|
||||
[-noclean_files] -- Reset previous run, but do not remove simulator generated files from the previous run.\n\n"
|
||||
echo -e $msg
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Launch script
|
||||
run $1 $2
|
||||
#!/bin/bash -f
|
||||
#*********************************************************************************************************
|
||||
# Vivado (TM) v2022.1 (64-bit)
|
||||
#
|
||||
# Filename : ddr3_dimm_micron_sim.sh
|
||||
# Simulator : Xilinx Vivado Simulator
|
||||
# Description : Simulation script for compiling, elaborating and verifying the project source files.
|
||||
# The script will automatically create the design libraries sub-directories in the run
|
||||
# directory, add the library logical mappings in the simulator setup file, create default
|
||||
# 'do/prj' file, execute compilation, elaboration and simulation steps.
|
||||
#
|
||||
# Generated by Vivado on Sat Jul 27 15:51:00 PST 2024
|
||||
# SW Build 3526262 on Mon Apr 18 15:47:01 MDT 2022
|
||||
#
|
||||
# Tool Version Limit: 2022.04
|
||||
#
|
||||
# usage: ddr3_dimm_micron_sim.sh [-help]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-lib_map_path]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-noclean_files]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-reset_run]
|
||||
#
|
||||
#*********************************************************************************************************
|
||||
|
||||
# Set xvlog options
|
||||
xvlog_opts="--incr --relax -L uvm"
|
||||
|
||||
# Script info
|
||||
echo -e "ddr3_dimm_micron_sim.sh - Script generated by export_simulation (Vivado v2022.1 (64-bit)-id)\n"
|
||||
|
||||
# Main steps
|
||||
run()
|
||||
{
|
||||
check_args $# $1
|
||||
setup $1 $2
|
||||
compile
|
||||
elaborate
|
||||
simulate
|
||||
}
|
||||
|
||||
# RUN_STEP: <compile>
|
||||
compile()
|
||||
{
|
||||
xvlog $xvlog_opts -prj vlog.prj 2>&1 | tee compile.log
|
||||
}
|
||||
|
||||
# RUN_STEP: <elaborate>
|
||||
elaborate()
|
||||
{
|
||||
xelab -generic_top "ECC_ENABLE=0" --incr --debug typical --relax --mt auto -L xil_defaultlib -L uvm -L unisims_ver -L unimacro_ver -L secureip --snapshot ddr3_dimm_micron_sim xil_defaultlib.ddr3_dimm_micron_sim xil_defaultlib.glbl -log elaborate.log
|
||||
}
|
||||
|
||||
# RUN_STEP: <simulate>
|
||||
simulate()
|
||||
{
|
||||
xsim ddr3_dimm_micron_sim -key {Behavioral:sim_1:Functional:ddr3_dimm_micron_sim} -tclbatch cmd.tcl -log simulate.log
|
||||
}
|
||||
|
||||
# STEP: setup
|
||||
setup()
|
||||
{
|
||||
case $1 in
|
||||
"-lib_map_path" )
|
||||
if [[ ($2 == "") ]]; then
|
||||
echo -e "ERROR: Simulation library directory path not specified (type \"./ddr3_dimm_micron_sim.sh -help\" for more information)\n"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
"-reset_run" )
|
||||
reset_run
|
||||
echo -e "INFO: Simulation run files deleted.\n"
|
||||
exit 0
|
||||
;;
|
||||
"-noclean_files" )
|
||||
# do not remove previous data
|
||||
;;
|
||||
* )
|
||||
esac
|
||||
|
||||
# Add any setup/initialization commands here:-
|
||||
|
||||
# <user specific commands>
|
||||
|
||||
}
|
||||
|
||||
# Delete generated data from the previous run
|
||||
reset_run()
|
||||
{
|
||||
files_to_remove=(xelab.pb xsim.jou xvhdl.log xvlog.log compile.log elaborate.log simulate.log xelab.log xsim.log run.log xvhdl.pb xvlog.pb ddr3_dimm_micron_sim.wdb xsim.dir)
|
||||
for (( i=0; i<${#files_to_remove[*]}; i++ )); do
|
||||
file="${files_to_remove[i]}"
|
||||
if [[ -e $file ]]; then
|
||||
rm -rf $file
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Check command line arguments
|
||||
check_args()
|
||||
{
|
||||
if [[ ($1 == 1 ) && ($2 != "-lib_map_path" && $2 != "-noclean_files" && $2 != "-reset_run" && $2 != "-help" && $2 != "-h") ]]; then
|
||||
echo -e "ERROR: Unknown option specified '$2' (type \"./ddr3_dimm_micron_sim.sh -help\" for more information)\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ($2 == "-help" || $2 == "-h") ]]; then
|
||||
usage
|
||||
fi
|
||||
}
|
||||
|
||||
# Script usage
|
||||
usage()
|
||||
{
|
||||
msg="Usage: ddr3_dimm_micron_sim.sh [-help]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-lib_map_path]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-reset_run]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-noclean_files]\n\n\
|
||||
[-help] -- Print help information for this script\n\n\
|
||||
[-lib_map_path <path>] -- Compiled simulation library directory path. The simulation library is compiled\n\
|
||||
using the compile_simlib tcl command. Please see 'compile_simlib -help' for more information.\n\n\
|
||||
[-reset_run] -- Recreate simulator setup files and library mappings for a clean run. The generated files\n\
|
||||
from the previous run will be removed. If you don't want to remove the simulator generated files, use the\n\
|
||||
-noclean_files switch.\n\n\
|
||||
[-noclean_files] -- Reset previous run, but do not remove simulator generated files from the previous run.\n\n"
|
||||
echo -e $msg
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Launch script
|
||||
run $1 $2
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,129 +1,129 @@
|
|||
#!/bin/bash -f
|
||||
#*********************************************************************************************************
|
||||
# Vivado (TM) v2022.1 (64-bit)
|
||||
#
|
||||
# Filename : ddr3_dimm_micron_sim.sh
|
||||
# Simulator : Xilinx Vivado Simulator
|
||||
# Description : Simulation script for compiling, elaborating and verifying the project source files.
|
||||
# The script will automatically create the design libraries sub-directories in the run
|
||||
# directory, add the library logical mappings in the simulator setup file, create default
|
||||
# 'do/prj' file, execute compilation, elaboration and simulation steps.
|
||||
#
|
||||
# Generated by Vivado on Sat Jul 27 15:51:00 PST 2024
|
||||
# SW Build 3526262 on Mon Apr 18 15:47:01 MDT 2022
|
||||
#
|
||||
# Tool Version Limit: 2022.04
|
||||
#
|
||||
# usage: ddr3_dimm_micron_sim.sh [-help]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-lib_map_path]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-noclean_files]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-reset_run]
|
||||
#
|
||||
#*********************************************************************************************************
|
||||
|
||||
# Set xvlog options
|
||||
xvlog_opts="--incr --relax -L uvm"
|
||||
|
||||
# Script info
|
||||
echo -e "ddr3_dimm_micron_sim.sh - Script generated by export_simulation (Vivado v2022.1 (64-bit)-id)\n"
|
||||
|
||||
# Main steps
|
||||
run()
|
||||
{
|
||||
check_args $# $1
|
||||
setup $1 $2
|
||||
compile
|
||||
elaborate
|
||||
simulate
|
||||
}
|
||||
|
||||
# RUN_STEP: <compile>
|
||||
compile()
|
||||
{
|
||||
xvlog $xvlog_opts -prj vlog.prj 2>&1 | tee compile.log
|
||||
}
|
||||
|
||||
# RUN_STEP: <elaborate>
|
||||
elaborate()
|
||||
{
|
||||
xelab -generic_top "ECC_ENABLE=1" --incr --debug typical --relax --mt auto -L xil_defaultlib -L uvm -L unisims_ver -L unimacro_ver -L secureip --snapshot ddr3_dimm_micron_sim xil_defaultlib.ddr3_dimm_micron_sim xil_defaultlib.glbl -log elaborate.log
|
||||
}
|
||||
|
||||
# RUN_STEP: <simulate>
|
||||
simulate()
|
||||
{
|
||||
xsim ddr3_dimm_micron_sim -key {Behavioral:sim_1:Functional:ddr3_dimm_micron_sim} -tclbatch cmd.tcl -log simulate.log
|
||||
}
|
||||
|
||||
# STEP: setup
|
||||
setup()
|
||||
{
|
||||
case $1 in
|
||||
"-lib_map_path" )
|
||||
if [[ ($2 == "") ]]; then
|
||||
echo -e "ERROR: Simulation library directory path not specified (type \"./ddr3_dimm_micron_sim.sh -help\" for more information)\n"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
"-reset_run" )
|
||||
reset_run
|
||||
echo -e "INFO: Simulation run files deleted.\n"
|
||||
exit 0
|
||||
;;
|
||||
"-noclean_files" )
|
||||
# do not remove previous data
|
||||
;;
|
||||
* )
|
||||
esac
|
||||
|
||||
# Add any setup/initialization commands here:-
|
||||
|
||||
# <user specific commands>
|
||||
|
||||
}
|
||||
|
||||
# Delete generated data from the previous run
|
||||
reset_run()
|
||||
{
|
||||
files_to_remove=(xelab.pb xsim.jou xvhdl.log xvlog.log compile.log elaborate.log simulate.log xelab.log xsim.log run.log xvhdl.pb xvlog.pb ddr3_dimm_micron_sim.wdb xsim.dir)
|
||||
for (( i=0; i<${#files_to_remove[*]}; i++ )); do
|
||||
file="${files_to_remove[i]}"
|
||||
if [[ -e $file ]]; then
|
||||
rm -rf $file
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Check command line arguments
|
||||
check_args()
|
||||
{
|
||||
if [[ ($1 == 1 ) && ($2 != "-lib_map_path" && $2 != "-noclean_files" && $2 != "-reset_run" && $2 != "-help" && $2 != "-h") ]]; then
|
||||
echo -e "ERROR: Unknown option specified '$2' (type \"./ddr3_dimm_micron_sim.sh -help\" for more information)\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ($2 == "-help" || $2 == "-h") ]]; then
|
||||
usage
|
||||
fi
|
||||
}
|
||||
|
||||
# Script usage
|
||||
usage()
|
||||
{
|
||||
msg="Usage: ddr3_dimm_micron_sim.sh [-help]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-lib_map_path]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-reset_run]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-noclean_files]\n\n\
|
||||
[-help] -- Print help information for this script\n\n\
|
||||
[-lib_map_path <path>] -- Compiled simulation library directory path. The simulation library is compiled\n\
|
||||
using the compile_simlib tcl command. Please see 'compile_simlib -help' for more information.\n\n\
|
||||
[-reset_run] -- Recreate simulator setup files and library mappings for a clean run. The generated files\n\
|
||||
from the previous run will be removed. If you don't want to remove the simulator generated files, use the\n\
|
||||
-noclean_files switch.\n\n\
|
||||
[-noclean_files] -- Reset previous run, but do not remove simulator generated files from the previous run.\n\n"
|
||||
echo -e $msg
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Launch script
|
||||
run $1 $2
|
||||
#!/bin/bash -f
|
||||
#*********************************************************************************************************
|
||||
# Vivado (TM) v2022.1 (64-bit)
|
||||
#
|
||||
# Filename : ddr3_dimm_micron_sim.sh
|
||||
# Simulator : Xilinx Vivado Simulator
|
||||
# Description : Simulation script for compiling, elaborating and verifying the project source files.
|
||||
# The script will automatically create the design libraries sub-directories in the run
|
||||
# directory, add the library logical mappings in the simulator setup file, create default
|
||||
# 'do/prj' file, execute compilation, elaboration and simulation steps.
|
||||
#
|
||||
# Generated by Vivado on Sat Jul 27 15:51:00 PST 2024
|
||||
# SW Build 3526262 on Mon Apr 18 15:47:01 MDT 2022
|
||||
#
|
||||
# Tool Version Limit: 2022.04
|
||||
#
|
||||
# usage: ddr3_dimm_micron_sim.sh [-help]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-lib_map_path]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-noclean_files]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-reset_run]
|
||||
#
|
||||
#*********************************************************************************************************
|
||||
|
||||
# Set xvlog options
|
||||
xvlog_opts="--incr --relax -L uvm"
|
||||
|
||||
# Script info
|
||||
echo -e "ddr3_dimm_micron_sim.sh - Script generated by export_simulation (Vivado v2022.1 (64-bit)-id)\n"
|
||||
|
||||
# Main steps
|
||||
run()
|
||||
{
|
||||
check_args $# $1
|
||||
setup $1 $2
|
||||
compile
|
||||
elaborate
|
||||
simulate
|
||||
}
|
||||
|
||||
# RUN_STEP: <compile>
|
||||
compile()
|
||||
{
|
||||
xvlog $xvlog_opts -prj vlog.prj 2>&1 | tee compile.log
|
||||
}
|
||||
|
||||
# RUN_STEP: <elaborate>
|
||||
elaborate()
|
||||
{
|
||||
xelab -generic_top "ECC_ENABLE=1" --incr --debug typical --relax --mt auto -L xil_defaultlib -L uvm -L unisims_ver -L unimacro_ver -L secureip --snapshot ddr3_dimm_micron_sim xil_defaultlib.ddr3_dimm_micron_sim xil_defaultlib.glbl -log elaborate.log
|
||||
}
|
||||
|
||||
# RUN_STEP: <simulate>
|
||||
simulate()
|
||||
{
|
||||
xsim ddr3_dimm_micron_sim -key {Behavioral:sim_1:Functional:ddr3_dimm_micron_sim} -tclbatch cmd.tcl -log simulate.log
|
||||
}
|
||||
|
||||
# STEP: setup
|
||||
setup()
|
||||
{
|
||||
case $1 in
|
||||
"-lib_map_path" )
|
||||
if [[ ($2 == "") ]]; then
|
||||
echo -e "ERROR: Simulation library directory path not specified (type \"./ddr3_dimm_micron_sim.sh -help\" for more information)\n"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
"-reset_run" )
|
||||
reset_run
|
||||
echo -e "INFO: Simulation run files deleted.\n"
|
||||
exit 0
|
||||
;;
|
||||
"-noclean_files" )
|
||||
# do not remove previous data
|
||||
;;
|
||||
* )
|
||||
esac
|
||||
|
||||
# Add any setup/initialization commands here:-
|
||||
|
||||
# <user specific commands>
|
||||
|
||||
}
|
||||
|
||||
# Delete generated data from the previous run
|
||||
reset_run()
|
||||
{
|
||||
files_to_remove=(xelab.pb xsim.jou xvhdl.log xvlog.log compile.log elaborate.log simulate.log xelab.log xsim.log run.log xvhdl.pb xvlog.pb ddr3_dimm_micron_sim.wdb xsim.dir)
|
||||
for (( i=0; i<${#files_to_remove[*]}; i++ )); do
|
||||
file="${files_to_remove[i]}"
|
||||
if [[ -e $file ]]; then
|
||||
rm -rf $file
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Check command line arguments
|
||||
check_args()
|
||||
{
|
||||
if [[ ($1 == 1 ) && ($2 != "-lib_map_path" && $2 != "-noclean_files" && $2 != "-reset_run" && $2 != "-help" && $2 != "-h") ]]; then
|
||||
echo -e "ERROR: Unknown option specified '$2' (type \"./ddr3_dimm_micron_sim.sh -help\" for more information)\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ($2 == "-help" || $2 == "-h") ]]; then
|
||||
usage
|
||||
fi
|
||||
}
|
||||
|
||||
# Script usage
|
||||
usage()
|
||||
{
|
||||
msg="Usage: ddr3_dimm_micron_sim.sh [-help]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-lib_map_path]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-reset_run]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-noclean_files]\n\n\
|
||||
[-help] -- Print help information for this script\n\n\
|
||||
[-lib_map_path <path>] -- Compiled simulation library directory path. The simulation library is compiled\n\
|
||||
using the compile_simlib tcl command. Please see 'compile_simlib -help' for more information.\n\n\
|
||||
[-reset_run] -- Recreate simulator setup files and library mappings for a clean run. The generated files\n\
|
||||
from the previous run will be removed. If you don't want to remove the simulator generated files, use the\n\
|
||||
-noclean_files switch.\n\n\
|
||||
[-noclean_files] -- Reset previous run, but do not remove simulator generated files from the previous run.\n\n"
|
||||
echo -e $msg
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Launch script
|
||||
run $1 $2
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,129 +1,129 @@
|
|||
#!/bin/bash -f
|
||||
#*********************************************************************************************************
|
||||
# Vivado (TM) v2022.1 (64-bit)
|
||||
#
|
||||
# Filename : ddr3_dimm_micron_sim.sh
|
||||
# Simulator : Xilinx Vivado Simulator
|
||||
# Description : Simulation script for compiling, elaborating and verifying the project source files.
|
||||
# The script will automatically create the design libraries sub-directories in the run
|
||||
# directory, add the library logical mappings in the simulator setup file, create default
|
||||
# 'do/prj' file, execute compilation, elaboration and simulation steps.
|
||||
#
|
||||
# Generated by Vivado on Sat Jul 27 15:51:00 PST 2024
|
||||
# SW Build 3526262 on Mon Apr 18 15:47:01 MDT 2022
|
||||
#
|
||||
# Tool Version Limit: 2022.04
|
||||
#
|
||||
# usage: ddr3_dimm_micron_sim.sh [-help]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-lib_map_path]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-noclean_files]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-reset_run]
|
||||
#
|
||||
#*********************************************************************************************************
|
||||
|
||||
# Set xvlog options
|
||||
xvlog_opts="--incr --relax -L uvm"
|
||||
|
||||
# Script info
|
||||
echo -e "ddr3_dimm_micron_sim.sh - Script generated by export_simulation (Vivado v2022.1 (64-bit)-id)\n"
|
||||
|
||||
# Main steps
|
||||
run()
|
||||
{
|
||||
check_args $# $1
|
||||
setup $1 $2
|
||||
compile
|
||||
elaborate
|
||||
simulate
|
||||
}
|
||||
|
||||
# RUN_STEP: <compile>
|
||||
compile()
|
||||
{
|
||||
xvlog $xvlog_opts -prj vlog.prj 2>&1 | tee compile.log
|
||||
}
|
||||
|
||||
# RUN_STEP: <elaborate>
|
||||
elaborate()
|
||||
{
|
||||
xelab -generic_top "ECC_ENABLE=2" --incr --debug typical --relax --mt auto -L xil_defaultlib -L uvm -L unisims_ver -L unimacro_ver -L secureip --snapshot ddr3_dimm_micron_sim xil_defaultlib.ddr3_dimm_micron_sim xil_defaultlib.glbl -log elaborate.log
|
||||
}
|
||||
|
||||
# RUN_STEP: <simulate>
|
||||
simulate()
|
||||
{
|
||||
xsim ddr3_dimm_micron_sim -key {Behavioral:sim_1:Functional:ddr3_dimm_micron_sim} -tclbatch cmd.tcl -log simulate.log
|
||||
}
|
||||
|
||||
# STEP: setup
|
||||
setup()
|
||||
{
|
||||
case $1 in
|
||||
"-lib_map_path" )
|
||||
if [[ ($2 == "") ]]; then
|
||||
echo -e "ERROR: Simulation library directory path not specified (type \"./ddr3_dimm_micron_sim.sh -help\" for more information)\n"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
"-reset_run" )
|
||||
reset_run
|
||||
echo -e "INFO: Simulation run files deleted.\n"
|
||||
exit 0
|
||||
;;
|
||||
"-noclean_files" )
|
||||
# do not remove previous data
|
||||
;;
|
||||
* )
|
||||
esac
|
||||
|
||||
# Add any setup/initialization commands here:-
|
||||
|
||||
# <user specific commands>
|
||||
|
||||
}
|
||||
|
||||
# Delete generated data from the previous run
|
||||
reset_run()
|
||||
{
|
||||
files_to_remove=(xelab.pb xsim.jou xvhdl.log xvlog.log compile.log elaborate.log simulate.log xelab.log xsim.log run.log xvhdl.pb xvlog.pb ddr3_dimm_micron_sim.wdb xsim.dir)
|
||||
for (( i=0; i<${#files_to_remove[*]}; i++ )); do
|
||||
file="${files_to_remove[i]}"
|
||||
if [[ -e $file ]]; then
|
||||
rm -rf $file
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Check command line arguments
|
||||
check_args()
|
||||
{
|
||||
if [[ ($1 == 1 ) && ($2 != "-lib_map_path" && $2 != "-noclean_files" && $2 != "-reset_run" && $2 != "-help" && $2 != "-h") ]]; then
|
||||
echo -e "ERROR: Unknown option specified '$2' (type \"./ddr3_dimm_micron_sim.sh -help\" for more information)\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ($2 == "-help" || $2 == "-h") ]]; then
|
||||
usage
|
||||
fi
|
||||
}
|
||||
|
||||
# Script usage
|
||||
usage()
|
||||
{
|
||||
msg="Usage: ddr3_dimm_micron_sim.sh [-help]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-lib_map_path]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-reset_run]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-noclean_files]\n\n\
|
||||
[-help] -- Print help information for this script\n\n\
|
||||
[-lib_map_path <path>] -- Compiled simulation library directory path. The simulation library is compiled\n\
|
||||
using the compile_simlib tcl command. Please see 'compile_simlib -help' for more information.\n\n\
|
||||
[-reset_run] -- Recreate simulator setup files and library mappings for a clean run. The generated files\n\
|
||||
from the previous run will be removed. If you don't want to remove the simulator generated files, use the\n\
|
||||
-noclean_files switch.\n\n\
|
||||
[-noclean_files] -- Reset previous run, but do not remove simulator generated files from the previous run.\n\n"
|
||||
echo -e $msg
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Launch script
|
||||
run $1 $2
|
||||
#!/bin/bash -f
|
||||
#*********************************************************************************************************
|
||||
# Vivado (TM) v2022.1 (64-bit)
|
||||
#
|
||||
# Filename : ddr3_dimm_micron_sim.sh
|
||||
# Simulator : Xilinx Vivado Simulator
|
||||
# Description : Simulation script for compiling, elaborating and verifying the project source files.
|
||||
# The script will automatically create the design libraries sub-directories in the run
|
||||
# directory, add the library logical mappings in the simulator setup file, create default
|
||||
# 'do/prj' file, execute compilation, elaboration and simulation steps.
|
||||
#
|
||||
# Generated by Vivado on Sat Jul 27 15:51:00 PST 2024
|
||||
# SW Build 3526262 on Mon Apr 18 15:47:01 MDT 2022
|
||||
#
|
||||
# Tool Version Limit: 2022.04
|
||||
#
|
||||
# usage: ddr3_dimm_micron_sim.sh [-help]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-lib_map_path]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-noclean_files]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-reset_run]
|
||||
#
|
||||
#*********************************************************************************************************
|
||||
|
||||
# Set xvlog options
|
||||
xvlog_opts="--incr --relax -L uvm"
|
||||
|
||||
# Script info
|
||||
echo -e "ddr3_dimm_micron_sim.sh - Script generated by export_simulation (Vivado v2022.1 (64-bit)-id)\n"
|
||||
|
||||
# Main steps
|
||||
run()
|
||||
{
|
||||
check_args $# $1
|
||||
setup $1 $2
|
||||
compile
|
||||
elaborate
|
||||
simulate
|
||||
}
|
||||
|
||||
# RUN_STEP: <compile>
|
||||
compile()
|
||||
{
|
||||
xvlog $xvlog_opts -prj vlog.prj 2>&1 | tee compile.log
|
||||
}
|
||||
|
||||
# RUN_STEP: <elaborate>
|
||||
elaborate()
|
||||
{
|
||||
xelab -generic_top "ECC_ENABLE=2" --incr --debug typical --relax --mt auto -L xil_defaultlib -L uvm -L unisims_ver -L unimacro_ver -L secureip --snapshot ddr3_dimm_micron_sim xil_defaultlib.ddr3_dimm_micron_sim xil_defaultlib.glbl -log elaborate.log
|
||||
}
|
||||
|
||||
# RUN_STEP: <simulate>
|
||||
simulate()
|
||||
{
|
||||
xsim ddr3_dimm_micron_sim -key {Behavioral:sim_1:Functional:ddr3_dimm_micron_sim} -tclbatch cmd.tcl -log simulate.log
|
||||
}
|
||||
|
||||
# STEP: setup
|
||||
setup()
|
||||
{
|
||||
case $1 in
|
||||
"-lib_map_path" )
|
||||
if [[ ($2 == "") ]]; then
|
||||
echo -e "ERROR: Simulation library directory path not specified (type \"./ddr3_dimm_micron_sim.sh -help\" for more information)\n"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
"-reset_run" )
|
||||
reset_run
|
||||
echo -e "INFO: Simulation run files deleted.\n"
|
||||
exit 0
|
||||
;;
|
||||
"-noclean_files" )
|
||||
# do not remove previous data
|
||||
;;
|
||||
* )
|
||||
esac
|
||||
|
||||
# Add any setup/initialization commands here:-
|
||||
|
||||
# <user specific commands>
|
||||
|
||||
}
|
||||
|
||||
# Delete generated data from the previous run
|
||||
reset_run()
|
||||
{
|
||||
files_to_remove=(xelab.pb xsim.jou xvhdl.log xvlog.log compile.log elaborate.log simulate.log xelab.log xsim.log run.log xvhdl.pb xvlog.pb ddr3_dimm_micron_sim.wdb xsim.dir)
|
||||
for (( i=0; i<${#files_to_remove[*]}; i++ )); do
|
||||
file="${files_to_remove[i]}"
|
||||
if [[ -e $file ]]; then
|
||||
rm -rf $file
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Check command line arguments
|
||||
check_args()
|
||||
{
|
||||
if [[ ($1 == 1 ) && ($2 != "-lib_map_path" && $2 != "-noclean_files" && $2 != "-reset_run" && $2 != "-help" && $2 != "-h") ]]; then
|
||||
echo -e "ERROR: Unknown option specified '$2' (type \"./ddr3_dimm_micron_sim.sh -help\" for more information)\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ($2 == "-help" || $2 == "-h") ]]; then
|
||||
usage
|
||||
fi
|
||||
}
|
||||
|
||||
# Script usage
|
||||
usage()
|
||||
{
|
||||
msg="Usage: ddr3_dimm_micron_sim.sh [-help]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-lib_map_path]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-reset_run]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-noclean_files]\n\n\
|
||||
[-help] -- Print help information for this script\n\n\
|
||||
[-lib_map_path <path>] -- Compiled simulation library directory path. The simulation library is compiled\n\
|
||||
using the compile_simlib tcl command. Please see 'compile_simlib -help' for more information.\n\n\
|
||||
[-reset_run] -- Recreate simulator setup files and library mappings for a clean run. The generated files\n\
|
||||
from the previous run will be removed. If you don't want to remove the simulator generated files, use the\n\
|
||||
-noclean_files switch.\n\n\
|
||||
[-noclean_files] -- Reset previous run, but do not remove simulator generated files from the previous run.\n\n"
|
||||
echo -e $msg
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Launch script
|
||||
run $1 $2
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,129 +1,129 @@
|
|||
#!/bin/bash -f
|
||||
#*********************************************************************************************************
|
||||
# Vivado (TM) v2022.1 (64-bit)
|
||||
#
|
||||
# Filename : ddr3_dimm_micron_sim.sh
|
||||
# Simulator : Xilinx Vivado Simulator
|
||||
# Description : Simulation script for compiling, elaborating and verifying the project source files.
|
||||
# The script will automatically create the design libraries sub-directories in the run
|
||||
# directory, add the library logical mappings in the simulator setup file, create default
|
||||
# 'do/prj' file, execute compilation, elaboration and simulation steps.
|
||||
#
|
||||
# Generated by Vivado on Sat Jul 27 15:51:00 PST 2024
|
||||
# SW Build 3526262 on Mon Apr 18 15:47:01 MDT 2022
|
||||
#
|
||||
# Tool Version Limit: 2022.04
|
||||
#
|
||||
# usage: ddr3_dimm_micron_sim.sh [-help]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-lib_map_path]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-noclean_files]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-reset_run]
|
||||
#
|
||||
#*********************************************************************************************************
|
||||
|
||||
# Set xvlog options
|
||||
xvlog_opts="--incr --relax -L uvm"
|
||||
|
||||
# Script info
|
||||
echo -e "ddr3_dimm_micron_sim.sh - Script generated by export_simulation (Vivado v2022.1 (64-bit)-id)\n"
|
||||
|
||||
# Main steps
|
||||
run()
|
||||
{
|
||||
check_args $# $1
|
||||
setup $1 $2
|
||||
compile
|
||||
elaborate
|
||||
simulate
|
||||
}
|
||||
|
||||
# RUN_STEP: <compile>
|
||||
compile()
|
||||
{
|
||||
xvlog $xvlog_opts -prj vlog.prj 2>&1 | tee compile.log
|
||||
}
|
||||
|
||||
# RUN_STEP: <elaborate>
|
||||
elaborate()
|
||||
{
|
||||
xelab -generic_top "ECC_ENABLE=3" --incr --debug typical --relax --mt auto -L xil_defaultlib -L uvm -L unisims_ver -L unimacro_ver -L secureip --snapshot ddr3_dimm_micron_sim xil_defaultlib.ddr3_dimm_micron_sim xil_defaultlib.glbl -log elaborate.log
|
||||
}
|
||||
|
||||
# RUN_STEP: <simulate>
|
||||
simulate()
|
||||
{
|
||||
xsim ddr3_dimm_micron_sim -key {Behavioral:sim_1:Functional:ddr3_dimm_micron_sim} -tclbatch cmd.tcl -log simulate.log
|
||||
}
|
||||
|
||||
# STEP: setup
|
||||
setup()
|
||||
{
|
||||
case $1 in
|
||||
"-lib_map_path" )
|
||||
if [[ ($2 == "") ]]; then
|
||||
echo -e "ERROR: Simulation library directory path not specified (type \"./ddr3_dimm_micron_sim.sh -help\" for more information)\n"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
"-reset_run" )
|
||||
reset_run
|
||||
echo -e "INFO: Simulation run files deleted.\n"
|
||||
exit 0
|
||||
;;
|
||||
"-noclean_files" )
|
||||
# do not remove previous data
|
||||
;;
|
||||
* )
|
||||
esac
|
||||
|
||||
# Add any setup/initialization commands here:-
|
||||
|
||||
# <user specific commands>
|
||||
|
||||
}
|
||||
|
||||
# Delete generated data from the previous run
|
||||
reset_run()
|
||||
{
|
||||
files_to_remove=(xelab.pb xsim.jou xvhdl.log xvlog.log compile.log elaborate.log simulate.log xelab.log xsim.log run.log xvhdl.pb xvlog.pb ddr3_dimm_micron_sim.wdb xsim.dir)
|
||||
for (( i=0; i<${#files_to_remove[*]}; i++ )); do
|
||||
file="${files_to_remove[i]}"
|
||||
if [[ -e $file ]]; then
|
||||
rm -rf $file
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Check command line arguments
|
||||
check_args()
|
||||
{
|
||||
if [[ ($1 == 1 ) && ($2 != "-lib_map_path" && $2 != "-noclean_files" && $2 != "-reset_run" && $2 != "-help" && $2 != "-h") ]]; then
|
||||
echo -e "ERROR: Unknown option specified '$2' (type \"./ddr3_dimm_micron_sim.sh -help\" for more information)\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ($2 == "-help" || $2 == "-h") ]]; then
|
||||
usage
|
||||
fi
|
||||
}
|
||||
|
||||
# Script usage
|
||||
usage()
|
||||
{
|
||||
msg="Usage: ddr3_dimm_micron_sim.sh [-help]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-lib_map_path]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-reset_run]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-noclean_files]\n\n\
|
||||
[-help] -- Print help information for this script\n\n\
|
||||
[-lib_map_path <path>] -- Compiled simulation library directory path. The simulation library is compiled\n\
|
||||
using the compile_simlib tcl command. Please see 'compile_simlib -help' for more information.\n\n\
|
||||
[-reset_run] -- Recreate simulator setup files and library mappings for a clean run. The generated files\n\
|
||||
from the previous run will be removed. If you don't want to remove the simulator generated files, use the\n\
|
||||
-noclean_files switch.\n\n\
|
||||
[-noclean_files] -- Reset previous run, but do not remove simulator generated files from the previous run.\n\n"
|
||||
echo -e $msg
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Launch script
|
||||
run $1 $2
|
||||
#!/bin/bash -f
|
||||
#*********************************************************************************************************
|
||||
# Vivado (TM) v2022.1 (64-bit)
|
||||
#
|
||||
# Filename : ddr3_dimm_micron_sim.sh
|
||||
# Simulator : Xilinx Vivado Simulator
|
||||
# Description : Simulation script for compiling, elaborating and verifying the project source files.
|
||||
# The script will automatically create the design libraries sub-directories in the run
|
||||
# directory, add the library logical mappings in the simulator setup file, create default
|
||||
# 'do/prj' file, execute compilation, elaboration and simulation steps.
|
||||
#
|
||||
# Generated by Vivado on Sat Jul 27 15:51:00 PST 2024
|
||||
# SW Build 3526262 on Mon Apr 18 15:47:01 MDT 2022
|
||||
#
|
||||
# Tool Version Limit: 2022.04
|
||||
#
|
||||
# usage: ddr3_dimm_micron_sim.sh [-help]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-lib_map_path]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-noclean_files]
|
||||
# usage: ddr3_dimm_micron_sim.sh [-reset_run]
|
||||
#
|
||||
#*********************************************************************************************************
|
||||
|
||||
# Set xvlog options
|
||||
xvlog_opts="--incr --relax -L uvm"
|
||||
|
||||
# Script info
|
||||
echo -e "ddr3_dimm_micron_sim.sh - Script generated by export_simulation (Vivado v2022.1 (64-bit)-id)\n"
|
||||
|
||||
# Main steps
|
||||
run()
|
||||
{
|
||||
check_args $# $1
|
||||
setup $1 $2
|
||||
compile
|
||||
elaborate
|
||||
simulate
|
||||
}
|
||||
|
||||
# RUN_STEP: <compile>
|
||||
compile()
|
||||
{
|
||||
xvlog $xvlog_opts -prj vlog.prj 2>&1 | tee compile.log
|
||||
}
|
||||
|
||||
# RUN_STEP: <elaborate>
|
||||
elaborate()
|
||||
{
|
||||
xelab -generic_top "ECC_ENABLE=3" --incr --debug typical --relax --mt auto -L xil_defaultlib -L uvm -L unisims_ver -L unimacro_ver -L secureip --snapshot ddr3_dimm_micron_sim xil_defaultlib.ddr3_dimm_micron_sim xil_defaultlib.glbl -log elaborate.log
|
||||
}
|
||||
|
||||
# RUN_STEP: <simulate>
|
||||
simulate()
|
||||
{
|
||||
xsim ddr3_dimm_micron_sim -key {Behavioral:sim_1:Functional:ddr3_dimm_micron_sim} -tclbatch cmd.tcl -log simulate.log
|
||||
}
|
||||
|
||||
# STEP: setup
|
||||
setup()
|
||||
{
|
||||
case $1 in
|
||||
"-lib_map_path" )
|
||||
if [[ ($2 == "") ]]; then
|
||||
echo -e "ERROR: Simulation library directory path not specified (type \"./ddr3_dimm_micron_sim.sh -help\" for more information)\n"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
"-reset_run" )
|
||||
reset_run
|
||||
echo -e "INFO: Simulation run files deleted.\n"
|
||||
exit 0
|
||||
;;
|
||||
"-noclean_files" )
|
||||
# do not remove previous data
|
||||
;;
|
||||
* )
|
||||
esac
|
||||
|
||||
# Add any setup/initialization commands here:-
|
||||
|
||||
# <user specific commands>
|
||||
|
||||
}
|
||||
|
||||
# Delete generated data from the previous run
|
||||
reset_run()
|
||||
{
|
||||
files_to_remove=(xelab.pb xsim.jou xvhdl.log xvlog.log compile.log elaborate.log simulate.log xelab.log xsim.log run.log xvhdl.pb xvlog.pb ddr3_dimm_micron_sim.wdb xsim.dir)
|
||||
for (( i=0; i<${#files_to_remove[*]}; i++ )); do
|
||||
file="${files_to_remove[i]}"
|
||||
if [[ -e $file ]]; then
|
||||
rm -rf $file
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Check command line arguments
|
||||
check_args()
|
||||
{
|
||||
if [[ ($1 == 1 ) && ($2 != "-lib_map_path" && $2 != "-noclean_files" && $2 != "-reset_run" && $2 != "-help" && $2 != "-h") ]]; then
|
||||
echo -e "ERROR: Unknown option specified '$2' (type \"./ddr3_dimm_micron_sim.sh -help\" for more information)\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ($2 == "-help" || $2 == "-h") ]]; then
|
||||
usage
|
||||
fi
|
||||
}
|
||||
|
||||
# Script usage
|
||||
usage()
|
||||
{
|
||||
msg="Usage: ddr3_dimm_micron_sim.sh [-help]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-lib_map_path]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-reset_run]\n\
|
||||
Usage: ddr3_dimm_micron_sim.sh [-noclean_files]\n\n\
|
||||
[-help] -- Print help information for this script\n\n\
|
||||
[-lib_map_path <path>] -- Compiled simulation library directory path. The simulation library is compiled\n\
|
||||
using the compile_simlib tcl command. Please see 'compile_simlib -help' for more information.\n\n\
|
||||
[-reset_run] -- Recreate simulator setup files and library mappings for a clean run. The generated files\n\
|
||||
from the previous run will be removed. If you don't want to remove the simulator generated files, use the\n\
|
||||
-noclean_files switch.\n\n\
|
||||
[-noclean_files] -- Reset previous run, but do not remove simulator generated files from the previous run.\n\n"
|
||||
echo -e $msg
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Launch script
|
||||
run $1 $2
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
verilog xil_defaultlib --include "../" \
|
||||
"../../rtl/ddr3_controller.v" \
|
||||
"../../rtl/ddr3_phy.v" \
|
||||
"../../rtl/ddr3_top.v" \
|
||||
|
||||
sv xil_defaultlib --include "../" \
|
||||
"../ddr3.sv" \
|
||||
"../../rtl/ecc/ecc_dec.sv" \
|
||||
"../../rtl/ecc/ecc_enc.sv" \
|
||||
"../ddr3_dimm_micron_sim.sv" \
|
||||
"../ddr3_module.sv" \
|
||||
|
||||
verilog xil_defaultlib "glbl.v"
|
||||
|
||||
nosort
|
||||
verilog xil_defaultlib --include "../" \
|
||||
"../../rtl/ddr3_controller.v" \
|
||||
"../../rtl/ddr3_phy.v" \
|
||||
"../../rtl/ddr3_top.v" \
|
||||
|
||||
sv xil_defaultlib --include "../" \
|
||||
"../ddr3.sv" \
|
||||
"../../rtl/ecc/ecc_dec.sv" \
|
||||
"../../rtl/ecc/ecc_enc.sv" \
|
||||
"../ddr3_dimm_micron_sim.sv" \
|
||||
"../ddr3_module.sv" \
|
||||
|
||||
verilog xil_defaultlib "glbl.v"
|
||||
|
||||
nosort
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
xil_defaultlib=xsim.dir/xil_defaultlib
|
||||
xil_defaultlib=xsim.dir/xil_defaultlib
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
################################################################################
|
||||
# DONOT REMOVE THIS FILE
|
||||
# Unified simulation database file for selected simulation model for IP
|
||||
#
|
||||
# File: ssm.db (Fri Nov 8 19:48:17 2024)
|
||||
#
|
||||
# This file is generated by the unified simulation automation and contains the
|
||||
# selected simulation model information for the IP/BD instances.
|
||||
# DONOT REMOVE THIS FILE
|
||||
################################################################################
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
version:1
|
||||
6d6f64655f636f756e7465727c4755494d6f6465:9
|
||||
eof:
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
version:1
|
||||
7873696d:7873696d5c636f6d6d616e645f6c696e655f6f7074696f6e73:2d73696d5f6d6f6465:6265686176696f72616c:00:00
|
||||
7873696d:7873696d5c636f6d6d616e645f6c696e655f6f7074696f6e73:2d73696d5f74797065:64656661756c743a3a:00:00
|
||||
eof:2427094519
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Product Version: Vivado v2022.2 (64-bit) -->
|
||||
<!-- -->
|
||||
<!-- Copyright 1986-2022 Xilinx, Inc. All Rights Reserved. -->
|
||||
|
||||
<labtools version="1" minor="0">
|
||||
<HWSession Dir="hw_1" File="hw.xml"/>
|
||||
</labtools>
|
||||
|
|
@ -1 +0,0 @@
|
|||
The files in this directory structure are automatically generated and managed by Vivado. Editing these files is not recommended.
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
@echo off
|
||||
REM ****************************************************************************
|
||||
REM Vivado (TM) v2022.2 (64-bit)
|
||||
REM
|
||||
REM Filename : compile.bat
|
||||
REM Simulator : Xilinx Vivado Simulator
|
||||
REM Description : Script for compiling the simulation design source files
|
||||
REM
|
||||
REM Generated by Vivado on Wed Nov 13 21:36:31 +0800 2024
|
||||
REM SW Build 3671981 on Fri Oct 14 05:00:03 MDT 2022
|
||||
REM
|
||||
REM IP Build 3669848 on Fri Oct 14 08:30:02 MDT 2022
|
||||
REM
|
||||
REM usage: compile.bat
|
||||
REM
|
||||
REM ****************************************************************************
|
||||
REM compile Verilog/System Verilog design sources
|
||||
echo "xvlog --incr --relax -L uvm -prj ddr3_dimm_micron_sim_vlog.prj"
|
||||
call xvlog --incr --relax -L uvm -prj ddr3_dimm_micron_sim_vlog.prj -log xvlog.log
|
||||
call type xvlog.log > compile.log
|
||||
if "%errorlevel%"=="1" goto END
|
||||
if "%errorlevel%"=="0" goto SUCCESS
|
||||
:END
|
||||
exit 1
|
||||
:SUCCESS
|
||||
exit 0
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
set curr_wave [current_wave_config]
|
||||
if { [string length $curr_wave] == 0 } {
|
||||
if { [llength [get_objects]] > 0} {
|
||||
add_wave /
|
||||
set_property needs_save false [current_wave_config]
|
||||
} else {
|
||||
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."
|
||||
}
|
||||
}
|
||||
|
||||
run 1000ns
|
||||
Binary file not shown.
|
|
@ -1,17 +0,0 @@
|
|||
# compile verilog/system verilog design source files
|
||||
verilog xil_defaultlib --include "../../../../../testbench" \
|
||||
"../../../../../rtl/ddr3_controller.v" \
|
||||
"../../../../../rtl/ddr3_phy.v" \
|
||||
"../../../../../rtl/ddr3_top.v" \
|
||||
|
||||
sv xil_defaultlib --include "../../../../../testbench" \
|
||||
"../../../../../testbench/ddr3.sv" \
|
||||
"../../../../../rtl/ecc/ecc_dec.sv" \
|
||||
"../../../../../rtl/ecc/ecc_enc.sv" \
|
||||
"../../../../../testbench/ddr3_dimm_micron_sim.sv" \
|
||||
|
||||
# compile glbl module
|
||||
verilog xil_defaultlib "glbl.v"
|
||||
|
||||
# Do not sort compile order
|
||||
nosort
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
@echo off
|
||||
REM ****************************************************************************
|
||||
REM Vivado (TM) v2022.2 (64-bit)
|
||||
REM
|
||||
REM Filename : elaborate.bat
|
||||
REM Simulator : Xilinx Vivado Simulator
|
||||
REM Description : Script for elaborating the compiled design
|
||||
REM
|
||||
REM Generated by Vivado on Wed Nov 13 21:36:38 +0800 2024
|
||||
REM SW Build 3671981 on Fri Oct 14 05:00:03 MDT 2022
|
||||
REM
|
||||
REM IP Build 3669848 on Fri Oct 14 08:30:02 MDT 2022
|
||||
REM
|
||||
REM usage: elaborate.bat
|
||||
REM
|
||||
REM ****************************************************************************
|
||||
REM elaborate design
|
||||
echo "xelab --incr --debug typical --relax --mt 2 -L xil_defaultlib -L uvm -L unisims_ver -L unimacro_ver -L secureip --snapshot ddr3_dimm_micron_sim_behav xil_defaultlib.ddr3_dimm_micron_sim xil_defaultlib.glbl -log elaborate.log"
|
||||
call xelab --incr --debug typical --relax --mt 2 -L xil_defaultlib -L uvm -L unisims_ver -L unimacro_ver -L secureip --snapshot ddr3_dimm_micron_sim_behav xil_defaultlib.ddr3_dimm_micron_sim xil_defaultlib.glbl -log elaborate.log
|
||||
if "%errorlevel%"=="0" goto SUCCESS
|
||||
if "%errorlevel%"=="1" goto END
|
||||
:END
|
||||
exit 1
|
||||
:SUCCESS
|
||||
exit 0
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
Vivado Simulator v2022.2
|
||||
Copyright 1986-1999, 2001-2022 Xilinx, Inc. All Rights Reserved.
|
||||
Running: C:/Xilinx/Vivado/2022.2/bin/unwrapped/win64.o/xelab.exe --incr --debug typical --relax --mt 2 -L xil_defaultlib -L uvm -L unisims_ver -L unimacro_ver -L secureip --snapshot ddr3_dimm_micron_sim_behav xil_defaultlib.ddr3_dimm_micron_sim xil_defaultlib.glbl -log elaborate.log
|
||||
Using 2 slave threads.
|
||||
Starting static elaboration
|
||||
Pass Through NonSizing Optimizer
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'SHIFTIN1' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:211]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'SHIFTIN2' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:212]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'T1' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:214]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'T2' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:215]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'T3' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:216]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'T4' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:217]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'TBYTEIN' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:218]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'TCE' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:220]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'SHIFTIN1' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:490]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'SHIFTIN2' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:491]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'T2' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:493]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'T3' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:494]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'T4' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:495]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'TBYTEIN' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:496]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'SHIFTIN1' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:742]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'SHIFTIN2' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:743]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'T1' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:745]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'T2' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:746]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'T3' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:747]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'T4' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:748]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'TBYTEIN' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:749]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'SHIFTIN1' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:926]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'SHIFTIN2' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:927]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'T2' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:929]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'T3' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:930]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'T4' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:931]
|
||||
WARNING: [VRFC 10-3091] actual bit length 32 differs from formal bit length 1 for port 'TBYTEIN' [C:/Users/AJacobo/Documents/UberDDR3_repo/rtl/ddr3_phy.v:932]
|
||||
Completed static elaboration
|
||||
Starting simulation data flow analysis
|
||||
Completed simulation data flow analysis
|
||||
Time Resolution for simulation is 1ps
|
||||
Compiling module xil_defaultlib.ddr3_controller(ROW_BITS=16,MICR...
|
||||
Compiling module unisims_ver.OSERDESE2(DATA_RATE_OQ="SDR",DAT...
|
||||
Compiling module unisims_ver.OBUFDS
|
||||
Compiling module unisims_ver.OSERDESE2(DATA_RATE_TQ="BUF",DAT...
|
||||
Compiling module unisims_ver.IOBUF(IBUF_LOW_PWR="FALSE",SLEW=...
|
||||
Compiling module unisims_ver.IDELAYE2(HIGH_PERFORMANCE_MODE="...
|
||||
Compiling module unisims_ver.ISERDESE2(DATA_WIDTH=8,INTERFACE...
|
||||
Compiling module unisims_ver.OBUF(SLEW="FAST")
|
||||
Compiling module unisims_ver.OSERDESE2(DATA_RATE_TQ="BUF",DAT...
|
||||
Compiling module unisims_ver.IOBUFDS(IBUF_LOW_PWR="FALSE")
|
||||
Compiling module unisims_ver.IDELAYE2(HIGH_PERFORMANCE_MODE="...
|
||||
Compiling module unisims_ver.IDELAYCTRL_default
|
||||
Compiling module xil_defaultlib.ddr3_phy(ROW_BITS=16,LANES=2,ODE...
|
||||
Compiling module xil_defaultlib.ddr3_top(CONTROLLER_CLK_PERIOD=1...
|
||||
Compiling module xil_defaultlib.ddr3_default
|
||||
Compiling module xil_defaultlib.ddr3_dimm_micron_sim
|
||||
Compiling module xil_defaultlib.glbl
|
||||
Built simulation snapshot ddr3_dimm_micron_sim_behav
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/glbl.v,v 1.14 2010/10/28 20:44:00 fphillip Exp $
|
||||
`ifndef GLBL
|
||||
`define GLBL
|
||||
`timescale 1 ps / 1 ps
|
||||
|
||||
module glbl ();
|
||||
|
||||
parameter ROC_WIDTH = 100000;
|
||||
parameter TOC_WIDTH = 0;
|
||||
parameter GRES_WIDTH = 10000;
|
||||
parameter GRES_START = 10000;
|
||||
|
||||
//-------- STARTUP Globals --------------
|
||||
wire GSR;
|
||||
wire GTS;
|
||||
wire GWE;
|
||||
wire PRLD;
|
||||
wire GRESTORE;
|
||||
tri1 p_up_tmp;
|
||||
tri (weak1, strong0) PLL_LOCKG = p_up_tmp;
|
||||
|
||||
wire PROGB_GLBL;
|
||||
wire CCLKO_GLBL;
|
||||
wire FCSBO_GLBL;
|
||||
wire [3:0] DO_GLBL;
|
||||
wire [3:0] DI_GLBL;
|
||||
|
||||
reg GSR_int;
|
||||
reg GTS_int;
|
||||
reg PRLD_int;
|
||||
reg GRESTORE_int;
|
||||
|
||||
//-------- JTAG Globals --------------
|
||||
wire JTAG_TDO_GLBL;
|
||||
wire JTAG_TCK_GLBL;
|
||||
wire JTAG_TDI_GLBL;
|
||||
wire JTAG_TMS_GLBL;
|
||||
wire JTAG_TRST_GLBL;
|
||||
|
||||
reg JTAG_CAPTURE_GLBL;
|
||||
reg JTAG_RESET_GLBL;
|
||||
reg JTAG_SHIFT_GLBL;
|
||||
reg JTAG_UPDATE_GLBL;
|
||||
reg JTAG_RUNTEST_GLBL;
|
||||
|
||||
reg JTAG_SEL1_GLBL = 0;
|
||||
reg JTAG_SEL2_GLBL = 0 ;
|
||||
reg JTAG_SEL3_GLBL = 0;
|
||||
reg JTAG_SEL4_GLBL = 0;
|
||||
|
||||
reg JTAG_USER_TDO1_GLBL = 1'bz;
|
||||
reg JTAG_USER_TDO2_GLBL = 1'bz;
|
||||
reg JTAG_USER_TDO3_GLBL = 1'bz;
|
||||
reg JTAG_USER_TDO4_GLBL = 1'bz;
|
||||
|
||||
assign (strong1, weak0) GSR = GSR_int;
|
||||
assign (strong1, weak0) GTS = GTS_int;
|
||||
assign (weak1, weak0) PRLD = PRLD_int;
|
||||
assign (strong1, weak0) GRESTORE = GRESTORE_int;
|
||||
|
||||
initial begin
|
||||
GSR_int = 1'b1;
|
||||
PRLD_int = 1'b1;
|
||||
#(ROC_WIDTH)
|
||||
GSR_int = 1'b0;
|
||||
PRLD_int = 1'b0;
|
||||
end
|
||||
|
||||
initial begin
|
||||
GTS_int = 1'b1;
|
||||
#(TOC_WIDTH)
|
||||
GTS_int = 1'b0;
|
||||
end
|
||||
|
||||
initial begin
|
||||
GRESTORE_int = 1'b0;
|
||||
#(GRES_START);
|
||||
GRESTORE_int = 1'b1;
|
||||
#(GRES_WIDTH);
|
||||
GRESTORE_int = 1'b0;
|
||||
end
|
||||
|
||||
endmodule
|
||||
`endif
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
@echo off
|
||||
REM ****************************************************************************
|
||||
REM Vivado (TM) v2022.2 (64-bit)
|
||||
REM
|
||||
REM Filename : simulate.bat
|
||||
REM Simulator : Xilinx Vivado Simulator
|
||||
REM Description : Script for simulating the design by launching the simulator
|
||||
REM
|
||||
REM Generated by Vivado on Wed Nov 13 18:56:53 +0800 2024
|
||||
REM SW Build 3671981 on Fri Oct 14 05:00:03 MDT 2022
|
||||
REM
|
||||
REM IP Build 3669848 on Fri Oct 14 08:30:02 MDT 2022
|
||||
REM
|
||||
REM usage: simulate.bat
|
||||
REM
|
||||
REM ****************************************************************************
|
||||
REM simulate design
|
||||
echo "xsim ddr3_dimm_micron_sim_behav -key {Behavioral:sim_1:Functional:ddr3_dimm_micron_sim} -tclbatch ddr3_dimm_micron_sim.tcl -log simulate.log"
|
||||
call xsim ddr3_dimm_micron_sim_behav -key {Behavioral:sim_1:Functional:ddr3_dimm_micron_sim} -tclbatch ddr3_dimm_micron_sim.tcl -log simulate.log
|
||||
if "%errorlevel%"=="0" goto SUCCESS
|
||||
if "%errorlevel%"=="1" goto END
|
||||
:END
|
||||
exit 1
|
||||
:SUCCESS
|
||||
exit 0
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue