Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | merge vhdl implementation into the tree; simulation with ghdl works; not tested on actual hardware yet |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
95e971fd442d40083dd5b89820806145 |
| User & Date: | crc 2026-06-26 12:57:42.003 |
Context
|
2026-06-26
| ||
| 12:57 | merge vhdl implementation into the tree; simulation with ghdl works; not tested on actual hardware yet Leaf check-in: 95e971fd44 user: crc tags: trunk | |
| 12:51 | merge ilo-wasm.wat, a webassembly version of ilo for wasmtime check-in: 0d2723f940 user: crc tags: trunk | |
Changes
Changes to RELEASE.txt.
| ︙ | ︙ | |||
45 46 47 48 49 50 51 52 53 54 55 56 57 58 | - Python - RetroForth - Rust - Scheme - Smalltalk - Swift - TypeScript - WebAssembly - Zig - x86-native (C & assembly) - x86 assembly (DOS) - Precompiled binaries for ilo for a variety of hosts: | > | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | - Python - RetroForth - Rust - Scheme - Smalltalk - Swift - TypeScript - VHDL - WebAssembly - Zig - x86-native (C & assembly) - x86 assembly (DOS) - Precompiled binaries for ilo for a variety of hosts: |
| ︙ | ︙ | |||
190 191 192 193 194 195 196 197 198 199 200 201 202 203 | - new implementation: gfortran, Fortran 77 - ilo-wasm.wat - new implementation (webassembly; for wasmtime) IMAGE - dictionary data now in konilo.pali instead of being built by separate preprocessor - inlined use of `tuck` (as `i dupuswpo`) at various points - `n:to-s` save a call/return per character - `n:limit` now falls through into `n:max`, saving a jump | > > > > > | 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
- new implementation: gfortran, Fortran 77
- ilo-wasm.wat
- new implementation (webassembly; for wasmtime)
- vhdl
- new VHDL implementation (can simulate w/ghdl)
Planned eventual fpga targets [cmod a7-35t, icepi zero]
IMAGE
- dictionary data now in konilo.pali instead of being built by
separate preprocessor
- inlined use of `tuck` (as `i dupuswpo`) at various points
- `n:to-s` save a call/return per character
- `n:limit` now falls through into `n:max`, saving a jump
|
| ︙ | ︙ |
Added ilo-vm/vhdl/Makefile.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | SHELL := /bin/sh .PHONY: all test ghdl-test compare synth synth-generic synth-generic-opt synth-generic-full synth-ice40 synth-ecp5 synth-xc7 synth-xc7+sram icepi-zero icepi-zero-sdram interactive clean distclean help all: test test: ghdl-test ghdl-test: ./scripts/run-ghdl-tests.sh compare: ./scripts/compare-c-vhdl.sh synth: ./scripts/synth-yosys.sh synth-generic: ./scripts/synth-yosys.sh generic synth-generic-opt: ./scripts/synth-yosys.sh generic-opt synth-generic-full: ./scripts/synth-yosys.sh generic-full synth-ice40: ./scripts/synth-yosys.sh ice40 synth-ecp5: ./scripts/synth-yosys.sh ecp5 synth-xc7: ./scripts/synth-yosys.sh xc7 synth-xc7+sram: ./scripts/synth-yosys.sh xc7+sram icepi-zero: ./scripts/build-icepi-zero.sh icepi-zero-sdram: ./scripts/build-icepi-zero.sh --sdram interactive: @if [ -z "$(ROM)" ]; then \ echo "usage: make interactive ROM=path/to/ilo.rom [BLOCKS=path/to/ilo.blocks] [MODE=--sdram] [MAX_CYCLES=0] [CLOCK_PERIOD_NS=10]" >&2; \ exit 2; \ fi @set -- $(MODE) "$(ROM)"; \ if [ -n "$(BLOCKS)" ]; then set -- "$$@" "$(BLOCKS)"; fi; \ if [ -n "$(MAX_CYCLES)" ]; then set -- "$$@" "$(MAX_CYCLES)"; fi; \ if [ -n "$(CLOCK_PERIOD_NS)" ]; then set -- "$$@" "$(CLOCK_PERIOD_NS)"; fi; \ ./scripts/run-ilo-rom-interactive.sh "$$@" clean: rm -rf build work-obj*.cf *_tb *_top_tb *.o e~*.o scripts/__pycache__ help: @printf '%s\n' \ 'Targets:' \ ' make test Run the GHDL regression suite' \ ' make compare Compare C VM and VHDL stack results' \ ' make synth Run generic Yosys synthesis for ilo_core' \ ' make synth-ecp5 Run ECP5 synthesis for ilo_core' \ ' make synth-xc7 Run Xilinx 7-series synthesis for ilo_core' \ ' make synth-xc7+sram Run Xilinx 7-series synthesis for Cmod A7 SRAM top' \ ' make icepi-zero Build the ICEPI Zero smoke bitstream' \ ' make icepi-zero-sdram Build the ICEPI Zero SDRAM bitstream' \ ' make interactive ROM=... [BLOCKS=...] [MODE=--sdram]' \ ' make clean Remove generated simulation/build output' |
Added ilo-vm/vhdl/constraints/cmod_a7.xdc.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
## ilo-vhdl Cmod A7 Rev. B constraints.
## Pin mappings are from Digilent Cmod-A7-Master.xdc.
set_property -dict { PACKAGE_PIN L17 IOSTANDARD LVCMOS33 } [get_ports { sysclk }]
create_clock -add -name sys_clk_pin -period 83.33 -waveform {0 41.66} [get_ports { sysclk }]
set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVCMOS33 } [get_ports { btn[0] }]
set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVCMOS33 } [get_ports { btn[1] }]
set_property -dict { PACKAGE_PIN A17 IOSTANDARD LVCMOS33 } [get_ports { led[0] }]
set_property -dict { PACKAGE_PIN C16 IOSTANDARD LVCMOS33 } [get_ports { led[1] }]
set_property -dict { PACKAGE_PIN B17 IOSTANDARD LVCMOS33 } [get_ports { led0_b }]
set_property -dict { PACKAGE_PIN B16 IOSTANDARD LVCMOS33 } [get_ports { led0_g }]
set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { led0_r }]
set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { uart_rxd_out }]
set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { uart_txd_in }]
set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[0] }]
set_property -dict { PACKAGE_PIN M19 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[1] }]
set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[2] }]
set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[3] }]
set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[4] }]
set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[5] }]
set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[6] }]
set_property -dict { PACKAGE_PIN W19 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[7] }]
set_property -dict { PACKAGE_PIN U19 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[8] }]
set_property -dict { PACKAGE_PIN V19 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[9] }]
set_property -dict { PACKAGE_PIN W18 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[10] }]
set_property -dict { PACKAGE_PIN T17 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[11] }]
set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[12] }]
set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[13] }]
set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[14] }]
set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[15] }]
set_property -dict { PACKAGE_PIN W16 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[16] }]
set_property -dict { PACKAGE_PIN W17 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[17] }]
set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[18] }]
set_property -dict { PACKAGE_PIN W15 IOSTANDARD LVCMOS33 } [get_ports { MemDB[0] }]
set_property -dict { PACKAGE_PIN W13 IOSTANDARD LVCMOS33 } [get_ports { MemDB[1] }]
set_property -dict { PACKAGE_PIN W14 IOSTANDARD LVCMOS33 } [get_ports { MemDB[2] }]
set_property -dict { PACKAGE_PIN U15 IOSTANDARD LVCMOS33 } [get_ports { MemDB[3] }]
set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { MemDB[4] }]
set_property -dict { PACKAGE_PIN V13 IOSTANDARD LVCMOS33 } [get_ports { MemDB[5] }]
set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { MemDB[6] }]
set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { MemDB[7] }]
set_property -dict { PACKAGE_PIN P19 IOSTANDARD LVCMOS33 } [get_ports { RamOEn }]
set_property -dict { PACKAGE_PIN R19 IOSTANDARD LVCMOS33 } [get_ports { RamWEn }]
set_property -dict { PACKAGE_PIN N19 IOSTANDARD LVCMOS33 } [get_ports { RamCEn }]
|
Added ilo-vm/vhdl/constraints/icepi_zero.lpf.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | SYSCONFIG CONFIG_IOVOLTAGE=3.3 COMPRESS_CONFIG=ON MCCLK_FREQ=62 MASTER_SPI_PORT=ENABLE SLAVE_SPI_PORT=DISABLE SLAVE_PARALLEL_PORT=DISABLE; BLOCK RESETPATHS; BLOCK ASYNCPATHS; # ICEPI Zero v1.3 subset for ilo-vhdl smoke top. LOCATE COMP "clk" SITE "M1"; IOBUF PORT "clk" IO_TYPE=LVCMOS33 PULLMODE=NONE; FREQUENCY PORT "clk" 50 MHZ; LOCATE COMP "usb_tx" SITE "K15"; IOBUF PORT "usb_tx" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; LOCATE COMP "usb_rx" SITE "K16"; IOBUF PORT "usb_rx" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; LOCATE COMP "led[0]" SITE "E13"; IOBUF PORT "led[0]" IO_TYPE=LVCMOS33 PULLMODE=DOWN DRIVE=4; LOCATE COMP "led[1]" SITE "D14"; IOBUF PORT "led[1]" IO_TYPE=LVCMOS33 PULLMODE=DOWN DRIVE=4; LOCATE COMP "led[2]" SITE "E12"; IOBUF PORT "led[2]" IO_TYPE=LVCMOS33 PULLMODE=DOWN DRIVE=4; LOCATE COMP "led[3]" SITE "C13"; IOBUF PORT "led[3]" IO_TYPE=LVCMOS33 PULLMODE=DOWN DRIVE=4; LOCATE COMP "led[4]" SITE "D13"; IOBUF PORT "led[4]" IO_TYPE=LVCMOS33 PULLMODE=DOWN DRIVE=4; LOCATE COMP "button[0]" SITE "C4"; IOBUF PORT "button[0]" IO_TYPE=LVCMOS33 PULLMODE=UP DRIVE=4; LOCATE COMP "button[1]" SITE "C5"; IOBUF PORT "button[1]" IO_TYPE=LVCMOS33 PULLMODE=UP DRIVE=4; LOCATE COMP "sdram_a[0]" SITE "B10"; IOBUF PORT "sdram_a[0]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_a[1]" SITE "A9"; IOBUF PORT "sdram_a[1]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_a[2]" SITE "B9"; IOBUF PORT "sdram_a[2]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_a[3]" SITE "A8"; IOBUF PORT "sdram_a[3]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_a[4]" SITE "B8"; IOBUF PORT "sdram_a[4]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_a[5]" SITE "A7"; IOBUF PORT "sdram_a[5]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_a[6]" SITE "B7"; IOBUF PORT "sdram_a[6]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_a[7]" SITE "A6"; IOBUF PORT "sdram_a[7]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_a[8]" SITE "B6"; IOBUF PORT "sdram_a[8]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_a[9]" SITE "A5"; IOBUF PORT "sdram_a[9]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_a[10]" SITE "A10"; IOBUF PORT "sdram_a[10]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_a[11]" SITE "B5"; IOBUF PORT "sdram_a[11]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_a[12]" SITE "A4"; IOBUF PORT "sdram_a[12]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_dq[0]" SITE "B16"; IOBUF PORT "sdram_dq[0]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_dq[1]" SITE "C14"; IOBUF PORT "sdram_dq[1]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_dq[2]" SITE "C16"; IOBUF PORT "sdram_dq[2]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_dq[3]" SITE "C15"; IOBUF PORT "sdram_dq[3]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_dq[4]" SITE "D16"; IOBUF PORT "sdram_dq[4]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_dq[5]" SITE "A15"; IOBUF PORT "sdram_dq[5]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_dq[6]" SITE "B15"; IOBUF PORT "sdram_dq[6]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_dq[7]" SITE "A14"; IOBUF PORT "sdram_dq[7]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_dq[8]" SITE "A2"; IOBUF PORT "sdram_dq[8]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_dq[9]" SITE "B2"; IOBUF PORT "sdram_dq[9]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_dq[10]" SITE "E2"; IOBUF PORT "sdram_dq[10]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_dq[11]" SITE "D1"; IOBUF PORT "sdram_dq[11]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_dq[12]" SITE "C2"; IOBUF PORT "sdram_dq[12]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_dq[13]" SITE "C1"; IOBUF PORT "sdram_dq[13]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_dq[14]" SITE "C3"; IOBUF PORT "sdram_dq[14]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_dq[15]" SITE "B1"; IOBUF PORT "sdram_dq[15]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_ba[0]" SITE "A11"; IOBUF PORT "sdram_ba[0]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_ba[1]" SITE "B11"; IOBUF PORT "sdram_ba[1]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_dqm[0]" SITE "B14"; IOBUF PORT "sdram_dqm[0]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_dqm[1]" SITE "B3"; IOBUF PORT "sdram_dqm[1]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_csn" SITE "B12"; IOBUF PORT "sdram_csn" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_cke" SITE "B4"; IOBUF PORT "sdram_cke" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_clk" SITE "A3"; IOBUF PORT "sdram_clk" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_wen" SITE "A13"; IOBUF PORT "sdram_wen" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_casn" SITE "B13"; IOBUF PORT "sdram_casn" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; LOCATE COMP "sdram_rasn" SITE "A12"; IOBUF PORT "sdram_rasn" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=4; |
Added ilo-vm/vhdl/rtl/boards/cmod_a7_top.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.ilo_pkg.all;
entity cmod_a7_top is
generic (
UART_CLKS_PER_BIT : positive := 104;
SRAM_READ_WAIT_CYCLES : natural := 1;
SRAM_WRITE_WAIT_CYCLES : natural := 1;
RESET_CYCLES : natural := 16
);
port (
sysclk : in std_logic;
btn : in std_logic_vector(1 downto 0);
led : out std_logic_vector(1 downto 0);
led0_b : out std_logic;
led0_g : out std_logic;
led0_r : out std_logic;
uart_rxd_out : in std_logic;
uart_txd_in : out std_logic;
MemAdr : out unsigned(18 downto 0);
MemDB : inout std_logic_vector(7 downto 0);
RamOEn : out std_logic;
RamWEn : out std_logic;
RamCEn : out std_logic
);
end entity;
architecture rtl of cmod_a7_top is
type boot_state_t is (S_RESET, S_BOOT_REQ, S_BOOT_WAIT, S_BOOT_GAP, S_RUN);
type boot_rom_t is array (0 to 4) of cell_t;
constant BOOT_ROM : boot_rom_t := (
to_signed(1900801, CELL_WIDTH),
to_signed(65, CELL_WIDTH),
to_signed(0, CELL_WIDTH),
to_signed(7425, CELL_WIDTH),
to_signed(6, CELL_WIDTH)
);
signal reset_pipe : std_logic_vector(1 downto 0) := (others => '1');
signal reset_sync : std_logic := '1';
signal reset_count : natural range 0 to RESET_CYCLES := RESET_CYCLES;
signal boot_state : boot_state_t := S_RESET;
signal boot_index : natural range 0 to BOOT_ROM'length := 0;
signal core_reset : std_logic := '1';
signal mem_req : std_logic;
signal mem_we : std_logic;
signal mem_addr : addr_t;
signal mem_wdata : cell_t;
signal mem_rdata : cell_t;
signal mem_ready : std_logic;
signal sram_req : std_logic;
signal sram_we : std_logic;
signal sram_addr : addr_t;
signal sram_wdata : cell_t;
signal sram_ready : std_logic;
signal sram_reset : std_logic;
signal serial_tx_valid : std_logic;
signal serial_tx_data : std_logic_vector(7 downto 0);
signal serial_tx_ready : std_logic;
signal serial_rx_req : std_logic;
signal serial_rx_valid : std_logic;
signal serial_rx_data : std_logic_vector(7 downto 0);
signal serial_rx_take : std_logic;
signal uart_rx_valid : std_logic;
signal uart_rx_data : std_logic_vector(7 downto 0);
signal uart_rx_take : std_logic;
signal uart_tx_busy : std_logic;
signal tx_fifo_push : std_logic;
signal tx_fifo_pop : std_logic;
signal tx_fifo_data : std_logic_vector(7 downto 0);
signal tx_fifo_empty : std_logic;
signal tx_fifo_full : std_logic;
signal rx_fifo_push : std_logic;
signal rx_fifo_pop : std_logic;
signal rx_fifo_empty : std_logic;
signal rx_fifo_full : std_logic;
signal block_req : std_logic;
signal block_ready : std_logic := '0';
signal reload_req : std_logic;
signal reload_ready: std_logic;
signal halted : std_logic;
signal errored : std_logic;
signal error_code : unsigned(7 downto 0);
begin
process(sysclk)
begin
if rising_edge(sysclk) then
reset_pipe <= reset_pipe(0) & btn(0);
if reset_pipe(1) = '1' then
reset_sync <= '1';
reset_count <= RESET_CYCLES;
elsif reset_count = 0 then
reset_sync <= '0';
else
reset_count <= reset_count - 1;
reset_sync <= '1';
end if;
end if;
end process;
process(sysclk)
begin
if rising_edge(sysclk) then
if reset_sync = '1' then
boot_state <= S_RESET;
boot_index <= 0;
core_reset <= '1';
else
case boot_state is
when S_RESET =>
boot_index <= 0;
core_reset <= '1';
boot_state <= S_BOOT_REQ;
when S_BOOT_REQ =>
core_reset <= '1';
boot_state <= S_BOOT_WAIT;
when S_BOOT_WAIT =>
core_reset <= '1';
if sram_ready = '1' then
if boot_index = BOOT_ROM'length - 1 then
boot_state <= S_RUN;
else
boot_state <= S_BOOT_GAP;
end if;
end if;
when S_BOOT_GAP =>
core_reset <= '1';
boot_index <= boot_index + 1;
boot_state <= S_BOOT_REQ;
when S_RUN =>
core_reset <= '0';
end case;
end if;
end if;
end process;
sram_req <= '1' when boot_state = S_BOOT_REQ or boot_state = S_BOOT_WAIT else mem_req;
sram_we <= '1' when boot_state = S_BOOT_REQ or boot_state = S_BOOT_WAIT else mem_we;
sram_addr <= to_unsigned(boot_index, sram_addr'length)
when boot_state = S_BOOT_REQ or boot_state = S_BOOT_WAIT else mem_addr;
sram_wdata <= BOOT_ROM(boot_index)
when boot_state = S_BOOT_REQ or boot_state = S_BOOT_WAIT else mem_wdata;
mem_ready <= sram_ready when boot_state = S_RUN else '0';
sram_reset <= reset_sync;
sram_i : entity work.ilo_sram8_controller
generic map (
SRAM_ADDR_WIDTH => 19,
READ_WAIT_CYCLES => SRAM_READ_WAIT_CYCLES,
WRITE_WAIT_CYCLES => SRAM_WRITE_WAIT_CYCLES
)
port map (
clk => sysclk,
reset => sram_reset,
req => sram_req,
we => sram_we,
addr => sram_addr,
wdata => sram_wdata,
rdata => mem_rdata,
ready => sram_ready,
reload_req => reload_req,
reload_ready => reload_ready,
sram_addr => MemAdr,
sram_data => MemDB,
sram_ce_n => RamCEn,
sram_oe_n => RamOEn,
sram_we_n => RamWEn
);
core_i : entity work.ilo_core
port map (
clk => sysclk,
reset => core_reset,
mem_req => mem_req,
mem_we => mem_we,
mem_addr => mem_addr,
mem_wdata => mem_wdata,
mem_rdata => mem_rdata,
mem_ready => mem_ready,
serial_tx_valid => serial_tx_valid,
serial_tx_data => serial_tx_data,
serial_tx_ready => serial_tx_ready,
serial_rx_req => serial_rx_req,
serial_rx_valid => serial_rx_valid,
serial_rx_data => serial_rx_data,
block_req => block_req,
block_we => open,
block_addr => open,
block_wdata => open,
block_rdata => CELL_ZERO,
block_ready => block_ready,
reload_req => reload_req,
reload_ready => reload_ready,
halted => halted,
errored => errored,
error_code => error_code
);
serial_tx_ready <= not tx_fifo_full;
tx_fifo_push <= serial_tx_valid and serial_tx_ready;
tx_fifo_pop <= '1' when tx_fifo_empty = '0' and uart_tx_busy = '0' else '0';
tx_fifo_i : entity work.ilo_byte_fifo
generic map (
DEPTH => 16
)
port map (
clk => sysclk,
reset => reset_sync,
push => tx_fifo_push,
wdata => serial_tx_data,
full => tx_fifo_full,
pop => tx_fifo_pop,
rdata => tx_fifo_data,
empty => tx_fifo_empty
);
tx_i : entity work.ilo_uart_tx
generic map (
CLKS_PER_BIT => UART_CLKS_PER_BIT
)
port map (
clk => sysclk,
reset => reset_sync,
data_valid => tx_fifo_pop,
data => tx_fifo_data,
tx => uart_txd_in,
busy => uart_tx_busy
);
rx_fifo_push <= uart_rx_valid and not rx_fifo_full;
uart_rx_take <= rx_fifo_push;
serial_rx_take <= serial_rx_req and serial_rx_valid;
rx_fifo_pop <= serial_rx_take;
serial_rx_valid <= not rx_fifo_empty;
rx_fifo_i : entity work.ilo_byte_fifo
generic map (
DEPTH => 16
)
port map (
clk => sysclk,
reset => reset_sync,
push => rx_fifo_push,
wdata => uart_rx_data,
full => rx_fifo_full,
pop => rx_fifo_pop,
rdata => serial_rx_data,
empty => rx_fifo_empty
);
rx_i : entity work.ilo_uart_rx
generic map (
CLKS_PER_BIT => UART_CLKS_PER_BIT
)
port map (
clk => sysclk,
reset => reset_sync,
rx => uart_rxd_out,
take => uart_rx_take,
data_valid => uart_rx_valid,
data => uart_rx_data
);
process(sysclk)
begin
if rising_edge(sysclk) then
if reset_sync = '1' then
block_ready <= '0';
else
block_ready <= block_req;
end if;
end if;
end process;
led(0) <= halted;
led(1) <= errored;
led0_r <= not errored;
led0_g <= not halted;
led0_b <= not uart_tx_busy;
end architecture;
|
Added ilo-vm/vhdl/rtl/boards/icepi_zero_sdram_top.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.ilo_pkg.all;
entity icepi_zero_sdram_top is
generic (
BOOT_IMAGE : string := "SMOKE";
UART_CLKS_PER_BIT : positive := 434;
RESET_CYCLES : natural := 16;
SDRAM_INIT_WAIT_CYCLES : natural := 10000;
SDRAM_REFRESH_INTERVAL_CYCLES : natural := 390;
SDRAM_TRCD_CYCLES : natural := 1;
SDRAM_TRP_CYCLES : natural := 1;
SDRAM_TRFC_CYCLES : natural := 4;
SDRAM_TMRD_CYCLES : natural := 2;
SDRAM_READ_WAIT_CYCLES : natural := 3;
SDRAM_WRITE_RECOVERY_CYCLES : natural := 2
);
port (
clk : in std_logic;
button : in std_logic_vector(1 downto 0);
led : out std_logic_vector(4 downto 0);
usb_rx : in std_logic;
usb_tx : out std_logic;
sdram_a : out unsigned(12 downto 0);
sdram_ba : out unsigned(1 downto 0);
sdram_dq : inout std_logic_vector(15 downto 0);
sdram_dqm : out std_logic_vector(1 downto 0);
sdram_csn : out std_logic;
sdram_cke : out std_logic;
sdram_clk : out std_logic;
sdram_wen : out std_logic;
sdram_casn : out std_logic;
sdram_rasn : out std_logic
);
end entity;
architecture rtl of icepi_zero_sdram_top is
type boot_state_t is (S_RESET, S_PRELOAD_WAIT, S_BOOT_REQ, S_BOOT_WAIT, S_BOOT_GAP, S_RUN);
constant UART_STRESS_TX_COUNT : natural := 20;
constant BOOT_MAX_CELLS : natural := UART_STRESS_TX_COUNT * 3 + 6;
function boot_length return natural is
begin
if BOOT_IMAGE = "PRELOADED" then
return 0;
end if;
if BOOT_IMAGE = "UART_STRESS" then
return BOOT_MAX_CELLS;
end if;
return 5;
end function;
function boot_word(index : natural) return cell_t is
variable tx_index : natural;
begin
if BOOT_IMAGE = "UART_STRESS" then
if index < UART_STRESS_TX_COUNT * 3 then
tx_index := index / 3;
if index mod 3 = 0 then
return to_signed(1900801, CELL_WIDTH);
elsif index mod 3 = 1 then
return to_signed(65 + tx_index, CELL_WIDTH);
end if;
return to_signed(0, CELL_WIDTH);
elsif index = UART_STRESS_TX_COUNT * 3 then
return to_signed(7425, CELL_WIDTH);
elsif index = UART_STRESS_TX_COUNT * 3 + 1 then
return to_signed(1, CELL_WIDTH);
elsif index = UART_STRESS_TX_COUNT * 3 + 2 then
return to_signed(7425, CELL_WIDTH);
elsif index = UART_STRESS_TX_COUNT * 3 + 3 then
return to_signed(0, CELL_WIDTH);
elsif index = UART_STRESS_TX_COUNT * 3 + 4 then
return to_signed(7425, CELL_WIDTH);
elsif index = UART_STRESS_TX_COUNT * 3 + 5 then
return to_signed(6, CELL_WIDTH);
end if;
return CELL_ZERO;
end if;
case index is
when 0 => return to_signed(1900801, CELL_WIDTH);
when 1 => return to_signed(65, CELL_WIDTH);
when 2 => return to_signed(0, CELL_WIDTH);
when 3 => return to_signed(7425, CELL_WIDTH);
when 4 => return to_signed(6, CELL_WIDTH);
when others => return CELL_ZERO;
end case;
end function;
signal reset_pipe : std_logic_vector(1 downto 0) := (others => '1');
signal reset_sync : std_logic := '1';
signal reset_count : natural range 0 to RESET_CYCLES := RESET_CYCLES;
signal boot_state : boot_state_t := S_RESET;
signal boot_index : natural range 0 to BOOT_MAX_CELLS := 0;
signal core_reset : std_logic := '1';
signal mem_req : std_logic;
signal mem_we : std_logic;
signal mem_addr : addr_t;
signal mem_wdata : cell_t;
signal mem_rdata : cell_t;
signal mem_ready : std_logic;
signal sdram_req : std_logic;
signal sdram_we : std_logic;
signal sdram_addr : addr_t;
signal sdram_wdata : cell_t;
signal sdram_ready : std_logic;
signal serial_tx_valid : std_logic;
signal serial_tx_data : std_logic_vector(7 downto 0);
signal serial_tx_ready : std_logic;
signal serial_rx_req : std_logic;
signal serial_rx_valid : std_logic;
signal serial_rx_data : std_logic_vector(7 downto 0);
signal serial_rx_take : std_logic;
signal uart_rx_valid : std_logic;
signal uart_rx_data : std_logic_vector(7 downto 0);
signal uart_rx_take : std_logic;
signal uart_tx_busy : std_logic;
signal tx_fifo_push : std_logic;
signal tx_fifo_pop : std_logic;
signal tx_fifo_data : std_logic_vector(7 downto 0);
signal tx_fifo_empty : std_logic;
signal tx_fifo_full : std_logic;
signal rx_fifo_push : std_logic;
signal rx_fifo_pop : std_logic;
signal rx_fifo_empty : std_logic;
signal rx_fifo_full : std_logic;
signal block_req : std_logic;
signal block_ready : std_logic := '0';
signal core_reload_req : std_logic;
signal sdram_reload_req : std_logic;
signal reload_ready: std_logic;
signal halted : std_logic;
signal errored : std_logic;
signal heartbeat : unsigned(23 downto 0) := (others => '0');
begin
process(clk)
begin
if rising_edge(clk) then
reset_pipe <= reset_pipe(0) & not button(0);
if reset_pipe(1) = '1' then
reset_sync <= '1';
reset_count <= RESET_CYCLES;
elsif reset_count = 0 then
reset_sync <= '0';
else
reset_count <= reset_count - 1;
reset_sync <= '1';
end if;
end if;
end process;
process(clk)
begin
if rising_edge(clk) then
if reset_sync = '1' then
boot_state <= S_RESET;
boot_index <= 0;
core_reset <= '1';
else
case boot_state is
when S_RESET =>
boot_index <= 0;
core_reset <= '1';
if boot_length = 0 then
boot_state <= S_PRELOAD_WAIT;
else
boot_state <= S_BOOT_REQ;
end if;
when S_PRELOAD_WAIT =>
core_reset <= '1';
if reload_ready = '1' then
boot_state <= S_RUN;
end if;
when S_BOOT_REQ =>
core_reset <= '1';
boot_state <= S_BOOT_WAIT;
when S_BOOT_WAIT =>
core_reset <= '1';
if sdram_ready = '1' then
if boot_index = boot_length - 1 then
boot_state <= S_RUN;
else
boot_state <= S_BOOT_GAP;
end if;
end if;
when S_BOOT_GAP =>
core_reset <= '1';
boot_index <= boot_index + 1;
boot_state <= S_BOOT_REQ;
when S_RUN =>
core_reset <= '0';
end case;
end if;
end if;
end process;
sdram_req <= '1' when boot_state = S_BOOT_REQ or boot_state = S_BOOT_WAIT else mem_req;
sdram_we <= '1' when boot_state = S_BOOT_REQ or boot_state = S_BOOT_WAIT else mem_we;
sdram_addr <= to_unsigned(boot_index, sdram_addr'length)
when boot_state = S_BOOT_REQ or boot_state = S_BOOT_WAIT else mem_addr;
sdram_wdata <= boot_word(boot_index)
when boot_state = S_BOOT_REQ or boot_state = S_BOOT_WAIT else mem_wdata;
mem_ready <= sdram_ready when boot_state = S_RUN else '0';
sdram_reload_req <= '1' when boot_state = S_PRELOAD_WAIT else core_reload_req;
mem_i : entity work.ilo_sdram_controller
generic map (
INIT_WAIT_CYCLES => SDRAM_INIT_WAIT_CYCLES,
REFRESH_INTERVAL_CYCLES => SDRAM_REFRESH_INTERVAL_CYCLES,
TRCD_CYCLES => SDRAM_TRCD_CYCLES,
TRP_CYCLES => SDRAM_TRP_CYCLES,
TRFC_CYCLES => SDRAM_TRFC_CYCLES,
TMRD_CYCLES => SDRAM_TMRD_CYCLES,
READ_WAIT_CYCLES => SDRAM_READ_WAIT_CYCLES,
WRITE_RECOVERY_CYCLES => SDRAM_WRITE_RECOVERY_CYCLES
)
port map (
clk => clk,
reset => reset_sync,
req => sdram_req,
we => sdram_we,
addr => sdram_addr,
wdata => sdram_wdata,
rdata => mem_rdata,
ready => sdram_ready,
reload_req => sdram_reload_req,
reload_ready => reload_ready,
sdram_a => sdram_a,
sdram_ba => sdram_ba,
sdram_dq => sdram_dq,
sdram_dqm => sdram_dqm,
sdram_csn => sdram_csn,
sdram_cke => sdram_cke,
sdram_clk => sdram_clk,
sdram_wen => sdram_wen,
sdram_casn => sdram_casn,
sdram_rasn => sdram_rasn
);
core_i : entity work.ilo_core
port map (
clk => clk,
reset => core_reset,
mem_req => mem_req,
mem_we => mem_we,
mem_addr => mem_addr,
mem_wdata => mem_wdata,
mem_rdata => mem_rdata,
mem_ready => mem_ready,
serial_tx_valid => serial_tx_valid,
serial_tx_data => serial_tx_data,
serial_tx_ready => serial_tx_ready,
serial_rx_req => serial_rx_req,
serial_rx_valid => serial_rx_valid,
serial_rx_data => serial_rx_data,
block_req => block_req,
block_we => open,
block_addr => open,
block_wdata => open,
block_rdata => CELL_ZERO,
block_ready => block_ready,
reload_req => core_reload_req,
reload_ready => reload_ready,
halted => halted,
errored => errored,
error_code => open
);
serial_tx_ready <= not tx_fifo_full;
tx_fifo_push <= serial_tx_valid and serial_tx_ready;
tx_fifo_pop <= '1' when tx_fifo_empty = '0' and uart_tx_busy = '0' else '0';
tx_fifo_i : entity work.ilo_byte_fifo
generic map (
DEPTH => 16
)
port map (
clk => clk,
reset => reset_sync,
push => tx_fifo_push,
wdata => serial_tx_data,
full => tx_fifo_full,
pop => tx_fifo_pop,
rdata => tx_fifo_data,
empty => tx_fifo_empty
);
tx_i : entity work.ilo_uart_tx
generic map (
CLKS_PER_BIT => UART_CLKS_PER_BIT
)
port map (
clk => clk,
reset => reset_sync,
data_valid => tx_fifo_pop,
data => tx_fifo_data,
tx => usb_tx,
busy => uart_tx_busy
);
rx_fifo_push <= uart_rx_valid and not rx_fifo_full;
uart_rx_take <= rx_fifo_push;
serial_rx_take <= serial_rx_req and serial_rx_valid;
rx_fifo_pop <= serial_rx_take;
serial_rx_valid <= not rx_fifo_empty;
rx_fifo_i : entity work.ilo_byte_fifo
generic map (
DEPTH => 16
)
port map (
clk => clk,
reset => reset_sync,
push => rx_fifo_push,
wdata => uart_rx_data,
full => rx_fifo_full,
pop => rx_fifo_pop,
rdata => serial_rx_data,
empty => rx_fifo_empty
);
rx_i : entity work.ilo_uart_rx
generic map (
CLKS_PER_BIT => UART_CLKS_PER_BIT
)
port map (
clk => clk,
reset => reset_sync,
rx => usb_rx,
take => uart_rx_take,
data_valid => uart_rx_valid,
data => uart_rx_data
);
process(clk)
begin
if rising_edge(clk) then
if reset_sync = '1' then
block_ready <= '0';
heartbeat <= (others => '0');
else
block_ready <= block_req;
heartbeat <= heartbeat + 1;
end if;
end if;
end process;
led(0) <= halted;
led(1) <= errored;
led(2) <= uart_tx_busy;
led(3) <= heartbeat(23);
led(4) <= not core_reset;
end architecture;
|
Added ilo-vm/vhdl/rtl/boards/icepi_zero_top.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.ilo_pkg.all;
entity icepi_zero_top is
generic (
UART_CLKS_PER_BIT : positive := 434;
RESET_CYCLES : natural := 16
);
port (
clk : in std_logic;
button : in std_logic_vector(1 downto 0);
led : out std_logic_vector(4 downto 0);
usb_rx : in std_logic;
usb_tx : out std_logic
);
end entity;
architecture rtl of icepi_zero_top is
type mem_state_t is (S_MEM_IDLE, S_MEM_READY, S_MEM_WAIT_RELEASE);
type boot_rom_t is array (0 to 4) of cell_t;
constant BOOT_ROM : boot_rom_t := (
to_signed(1900801, CELL_WIDTH),
to_signed(65, CELL_WIDTH),
to_signed(0, CELL_WIDTH),
to_signed(7425, CELL_WIDTH),
to_signed(6, CELL_WIDTH)
);
signal reset_pipe : std_logic_vector(1 downto 0) := (others => '1');
signal reset_sync : std_logic := '1';
signal reset_count : natural range 0 to RESET_CYCLES := RESET_CYCLES;
signal mem_req : std_logic;
signal mem_we : std_logic;
signal mem_addr : addr_t;
signal mem_wdata : cell_t;
signal mem_rdata : cell_t := CELL_ZERO;
signal mem_ready : std_logic := '0';
signal mem_state : mem_state_t := S_MEM_IDLE;
signal serial_tx_valid : std_logic;
signal serial_tx_data : std_logic_vector(7 downto 0);
signal serial_tx_ready : std_logic;
signal serial_rx_req : std_logic;
signal serial_rx_valid : std_logic;
signal serial_rx_data : std_logic_vector(7 downto 0);
signal serial_rx_take : std_logic;
signal uart_rx_valid : std_logic;
signal uart_rx_data : std_logic_vector(7 downto 0);
signal uart_rx_take : std_logic;
signal uart_tx_busy : std_logic;
signal tx_fifo_push : std_logic;
signal tx_fifo_pop : std_logic;
signal tx_fifo_data : std_logic_vector(7 downto 0);
signal tx_fifo_empty : std_logic;
signal tx_fifo_full : std_logic;
signal rx_fifo_push : std_logic;
signal rx_fifo_pop : std_logic;
signal rx_fifo_empty : std_logic;
signal rx_fifo_full : std_logic;
signal block_req : std_logic;
signal block_ready : std_logic := '0';
signal reload_req : std_logic;
signal reload_ready: std_logic;
signal halted : std_logic;
signal errored : std_logic;
signal heartbeat : unsigned(23 downto 0) := (others => '0');
begin
process(clk)
begin
if rising_edge(clk) then
reset_pipe <= reset_pipe(0) & not button(0);
if reset_pipe(1) = '1' then
reset_sync <= '1';
reset_count <= RESET_CYCLES;
elsif reset_count = 0 then
reset_sync <= '0';
else
reset_count <= reset_count - 1;
reset_sync <= '1';
end if;
end if;
end process;
process(clk)
variable a : natural;
begin
if rising_edge(clk) then
mem_ready <= '0';
reload_ready <= '0';
if reset_sync = '1' then
mem_rdata <= CELL_ZERO;
mem_state <= S_MEM_IDLE;
elsif reload_req = '1' then
reload_ready <= '1';
mem_state <= S_MEM_IDLE;
else
case mem_state is
when S_MEM_IDLE =>
if mem_req = '1' then
a := to_integer(mem_addr);
if mem_we = '1' then
mem_rdata <= mem_wdata;
elsif a < BOOT_ROM'length then
mem_rdata <= BOOT_ROM(a);
else
mem_rdata <= CELL_ZERO;
end if;
mem_ready <= '1';
mem_state <= S_MEM_READY;
end if;
when S_MEM_READY =>
mem_state <= S_MEM_WAIT_RELEASE;
when S_MEM_WAIT_RELEASE =>
if mem_req = '0' then
mem_state <= S_MEM_IDLE;
end if;
end case;
end if;
end if;
end process;
core_i : entity work.ilo_core
port map (
clk => clk,
reset => reset_sync,
mem_req => mem_req,
mem_we => mem_we,
mem_addr => mem_addr,
mem_wdata => mem_wdata,
mem_rdata => mem_rdata,
mem_ready => mem_ready,
serial_tx_valid => serial_tx_valid,
serial_tx_data => serial_tx_data,
serial_tx_ready => serial_tx_ready,
serial_rx_req => serial_rx_req,
serial_rx_valid => serial_rx_valid,
serial_rx_data => serial_rx_data,
block_req => block_req,
block_we => open,
block_addr => open,
block_wdata => open,
block_rdata => CELL_ZERO,
block_ready => block_ready,
reload_req => reload_req,
reload_ready => reload_ready,
halted => halted,
errored => errored,
error_code => open
);
serial_tx_ready <= not tx_fifo_full;
tx_fifo_push <= serial_tx_valid and serial_tx_ready;
tx_fifo_pop <= '1' when tx_fifo_empty = '0' and uart_tx_busy = '0' else '0';
tx_fifo_i : entity work.ilo_byte_fifo
generic map (
DEPTH => 16
)
port map (
clk => clk,
reset => reset_sync,
push => tx_fifo_push,
wdata => serial_tx_data,
full => tx_fifo_full,
pop => tx_fifo_pop,
rdata => tx_fifo_data,
empty => tx_fifo_empty
);
tx_i : entity work.ilo_uart_tx
generic map (
CLKS_PER_BIT => UART_CLKS_PER_BIT
)
port map (
clk => clk,
reset => reset_sync,
data_valid => tx_fifo_pop,
data => tx_fifo_data,
tx => usb_tx,
busy => uart_tx_busy
);
rx_fifo_push <= uart_rx_valid and not rx_fifo_full;
uart_rx_take <= rx_fifo_push;
serial_rx_take <= serial_rx_req and serial_rx_valid;
rx_fifo_pop <= serial_rx_take;
serial_rx_valid <= not rx_fifo_empty;
rx_fifo_i : entity work.ilo_byte_fifo
generic map (
DEPTH => 16
)
port map (
clk => clk,
reset => reset_sync,
push => rx_fifo_push,
wdata => uart_rx_data,
full => rx_fifo_full,
pop => rx_fifo_pop,
rdata => serial_rx_data,
empty => rx_fifo_empty
);
rx_i : entity work.ilo_uart_rx
generic map (
CLKS_PER_BIT => UART_CLKS_PER_BIT
)
port map (
clk => clk,
reset => reset_sync,
rx => usb_rx,
take => uart_rx_take,
data_valid => uart_rx_valid,
data => uart_rx_data
);
process(clk)
begin
if rising_edge(clk) then
if reset_sync = '1' then
block_ready <= '0';
heartbeat <= (others => '0');
else
block_ready <= block_req;
heartbeat <= heartbeat + 1;
end if;
end if;
end process;
led(0) <= halted;
led(1) <= errored;
led(2) <= uart_tx_busy;
led(3) <= heartbeat(23);
led(4) <= not reset_sync;
end architecture;
|
Added ilo-vm/vhdl/rtl/ilo_block_store.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use work.ilo_pkg.all;
entity ilo_block_store is
generic (
BLOCK_FILE : string := "";
BLOCK_CELLS : natural := 1024;
READ_WAIT_CYCLES : natural := 0;
WRITE_WAIT_CYCLES : natural := 0;
POISON_UNINITIALIZED : boolean := false
);
port (
clk : in std_logic;
req : in std_logic;
we : in std_logic;
addr : in unsigned(31 downto 0);
wdata : in cell_t;
rdata : out cell_t;
ready : out std_logic
);
end entity;
architecture rtl of ilo_block_store is
type state_t is (S_IDLE, S_WAIT, S_READY, S_WAIT_RELEASE);
type block_array_t is array (0 to BLOCK_CELLS - 1) of cell_t;
signal ram : block_array_t := (others => CELL_ZERO);
signal rdata_reg : cell_t := CELL_ZERO;
signal ready_reg : std_logic := '0';
signal state : state_t := S_IDLE;
signal wait_count : natural := 0;
-- synthesis translate_off
constant POISON_CELL : cell_t := to_signed(-559038737, CELL_WIDTH); -- 0xDEADBEEF
type block_valid_array_t is array (0 to BLOCK_CELLS - 1) of boolean;
-- synthesis translate_on
begin
rdata <= rdata_reg;
ready <= ready_reg;
process(clk)
-- synthesis translate_off
file f : text;
variable l : line;
variable v : integer;
variable i : natural := 0;
variable initialized : boolean := false;
variable valid : block_valid_array_t := (others => false);
-- synthesis translate_on
variable a : natural;
variable target_wait : natural;
begin
if rising_edge(clk) then
-- synthesis translate_off
if not initialized then
if BLOCK_FILE /= "" then
file_open(f, BLOCK_FILE, read_mode);
while not endfile(f) and i < BLOCK_CELLS loop
readline(f, l);
read(l, v);
ram(i) <= to_signed(v, CELL_WIDTH);
valid(i) := true;
i := i + 1;
end loop;
file_close(f);
end if;
initialized := true;
end if;
-- synthesis translate_on
ready_reg <= '0';
case state is
when S_IDLE =>
wait_count <= 0;
if req = '1' then
state <= S_WAIT;
end if;
when S_WAIT =>
if we = '1' then
target_wait := WRITE_WAIT_CYCLES;
else
target_wait := READ_WAIT_CYCLES;
end if;
if wait_count >= target_wait then
if addr < to_unsigned(BLOCK_CELLS, addr'length) then
a := to_integer(addr);
if we = '1' then
ram(a) <= wdata;
rdata_reg <= wdata;
-- synthesis translate_off
valid(a) := true;
-- synthesis translate_on
else
-- synthesis translate_off
if POISON_UNINITIALIZED and not valid(a) then
rdata_reg <= POISON_CELL;
else
-- synthesis translate_on
rdata_reg <= ram(a);
-- synthesis translate_off
end if;
-- synthesis translate_on
end if;
else
rdata_reg <= CELL_ZERO;
end if;
ready_reg <= '1';
wait_count <= 0;
state <= S_READY;
else
wait_count <= wait_count + 1;
end if;
when S_READY =>
state <= S_WAIT_RELEASE;
when S_WAIT_RELEASE =>
if req = '0' then
state <= S_IDLE;
end if;
end case;
end if;
end process;
end architecture;
|
Added ilo-vm/vhdl/rtl/ilo_byte_fifo.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ilo_byte_fifo is
generic (
DEPTH : positive := 16
);
port (
clk : in std_logic;
reset : in std_logic;
push : in std_logic;
wdata : in std_logic_vector(7 downto 0);
full : out std_logic;
pop : in std_logic;
rdata : out std_logic_vector(7 downto 0);
empty : out std_logic
);
end entity;
architecture rtl of ilo_byte_fifo is
type mem_t is array (0 to DEPTH - 1) of std_logic_vector(7 downto 0);
signal mem : mem_t := (others => (others => '0'));
signal rd_index : natural range 0 to DEPTH - 1 := 0;
signal wr_index : natural range 0 to DEPTH - 1 := 0;
signal count : natural range 0 to DEPTH := 0;
function bump(index : natural) return natural is
begin
if index = DEPTH - 1 then
return 0;
end if;
return index + 1;
end function;
begin
rdata <= mem(rd_index);
empty <= '1' when count = 0 else '0';
full <= '1' when count = DEPTH else '0';
process(clk)
variable do_push : boolean;
variable do_pop : boolean;
begin
if rising_edge(clk) then
if reset = '1' then
rd_index <= 0;
wr_index <= 0;
count <= 0;
else
do_push := push = '1' and (count < DEPTH or pop = '1');
do_pop := pop = '1' and count > 0;
if do_push then
mem(wr_index) <= wdata;
wr_index <= bump(wr_index);
end if;
if do_pop then
rd_index <= bump(rd_index);
end if;
if do_push and not do_pop then
count <= count + 1;
elsif do_pop and not do_push then
count <= count - 1;
end if;
end if;
end if;
end process;
end architecture;
|
Added ilo-vm/vhdl/rtl/ilo_core.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.ilo_pkg.all;
entity ilo_core is
generic (
STRICT_ERRORS : boolean := true
);
port (
clk : in std_logic;
reset : in std_logic;
-- On reads, mem_ready='1' means mem_rdata is valid for this rising edge.
-- External asynchronous memories need a synchronizing/registering wrapper.
mem_req : out std_logic;
mem_we : out std_logic;
mem_addr : out addr_t;
mem_wdata : out cell_t;
mem_rdata : in cell_t;
mem_ready : in std_logic;
serial_tx_valid : out std_logic;
serial_tx_data : out std_logic_vector(7 downto 0);
serial_tx_ready : in std_logic;
-- serial_rx_valid/data are synchronous to clk. When serial_rx_valid='1',
-- serial_rx_data must be valid for that rising edge.
serial_rx_req : out std_logic;
serial_rx_valid : in std_logic;
serial_rx_data : in std_logic_vector(7 downto 0);
-- On reads, block_ready='1' means block_rdata is valid for this rising edge.
block_req : out std_logic;
block_we : out std_logic;
block_addr : out unsigned(31 downto 0);
block_wdata : out cell_t;
block_rdata : in cell_t;
block_ready : in std_logic;
reload_req : out std_logic;
reload_ready : in std_logic;
halted : out std_logic;
errored : out std_logic;
error_code: out unsigned(7 downto 0)
);
end entity;
architecture rtl of ilo_core is
type state_t is (
S_RESET,
S_FETCH_REQ,
S_FETCH_WAIT,
S_DECODE,
S_EXECUTE,
S_MEM_READ_REQ,
S_MEM_READ_WAIT,
S_MEM_WRITE_REQ,
S_MEM_WRITE_WAIT,
S_CP_READ_SRC_REQ,
S_CP_READ_SRC_WAIT,
S_CP_READ_DST_REQ,
S_CP_READ_DST_WAIT,
S_CY_READ_REQ,
S_CY_READ_WAIT,
S_CY_WRITE_REQ,
S_CY_WRITE_WAIT,
S_IO_WAIT,
S_TX_WAIT,
S_BLOCK_READ_REQ,
S_BLOCK_READ_WAIT,
S_BLOCK_MEM_WRITE_REQ,
S_BLOCK_MEM_WRITE_WAIT,
S_BLOCK_MEM_READ_REQ,
S_BLOCK_MEM_READ_WAIT,
S_BLOCK_WRITE_REQ,
S_BLOCK_WRITE_WAIT,
S_RELOAD_REQ,
S_RELOAD_WAIT,
S_DS_REFILL_WAIT,
S_DS_REFILL_CAPTURE,
S_PO_REFILL_WAIT,
S_PO_REFILL_CAPTURE,
S_RE_REFILL_WAIT,
S_RE_REFILL_CAPTURE,
S_MUL_WRITEBACK,
S_DIV_STEP,
S_NEXT_OPCODE,
S_HALT,
S_ERROR
);
type mem_op_t is (M_NONE, M_LI, M_FE);
type ds_refill_target_t is (DS_REFILL_TOP, DS_REFILL_N, DS_REFILL_D2);
constant ERR_NONE : unsigned(7 downto 0) := x"00";
constant ERR_DSU : unsigned(7 downto 0) := x"01";
constant ERR_DSO : unsigned(7 downto 0) := x"02";
constant ERR_RSU : unsigned(7 downto 0) := x"03";
constant ERR_RSO : unsigned(7 downto 0) := x"04";
constant ERR_DBZ : unsigned(7 downto 0) := x"05";
constant ERR_MEM : unsigned(7 downto 0) := x"06";
constant ERR_BLK : unsigned(7 downto 0) := x"07";
subtype stack_index_t is natural range 0 to RS_DEPTH - 1;
subtype ds_index_t is natural range 0 to DS_DEPTH - 1;
signal state : state_t := S_RESET;
signal mem_op : mem_op_t := M_NONE;
signal ip : unsigned(16 downto 0) := (others => '0');
signal bundle : std_logic_vector(31 downto 0) := (others => '0');
signal idx : unsigned(1 downto 0) := (others => '0');
signal opcode : unsigned(7 downto 0) := (others => '0');
signal ds_mem : ds_array_t := (others => CELL_ZERO);
signal ds_t : cell_t := CELL_ZERO;
signal ds_n : cell_t := CELL_ZERO;
signal ds_d2 : cell_t := CELL_ZERO;
signal rs_mem : rs_array_t := (others => CELL_ZERO);
signal rs_t : cell_t := CELL_ZERO;
signal sp : natural range 0 to DS_DEPTH := 0;
signal rp : natural range 0 to RS_DEPTH := 0;
signal halted_reg : std_logic := '0';
signal error_reg : std_logic := '0';
signal err_reg : unsigned(7 downto 0) := ERR_NONE;
signal mem_req_reg : std_logic := '0';
signal mem_we_reg : std_logic := '0';
signal mem_addr_reg : addr_t := (others => '0');
signal mem_wdata_reg : cell_t := CELL_ZERO;
signal tx_valid_reg : std_logic := '0';
signal tx_data_reg : std_logic_vector(7 downto 0) := (others => '0');
signal tx_pending_data : std_logic_vector(7 downto 0) := (others => '0');
signal rx_req_reg : std_logic := '0';
signal block_req_reg : std_logic := '0';
signal block_we_reg : std_logic := '0';
signal block_addr_reg : unsigned(31 downto 0) := (others => '0');
signal block_wdata_reg : cell_t := CELL_ZERO;
signal reload_req_reg : std_logic := '0';
signal cp_src : addr_t := (others => '0');
signal cp_dst : addr_t := (others => '0');
signal cp_len : unsigned(31 downto 0) := (others => '0');
signal cp_flag : cell_t := CELL_TRUE;
signal cp_src_val : cell_t := CELL_ZERO;
signal cy_src : addr_t := (others => '0');
signal cy_dst : addr_t := (others => '0');
signal cy_len : unsigned(31 downto 0) := (others => '0');
signal cy_value : cell_t := CELL_ZERO;
signal io_block_base : unsigned(31 downto 0) := (others => '0');
signal io_buffer : addr_t := (others => '0');
signal io_offset : unsigned(9 downto 0) := (others => '0');
signal io_cell : cell_t := CELL_ZERO;
signal div_divisor_abs : unsigned(31 downto 0) := (others => '0');
signal div_quotient : unsigned(31 downto 0) := (others => '0');
signal div_remainder : unsigned(32 downto 0) := (others => '0');
signal div_count : unsigned(5 downto 0) := (others => '0');
signal div_quot_neg : std_logic := '0';
signal div_rem_neg : std_logic := '0';
signal div_sp : natural range 0 to DS_DEPTH := 0;
signal mul_product : signed(63 downto 0) := (others => '0');
signal mul_sp : natural range 0 to DS_DEPTH := 0;
signal ds_rd_addr : ds_index_t := 0;
signal ds_rd_data : cell_t := CELL_ZERO;
signal ds_wr_en : std_logic := '0';
signal ds_wr_addr : ds_index_t := 0;
signal ds_wr_data : cell_t := CELL_ZERO;
signal ds_refill_count : natural range 0 to 3 := 0;
signal ds_refill_target : ds_refill_target_t := DS_REFILL_D2;
signal ds_refill_resume : state_t := S_NEXT_OPCODE;
signal rs_rd_addr : stack_index_t := 0;
signal rs_rd_data : cell_t := CELL_ZERO;
signal rs_wr_en : std_logic := '0';
signal rs_wr_addr : stack_index_t := 0;
signal rs_wr_data : cell_t := CELL_ZERO;
function ds_cell(
mem : ds_array_t;
top : cell_t;
nxt : cell_t;
third : cell_t;
depth : natural;
index : natural
) return cell_t is
begin
if index = 0 or index > depth then
return CELL_ZERO;
elsif index = depth then
return top;
elsif depth >= 2 and index = depth - 1 then
return nxt;
elsif depth >= 3 and index = depth - 2 then
return third;
end if;
return mem(index);
end function;
procedure ds_resume_or_refill(
signal rd_addr : out ds_index_t;
signal count : out natural range 0 to 3;
signal target : out ds_refill_target_t;
signal resume : out state_t;
signal st : out state_t;
reads : natural;
first_addr : natural;
first_target : ds_refill_target_t;
resume_state : state_t
) is
begin
if reads = 0 then
st <= resume_state;
else
rd_addr <= first_addr;
count <= reads;
target <= first_target;
resume <= resume_state;
st <= S_DS_REFILL_WAIT;
end if;
end procedure;
procedure ds_push(
signal wr_en : out std_logic;
signal wr_addr : out ds_index_t;
signal wr_data : out cell_t;
signal top : inout cell_t;
signal nxt : inout cell_t;
signal third : inout cell_t;
depth : natural;
value : cell_t
) is
begin
if depth >= 3 then
wr_addr <= depth - 2;
wr_data <= third;
wr_en <= '1';
end if;
third <= nxt;
nxt <= top;
top <= value;
end procedure;
procedure ds_drop1(
signal rd_addr : out ds_index_t;
signal refill_count : out natural range 0 to 3;
signal refill_target : out ds_refill_target_t;
signal refill_resume : out state_t;
signal st : out state_t;
signal top : inout cell_t;
signal nxt : inout cell_t;
signal third : inout cell_t;
depth : natural;
resume_state : state_t
) is
begin
if depth > 1 then
top <= nxt;
else
top <= CELL_ZERO;
end if;
if depth > 2 then
nxt <= third;
else
nxt <= CELL_ZERO;
end if;
if depth > 3 then
ds_resume_or_refill(rd_addr, refill_count, refill_target, refill_resume, st,
1, depth - 3, DS_REFILL_D2, resume_state);
else
third <= CELL_ZERO;
st <= resume_state;
end if;
end procedure;
procedure ds_drop2(
signal rd_addr : out ds_index_t;
signal refill_count : out natural range 0 to 3;
signal refill_target : out ds_refill_target_t;
signal refill_resume : out state_t;
signal st : out state_t;
signal top : inout cell_t;
signal nxt : inout cell_t;
signal third : inout cell_t;
depth : natural;
resume_state : state_t
) is
begin
if depth > 2 then
top <= third;
else
top <= CELL_ZERO;
end if;
if depth > 3 then
ds_resume_or_refill(rd_addr, refill_count, refill_target, refill_resume, st,
1, depth - 3, DS_REFILL_N, resume_state);
else
nxt <= CELL_ZERO;
st <= resume_state;
end if;
if depth > 4 then
ds_resume_or_refill(rd_addr, refill_count, refill_target, refill_resume, st,
2, depth - 3, DS_REFILL_N, resume_state);
else
third <= CELL_ZERO;
end if;
end procedure;
procedure ds_drop2_to(
signal rd_addr : out ds_index_t;
signal refill_count : out natural range 0 to 3;
signal refill_target : out ds_refill_target_t;
signal refill_resume : out state_t;
signal st : out state_t;
signal top : inout cell_t;
signal nxt : inout cell_t;
signal third : inout cell_t;
depth : natural;
value : cell_t;
resume_state : state_t
) is
begin
top <= value;
if depth > 3 then
ds_resume_or_refill(rd_addr, refill_count, refill_target, refill_resume, st,
1, depth - 3, DS_REFILL_N, resume_state);
else
nxt <= CELL_ZERO;
st <= resume_state;
end if;
if depth > 4 then
ds_resume_or_refill(rd_addr, refill_count, refill_target, refill_resume, st,
2, depth - 3, DS_REFILL_N, resume_state);
else
third <= CELL_ZERO;
end if;
end procedure;
procedure ds_drop3(
signal rd_addr : out ds_index_t;
signal refill_count : out natural range 0 to 3;
signal refill_target : out ds_refill_target_t;
signal refill_resume : out state_t;
signal st : out state_t;
signal top : inout cell_t;
signal nxt : inout cell_t;
signal third : inout cell_t;
depth : natural;
resume_state : state_t
) is
begin
if depth > 3 then
ds_resume_or_refill(rd_addr, refill_count, refill_target, refill_resume, st,
1, depth - 3, DS_REFILL_TOP, resume_state);
else
top <= CELL_ZERO;
st <= resume_state;
end if;
if depth > 4 then
ds_resume_or_refill(rd_addr, refill_count, refill_target, refill_resume, st,
2, depth - 3, DS_REFILL_TOP, resume_state);
else
nxt <= CELL_ZERO;
end if;
if depth > 5 then
ds_resume_or_refill(rd_addr, refill_count, refill_target, refill_resume, st,
3, depth - 3, DS_REFILL_TOP, resume_state);
else
third <= CELL_ZERO;
end if;
end procedure;
procedure ds_binary_result(
signal rd_addr : out ds_index_t;
signal refill_count : out natural range 0 to 3;
signal refill_target : out ds_refill_target_t;
signal refill_resume : out state_t;
signal st : out state_t;
signal top : inout cell_t;
signal nxt : inout cell_t;
signal third : inout cell_t;
depth : natural;
value : cell_t;
resume_state : state_t
) is
begin
top <= value;
if depth > 2 then
nxt <= third;
else
nxt <= CELL_ZERO;
end if;
if depth > 3 then
ds_resume_or_refill(rd_addr, refill_count, refill_target, refill_resume, st,
1, depth - 3, DS_REFILL_D2, resume_state);
else
third <= CELL_ZERO;
st <= resume_state;
end if;
end procedure;
function valid_addr(value : cell_t) return boolean is
begin
return value >= to_signed(0, CELL_WIDTH) and value <= to_signed(65535, CELL_WIDTH);
end function;
function abs_cell(value : cell_t) return unsigned is
begin
if value(CELL_WIDTH - 1) = '1' then
return unsigned(-value);
end if;
return unsigned(value);
end function;
function signed_magnitude(value : unsigned(31 downto 0); negative : std_logic) return cell_t is
variable mag : cell_t;
begin
mag := signed(value);
if negative = '1' then
return -mag;
end if;
return mag;
end function;
begin
mem_req <= mem_req_reg;
mem_we <= mem_we_reg;
mem_addr <= mem_addr_reg;
mem_wdata <= mem_wdata_reg;
halted <= halted_reg;
errored <= error_reg;
error_code <= err_reg;
serial_tx_valid <= tx_valid_reg;
serial_tx_data <= tx_data_reg;
serial_rx_req <= rx_req_reg;
block_req <= block_req_reg;
block_we <= block_we_reg;
block_addr <= block_addr_reg;
block_wdata <= block_wdata_reg;
reload_req <= reload_req_reg;
process(clk)
begin
if rising_edge(clk) then
-- synthesis translate_off
assert not (state = S_DS_REFILL_WAIT and ds_wr_en = '1' and ds_wr_addr = ds_rd_addr)
report "ilo_core: data stack RAM read/write address collision"
severity failure;
assert not ((state = S_PO_REFILL_WAIT or state = S_RE_REFILL_WAIT) and
rs_wr_en = '1' and rs_wr_addr = rs_rd_addr)
report "ilo_core: return stack RAM read/write address collision"
severity failure;
-- synthesis translate_on
if ds_wr_en = '1' then
ds_mem(ds_wr_addr) <= ds_wr_data;
end if;
ds_rd_data <= ds_mem(ds_rd_addr);
if rs_wr_en = '1' then
rs_mem(rs_wr_addr) <= rs_wr_data;
end if;
rs_rd_data <= rs_mem(rs_rd_addr);
end if;
end process;
-- synthesis translate_off
process(all)
begin
sim_debug.set_sp(sp);
sim_debug.set_rp(rp);
for i in 0 to DS_DEPTH loop
sim_debug.set_ds(i, ds_cell(ds_mem, ds_t, ds_n, ds_d2, sp, i));
end loop;
end process;
process(clk)
variable prev_mem_req : std_logic := '0';
variable prev_mem_ready : std_logic := '0';
variable prev_mem_we : std_logic := '0';
variable prev_mem_addr : addr_t := (others => '0');
variable prev_mem_wdata : cell_t := CELL_ZERO;
variable prev_block_req : std_logic := '0';
variable prev_block_ready : std_logic := '0';
variable prev_block_we : std_logic := '0';
variable prev_block_addr : unsigned(31 downto 0) := (others => '0');
variable prev_block_wdata : cell_t := CELL_ZERO;
begin
if rising_edge(clk) then
if reset = '1' then
prev_mem_req := '0';
prev_mem_ready := '0';
prev_mem_we := '0';
prev_mem_addr := (others => '0');
prev_mem_wdata := CELL_ZERO;
prev_block_req := '0';
prev_block_ready := '0';
prev_block_we := '0';
prev_block_addr := (others => '0');
prev_block_wdata := CELL_ZERO;
else
if prev_mem_req = '1' and prev_mem_ready = '0' then
assert mem_req_reg = '1'
report "ilo_core: mem_req dropped before mem_ready"
severity failure;
assert mem_we_reg = prev_mem_we and mem_addr_reg = prev_mem_addr
report "ilo_core: memory request controls changed before mem_ready"
severity failure;
if prev_mem_we = '1' then
assert mem_wdata_reg = prev_mem_wdata
report "ilo_core: memory write data changed before mem_ready"
severity failure;
end if;
end if;
if prev_block_req = '1' and prev_block_ready = '0' then
assert block_req_reg = '1'
report "ilo_core: block_req dropped before block_ready"
severity failure;
assert block_we_reg = prev_block_we and block_addr_reg = prev_block_addr
report "ilo_core: block request controls changed before block_ready"
severity failure;
if prev_block_we = '1' then
assert block_wdata_reg = prev_block_wdata
report "ilo_core: block write data changed before block_ready"
severity failure;
end if;
end if;
prev_mem_req := mem_req_reg;
prev_mem_ready := mem_ready;
prev_mem_we := mem_we_reg;
prev_mem_addr := mem_addr_reg;
prev_mem_wdata := mem_wdata_reg;
prev_block_req := block_req_reg;
prev_block_ready := block_ready;
prev_block_we := block_we_reg;
prev_block_addr := block_addr_reg;
prev_block_wdata := block_wdata_reg;
end if;
end if;
end process;
-- synthesis translate_on
process(clk)
variable op : natural;
variable t : cell_t;
variable n : cell_t;
variable d : cell_t;
variable target17 : unsigned(16 downto 0);
variable rem_shift : unsigned(32 downto 0);
variable quot_shift : unsigned(31 downto 0);
variable divisor_ext : unsigned(32 downto 0);
variable quot_cell : cell_t;
variable rem_cell : cell_t;
begin
if rising_edge(clk) then
mem_req_reg <= '0';
mem_we_reg <= '0';
tx_valid_reg <= '0';
block_req_reg <= '0';
block_we_reg <= '0';
reload_req_reg <= '0';
ds_wr_en <= '0';
rs_wr_en <= '0';
if reset = '1' then
state <= S_RESET;
ip <= (others => '0');
idx <= (others => '0');
sp <= 0;
rp <= 0;
ds_t <= CELL_ZERO;
ds_n <= CELL_ZERO;
ds_d2 <= CELL_ZERO;
rs_t <= CELL_ZERO;
halted_reg <= '0';
error_reg <= '0';
err_reg <= ERR_NONE;
mem_op <= M_NONE;
rx_req_reg <= '0';
reload_req_reg <= '0';
ds_rd_addr <= 0;
ds_wr_addr <= 0;
ds_wr_data <= CELL_ZERO;
ds_refill_count <= 0;
ds_refill_resume <= S_NEXT_OPCODE;
rs_rd_addr <= 0;
rs_wr_addr <= 0;
rs_wr_data <= CELL_ZERO;
else
case state is
when S_RESET =>
ip <= (others => '0');
idx <= (others => '0');
sp <= 0;
rp <= 0;
halted_reg <= '0';
error_reg <= '0';
err_reg <= ERR_NONE;
mem_op <= M_NONE;
rx_req_reg <= '0';
reload_req_reg <= '0';
ds_t <= CELL_ZERO;
ds_n <= CELL_ZERO;
ds_d2 <= CELL_ZERO;
ds_rd_addr <= 0;
ds_wr_addr <= 0;
ds_wr_data <= CELL_ZERO;
ds_refill_count <= 0;
ds_refill_resume <= S_NEXT_OPCODE;
rs_t <= CELL_ZERO;
rs_rd_addr <= 0;
rs_wr_addr <= 0;
rs_wr_data <= CELL_ZERO;
state <= S_FETCH_REQ;
when S_FETCH_REQ =>
if ip >= to_unsigned(MEM_DEPTH, ip'length) then
state <= S_HALT;
else
mem_addr_reg <= ip(15 downto 0);
mem_req_reg <= '1';
state <= S_FETCH_WAIT;
end if;
when S_FETCH_WAIT =>
mem_req_reg <= '1';
if mem_ready = '1' then
mem_req_reg <= '0';
bundle <= std_logic_vector(mem_rdata);
idx <= (others => '0');
state <= S_DECODE;
end if;
when S_DECODE =>
case idx is
when "00" => opcode <= unsigned(bundle(7 downto 0));
when "01" => opcode <= unsigned(bundle(15 downto 8));
when "10" => opcode <= unsigned(bundle(23 downto 16));
when others => opcode <= unsigned(bundle(31 downto 24));
end case;
state <= S_EXECUTE;
when S_EXECUTE =>
op := to_integer(opcode);
t := ds_t;
n := ds_n;
d := ds_d2;
case op is
when OP_NOP =>
state <= S_NEXT_OPCODE;
when OP_LI =>
if sp = DS_DEPTH then
err_reg <= ERR_DSO;
state <= S_ERROR;
else
ip <= ip + 1;
target17 := ip + 1;
mem_addr_reg <= target17(15 downto 0);
mem_op <= M_LI;
state <= S_MEM_READ_REQ;
end if;
when OP_DU =>
if sp = DS_DEPTH then
err_reg <= ERR_DSO;
state <= S_ERROR;
elsif sp = 0 then
err_reg <= ERR_DSU;
state <= S_ERROR;
else
ds_push(ds_wr_en, ds_wr_addr, ds_wr_data, ds_t, ds_n, ds_d2, sp, t);
sp <= sp + 1;
state <= S_NEXT_OPCODE;
end if;
when OP_DR =>
if sp = 0 then
err_reg <= ERR_DSU;
state <= S_ERROR;
else
ds_drop1(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, S_NEXT_OPCODE);
sp <= sp - 1;
end if;
when OP_SW =>
if sp < 2 then
err_reg <= ERR_DSU;
state <= S_ERROR;
else
ds_t <= n;
ds_n <= t;
state <= S_NEXT_OPCODE;
end if;
when OP_PU =>
if sp = 0 then
err_reg <= ERR_DSU;
state <= S_ERROR;
elsif rp = RS_DEPTH then
err_reg <= ERR_RSO;
state <= S_ERROR;
else
if rp >= 1 then
rs_wr_addr <= rp;
rs_wr_data <= rs_t;
rs_wr_en <= '1';
end if;
rs_t <= t;
rp <= rp + 1;
ds_drop1(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, S_NEXT_OPCODE);
sp <= sp - 1;
end if;
when OP_PO =>
if rp = 0 then
err_reg <= ERR_RSU;
state <= S_ERROR;
elsif sp = DS_DEPTH then
err_reg <= ERR_DSO;
state <= S_ERROR;
else
ds_push(ds_wr_en, ds_wr_addr, ds_wr_data, ds_t, ds_n, ds_d2, sp, rs_t);
sp <= sp + 1;
rp <= rp - 1;
if rp > 1 then
rs_rd_addr <= rp - 1;
state <= S_PO_REFILL_WAIT;
else
rs_t <= CELL_ZERO;
state <= S_NEXT_OPCODE;
end if;
end if;
when OP_JU =>
if sp = 0 then
err_reg <= ERR_DSU;
state <= S_ERROR;
elsif STRICT_ERRORS and not valid_addr(t) then
err_reg <= ERR_MEM;
state <= S_ERROR;
else
target17 := resize(cell_addr(t), target17'length);
ip <= target17 - 1;
ds_drop1(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, S_NEXT_OPCODE);
sp <= sp - 1;
end if;
when OP_CA =>
if sp = 0 then
err_reg <= ERR_DSU;
state <= S_ERROR;
elsif rp = RS_DEPTH then
err_reg <= ERR_RSO;
state <= S_ERROR;
elsif STRICT_ERRORS and not valid_addr(t) then
err_reg <= ERR_MEM;
state <= S_ERROR;
else
if rp >= 1 then
rs_wr_addr <= rp;
rs_wr_data <= rs_t;
rs_wr_en <= '1';
end if;
rs_t <= signed(resize(ip, CELL_WIDTH));
rp <= rp + 1;
target17 := resize(cell_addr(t), target17'length);
ip <= target17 - 1;
ds_drop1(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, S_NEXT_OPCODE);
sp <= sp - 1;
end if;
when OP_CC =>
if sp < 2 then
err_reg <= ERR_DSU;
state <= S_ERROR;
elsif n /= CELL_ZERO and rp = RS_DEPTH then
err_reg <= ERR_RSO;
state <= S_ERROR;
elsif STRICT_ERRORS and n /= CELL_ZERO and not valid_addr(t) then
err_reg <= ERR_MEM;
state <= S_ERROR;
else
if n /= CELL_ZERO then
if rp >= 1 then
rs_wr_addr <= rp;
rs_wr_data <= rs_t;
rs_wr_en <= '1';
end if;
rs_t <= signed(resize(ip, CELL_WIDTH));
rp <= rp + 1;
target17 := resize(cell_addr(t), target17'length);
ip <= target17 - 1;
end if;
ds_drop2(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, S_NEXT_OPCODE);
sp <= sp - 2;
end if;
when OP_CJ =>
if sp < 2 then
err_reg <= ERR_DSU;
state <= S_ERROR;
elsif STRICT_ERRORS and n /= CELL_ZERO and not valid_addr(t) then
err_reg <= ERR_MEM;
state <= S_ERROR;
else
if n /= CELL_ZERO then
target17 := resize(cell_addr(t), target17'length);
ip <= target17 - 1;
end if;
ds_drop2(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, S_NEXT_OPCODE);
sp <= sp - 2;
end if;
when OP_RE =>
if rp = 0 then
err_reg <= ERR_RSU;
state <= S_ERROR;
else
ip <= resize(unsigned(std_logic_vector(rs_t(16 downto 0))), ip'length);
rp <= rp - 1;
if rp > 1 then
rs_rd_addr <= rp - 1;
state <= S_RE_REFILL_WAIT;
else
rs_t <= CELL_ZERO;
state <= S_NEXT_OPCODE;
end if;
end if;
when OP_EQ | OP_NE | OP_LT | OP_GT =>
if sp < 2 then
err_reg <= ERR_DSU;
state <= S_ERROR;
else
if op = OP_EQ then
ds_binary_result(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, bool_cell(n = t), S_NEXT_OPCODE);
elsif op = OP_NE then
ds_binary_result(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, bool_cell(n /= t), S_NEXT_OPCODE);
elsif op = OP_LT then
ds_binary_result(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, bool_cell(n < t), S_NEXT_OPCODE);
else
ds_binary_result(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, bool_cell(n > t), S_NEXT_OPCODE);
end if;
sp <= sp - 1;
end if;
when OP_FE =>
if sp = 0 then
err_reg <= ERR_DSU;
state <= S_ERROR;
elsif STRICT_ERRORS and not valid_addr(t) then
err_reg <= ERR_MEM;
state <= S_ERROR;
else
mem_addr_reg <= cell_addr(t);
mem_op <= M_FE;
state <= S_MEM_READ_REQ;
end if;
when OP_ST =>
if sp < 2 then
err_reg <= ERR_DSU;
state <= S_ERROR;
elsif STRICT_ERRORS and not valid_addr(t) then
err_reg <= ERR_MEM;
state <= S_ERROR;
else
mem_addr_reg <= cell_addr(t);
mem_wdata_reg <= n;
state <= S_MEM_WRITE_REQ;
end if;
when OP_AD | OP_SU | OP_MU | OP_AN | OP_OR | OP_XO | OP_SL | OP_SR =>
if sp < 2 then
err_reg <= ERR_DSU;
state <= S_ERROR;
else
if op = OP_AD then
ds_binary_result(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, n + t, S_NEXT_OPCODE);
elsif op = OP_SU then
ds_binary_result(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, n - t, S_NEXT_OPCODE);
elsif op = OP_MU then
mul_product <= n * t;
mul_sp <= sp;
state <= S_MUL_WRITEBACK;
elsif op = OP_AN then
ds_binary_result(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, n and t, S_NEXT_OPCODE);
elsif op = OP_OR then
ds_binary_result(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, n or t, S_NEXT_OPCODE);
elsif op = OP_XO then
ds_binary_result(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, n xor t, S_NEXT_OPCODE);
elsif op = OP_SL then
ds_binary_result(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, shift_left(n, shift_amount(t)), S_NEXT_OPCODE);
else
ds_binary_result(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, shift_right(n, shift_amount(t)), S_NEXT_OPCODE);
end if;
if op /= OP_MU then
sp <= sp - 1;
end if;
end if;
when OP_DI =>
if sp < 2 then
err_reg <= ERR_DSU;
state <= S_ERROR;
elsif t = CELL_ZERO then
err_reg <= ERR_DBZ;
state <= S_ERROR;
else
div_divisor_abs <= abs_cell(t);
div_quotient <= abs_cell(n);
div_remainder <= (others => '0');
div_count <= to_unsigned(32, div_count'length);
div_quot_neg <= n(CELL_WIDTH - 1) xor t(CELL_WIDTH - 1);
div_rem_neg <= n(CELL_WIDTH - 1);
div_sp <= sp;
state <= S_DIV_STEP;
end if;
when OP_CP =>
if sp < 3 then
err_reg <= ERR_DSU;
state <= S_ERROR;
elsif STRICT_ERRORS and
(not valid_addr(d) or
not valid_addr(n) or
t < CELL_ZERO) then
err_reg <= ERR_MEM;
state <= S_ERROR;
else
cp_src <= cell_addr(d);
cp_dst <= cell_addr(n);
cp_len <= unsigned(std_logic_vector(t));
cp_flag <= CELL_TRUE;
if t = CELL_ZERO then
ds_drop2_to(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, CELL_TRUE, S_NEXT_OPCODE);
sp <= sp - 2;
else
ds_drop2(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, S_CP_READ_SRC_REQ);
sp <= sp - 2;
end if;
end if;
when OP_CY =>
if sp < 3 then
err_reg <= ERR_DSU;
state <= S_ERROR;
elsif STRICT_ERRORS and
(not valid_addr(d) or
not valid_addr(n) or
t < CELL_ZERO) then
err_reg <= ERR_MEM;
state <= S_ERROR;
else
cy_src <= cell_addr(d);
cy_dst <= cell_addr(n);
cy_len <= unsigned(std_logic_vector(t));
sp <= sp - 3;
if t = CELL_ZERO then
ds_drop3(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, S_NEXT_OPCODE);
else
ds_drop3(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, S_CY_READ_REQ);
end if;
end if;
when OP_IO =>
if sp = 0 then
err_reg <= ERR_DSU;
state <= S_ERROR;
else
if t = to_signed(0, CELL_WIDTH) then
if sp < 2 then
err_reg <= ERR_DSU;
state <= S_ERROR;
else
tx_pending_data <= std_logic_vector(n(7 downto 0));
state <= S_TX_WAIT;
end if;
elsif t = to_signed(1, CELL_WIDTH) then
if sp = DS_DEPTH then
err_reg <= ERR_DSO;
state <= S_ERROR;
else
ds_drop1(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, S_IO_WAIT);
sp <= sp - 1;
rx_req_reg <= '1';
end if;
elsif t = to_signed(2, CELL_WIDTH) then
if sp < 3 then
err_reg <= ERR_DSU;
state <= S_ERROR;
elsif STRICT_ERRORS and
(d < CELL_ZERO or
not valid_addr(n) or
n > to_signed(64512, CELL_WIDTH)) then
err_reg <= ERR_MEM;
state <= S_ERROR;
else
io_block_base <= shift_left(unsigned(std_logic_vector(d)), 10);
io_buffer <= cell_addr(n);
io_offset <= (others => '0');
ds_drop3(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, S_BLOCK_READ_REQ);
sp <= sp - 3;
end if;
elsif t = to_signed(3, CELL_WIDTH) then
if sp < 3 then
err_reg <= ERR_DSU;
state <= S_ERROR;
elsif STRICT_ERRORS and
(d < CELL_ZERO or
not valid_addr(n) or
n > to_signed(64512, CELL_WIDTH)) then
err_reg <= ERR_MEM;
state <= S_ERROR;
else
io_block_base <= shift_left(unsigned(std_logic_vector(d)), 10);
io_buffer <= cell_addr(n);
io_offset <= (others => '0');
ds_drop3(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, S_BLOCK_MEM_READ_REQ);
sp <= sp - 3;
end if;
elsif t = to_signed(5, CELL_WIDTH) then
ds_drop1(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, S_RELOAD_REQ);
sp <= sp - 1;
elsif t = to_signed(6, CELL_WIDTH) then
ds_drop1(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, S_HALT);
sp <= sp - 1;
elsif t = to_signed(7, CELL_WIDTH) then
if sp > DS_DEPTH - 1 then
err_reg <= ERR_DSO;
state <= S_ERROR;
else
if sp >= 3 then
ds_wr_addr <= sp - 2;
ds_wr_data <= d;
ds_wr_en <= '1';
end if;
ds_d2 <= n;
ds_n <= to_signed(sp - 1, CELL_WIDTH);
ds_t <= to_signed(rp, CELL_WIDTH);
sp <= sp + 1;
state <= S_NEXT_OPCODE;
end if;
elsif STRICT_ERRORS then
err_reg <= ERR_MEM;
state <= S_ERROR;
else
ds_drop1(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, S_NEXT_OPCODE);
sp <= sp - 1;
end if;
end if;
when others =>
state <= S_NEXT_OPCODE;
end case;
when S_MEM_READ_REQ =>
mem_req_reg <= '1';
state <= S_MEM_READ_WAIT;
when S_MEM_READ_WAIT =>
mem_req_reg <= '1';
if mem_ready = '1' then
mem_req_reg <= '0';
if mem_op = M_LI then
ds_push(ds_wr_en, ds_wr_addr, ds_wr_data, ds_t, ds_n, ds_d2, sp, mem_rdata);
sp <= sp + 1;
elsif mem_op = M_FE then
ds_t <= mem_rdata;
end if;
mem_op <= M_NONE;
state <= S_NEXT_OPCODE;
end if;
when S_MEM_WRITE_REQ =>
mem_req_reg <= '1';
mem_we_reg <= '1';
state <= S_MEM_WRITE_WAIT;
when S_MEM_WRITE_WAIT =>
mem_req_reg <= '1';
mem_we_reg <= '1';
if mem_ready = '1' then
mem_req_reg <= '0';
mem_we_reg <= '0';
ds_drop2(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, S_NEXT_OPCODE);
sp <= sp - 2;
end if;
when S_CP_READ_SRC_REQ =>
mem_addr_reg <= cp_src;
mem_req_reg <= '1';
state <= S_CP_READ_SRC_WAIT;
when S_CP_READ_SRC_WAIT =>
mem_req_reg <= '1';
if mem_ready = '1' then
mem_req_reg <= '0';
cp_src_val <= mem_rdata;
state <= S_CP_READ_DST_REQ;
end if;
when S_CP_READ_DST_REQ =>
mem_addr_reg <= cp_dst;
mem_req_reg <= '1';
state <= S_CP_READ_DST_WAIT;
when S_CP_READ_DST_WAIT =>
mem_req_reg <= '1';
if mem_ready = '1' then
mem_req_reg <= '0';
if cp_src_val /= mem_rdata then
cp_flag <= CELL_ZERO;
end if;
if cp_len = 1 then
if cp_src_val /= mem_rdata then
ds_t <= CELL_ZERO;
else
ds_t <= cp_flag;
end if;
state <= S_NEXT_OPCODE;
else
cp_src <= cp_src + 1;
cp_dst <= cp_dst + 1;
cp_len <= cp_len - 1;
state <= S_CP_READ_SRC_REQ;
end if;
end if;
when S_CY_READ_REQ =>
mem_addr_reg <= cy_src;
mem_req_reg <= '1';
state <= S_CY_READ_WAIT;
when S_CY_READ_WAIT =>
mem_req_reg <= '1';
if mem_ready = '1' then
mem_req_reg <= '0';
cy_value <= mem_rdata;
state <= S_CY_WRITE_REQ;
end if;
when S_CY_WRITE_REQ =>
mem_addr_reg <= cy_dst;
mem_wdata_reg <= cy_value;
mem_req_reg <= '1';
mem_we_reg <= '1';
state <= S_CY_WRITE_WAIT;
when S_CY_WRITE_WAIT =>
mem_req_reg <= '1';
mem_we_reg <= '1';
if mem_ready = '1' then
mem_req_reg <= '0';
mem_we_reg <= '0';
if cy_len = 1 then
state <= S_NEXT_OPCODE;
else
cy_src <= cy_src + 1;
cy_dst <= cy_dst + 1;
cy_len <= cy_len - 1;
state <= S_CY_READ_REQ;
end if;
end if;
when S_IO_WAIT =>
if serial_rx_valid = '1' then
rx_req_reg <= '0';
ds_push(ds_wr_en, ds_wr_addr, ds_wr_data,
ds_t, ds_n, ds_d2, sp, signed(resize(unsigned(serial_rx_data), CELL_WIDTH)));
sp <= sp + 1;
state <= S_NEXT_OPCODE;
end if;
when S_TX_WAIT =>
if serial_tx_ready = '1' then
tx_data_reg <= tx_pending_data;
tx_valid_reg <= '1';
ds_drop2(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, S_NEXT_OPCODE);
sp <= sp - 2;
end if;
when S_BLOCK_READ_REQ =>
block_addr_reg <= io_block_base + resize(io_offset, block_addr_reg'length);
block_req_reg <= '1';
state <= S_BLOCK_READ_WAIT;
when S_BLOCK_READ_WAIT =>
block_req_reg <= '1';
if block_ready = '1' then
block_req_reg <= '0';
io_cell <= block_rdata;
state <= S_BLOCK_MEM_WRITE_REQ;
end if;
when S_BLOCK_MEM_WRITE_REQ =>
mem_addr_reg <= io_buffer + resize(io_offset, mem_addr_reg'length);
mem_wdata_reg <= io_cell;
mem_req_reg <= '1';
mem_we_reg <= '1';
state <= S_BLOCK_MEM_WRITE_WAIT;
when S_BLOCK_MEM_WRITE_WAIT =>
mem_req_reg <= '1';
mem_we_reg <= '1';
if mem_ready = '1' then
mem_req_reg <= '0';
mem_we_reg <= '0';
if io_offset = to_unsigned(1023, io_offset'length) then
state <= S_NEXT_OPCODE;
else
io_offset <= io_offset + 1;
state <= S_BLOCK_READ_REQ;
end if;
end if;
when S_BLOCK_MEM_READ_REQ =>
mem_addr_reg <= io_buffer + resize(io_offset, mem_addr_reg'length);
mem_req_reg <= '1';
state <= S_BLOCK_MEM_READ_WAIT;
when S_BLOCK_MEM_READ_WAIT =>
mem_req_reg <= '1';
if mem_ready = '1' then
mem_req_reg <= '0';
io_cell <= mem_rdata;
state <= S_BLOCK_WRITE_REQ;
end if;
when S_BLOCK_WRITE_REQ =>
block_addr_reg <= io_block_base + resize(io_offset, block_addr_reg'length);
block_wdata_reg <= io_cell;
block_req_reg <= '1';
block_we_reg <= '1';
state <= S_BLOCK_WRITE_WAIT;
when S_BLOCK_WRITE_WAIT =>
block_req_reg <= '1';
block_we_reg <= '1';
if block_ready = '1' then
block_req_reg <= '0';
block_we_reg <= '0';
if io_offset = to_unsigned(1023, io_offset'length) then
state <= S_NEXT_OPCODE;
else
io_offset <= io_offset + 1;
state <= S_BLOCK_MEM_READ_REQ;
end if;
end if;
when S_RELOAD_REQ =>
reload_req_reg <= '1';
state <= S_RELOAD_WAIT;
when S_RELOAD_WAIT =>
reload_req_reg <= '1';
if reload_ready = '1' then
reload_req_reg <= '0';
ip <= (others => '0');
idx <= (others => '0');
sp <= 0;
rp <= 0;
ds_t <= CELL_ZERO;
ds_n <= CELL_ZERO;
ds_d2 <= CELL_ZERO;
rs_t <= CELL_ZERO;
mem_op <= M_NONE;
rx_req_reg <= '0';
ds_rd_addr <= 0;
ds_wr_addr <= 0;
ds_wr_data <= CELL_ZERO;
ds_refill_count <= 0;
ds_refill_resume <= S_NEXT_OPCODE;
rs_rd_addr <= 0;
rs_wr_addr <= 0;
rs_wr_data <= CELL_ZERO;
state <= S_FETCH_REQ;
end if;
when S_DS_REFILL_WAIT =>
state <= S_DS_REFILL_CAPTURE;
when S_DS_REFILL_CAPTURE =>
case ds_refill_target is
when DS_REFILL_TOP => ds_t <= ds_rd_data;
when DS_REFILL_N => ds_n <= ds_rd_data;
when DS_REFILL_D2 => ds_d2 <= ds_rd_data;
end case;
if ds_refill_count = 1 then
ds_refill_count <= 0;
state <= ds_refill_resume;
else
ds_refill_count <= ds_refill_count - 1;
ds_rd_addr <= ds_rd_addr - 1;
case ds_refill_target is
when DS_REFILL_TOP => ds_refill_target <= DS_REFILL_N;
when DS_REFILL_N => ds_refill_target <= DS_REFILL_D2;
when DS_REFILL_D2 => ds_refill_target <= DS_REFILL_D2;
end case;
state <= S_DS_REFILL_WAIT;
end if;
when S_PO_REFILL_WAIT =>
state <= S_PO_REFILL_CAPTURE;
when S_PO_REFILL_CAPTURE =>
rs_t <= rs_rd_data;
state <= S_NEXT_OPCODE;
when S_RE_REFILL_WAIT =>
state <= S_RE_REFILL_CAPTURE;
when S_RE_REFILL_CAPTURE =>
rs_t <= rs_rd_data;
state <= S_NEXT_OPCODE;
when S_MUL_WRITEBACK =>
ds_binary_result(ds_rd_addr, ds_refill_count, ds_refill_target, ds_refill_resume, state,
ds_t, ds_n, ds_d2, sp, mul_product(31 downto 0), S_NEXT_OPCODE);
sp <= sp - 1;
when S_DIV_STEP =>
rem_shift := div_remainder(31 downto 0) & div_quotient(31);
quot_shift := div_quotient(30 downto 0) & '0';
divisor_ext := '0' & div_divisor_abs;
if rem_shift >= divisor_ext then
rem_shift := rem_shift - divisor_ext;
quot_shift(0) := '1';
end if;
div_remainder <= rem_shift;
div_quotient <= quot_shift;
div_count <= div_count - 1;
if div_count = 1 then
quot_cell := signed_magnitude(quot_shift, div_quot_neg);
rem_cell := signed_magnitude(rem_shift(31 downto 0), div_rem_neg);
ds_t <= quot_cell;
ds_n <= rem_cell;
state <= S_NEXT_OPCODE;
end if;
when S_NEXT_OPCODE =>
if idx = 3 then
ip <= ip + 1;
idx <= (others => '0');
state <= S_FETCH_REQ;
else
idx <= idx + 1;
state <= S_DECODE;
end if;
when S_HALT =>
-- HALT and ERROR are sticky terminal states until external reset.
halted_reg <= '1';
state <= S_HALT;
when S_ERROR =>
error_reg <= '1';
state <= S_ERROR;
end case;
end if;
end if;
end process;
end architecture;
|
Added ilo-vm/vhdl/rtl/ilo_memory.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use work.ilo_pkg.all;
entity ilo_memory is
generic (
ROM_FILE : string := "";
READ_WAIT_CYCLES : natural := 0;
WRITE_WAIT_CYCLES : natural := 0;
POISON_UNINITIALIZED : boolean := false
);
port (
clk : in std_logic;
req : in std_logic;
we : in std_logic;
addr : in addr_t;
wdata : in cell_t;
rdata : out cell_t;
ready : out std_logic;
reload_req : in std_logic;
reload_ready : out std_logic
);
end entity;
architecture rtl of ilo_memory is
type state_t is (S_IDLE, S_WAIT, S_READY, S_WAIT_RELEASE);
signal ram : mem_array_t := (others => CELL_ZERO);
signal rdata_reg : cell_t := CELL_ZERO;
signal ready_reg : std_logic := '0';
signal reload_ready_reg : std_logic := '0';
signal state : state_t := S_IDLE;
signal wait_count : natural := 0;
-- synthesis translate_off
constant POISON_CELL : cell_t := to_signed(-559038737, CELL_WIDTH); -- 0xDEADBEEF
type mem_valid_array_t is array (0 to MEM_DEPTH - 1) of boolean;
-- synthesis translate_on
begin
rdata <= rdata_reg;
ready <= ready_reg;
reload_ready <= reload_ready_reg;
process(clk)
-- synthesis translate_off
file f : text;
variable l : line;
variable v : integer;
variable i : natural := 0;
variable initialized : boolean := false;
variable valid : mem_valid_array_t := (others => false);
-- synthesis translate_on
variable a : natural;
variable target_wait : natural;
begin
if rising_edge(clk) then
-- synthesis translate_off
if not initialized then
if ROM_FILE /= "" then
file_open(f, ROM_FILE, read_mode);
while not endfile(f) and i < MEM_DEPTH loop
readline(f, l);
read(l, v);
ram(i) <= to_signed(v, CELL_WIDTH);
valid(i) := true;
i := i + 1;
end loop;
file_close(f);
end if;
initialized := true;
end if;
-- synthesis translate_on
ready_reg <= '0';
reload_ready_reg <= '0';
if reload_req = '1' then
ready_reg <= '0';
reload_ready_reg <= '1';
state <= S_IDLE;
wait_count <= 0;
else
case state is
when S_IDLE =>
wait_count <= 0;
if req = '1' then
state <= S_WAIT;
end if;
when S_WAIT =>
if we = '1' then
target_wait := WRITE_WAIT_CYCLES;
else
target_wait := READ_WAIT_CYCLES;
end if;
if wait_count >= target_wait then
a := to_integer(addr);
if we = '1' then
ram(a) <= wdata;
rdata_reg <= wdata;
-- synthesis translate_off
valid(a) := true;
-- synthesis translate_on
else
-- synthesis translate_off
if POISON_UNINITIALIZED and not valid(a) then
rdata_reg <= POISON_CELL;
else
-- synthesis translate_on
rdata_reg <= ram(a);
-- synthesis translate_off
end if;
-- synthesis translate_on
end if;
ready_reg <= '1';
wait_count <= 0;
state <= S_READY;
else
wait_count <= wait_count + 1;
end if;
when S_READY =>
state <= S_WAIT_RELEASE;
when S_WAIT_RELEASE =>
if req = '0' then
state <= S_IDLE;
end if;
end case;
end if;
end if;
end process;
end architecture;
|
Added ilo-vm/vhdl/rtl/ilo_pkg.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package ilo_pkg is
constant CELL_WIDTH : natural := 32;
constant MEM_ADDR_WIDTH : natural := 16;
constant MEM_DEPTH : natural := 65536;
constant DS_DEPTH : natural := 32;
constant RS_DEPTH : natural := 256;
subtype cell_t is signed(CELL_WIDTH - 1 downto 0);
subtype addr_t is unsigned(MEM_ADDR_WIDTH - 1 downto 0);
type mem_array_t is array (0 to MEM_DEPTH - 1) of cell_t;
type ds_array_t is array (0 to DS_DEPTH - 1) of cell_t;
type rs_array_t is array (0 to RS_DEPTH - 1) of cell_t;
constant CELL_ZERO : cell_t := to_signed(0, CELL_WIDTH);
constant CELL_TRUE : cell_t := to_signed(-1, CELL_WIDTH);
constant OP_NOP : natural := 0;
constant OP_LI : natural := 1;
constant OP_DU : natural := 2;
constant OP_DR : natural := 3;
constant OP_SW : natural := 4;
constant OP_PU : natural := 5;
constant OP_PO : natural := 6;
constant OP_JU : natural := 7;
constant OP_CA : natural := 8;
constant OP_CC : natural := 9;
constant OP_CJ : natural := 10;
constant OP_RE : natural := 11;
constant OP_EQ : natural := 12;
constant OP_NE : natural := 13;
constant OP_LT : natural := 14;
constant OP_GT : natural := 15;
constant OP_FE : natural := 16;
constant OP_ST : natural := 17;
constant OP_AD : natural := 18;
constant OP_SU : natural := 19;
constant OP_MU : natural := 20;
constant OP_DI : natural := 21;
constant OP_AN : natural := 22;
constant OP_OR : natural := 23;
constant OP_XO : natural := 24;
constant OP_SL : natural := 25;
constant OP_SR : natural := 26;
constant OP_CP : natural := 27;
constant OP_CY : natural := 28;
constant OP_IO : natural := 29;
function bool_cell(value : boolean) return cell_t;
function cell_addr(value : cell_t) return addr_t;
function shift_amount(value : cell_t) return natural;
-- synthesis translate_off
type ds_debug_array_t is array (0 to DS_DEPTH) of cell_t;
type sim_debug_t is protected
procedure set_sp(value : natural);
procedure set_rp(value : natural);
procedure set_ds(index : natural; value : cell_t);
impure function get_sp return natural;
impure function get_rp return natural;
impure function get_ds(index : natural) return cell_t;
end protected sim_debug_t;
shared variable sim_debug : sim_debug_t;
-- synthesis translate_on
end package;
package body ilo_pkg is
function bool_cell(value : boolean) return cell_t is
begin
if value then
return CELL_TRUE;
end if;
return CELL_ZERO;
end function;
function cell_addr(value : cell_t) return addr_t is
begin
return unsigned(std_logic_vector(value(15 downto 0)));
end function;
function shift_amount(value : cell_t) return natural is
variable raw : unsigned(4 downto 0);
begin
raw := unsigned(std_logic_vector(value(4 downto 0)));
return to_integer(raw);
end function;
-- synthesis translate_off
type sim_debug_t is protected body
variable sp_value : natural := 0;
variable rp_value : natural := 0;
variable ds_value : ds_debug_array_t := (others => CELL_ZERO);
procedure set_sp(value : natural) is
begin
sp_value := value;
end procedure;
procedure set_rp(value : natural) is
begin
rp_value := value;
end procedure;
procedure set_ds(index : natural; value : cell_t) is
begin
if index <= DS_DEPTH then
ds_value(index) := value;
end if;
end procedure;
impure function get_sp return natural is
begin
return sp_value;
end function;
impure function get_rp return natural is
begin
return rp_value;
end function;
impure function get_ds(index : natural) return cell_t is
begin
if index <= DS_DEPTH then
return ds_value(index);
end if;
return CELL_ZERO;
end function;
end protected body sim_debug_t;
-- synthesis translate_on
end package body;
|
Added ilo-vm/vhdl/rtl/ilo_sdram_controller.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.ilo_pkg.all;
entity ilo_sdram_controller is
generic (
INIT_WAIT_CYCLES : natural := 10000;
REFRESH_INTERVAL_CYCLES : natural := 390;
TRCD_CYCLES : natural := 1;
TRP_CYCLES : natural := 1;
TRFC_CYCLES : natural := 4;
TMRD_CYCLES : natural := 2;
READ_WAIT_CYCLES : natural := 3;
WRITE_RECOVERY_CYCLES : natural := 2
);
port (
clk : in std_logic;
reset : in std_logic;
req : in std_logic;
we : in std_logic;
addr : in addr_t;
wdata : in cell_t;
rdata : out cell_t;
ready : out std_logic;
reload_req : in std_logic;
reload_ready : out std_logic;
sdram_a : out unsigned(12 downto 0);
sdram_ba : out unsigned(1 downto 0);
sdram_dq : inout std_logic_vector(15 downto 0);
sdram_dqm : out std_logic_vector(1 downto 0);
sdram_csn : out std_logic;
sdram_cke : out std_logic;
sdram_clk : out std_logic;
sdram_wen : out std_logic;
sdram_casn : out std_logic;
sdram_rasn : out std_logic
);
end entity;
architecture rtl of ilo_sdram_controller is
type state_t is (
S_INIT_WAIT,
S_INIT_PRECHARGE,
S_INIT_PRECHARGE_WAIT,
S_INIT_REFRESH_1,
S_INIT_REFRESH_1_WAIT,
S_INIT_REFRESH_2,
S_INIT_REFRESH_2_WAIT,
S_INIT_MODE,
S_INIT_MODE_WAIT,
S_IDLE,
S_REFRESH,
S_REFRESH_WAIT,
S_ACTIVE,
S_ACTIVE_WAIT,
S_READ_CMD,
S_READ_WAIT,
S_READ_SAMPLE,
S_WRITE_CMD,
S_WRITE_WAIT,
S_DONE,
S_WAIT_RELEASE
);
constant CMD_DESELECT : std_logic_vector(3 downto 0) := "1111";
constant CMD_NOP : std_logic_vector(3 downto 0) := "0111";
constant CMD_ACTIVE : std_logic_vector(3 downto 0) := "0011";
constant CMD_READ : std_logic_vector(3 downto 0) := "0101";
constant CMD_WRITE : std_logic_vector(3 downto 0) := "0100";
constant CMD_PRECHARGE: std_logic_vector(3 downto 0) := "0010";
constant CMD_REFRESH : std_logic_vector(3 downto 0) := "0001";
constant CMD_MODE : std_logic_vector(3 downto 0) := "0000";
signal state : state_t := S_INIT_WAIT;
signal wait_count : natural := 0;
signal refresh_count : natural := 0;
signal latched_we : std_logic := '0';
signal latched_addr : addr_t := (others => '0');
signal latched_wdata : cell_t := CELL_ZERO;
signal half_index : std_logic := '0';
signal rdata_reg : cell_t := CELL_ZERO;
signal ready_reg : std_logic := '0';
signal reload_ready_reg : std_logic := '0';
signal sdram_a_reg : unsigned(12 downto 0) := (others => '0');
signal sdram_ba_reg : unsigned(1 downto 0) := (others => '0');
signal sdram_dq_out : std_logic_vector(15 downto 0) := (others => '0');
signal sdram_dq_drive : std_logic := '0';
signal sdram_dqm_reg : std_logic_vector(1 downto 0) := (others => '0');
signal sdram_cmd : std_logic_vector(3 downto 0) := CMD_DESELECT;
signal sdram_cke_reg : std_logic := '0';
function halfword_addr(word_addr : addr_t; half_sel : std_logic) return unsigned is
variable result : unsigned(MEM_ADDR_WIDTH downto 0);
begin
result := word_addr & half_sel;
return result;
end function;
function row_addr(word_addr : addr_t; half_sel : std_logic) return unsigned is
variable h : unsigned(MEM_ADDR_WIDTH downto 0);
variable result : unsigned(12 downto 0) := (others => '0');
begin
h := halfword_addr(word_addr, half_sel);
result(5 downto 0) := h(16 downto 11);
return result;
end function;
function col_addr(word_addr : addr_t; half_sel : std_logic) return unsigned is
variable h : unsigned(MEM_ADDR_WIDTH downto 0);
variable result : unsigned(12 downto 0) := (others => '0');
begin
h := halfword_addr(word_addr, half_sel);
result(8 downto 0) := h(8 downto 0);
result(10) := '1';
return result;
end function;
function bank_addr(word_addr : addr_t; half_sel : std_logic) return unsigned is
variable h : unsigned(MEM_ADDR_WIDTH downto 0);
begin
h := halfword_addr(word_addr, half_sel);
return h(10 downto 9);
end function;
function select_half(value : cell_t; half_sel : std_logic) return std_logic_vector is
variable bits : std_logic_vector(CELL_WIDTH - 1 downto 0);
begin
bits := std_logic_vector(value);
if half_sel = '0' then
return bits(15 downto 0);
end if;
return bits(31 downto 16);
end function;
begin
rdata <= rdata_reg;
ready <= ready_reg;
reload_ready <= reload_ready_reg;
sdram_a <= sdram_a_reg;
sdram_ba <= sdram_ba_reg;
sdram_dq <= sdram_dq_out when sdram_dq_drive = '1' else (others => 'Z');
sdram_dqm <= sdram_dqm_reg;
sdram_csn <= sdram_cmd(3);
sdram_rasn <= sdram_cmd(2);
sdram_casn <= sdram_cmd(1);
sdram_wen <= sdram_cmd(0);
sdram_cke <= sdram_cke_reg;
sdram_clk <= clk;
process(clk)
variable rbits : std_logic_vector(CELL_WIDTH - 1 downto 0);
begin
if rising_edge(clk) then
ready_reg <= '0';
reload_ready_reg <= '0';
sdram_cmd <= CMD_NOP;
sdram_dq_drive <= '0';
sdram_dqm_reg <= (others => '0');
if reset = '1' then
state <= S_INIT_WAIT;
wait_count <= 0;
refresh_count <= 0;
latched_we <= '0';
latched_addr <= (others => '0');
latched_wdata <= CELL_ZERO;
half_index <= '0';
rdata_reg <= CELL_ZERO;
sdram_a_reg <= (others => '0');
sdram_ba_reg <= (others => '0');
sdram_dq_out <= (others => '0');
sdram_cmd <= CMD_DESELECT;
sdram_cke_reg <= '0';
else
if state /= S_INIT_WAIT and state /= S_INIT_PRECHARGE and
state /= S_INIT_PRECHARGE_WAIT and state /= S_INIT_REFRESH_1 and
state /= S_INIT_REFRESH_1_WAIT and state /= S_INIT_REFRESH_2 and
state /= S_INIT_REFRESH_2_WAIT and state /= S_INIT_MODE and
state /= S_INIT_MODE_WAIT and state /= S_REFRESH and
state /= S_REFRESH_WAIT then
if refresh_count < REFRESH_INTERVAL_CYCLES then
refresh_count <= refresh_count + 1;
end if;
end if;
case state is
when S_INIT_WAIT =>
sdram_cke_reg <= '1';
if wait_count >= INIT_WAIT_CYCLES then
wait_count <= 0;
state <= S_INIT_PRECHARGE;
else
wait_count <= wait_count + 1;
end if;
when S_INIT_PRECHARGE =>
sdram_cmd <= CMD_PRECHARGE;
sdram_a_reg <= (others => '0');
sdram_a_reg(10) <= '1';
wait_count <= 0;
state <= S_INIT_PRECHARGE_WAIT;
when S_INIT_PRECHARGE_WAIT =>
if wait_count >= TRP_CYCLES then
wait_count <= 0;
state <= S_INIT_REFRESH_1;
else
wait_count <= wait_count + 1;
end if;
when S_INIT_REFRESH_1 =>
sdram_cmd <= CMD_REFRESH;
wait_count <= 0;
state <= S_INIT_REFRESH_1_WAIT;
when S_INIT_REFRESH_1_WAIT =>
if wait_count >= TRFC_CYCLES then
wait_count <= 0;
state <= S_INIT_REFRESH_2;
else
wait_count <= wait_count + 1;
end if;
when S_INIT_REFRESH_2 =>
sdram_cmd <= CMD_REFRESH;
wait_count <= 0;
state <= S_INIT_REFRESH_2_WAIT;
when S_INIT_REFRESH_2_WAIT =>
if wait_count >= TRFC_CYCLES then
wait_count <= 0;
state <= S_INIT_MODE;
else
wait_count <= wait_count + 1;
end if;
when S_INIT_MODE =>
sdram_cmd <= CMD_MODE;
sdram_ba_reg <= (others => '0');
sdram_a_reg <= (others => '0');
sdram_a_reg(6 downto 4) <= "010";
wait_count <= 0;
state <= S_INIT_MODE_WAIT;
when S_INIT_MODE_WAIT =>
if wait_count >= TMRD_CYCLES then
wait_count <= 0;
refresh_count <= 0;
state <= S_IDLE;
else
wait_count <= wait_count + 1;
end if;
when S_IDLE =>
if refresh_count >= REFRESH_INTERVAL_CYCLES then
state <= S_REFRESH;
elsif reload_req = '1' then
reload_ready_reg <= '1';
elsif req = '1' then
latched_we <= we;
latched_addr <= addr;
latched_wdata <= wdata;
half_index <= '0';
state <= S_ACTIVE;
end if;
when S_REFRESH =>
sdram_cmd <= CMD_REFRESH;
wait_count <= 0;
refresh_count <= 0;
state <= S_REFRESH_WAIT;
when S_REFRESH_WAIT =>
if wait_count >= TRFC_CYCLES then
wait_count <= 0;
state <= S_IDLE;
else
wait_count <= wait_count + 1;
end if;
when S_ACTIVE =>
sdram_cmd <= CMD_ACTIVE;
sdram_a_reg <= row_addr(latched_addr, half_index);
sdram_ba_reg <= bank_addr(latched_addr, half_index);
wait_count <= 0;
state <= S_ACTIVE_WAIT;
when S_ACTIVE_WAIT =>
if wait_count >= TRCD_CYCLES then
wait_count <= 0;
if latched_we = '1' then
state <= S_WRITE_CMD;
else
state <= S_READ_CMD;
end if;
else
wait_count <= wait_count + 1;
end if;
when S_READ_CMD =>
sdram_cmd <= CMD_READ;
sdram_a_reg <= col_addr(latched_addr, half_index);
sdram_ba_reg <= bank_addr(latched_addr, half_index);
wait_count <= 0;
state <= S_READ_WAIT;
when S_READ_WAIT =>
if wait_count >= READ_WAIT_CYCLES then
wait_count <= 0;
state <= S_READ_SAMPLE;
else
wait_count <= wait_count + 1;
end if;
when S_READ_SAMPLE =>
rbits := std_logic_vector(rdata_reg);
if half_index = '0' then
rbits(15 downto 0) := sdram_dq;
half_index <= '1';
rdata_reg <= signed(rbits);
state <= S_ACTIVE;
else
rbits(31 downto 16) := sdram_dq;
rdata_reg <= signed(rbits);
state <= S_DONE;
end if;
when S_WRITE_CMD =>
sdram_cmd <= CMD_WRITE;
sdram_a_reg <= col_addr(latched_addr, half_index);
sdram_ba_reg <= bank_addr(latched_addr, half_index);
sdram_dq_out <= select_half(latched_wdata, half_index);
sdram_dq_drive <= '1';
wait_count <= 0;
state <= S_WRITE_WAIT;
when S_WRITE_WAIT =>
if wait_count >= WRITE_RECOVERY_CYCLES then
wait_count <= 0;
if half_index = '0' then
half_index <= '1';
state <= S_ACTIVE;
else
rdata_reg <= latched_wdata;
state <= S_DONE;
end if;
else
wait_count <= wait_count + 1;
end if;
when S_DONE =>
ready_reg <= '1';
state <= S_WAIT_RELEASE;
when S_WAIT_RELEASE =>
if req = '0' then
state <= S_IDLE;
end if;
end case;
end if;
end if;
end process;
end architecture;
|
Added ilo-vm/vhdl/rtl/ilo_sram8_controller.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.ilo_pkg.all;
entity ilo_sram8_controller is
generic (
SRAM_ADDR_WIDTH : natural := 19;
READ_WAIT_CYCLES : natural := 1;
WRITE_WAIT_CYCLES : natural := 1
);
port (
clk : in std_logic;
reset : in std_logic;
req : in std_logic;
we : in std_logic;
addr : in addr_t;
wdata : in cell_t;
rdata : out cell_t;
ready : out std_logic;
reload_req : in std_logic;
reload_ready : out std_logic;
sram_addr : out unsigned(SRAM_ADDR_WIDTH - 1 downto 0);
sram_data : inout std_logic_vector(7 downto 0);
sram_ce_n : out std_logic;
sram_oe_n : out std_logic;
sram_we_n : out std_logic
);
end entity;
architecture rtl of ilo_sram8_controller is
type state_t is (
S_IDLE,
S_READ_SETUP,
S_READ_WAIT,
S_READ_SAMPLE,
S_WRITE_SETUP,
S_WRITE_PULSE,
S_WRITE_HOLD,
S_DONE,
S_WAIT_RELEASE
);
signal state : state_t := S_IDLE;
signal latched_we : std_logic := '0';
signal latched_addr : addr_t := (others => '0');
signal latched_wdata : cell_t := CELL_ZERO;
signal rdata_reg : cell_t := CELL_ZERO;
signal ready_reg : std_logic := '0';
signal reload_ready_reg : std_logic := '0';
signal byte_index : unsigned(1 downto 0) := (others => '0');
signal wait_count : natural := 0;
signal sram_addr_reg : unsigned(SRAM_ADDR_WIDTH - 1 downto 0) := (others => '0');
signal sram_dout_reg : std_logic_vector(7 downto 0) := (others => '0');
signal sram_drive_reg : std_logic := '0';
signal sram_ce_n_reg : std_logic := '1';
signal sram_oe_n_reg : std_logic := '1';
signal sram_we_n_reg : std_logic := '1';
function byte_addr(
word_addr : addr_t;
byte_sel : unsigned(1 downto 0);
width : natural
) return unsigned is
variable result : unsigned(width - 1 downto 0) := (others => '0');
variable raw : unsigned(word_addr'length + byte_sel'length - 1 downto 0);
begin
raw := word_addr & byte_sel;
result(raw'length - 1 downto 0) := raw;
return result;
end function;
function select_byte(value : cell_t; byte_sel : unsigned(1 downto 0)) return std_logic_vector is
variable bits : std_logic_vector(CELL_WIDTH - 1 downto 0);
begin
bits := std_logic_vector(value);
case byte_sel is
when "00" => return bits(7 downto 0);
when "01" => return bits(15 downto 8);
when "10" => return bits(23 downto 16);
when others => return bits(31 downto 24);
end case;
end function;
begin
rdata <= rdata_reg;
ready <= ready_reg;
reload_ready <= reload_ready_reg;
sram_addr <= sram_addr_reg;
sram_ce_n <= sram_ce_n_reg;
sram_oe_n <= sram_oe_n_reg;
sram_we_n <= sram_we_n_reg;
sram_data <= sram_dout_reg when sram_drive_reg = '1' else (others => 'Z');
process(clk)
variable rbits : std_logic_vector(CELL_WIDTH - 1 downto 0);
begin
if rising_edge(clk) then
ready_reg <= '0';
reload_ready_reg <= '0';
if reset = '1' then
state <= S_IDLE;
latched_we <= '0';
latched_addr <= (others => '0');
latched_wdata <= CELL_ZERO;
rdata_reg <= CELL_ZERO;
byte_index <= (others => '0');
wait_count <= 0;
sram_addr_reg <= (others => '0');
sram_dout_reg <= (others => '0');
sram_drive_reg <= '0';
sram_ce_n_reg <= '1';
sram_oe_n_reg <= '1';
sram_we_n_reg <= '1';
else
case state is
when S_IDLE =>
sram_drive_reg <= '0';
sram_ce_n_reg <= '1';
sram_oe_n_reg <= '1';
sram_we_n_reg <= '1';
if reload_req = '1' then
reload_ready_reg <= '1';
elsif req = '1' then
latched_we <= we;
latched_addr <= addr;
latched_wdata <= wdata;
byte_index <= (others => '0');
if we = '1' then
state <= S_WRITE_SETUP;
else
state <= S_READ_SETUP;
end if;
end if;
when S_READ_SETUP =>
sram_addr_reg <= byte_addr(latched_addr, byte_index, SRAM_ADDR_WIDTH);
sram_drive_reg <= '0';
sram_ce_n_reg <= '0';
sram_oe_n_reg <= '0';
sram_we_n_reg <= '1';
wait_count <= 0;
state <= S_READ_WAIT;
when S_READ_WAIT =>
if wait_count >= READ_WAIT_CYCLES then
state <= S_READ_SAMPLE;
else
wait_count <= wait_count + 1;
end if;
when S_READ_SAMPLE =>
rbits := std_logic_vector(rdata_reg);
case byte_index is
when "00" => rbits(7 downto 0) := sram_data;
when "01" => rbits(15 downto 8) := sram_data;
when "10" => rbits(23 downto 16) := sram_data;
when others => rbits(31 downto 24) := sram_data;
end case;
rdata_reg <= signed(rbits);
sram_oe_n_reg <= '1';
sram_ce_n_reg <= '1';
if byte_index = "11" then
state <= S_DONE;
else
byte_index <= byte_index + 1;
state <= S_READ_SETUP;
end if;
when S_WRITE_SETUP =>
sram_addr_reg <= byte_addr(latched_addr, byte_index, SRAM_ADDR_WIDTH);
sram_dout_reg <= select_byte(latched_wdata, byte_index);
sram_drive_reg <= '1';
sram_ce_n_reg <= '0';
sram_oe_n_reg <= '1';
sram_we_n_reg <= '1';
wait_count <= 0;
state <= S_WRITE_PULSE;
when S_WRITE_PULSE =>
sram_we_n_reg <= '0';
if wait_count >= WRITE_WAIT_CYCLES then
wait_count <= 0;
state <= S_WRITE_HOLD;
else
wait_count <= wait_count + 1;
end if;
when S_WRITE_HOLD =>
sram_we_n_reg <= '1';
sram_ce_n_reg <= '1';
sram_drive_reg <= '0';
if byte_index = "11" then
rdata_reg <= latched_wdata;
state <= S_DONE;
else
byte_index <= byte_index + 1;
state <= S_WRITE_SETUP;
end if;
when S_DONE =>
ready_reg <= '1';
if latched_we = '1' then
rdata_reg <= latched_wdata;
end if;
state <= S_WAIT_RELEASE;
when S_WAIT_RELEASE =>
sram_drive_reg <= '0';
sram_ce_n_reg <= '1';
sram_oe_n_reg <= '1';
sram_we_n_reg <= '1';
if req = '0' then
state <= S_IDLE;
end if;
end case;
end if;
end if;
end process;
end architecture;
|
Added ilo-vm/vhdl/rtl/ilo_system.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.ilo_pkg.all;
entity ilo_system is
generic (
ROM_FILE : string := "";
BLOCK_FILE : string := "";
BLOCK_CELLS : natural := 1024;
MEM_READ_WAIT_CYCLES : natural := 0;
MEM_WRITE_WAIT_CYCLES : natural := 0;
BLOCK_READ_WAIT_CYCLES : natural := 0;
BLOCK_WRITE_WAIT_CYCLES : natural := 0;
RESET_CYCLES : natural := 4;
STRICT_ERRORS : boolean := true;
POISON_UNINITIALIZED : boolean := false
);
port (
clk : in std_logic;
reset : in std_logic;
serial_tx_valid : out std_logic;
serial_tx_data : out std_logic_vector(7 downto 0);
serial_rx_req : out std_logic;
serial_rx_valid : in std_logic;
serial_rx_data : in std_logic_vector(7 downto 0);
halted : out std_logic;
errored : out std_logic;
error_code : out unsigned(7 downto 0)
);
end entity;
architecture rtl of ilo_system is
signal core_reset : std_logic := '1';
signal reset_count : natural range 0 to RESET_CYCLES := RESET_CYCLES;
signal mem_req : std_logic;
signal mem_we : std_logic;
signal mem_addr : addr_t;
signal mem_wdata : cell_t;
signal mem_rdata : cell_t;
signal mem_ready : std_logic;
signal block_req : std_logic;
signal block_we : std_logic;
signal block_addr : unsigned(31 downto 0);
signal block_wdata : cell_t;
signal block_rdata : cell_t;
signal block_ready : std_logic;
signal reload_req : std_logic;
signal reload_ready : std_logic;
begin
process(clk)
begin
if rising_edge(clk) then
if reset = '1' then
core_reset <= '1';
reset_count <= RESET_CYCLES;
elsif reset_count = 0 then
core_reset <= '0';
else
reset_count <= reset_count - 1;
core_reset <= '1';
end if;
end if;
end process;
core_i : entity work.ilo_core
generic map (
STRICT_ERRORS => STRICT_ERRORS
)
port map (
clk => clk,
reset => core_reset,
mem_req => mem_req,
mem_we => mem_we,
mem_addr => mem_addr,
mem_wdata => mem_wdata,
mem_rdata => mem_rdata,
mem_ready => mem_ready,
serial_tx_valid => serial_tx_valid,
serial_tx_data => serial_tx_data,
serial_tx_ready => '1',
serial_rx_req => serial_rx_req,
serial_rx_valid => serial_rx_valid,
serial_rx_data => serial_rx_data,
block_req => block_req,
block_we => block_we,
block_addr => block_addr,
block_wdata => block_wdata,
block_rdata => block_rdata,
block_ready => block_ready,
reload_req => reload_req,
reload_ready => reload_ready,
halted => halted,
errored => errored,
error_code => error_code
);
memory_i : entity work.ilo_memory
generic map (
ROM_FILE => ROM_FILE,
READ_WAIT_CYCLES => MEM_READ_WAIT_CYCLES,
WRITE_WAIT_CYCLES => MEM_WRITE_WAIT_CYCLES,
POISON_UNINITIALIZED => POISON_UNINITIALIZED
)
port map (
clk => clk,
req => mem_req,
we => mem_we,
addr => mem_addr,
wdata => mem_wdata,
rdata => mem_rdata,
ready => mem_ready,
reload_req => reload_req,
reload_ready => reload_ready
);
block_i : entity work.ilo_block_store
generic map (
BLOCK_FILE => BLOCK_FILE,
BLOCK_CELLS => BLOCK_CELLS,
READ_WAIT_CYCLES => BLOCK_READ_WAIT_CYCLES,
WRITE_WAIT_CYCLES => BLOCK_WRITE_WAIT_CYCLES,
POISON_UNINITIALIZED => POISON_UNINITIALIZED
)
port map (
clk => clk,
req => block_req,
we => block_we,
addr => block_addr,
wdata => block_wdata,
rdata => block_rdata,
ready => block_ready
);
end architecture;
|
Added ilo-vm/vhdl/rtl/ilo_uart_rx.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ilo_uart_rx is
generic (
CLKS_PER_BIT : positive := 104
);
port (
clk : in std_logic;
reset : in std_logic;
rx : in std_logic;
take : in std_logic;
data_valid: out std_logic;
data : out std_logic_vector(7 downto 0)
);
end entity;
architecture rtl of ilo_uart_rx is
type state_t is (S_IDLE, S_START, S_DATA, S_STOP);
signal rx_meta : std_logic := '1';
signal rx_sync : std_logic := '1';
signal state : state_t := S_IDLE;
signal clk_count : natural range 0 to CLKS_PER_BIT - 1 := 0;
signal bit_index : natural range 0 to 7 := 0;
signal shifter : std_logic_vector(7 downto 0) := (others => '0');
signal data_reg : std_logic_vector(7 downto 0) := (others => '0');
signal valid_reg : std_logic := '0';
begin
data_valid <= valid_reg;
data <= data_reg;
process(clk)
begin
if rising_edge(clk) then
rx_meta <= rx;
rx_sync <= rx_meta;
if reset = '1' then
state <= S_IDLE;
clk_count <= 0;
bit_index <= 0;
shifter <= (others => '0');
data_reg <= (others => '0');
valid_reg <= '0';
else
if take = '1' then
valid_reg <= '0';
end if;
case state is
when S_IDLE =>
clk_count <= 0;
bit_index <= 0;
if rx_sync = '0' then
state <= S_START;
end if;
when S_START =>
if clk_count = (CLKS_PER_BIT - 1) / 2 then
if rx_sync = '0' then
clk_count <= 0;
state <= S_DATA;
else
state <= S_IDLE;
end if;
else
clk_count <= clk_count + 1;
end if;
when S_DATA =>
if clk_count = CLKS_PER_BIT - 1 then
clk_count <= 0;
shifter(bit_index) <= rx_sync;
if bit_index = 7 then
bit_index <= 0;
state <= S_STOP;
else
bit_index <= bit_index + 1;
end if;
else
clk_count <= clk_count + 1;
end if;
when S_STOP =>
if clk_count = CLKS_PER_BIT - 1 then
clk_count <= 0;
if valid_reg = '0' then
data_reg <= shifter;
valid_reg <= '1';
end if;
state <= S_IDLE;
else
clk_count <= clk_count + 1;
end if;
end case;
end if;
end if;
end process;
end architecture;
|
Added ilo-vm/vhdl/rtl/ilo_uart_tx.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ilo_uart_tx is
generic (
CLKS_PER_BIT : positive := 104
);
port (
clk : in std_logic;
reset : in std_logic;
data_valid: in std_logic;
data : in std_logic_vector(7 downto 0);
tx : out std_logic;
busy : out std_logic
);
end entity;
architecture rtl of ilo_uart_tx is
type state_t is (S_IDLE, S_START, S_DATA, S_STOP);
signal state : state_t := S_IDLE;
signal clk_count : natural range 0 to CLKS_PER_BIT - 1 := 0;
signal bit_index : natural range 0 to 7 := 0;
signal shifter : std_logic_vector(7 downto 0) := (others => '0');
signal tx_reg : std_logic := '1';
begin
tx <= tx_reg;
busy <= '0' when state = S_IDLE else '1';
process(clk)
begin
if rising_edge(clk) then
if reset = '1' then
state <= S_IDLE;
clk_count <= 0;
bit_index <= 0;
shifter <= (others => '0');
tx_reg <= '1';
else
case state is
when S_IDLE =>
tx_reg <= '1';
clk_count <= 0;
bit_index <= 0;
if data_valid = '1' then
shifter <= data;
state <= S_START;
end if;
when S_START =>
tx_reg <= '0';
if clk_count = CLKS_PER_BIT - 1 then
clk_count <= 0;
state <= S_DATA;
else
clk_count <= clk_count + 1;
end if;
when S_DATA =>
tx_reg <= shifter(bit_index);
if clk_count = CLKS_PER_BIT - 1 then
clk_count <= 0;
if bit_index = 7 then
bit_index <= 0;
state <= S_STOP;
else
bit_index <= bit_index + 1;
end if;
else
clk_count <= clk_count + 1;
end if;
when S_STOP =>
tx_reg <= '1';
if clk_count = CLKS_PER_BIT - 1 then
clk_count <= 0;
state <= S_IDLE;
else
clk_count <= clk_count + 1;
end if;
end case;
end if;
end if;
end process;
end architecture;
|
Added ilo-vm/vhdl/scripts/blocks-to-mem.sh.
> > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #!/bin/sh set -eu if [ "$#" -ne 2 ]; then echo "usage: $0 input.blocks output.blocks.mem" >&2 exit 2 fi input="$1" output="$2" mkdir -p "$(dirname "$output")" od -An -td4 -w4 -v "$input" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' > "$output" |
Added ilo-vm/vhdl/scripts/build-icepi-zero.sh.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
#!/bin/sh
set -eu
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
. "$SCRIPT_DIR/common.sh"
root="$VHDL_ROOT"
top="icepi_zero_top"
mode="smoke"
usage() {
cat >&2 <<EOF
Usage: $0 [--sdram]
Build the ICEPI Zero ECP5 bitstream.
--sdram build icepi_zero_sdram_top instead of the internal-memory smoke top
EOF
}
while [ "$#" -gt 0 ]; do
case "$1" in
--sdram)
top="icepi_zero_sdram_top"
mode="sdram"
;;
-h|--help)
usage
exit 0
;;
*)
usage
exit 2
;;
esac
shift
done
build="$root/build/icepi-zero/$mode"
missing=""
for tool in ghdl yosys nextpnr-ecp5 ecppack; do
if ! command -v "$tool" >/dev/null 2>&1; then
missing="${missing}${missing:+ }$tool"
fi
done
if [ -n "$missing" ]; then
printf 'Missing required ICEPI Zero build tools: %s\n' "$missing" >&2
printf 'Install OSS CAD Suite and add its bin directory to PATH.\n' >&2
printf 'Debian packages commonly include nextpnr-ice40 but not nextpnr-ecp5/ecppack.\n' >&2
exit 1
fi
mkdir -p "$build"
verilog="$build/$top.v"
json="$build/$top.json"
config="$build/$top.config"
bit="$build/$top.bit"
log="$build/build.log"
if [ "$mode" = "sdram" ]; then
set -- \
"$root/rtl/ilo_pkg.vhd" \
"$root/rtl/ilo_core.vhd" \
"$root/rtl/ilo_sdram_controller.vhd" \
"$root/rtl/ilo_byte_fifo.vhd" \
"$root/rtl/ilo_uart_tx.vhd" \
"$root/rtl/ilo_uart_rx.vhd" \
"$root/rtl/boards/$top.vhd"
else
set -- \
"$root/rtl/ilo_pkg.vhd" \
"$root/rtl/ilo_core.vhd" \
"$root/rtl/ilo_byte_fifo.vhd" \
"$root/rtl/ilo_uart_tx.vhd" \
"$root/rtl/ilo_uart_rx.vhd" \
"$root/rtl/boards/$top.vhd"
fi
echo "Translating VHDL top '$top' with GHDL..."
ghdl --synth --std=08 --out=verilog "$@" -e "$top" > "$verilog"
echo "Running Yosys ECP5 synthesis..."
yosys -p "read_verilog -nolatches $verilog; synth_ecp5 -top $top -json $json" > "$log" 2>&1
cat "$log"
echo "Running nextpnr-ecp5..."
nextpnr-ecp5 --25k --package CABGA256 --lpf "$root/constraints/icepi_zero.lpf" --json "$json" --textcfg "$config" > "$build/nextpnr.log" 2>&1
cat "$build/nextpnr.log"
cat "$build/nextpnr.log" >> "$log"
echo "Packing bitstream..."
ecppack --compress "$config" "$bit" > "$build/ecppack.log" 2>&1
cat "$build/ecppack.log"
cat "$build/ecppack.log" >> "$log"
echo "Wrote:"
echo " $verilog"
echo " $json"
echo " $config"
echo " $bit"
echo " $log"
|
Added ilo-vm/vhdl/scripts/common.sh.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#!/bin/sh
if [ -z "${SCRIPT_DIR:-}" ]; then
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
fi
VHDL_ROOT="${VHDL_ROOT:-$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd)}"
find_ilo_vm_root() {
dir="$VHDL_ROOT"
while [ "$dir" != "/" ]; do
if [ -f "$dir/tools/pali.c" ] && [ -d "$dir/test-ilo" ]; then
printf '%s\n' "$dir"
return 0
fi
dir="$(dirname "$dir")"
done
return 1
}
if [ -z "${ILO_VM_ROOT:-}" ]; then
if ILO_VM_ROOT="$(find_ilo_vm_root)"; then
export ILO_VM_ROOT
else
ILO_VM_ROOT="$(CDPATH= cd -- "$VHDL_ROOT/../.." && pwd)"
export ILO_VM_ROOT
fi
fi
export VHDL_ROOT
|
Added ilo-vm/vhdl/scripts/compare-c-vhdl.sh.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
#!/bin/sh
set -eu
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
. "$SCRIPT_DIR/common.sh"
build="$VHDL_ROOT/build"
tool_build="$build/tools"
pali_tool="${PALI:-$ILO_VM_ROOT/tools/pali}"
ilo="${ILO:-$ILO_VM_ROOT/ilo}"
ilo_src="$ILO_VM_ROOT/ilo.c"
cd "$VHDL_ROOT"
mkdir -p "$build" "$tool_build"
if [ ! -x "$pali_tool" ]; then
pali_tool="$tool_build/pali"
cc "$ILO_VM_ROOT/tools/pali.c" -o "$pali_tool"
fi
if [ ! -x "$ilo" ]; then
ilo="$tool_build/ilo"
if [ ! -f "$ilo_src" ] && [ -f "$ILO_VM_ROOT/ilo-vm/ilo.c" ]; then
ilo_src="$ILO_VM_ROOT/ilo-vm/ilo.c"
fi
cc "$ilo_src" -o "$ilo"
fi
ghdl -a --std=08 "$VHDL_ROOT/rtl/ilo_pkg.vhd"
ghdl -a --std=08 "$VHDL_ROOT/rtl/ilo_memory.vhd"
ghdl -a --std=08 "$VHDL_ROOT/rtl/ilo_block_store.vhd"
ghdl -a --std=08 "$VHDL_ROOT/rtl/ilo_core.vhd"
ghdl -a --std=08 "$VHDL_ROOT/sim/ilo_tb.vhd"
ghdl -e --std=08 ilo_tb
if [ "$#" -eq 0 ]; then
set -- \
test-ilo/test-li.pali \
test-ilo/test-du.pali \
test-ilo/test-dr.pali \
test-ilo/test-sw.pali \
test-ilo/test-pu-po.pali \
test-ilo/test-ad.pali \
test-ilo/test-su.pali \
test-ilo/test-mu.pali \
test-ilo/test-di.pali \
test-ilo/test-eq.pali \
test-ilo/test-ne.pali \
test-ilo/test-lt.pali \
test-ilo/test-gt.pali \
test-ilo/test-an.pali \
test-ilo/test-or.pali \
test-ilo/test-xo.pali \
test-ilo/test-sl.pali \
test-ilo/test-sr.pali \
test-ilo/test-ju.pali \
test-ilo/test-ca-re.pali \
test-ilo/test-cc.pali \
test-ilo/test-cj.pali \
test-ilo/test-fe-st.pali \
test-ilo/test-cp.pali \
test-ilo/test-cy.pali \
test-ilo/test-io-stack-depth.pali
fi
passed=0
failed=0
for pali in "$@"; do
test_name="$(basename "$pali" .pali)"
mem="$build/$test_name.mem"
rom="$build/$test_name.rom"
work="$build/compare-work"
"$VHDL_ROOT/scripts/pali-to-mem.sh" "$ILO_VM_ROOT/$pali" "$mem"
mkdir -p "$work"
(
cd "$work"
"$pali_tool" "$ILO_VM_ROOT/$pali" >/dev/null
cp ilo.rom "$rom"
)
c_stack="$(timeout 5s "$ilo" "$ILO_VM_ROOT/ilo.blocks" "$rom" 2>/dev/null | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
set +e
vhdl_output="$(ghdl -r --std=08 ilo_tb -gROM_FILE="$mem" --assert-level=error 2>&1)"
vhdl_status=$?
set -e
vhdl_stack="$(printf '%s\n' "$vhdl_output" | sed -n 's/^FINAL_STACK:[[:space:]]*//p' | tail -1 | sed 's/[[:space:]]*$//')"
if [ "$c_stack" = "$vhdl_stack" ]; then
printf 'PASS %s\n' "$test_name"
passed=$((passed + 1))
else
printf 'FAIL %s\n' "$test_name"
printf ' C: %s\n' "$c_stack"
printf ' VHDL: %s\n' "$vhdl_stack"
printf ' ghdl exit: %s\n' "$vhdl_status"
failed=$((failed + 1))
fi
done
printf '\nC/VHDL compare: %d passed, %d failed\n' "$passed" "$failed"
if [ "$failed" -ne 0 ]; then
exit 1
fi
|
Added ilo-vm/vhdl/scripts/pali-to-mem.sh.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#!/bin/sh
set -eu
if [ "$#" -ne 2 ]; then
echo "usage: $0 input.pali output.mem" >&2
exit 2
fi
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
. "$SCRIPT_DIR/common.sh"
input="$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
output="$(cd "$(dirname "$2")" && pwd)/$(basename "$2")"
work="$VHDL_ROOT/build/pali-work"
pali="${PALI:-$ILO_VM_ROOT/tools/pali}"
mkdir -p "$work" "$(dirname "$output")"
if [ ! -x "$pali" ]; then
pali="$VHDL_ROOT/build/tools/pali"
mkdir -p "$(dirname "$pali")"
cc "$ILO_VM_ROOT/tools/pali.c" -o "$pali"
fi
(
cd "$work"
"$pali" "$input" >/dev/null
)
od -An -td4 -w4 -v "$work/ilo.rom" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' > "$output"
|
Added ilo-vm/vhdl/scripts/rom-to-mem.sh.
> > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #!/bin/sh set -eu if [ "$#" -ne 2 ]; then echo "usage: $0 input.rom output.mem" >&2 exit 2 fi input="$1" output="$2" mkdir -p "$(dirname "$output")" od -An -td4 -w4 -v "$input" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' > "$output" |
Added ilo-vm/vhdl/scripts/run-ghdl-tests.sh.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 |
#!/bin/sh
set -eu
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
. "$SCRIPT_DIR/common.sh"
build="$VHDL_ROOT/build"
mem_read_wait_cycles="${MEM_READ_WAIT_CYCLES:-0}"
mem_write_wait_cycles="${MEM_WRITE_WAIT_CYCLES:-0}"
block_read_wait_cycles="${BLOCK_READ_WAIT_CYCLES:-0}"
block_write_wait_cycles="${BLOCK_WRITE_WAIT_CYCLES:-0}"
sram8_read_wait_cycles="${SRAM8_READ_WAIT_CYCLES:-1}"
sram8_write_wait_cycles="${SRAM8_WRITE_WAIT_CYCLES:-1}"
sram8_output_delay_ns="${SRAM8_OUTPUT_DELAY_NS:-1}"
poison_uninitialized="${POISON_UNINITIALIZED:-false}"
tests="test-li test-du test-dr test-sw test-pu-po test-ad test-su test-mu test-di test-eq test-ne test-lt test-gt test-an test-or test-xo test-sl test-sr test-ju test-ca-re test-cc test-cj test-fe-st test-cp test-cy test-io-stack-depth"
serial_tests="test-io-emit test-io-read"
block_tests="test-io-block-read test-io-block-write"
sdram_address_tests="test-sdram-address-boundaries"
system_tests="test-ad test-cp"
sdram_timing_violations="TRCD TRP TRFC CAS WRITE_RECOVERY REFRESH_INTERVAL INIT_READ INIT_WRITE INIT_PRECHARGE_BANK INIT_REFRESH_EARLY INIT_MODE_EARLY"
passed=0
failed=0
output=""
status=0
mkdir -p "$build"
run_capture() {
set +e
output="$("$@" 2>&1)"
status=$?
set -e
}
compile_pali() {
"$VHDL_ROOT/scripts/pali-to-mem.sh" "$1" "$2"
}
final_stack() {
printf '%s\n' "$1" | sed -n 's/^FINAL_STACK:[[:space:]]*//p' | tail -1 | sed 's/[[:space:]]*$//'
}
serial_tx() {
printf '%s\n' "$1" | sed -n 's/^SERIAL_TX:[[:space:]]*//p' | paste -sd ' ' -
}
core_expected() {
case "$1" in
test-li) printf '%s\n' "123 42" ;;
test-du) printf '%s\n' "42 42" ;;
test-dr) printf '%s\n' "42" ;;
test-sw) printf '%s\n' "42 123" ;;
test-pu-po) printf '%s\n' "42" ;;
test-ju) printf '%s\n' "42" ;;
test-ca-re) printf '%s\n' "999 42" ;;
test-cc) printf '%s\n' "999 42" ;;
test-cj) printf '%s\n' "42" ;;
test-eq) printf '%s\n' "0 -1" ;;
test-ne) printf '%s\n' "-1 0" ;;
test-lt) printf '%s\n' "0 -1" ;;
test-gt) printf '%s\n' "0 -1" ;;
test-fe-st) printf '%s\n' "42" ;;
test-ad) printf '%s\n' "65" ;;
test-su) printf '%s\n' "19" ;;
test-mu) printf '%s\n' "966" ;;
test-di) printf '%s\n' "0 23" ;;
test-an) printf '%s\n' "2" ;;
test-or) printf '%s\n' "63" ;;
test-xo) printf '%s\n' "61" ;;
test-sl) printf '%s\n' "168" ;;
test-sr) printf '%s\n' "10" ;;
test-cp) printf '%s\n' "0 -1" ;;
test-cy) printf '%s\n' "42" ;;
test-io-stack-depth) printf '%s\n' "0 2 23 42" ;;
*) printf '%s\n' "" ;;
esac
}
serial_expected_stack() {
case "$1" in
test-io-read) printf '%s\n' "65" ;;
*) printf '%s\n' "" ;;
esac
}
serial_expected_tx() {
case "$1" in
test-io-emit) printf '%s\n' "65" ;;
*) printf '%s\n' "" ;;
esac
}
serial_rx_text() {
case "$1" in
test-io-read) printf '%s\n' "A" ;;
*) printf '%s\n' "" ;;
esac
}
block_expected_stack() {
case "$1" in
test-io-block-read) printf '%s\n' "123" ;;
test-io-block-write) printf '%s\n' "77" ;;
*) printf '%s\n' "" ;;
esac
}
block_file() {
case "$1" in
test-io-block-read) printf '%s\n' "$VHDL_ROOT/testdata/block-read.blocks.mem" ;;
*) printf '%s\n' "" ;;
esac
}
sdram_address_expected_stack() {
case "$1" in
test-sdram-address-boundaries) printf '%s\n' "501 402 401 302 301 202 201 102 101" ;;
*) printf '%s\n' "" ;;
esac
}
sdram_timing_expected() {
case "$1" in
TRCD) printf '%s\n' "sdram_model: READ violates tRCD" ;;
TRP) printf '%s\n' "sdram_model: ACTIVE violates tRP" ;;
TRFC) printf '%s\n' "sdram_model: ACTIVE violates tRFC" ;;
CAS) printf '%s\n' "sdram_model: mode register CAS latency does not match model CAS_LATENCY" ;;
WRITE_RECOVERY) printf '%s\n' "sdram_model: ACTIVE violates write recovery" ;;
REFRESH_INTERVAL) printf '%s\n' "sdram_model: maximum refresh interval exceeded" ;;
INIT_READ) printf '%s\n' "sdram_model: READ before initialization complete" ;;
INIT_WRITE) printf '%s\n' "sdram_model: WRITE before initialization complete" ;;
INIT_PRECHARGE_BANK) printf '%s\n' "sdram_model: initialization requires PRECHARGE ALL" ;;
INIT_REFRESH_EARLY) printf '%s\n' "sdram_model: REFRESH before expected init step" ;;
INIT_MODE_EARLY) printf '%s\n' "sdram_model: MODE REGISTER SET before expected init step" ;;
*) printf '%s\n' "" ;;
esac
}
pass() {
printf 'PASS %s\n' "$1"
passed=$((passed + 1))
}
fail_output() {
printf 'FAIL %s\n' "$1"
printf '%s\n' "$output" | sed 's/^/ | /'
failed=$((failed + 1))
}
check_stack_result() {
label="$1"
want="$2"
got="$(final_stack "$output")"
if [ "$got" = "$want" ]; then
pass "$label"
else
printf 'FAIL %s\n' "$label"
printf ' expected: %s\n' "$want"
printf ' got: %s\n' "$got"
if [ "$status" -ne 1 ]; then
printf ' ghdl exit: %s\n' "$status"
fi
printf '%s\n' "$output" | sed 's/^/ | /'
failed=$((failed + 1))
fi
}
check_serial_result() {
label="$1"
want_stack="$2"
want_tx="$3"
got_stack="$(final_stack "$output")"
got_tx="$(serial_tx "$output")"
if [ "$got_stack" = "$want_stack" ] && [ "$got_tx" = "$want_tx" ]; then
pass "$label"
else
printf 'FAIL %s\n' "$label"
printf ' expected stack: %s\n' "$want_stack"
printf ' got stack: %s\n' "$got_stack"
printf ' expected tx: %s\n' "$want_tx"
printf ' got tx: %s\n' "$got_tx"
if [ "$status" -ne 1 ]; then
printf ' ghdl exit: %s\n' "$status"
fi
printf '%s\n' "$output" | sed 's/^/ | /'
failed=$((failed + 1))
fi
}
run_fast_tb() {
tb="$1"
mem="$2"
shift 2
run_capture ghdl -r --std=08 "$tb" \
-gROM_FILE="$mem" \
-gMEM_READ_WAIT_CYCLES="$mem_read_wait_cycles" \
-gMEM_WRITE_WAIT_CYCLES="$mem_write_wait_cycles" \
-gBLOCK_READ_WAIT_CYCLES="$block_read_wait_cycles" \
-gBLOCK_WRITE_WAIT_CYCLES="$block_write_wait_cycles" \
-gPOISON_UNINITIALIZED="$poison_uninitialized" \
"$@" --assert-level=error
}
run_strict_fast_tb() {
tb="$1"
mem="$2"
shift 2
run_capture ghdl -r --std=08 "$tb" \
-gROM_FILE="$mem" \
-gMEM_READ_WAIT_CYCLES="$mem_read_wait_cycles" \
-gMEM_WRITE_WAIT_CYCLES="$mem_write_wait_cycles" \
-gBLOCK_READ_WAIT_CYCLES="$block_read_wait_cycles" \
-gBLOCK_WRITE_WAIT_CYCLES="$block_write_wait_cycles" \
-gPOISON_UNINITIALIZED=true \
"$@" --assert-level=error
}
run_sram8_tb() {
tb="$1"
mem="$2"
shift 2
run_capture ghdl -r --std=08 "$tb" \
-gROM_FILE="$mem" \
-gREAD_WAIT_CYCLES="$sram8_read_wait_cycles" \
-gWRITE_WAIT_CYCLES="$sram8_write_wait_cycles" \
-gSRAM_OUTPUT_DELAY_NS="$sram8_output_delay_ns" \
-gBLOCK_READ_WAIT_CYCLES="$block_read_wait_cycles" \
-gBLOCK_WRITE_WAIT_CYCLES="$block_write_wait_cycles" \
-gPOISON_UNINITIALIZED="$poison_uninitialized" \
"$@" --assert-level=error
}
run_strict_sram8_tb() {
tb="$1"
mem="$2"
shift 2
run_capture ghdl -r --std=08 "$tb" \
-gROM_FILE="$mem" \
-gREAD_WAIT_CYCLES="$sram8_read_wait_cycles" \
-gWRITE_WAIT_CYCLES="$sram8_write_wait_cycles" \
-gSRAM_OUTPUT_DELAY_NS="$sram8_output_delay_ns" \
-gBLOCK_READ_WAIT_CYCLES="$block_read_wait_cycles" \
-gBLOCK_WRITE_WAIT_CYCLES="$block_write_wait_cycles" \
-gPOISON_UNINITIALIZED=true \
"$@" --assert-level=error
}
ghdl -a --std=08 "$VHDL_ROOT/rtl/ilo_pkg.vhd"
ghdl -a --std=08 "$VHDL_ROOT/rtl/ilo_memory.vhd"
ghdl -a --std=08 "$VHDL_ROOT/rtl/ilo_block_store.vhd"
ghdl -a --std=08 "$VHDL_ROOT/rtl/ilo_core.vhd"
ghdl -a --std=08 "$VHDL_ROOT/rtl/ilo_system.vhd"
ghdl -a --std=08 "$VHDL_ROOT/rtl/ilo_sram8_controller.vhd"
ghdl -a --std=08 "$VHDL_ROOT/rtl/ilo_sdram_controller.vhd"
ghdl -a --std=08 "$VHDL_ROOT/rtl/ilo_byte_fifo.vhd"
ghdl -a --std=08 "$VHDL_ROOT/rtl/ilo_uart_tx.vhd"
ghdl -a --std=08 "$VHDL_ROOT/rtl/ilo_uart_rx.vhd"
ghdl -a --std=08 "$VHDL_ROOT/rtl/boards/cmod_a7_top.vhd"
ghdl -a --std=08 "$VHDL_ROOT/rtl/boards/icepi_zero_top.vhd"
ghdl -a --std=08 "$VHDL_ROOT/rtl/boards/icepi_zero_sdram_top.vhd"
ghdl -a --std=08 "$VHDL_ROOT/sim/sram8_model.vhd"
ghdl -a --std=08 "$VHDL_ROOT/sim/sdram_model.vhd"
ghdl -a --std=08 "$VHDL_ROOT/sim/sdram_model_timing_tb.vhd"
ghdl -a --std=08 "$VHDL_ROOT/sim/ilo_tb.vhd"
ghdl -a --std=08 "$VHDL_ROOT/sim/ilo_system_tb.vhd"
ghdl -a --std=08 "$VHDL_ROOT/sim/ilo_sram8_tb.vhd"
ghdl -a --std=08 "$VHDL_ROOT/sim/ilo_sdram_tb.vhd"
ghdl -a --std=08 "$VHDL_ROOT/sim/ilo_reload_tb.vhd"
ghdl -a --std=08 "$VHDL_ROOT/sim/cmod_a7_top_tb.vhd"
ghdl -a --std=08 "$VHDL_ROOT/sim/icepi_zero_top_tb.vhd"
ghdl -a --std=08 "$VHDL_ROOT/sim/icepi_zero_sdram_top_tb.vhd"
ghdl -a --std=08 "$VHDL_ROOT/sim/ilo_sdram_controller_tb.vhd"
ghdl -a --std=08 "$VHDL_ROOT/sim/ilo_sdram_terminal_tb.vhd"
ghdl -e --std=08 ilo_tb
ghdl -e --std=08 ilo_system_tb
ghdl -e --std=08 ilo_sram8_tb
ghdl -e --std=08 ilo_sdram_tb
ghdl -e --std=08 ilo_reload_tb
ghdl -e --std=08 cmod_a7_top_tb
ghdl -e --std=08 icepi_zero_top_tb
ghdl -e --std=08 icepi_zero_sdram_top_tb
ghdl -e --std=08 ilo_sdram_controller_tb
ghdl -e --std=08 sdram_model_timing_tb
ghdl -e --std=08 ilo_sdram_terminal_tb
for test in $tests; do
mem="$build/$test.mem"
compile_pali "$ILO_VM_ROOT/test-ilo/$test.pali" "$mem"
run_fast_tb ilo_tb "$mem"
check_stack_result "$test" "$(core_expected "$test")"
done
for test in $tests; do
mem="$build/$test.mem"
compile_pali "$ILO_VM_ROOT/test-ilo/$test.pali" "$mem"
run_capture ghdl -r --std=08 ilo_sdram_tb -gROM_FILE="$mem" --assert-level=error
check_stack_result "sdram:$test" "$(core_expected "$test")"
done
for test in $serial_tests; do
mem="$build/$test.mem"
rx_text="$(serial_rx_text "$test")"
compile_pali "$VHDL_ROOT/testdata/$test.pali" "$mem"
if [ -n "$rx_text" ]; then
run_capture ghdl -r --std=08 ilo_sdram_tb -gROM_FILE="$mem" -gRX_TEXT="$rx_text" --assert-level=error
else
run_capture ghdl -r --std=08 ilo_sdram_tb -gROM_FILE="$mem" --assert-level=error
fi
check_serial_result "sdram:$test" "$(serial_expected_stack "$test")" "$(serial_expected_tx "$test")"
done
for test in $block_tests; do
mem="$build/$test.mem"
file="$(block_file "$test")"
compile_pali "$VHDL_ROOT/testdata/$test.pali" "$mem"
if [ -n "$file" ]; then
run_capture ghdl -r --std=08 ilo_sdram_tb -gROM_FILE="$mem" -gBLOCK_FILE="$file" -gMAX_CYCLES=2000000 --assert-level=error
else
run_capture ghdl -r --std=08 ilo_sdram_tb -gROM_FILE="$mem" -gMAX_CYCLES=2000000 --assert-level=error
fi
check_stack_result "sdram:$test" "$(block_expected_stack "$test")"
done
for test in $sdram_address_tests; do
mem="$build/$test.mem"
compile_pali "$VHDL_ROOT/testdata/$test.pali" "$mem"
run_capture ghdl -r --std=08 ilo_sdram_tb -gROM_FILE="$mem" -gMAX_CYCLES=2000000 --assert-level=error
check_stack_result "sdram:$test" "$(sdram_address_expected_stack "$test")"
done
printf '\nGHDL ilo tests: %d passed, %d failed\n' "$passed" "$failed"
for test in $serial_tests; do
mem="$build/$test.mem"
rx_text="$(serial_rx_text "$test")"
compile_pali "$VHDL_ROOT/testdata/$test.pali" "$mem"
if [ -n "$rx_text" ]; then
run_fast_tb ilo_tb "$mem" -gRX_TEXT="$rx_text"
else
run_fast_tb ilo_tb "$mem"
fi
check_serial_result "$test" "$(serial_expected_stack "$test")" "$(serial_expected_tx "$test")"
done
tx_ready_mem="$build/test-io-emit.mem"
run_fast_tb ilo_tb "$tx_ready_mem" -gTX_READY_DELAY_CYCLES=5000
check_serial_result "test-io-emit-tx-ready-delay" "" "65"
for test in $block_tests; do
mem="$build/$test.mem"
file="$(block_file "$test")"
compile_pali "$VHDL_ROOT/testdata/$test.pali" "$mem"
if [ -n "$file" ]; then
run_fast_tb ilo_tb "$mem" -gBLOCK_FILE="$file" -gMAX_CYCLES=200000
else
run_fast_tb ilo_tb "$mem" -gMAX_CYCLES=200000
fi
check_stack_result "$test" "$(block_expected_stack "$test")"
done
for test in $system_tests; do
mem="$build/$test.mem"
compile_pali "$ILO_VM_ROOT/test-ilo/$test.pali" "$mem"
run_fast_tb ilo_system_tb "$mem" -gRESET_CYCLES=7
check_stack_result "system:$test" "$(core_expected "$test")"
done
for test in $serial_tests; do
mem="$build/$test.mem"
rx_text="$(serial_rx_text "$test")"
compile_pali "$VHDL_ROOT/testdata/$test.pali" "$mem"
if [ -n "$rx_text" ]; then
run_fast_tb ilo_system_tb "$mem" -gRESET_CYCLES=7 -gRX_TEXT="$rx_text"
else
run_fast_tb ilo_system_tb "$mem" -gRESET_CYCLES=7
fi
check_serial_result "system:$test" "$(serial_expected_stack "$test")" "$(serial_expected_tx "$test")"
done
for test in $block_tests; do
mem="$build/$test.mem"
file="$(block_file "$test")"
compile_pali "$VHDL_ROOT/testdata/$test.pali" "$mem"
if [ -n "$file" ]; then
run_fast_tb ilo_system_tb "$mem" -gRESET_CYCLES=7 -gBLOCK_FILE="$file" -gMAX_CYCLES=200000
else
run_fast_tb ilo_system_tb "$mem" -gRESET_CYCLES=7 -gMAX_CYCLES=200000
fi
check_stack_result "system:$test" "$(block_expected_stack "$test")"
done
for test in $tests; do
mem="$build/$test.mem"
compile_pali "$ILO_VM_ROOT/test-ilo/$test.pali" "$mem"
run_sram8_tb ilo_sram8_tb "$mem"
check_stack_result "sram8:$test" "$(core_expected "$test")"
done
for test in $serial_tests; do
mem="$build/$test.mem"
rx_text="$(serial_rx_text "$test")"
compile_pali "$VHDL_ROOT/testdata/$test.pali" "$mem"
if [ -n "$rx_text" ]; then
run_sram8_tb ilo_sram8_tb "$mem" -gRX_TEXT="$rx_text"
else
run_sram8_tb ilo_sram8_tb "$mem"
fi
check_serial_result "sram8:$test" "$(serial_expected_stack "$test")" "$(serial_expected_tx "$test")"
done
for test in $block_tests; do
mem="$build/$test.mem"
file="$(block_file "$test")"
compile_pali "$VHDL_ROOT/testdata/$test.pali" "$mem"
if [ -n "$file" ]; then
run_sram8_tb ilo_sram8_tb "$mem" -gBLOCK_FILE="$file" -gMAX_CYCLES=500000
else
run_sram8_tb ilo_sram8_tb "$mem" -gMAX_CYCLES=500000
fi
check_stack_result "sram8:$test" "$(block_expected_stack "$test")"
done
reload_mem="$build/test-io-reload.mem"
compile_pali "$VHDL_ROOT/testdata/test-io-reload.pali" "$reload_mem"
run_capture ghdl -r --std=08 ilo_reload_tb \
-gROM_FILE="$reload_mem" \
-gMEM_READ_WAIT_CYCLES="$mem_read_wait_cycles" \
-gMEM_WRITE_WAIT_CYCLES="$mem_write_wait_cycles" \
-gPOISON_UNINITIALIZED="$poison_uninitialized" \
--assert-level=error
if [ "$status" -eq 0 ] && printf '%s\n' "$output" | grep -q "RELOAD PASS"; then
pass "test-io-reload"
else
fail_output "test-io-reload"
fi
run_capture ghdl -r --std=08 cmod_a7_top_tb --assert-level=error
if [ "$status" -eq 0 ] && printf '%s\n' "$output" | grep -q "CMOD_A7_SMOKE_TX: 65"; then
pass "cmod-a7-smoke"
else
fail_output "cmod-a7-smoke"
fi
run_capture ghdl -r --std=08 icepi_zero_top_tb --assert-level=error
if [ "$status" -eq 0 ] && printf '%s\n' "$output" | grep -q "ICEPI_ZERO_SMOKE_TX: 65"; then
pass "icepi-zero-smoke"
else
fail_output "icepi-zero-smoke"
fi
run_capture ghdl -r --std=08 icepi_zero_sdram_top_tb --assert-level=error
if [ "$status" -eq 0 ] && printf '%s\n' "$output" | grep -q "ICEPI_ZERO_SDRAM_SMOKE_TX: 65"; then
pass "icepi-zero-sdram-smoke"
else
fail_output "icepi-zero-sdram-smoke"
fi
run_capture ghdl -r --std=08 icepi_zero_sdram_top_tb -gTEST=UART_STRESS --assert-level=error
if [ "$status" -eq 0 ] && printf '%s\n' "$output" | grep -q "ICEPI_ZERO_SDRAM_UART_STRESS_TX: 21"; then
pass "icepi-zero-sdram-uart-stress"
else
fail_output "icepi-zero-sdram-uart-stress"
fi
board_boot_mem="$build/test-board-boot-preloaded.mem"
compile_pali "$VHDL_ROOT/testdata/test-board-boot-preloaded.pali" "$board_boot_mem"
run_capture ghdl -r --std=08 icepi_zero_sdram_top_tb -gTEST=PRELOADED -gBOOT_MEM_FILE="$board_boot_mem" --assert-level=error
if [ "$status" -eq 0 ] && printf '%s\n' "$output" | grep -q "ICEPI_ZERO_SDRAM_PRELOADED_BOOT_TX: 4"; then
pass "icepi-zero-sdram-preloaded-boot"
else
fail_output "icepi-zero-sdram-preloaded-boot"
fi
run_capture ghdl -r --std=08 icepi_zero_sdram_top_tb -gPROFILE=ICEPI --assert-level=error
if [ "$status" -eq 0 ] && printf '%s\n' "$output" | grep -q "ICEPI_ZERO_SDRAM_SMOKE_TX: 65"; then
pass "icepi-zero-sdram-icepi-profile"
else
fail_output "icepi-zero-sdram-icepi-profile"
fi
run_capture ghdl -r --std=08 ilo_sdram_controller_tb --assert-level=error
if [ "$status" -eq 0 ] && printf '%s\n' "$output" | grep -q "ILO_SDRAM_CONTROLLER_OK"; then
pass "sdram-controller"
else
fail_output "sdram-controller"
fi
for violation in $sdram_timing_violations; do
want="$(sdram_timing_expected "$violation")"
run_capture ghdl -r --std=08 sdram_model_timing_tb -gVIOLATION="$violation" --assert-level=error
if [ "$status" -ne 0 ] && printf '%s\n' "$output" | grep -q "$want"; then
pass "sdram-model-timing:$violation"
else
printf 'FAIL %s\n' "sdram-model-timing:$violation"
printf ' expected assertion: %s\n' "$want"
printf '%s\n' "$output" | sed 's/^/ | /'
failed=$((failed + 1))
fi
done
uninitialized_mem="$VHDL_ROOT/testdata/test-uninitialized-read.partial.mem"
for tb in ilo_tb ilo_system_tb ilo_sram8_tb; do
case "$tb" in
ilo_tb)
run_strict_fast_tb "$tb" "$uninitialized_mem"
;;
ilo_system_tb)
run_strict_fast_tb "$tb" "$uninitialized_mem" -gRESET_CYCLES=7
;;
*)
run_strict_sram8_tb "$tb" "$uninitialized_mem"
;;
esac
check_stack_result "$tb:test-uninitialized-read" "-559038737"
done
printf '\nGHDL ilo tests including serial, block, and reload I/O: %d passed, %d failed\n' "$passed" "$failed"
if [ "$failed" -ne 0 ]; then
exit 1
fi
|
Added ilo-vm/vhdl/scripts/run-ilo-rom-interactive.sh.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
#!/bin/sh
set -eu
use_sram8=""
use_sdram=""
case "${1:-}" in
--sram8)
use_sram8="1"
shift
;;
--sdram)
use_sdram="1"
shift
;;
esac
if [ "$#" -lt 1 ] || [ "$#" -gt 4 ]; then
echo "usage: $0 [--sram8|--sdram] rom-or-mem [blocks-or-blocks-mem] [max-cycles] [clock-period-ns]" >&2
exit 2
fi
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
. "$SCRIPT_DIR/common.sh"
build="$VHDL_ROOT/build"
rom_input="$1"
blocks_input="${2:-}"
max_cycles="${3:-0}"
clock_period_ns="${4:-10}"
rx_fifo="$build/terminal.rx"
tx_fifo="$build/terminal.tx"
log="$build/interactive-ghdl.log"
mem="$build/interactive.mem"
blocks_mem=""
block_cells="1024"
ghdl_pid=""
cleanup() {
if [ -n "$ghdl_pid" ] && kill -0 "$ghdl_pid" 2>/dev/null; then
kill "$ghdl_pid" 2>/dev/null || true
wait "$ghdl_pid" 2>/dev/null || true
fi
rm -f "$rx_fifo" "$tx_fifo"
}
trap cleanup EXIT INT TERM
mkdir -p "$build"
rm -f "$rx_fifo" "$tx_fifo"
mkfifo "$rx_fifo" "$tx_fifo"
if [ -n "$blocks_input" ] && [ "$#" -eq 2 ]; then
case "$blocks_input" in
*[!0-9]*)
;;
*)
max_cycles="$blocks_input"
blocks_input=""
;;
esac
fi
case "$clock_period_ns" in
''|*[!0-9]*)
echo "error: clock-period-ns must be a positive integer" >&2
exit 2
;;
0)
echo "error: clock-period-ns must be greater than zero" >&2
exit 2
;;
esac
case "$rom_input" in
*.mem)
mem="$rom_input"
;;
*)
"$VHDL_ROOT/scripts/rom-to-mem.sh" "$rom_input" "$mem"
;;
esac
if [ -n "$blocks_input" ]; then
case "$blocks_input" in
*.mem)
blocks_mem="$blocks_input"
;;
*)
blocks_mem="$build/interactive.blocks.mem"
"$VHDL_ROOT/scripts/blocks-to-mem.sh" "$blocks_input" "$blocks_mem"
;;
esac
block_cells="$(wc -l < "$blocks_mem" | tr -d '[:space:]')"
fi
ghdl -a --std=08 "$VHDL_ROOT/rtl/ilo_pkg.vhd"
ghdl -a --std=08 "$VHDL_ROOT/rtl/ilo_block_store.vhd"
ghdl -a --std=08 "$VHDL_ROOT/rtl/ilo_core.vhd"
: > "$log"
if [ -n "$use_sram8" ]; then
ghdl -a --std=08 "$VHDL_ROOT/rtl/ilo_sram8_controller.vhd"
ghdl -a --std=08 "$VHDL_ROOT/sim/sram8_model.vhd"
ghdl -a --std=08 "$VHDL_ROOT/sim/ilo_sram8_terminal_tb.vhd"
ghdl -e --std=08 ilo_sram8_terminal_tb
if [ -n "$blocks_mem" ]; then
ghdl -r --std=08 ilo_sram8_terminal_tb \
--max-stack-alloc=0 \
-gROM_FILE="$mem" \
-gBLOCK_FILE="$blocks_mem" \
-gBLOCK_CELLS="$block_cells" \
-gRX_FIFO="$rx_fifo" \
-gTX_FIFO="$tx_fifo" \
-gMAX_CYCLES="$max_cycles" \
-gCLOCK_PERIOD_NS="$clock_period_ns" \
--assert-level=error >"$log" 2>&1 &
else
ghdl -r --std=08 ilo_sram8_terminal_tb \
--max-stack-alloc=0 \
-gROM_FILE="$mem" \
-gBLOCK_CELLS="$block_cells" \
-gRX_FIFO="$rx_fifo" \
-gTX_FIFO="$tx_fifo" \
-gMAX_CYCLES="$max_cycles" \
-gCLOCK_PERIOD_NS="$clock_period_ns" \
--assert-level=error >"$log" 2>&1 &
fi
elif [ -n "$use_sdram" ]; then
ghdl -a --std=08 "$VHDL_ROOT/rtl/ilo_sdram_controller.vhd"
ghdl -a --std=08 "$VHDL_ROOT/sim/sdram_model.vhd"
ghdl -a --std=08 "$VHDL_ROOT/sim/ilo_sdram_terminal_tb.vhd"
ghdl -e --std=08 ilo_sdram_terminal_tb
if [ -n "$blocks_mem" ]; then
ghdl -r --std=08 ilo_sdram_terminal_tb \
--max-stack-alloc=0 \
-gROM_FILE="$mem" \
-gBLOCK_FILE="$blocks_mem" \
-gBLOCK_CELLS="$block_cells" \
-gRX_FIFO="$rx_fifo" \
-gTX_FIFO="$tx_fifo" \
-gMAX_CYCLES="$max_cycles" \
-gCLOCK_PERIOD_NS="$clock_period_ns" \
--assert-level=error >"$log" 2>&1 &
else
ghdl -r --std=08 ilo_sdram_terminal_tb \
--max-stack-alloc=0 \
-gROM_FILE="$mem" \
-gBLOCK_CELLS="$block_cells" \
-gRX_FIFO="$rx_fifo" \
-gTX_FIFO="$tx_fifo" \
-gMAX_CYCLES="$max_cycles" \
-gCLOCK_PERIOD_NS="$clock_period_ns" \
--assert-level=error >"$log" 2>&1 &
fi
else
ghdl -a --std=08 "$VHDL_ROOT/rtl/ilo_memory.vhd"
ghdl -a --std=08 "$VHDL_ROOT/sim/ilo_terminal_tb.vhd"
ghdl -e --std=08 ilo_terminal_tb
if [ -n "$blocks_mem" ]; then
ghdl -r --std=08 ilo_terminal_tb \
--max-stack-alloc=0 \
-gROM_FILE="$mem" \
-gBLOCK_FILE="$blocks_mem" \
-gBLOCK_CELLS="$block_cells" \
-gRX_FIFO="$rx_fifo" \
-gTX_FIFO="$tx_fifo" \
-gMAX_CYCLES="$max_cycles" \
-gCLOCK_PERIOD_NS="$clock_period_ns" \
--assert-level=error >"$log" 2>&1 &
else
ghdl -r --std=08 ilo_terminal_tb \
--max-stack-alloc=0 \
-gROM_FILE="$mem" \
-gBLOCK_CELLS="$block_cells" \
-gRX_FIFO="$rx_fifo" \
-gTX_FIFO="$tx_fifo" \
-gMAX_CYCLES="$max_cycles" \
-gCLOCK_PERIOD_NS="$clock_period_ns" \
--assert-level=error >"$log" 2>&1 &
fi
fi
ghdl_pid="$!"
python3 "$VHDL_ROOT/scripts/serial-bridge.py" --rx "$rx_fifo" --tx "$tx_fifo"
|
Added ilo-vm/vhdl/scripts/serial-bridge.py.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
#!/usr/bin/env python3
import argparse
import os
import select
import signal
import sys
import termios
import tty
def open_fifo(path):
return os.open(path, os.O_RDWR | os.O_NONBLOCK)
def echo_byte(byte):
if byte == 10:
os.write(sys.stdout.fileno(), b"\r\n")
elif byte == 8 or byte == 127:
os.write(sys.stdout.fileno(), b"\b \b")
else:
os.write(sys.stdout.fileno(), bytes([byte]))
def write_rx(fd, data):
for byte in data:
if byte == 3:
raise KeyboardInterrupt
if byte == 13:
byte = 10
os.write(fd, f"{byte}\n".encode("ascii"))
echo_byte(byte)
def drain_tx(fd, pending):
try:
chunk = os.read(fd, 4096)
except BlockingIOError:
return pending
if not chunk:
return pending
pending += chunk
while b"\n" in pending:
line, pending = pending.split(b"\n", 1)
line = line.strip()
if not line:
continue
try:
byte = int(line, 10) & 0xFF
except ValueError:
continue
os.write(sys.stdout.fileno(), bytes([byte]))
return pending
def main():
parser = argparse.ArgumentParser(description="Bridge a terminal to ilo GHDL serial FIFOs.")
parser.add_argument("--rx", required=True, help="FIFO receiving terminal input for VHDL")
parser.add_argument("--tx", required=True, help="FIFO carrying VHDL output bytes")
args = parser.parse_args()
rx_fd = open_fifo(args.rx)
tx_fd = open_fifo(args.tx)
stdin_fd = sys.stdin.fileno()
old_term = termios.tcgetattr(stdin_fd)
pending_tx = b""
def restore(*_):
termios.tcsetattr(stdin_fd, termios.TCSADRAIN, old_term)
os.close(rx_fd)
os.close(tx_fd)
signal.signal(signal.SIGTERM, restore)
try:
tty.setcbreak(stdin_fd)
os.write(sys.stdout.fileno(), b"\r\n[ilo serial bridge: Ctrl-C exits]\r\n")
while True:
readable, _, _ = select.select([stdin_fd, tx_fd], [], [])
if stdin_fd in readable:
data = os.read(stdin_fd, 1024)
if not data:
break
write_rx(rx_fd, data)
if tx_fd in readable:
pending_tx = drain_tx(tx_fd, pending_tx)
except KeyboardInterrupt:
pass
finally:
restore()
os.write(sys.stdout.fileno(), b"\r\n[ilo serial bridge closed]\r\n")
if __name__ == "__main__":
main()
|
Added ilo-vm/vhdl/scripts/synth-yosys.sh.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
#!/bin/sh
set -eu
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
. "$SCRIPT_DIR/common.sh"
root="$VHDL_ROOT"
build="$VHDL_ROOT/build/synth"
target="${1:-generic}"
top="${2:-ilo_core}"
mkdir -p "$build"
case "$target" in
generic|generic-opt|generic-full|ice40|ecp5|xc7)
set -- \
"$root/rtl/ilo_pkg.vhd" \
"$root/rtl/ilo_core.vhd"
;;
xc7+sram|xc7-sram)
target="xc7+sram"
top="${2:-cmod_a7_top}"
set -- \
"$root/rtl/ilo_pkg.vhd" \
"$root/rtl/ilo_core.vhd" \
"$root/rtl/ilo_sram8_controller.vhd" \
"$root/rtl/ilo_byte_fifo.vhd" \
"$root/rtl/ilo_uart_tx.vhd" \
"$root/rtl/ilo_uart_rx.vhd" \
"$root/rtl/boards/cmod_a7_top.vhd"
;;
*)
echo "usage: $0 [generic|generic-opt|generic-full|ice40|ecp5|xc7|xc7+sram] [top]" >&2
exit 2
;;
esac
verilog="$build/$top.v"
json="$build/$top-$target.json"
log="$build/$top-$target.log"
echo "Translating VHDL top '$top' with GHDL..."
ghdl --synth --std=08 --out=verilog "$@" -e "$top" > "$verilog"
case "$target" in
generic)
yosys_script="read_verilog -nolatches $verilog; hierarchy -check -top $top; proc; stat; write_json $json"
;;
generic-opt)
yosys_script="read_verilog -nolatches $verilog; hierarchy -check -top $top; proc; opt_expr; opt_clean; check; fsm; opt; wreduce; peepopt; opt_clean; alumacc; share; opt; memory -nomap; opt_clean; stat; write_json $json"
;;
generic-full)
yosys_script="read_verilog -nolatches $verilog; synth -top $top; stat; write_json $json"
;;
ice40)
yosys_script="read_verilog -nolatches $verilog; synth_ice40 -top $top -json $json"
;;
ecp5)
yosys_script="read_verilog -nolatches $verilog; synth_ecp5 -top $top -json $json"
;;
xc7|xc7+sram)
yosys_script="read_verilog -nolatches $verilog; synth_xilinx -family xc7 -top $top; write_json $json"
;;
esac
echo "Running Yosys target '$target'..."
yosys -p "$yosys_script" > "$log"
echo "Wrote:"
echo " $verilog"
echo " $json"
echo " $log"
echo
echo "Resource summary:"
if ! awk '
/^[0-9]+(\.[0-9]+)*\. Printing statistics\./ {
buf = $0 ORS
in_stats = 1
next
}
in_stats && (/^[0-9]+(\.[0-9]+)*\. Executing / || /^End of script\./) {
last = buf
buf = ""
in_stats = 0
next
}
in_stats {
buf = buf $0 ORS
}
END {
if (in_stats && buf != "")
last = buf
if (last == "")
exit 1
printf "%s", last
}
' "$log"; then
echo "No Yosys statistics block found in $log" >&2
fi
|
Added ilo-vm/vhdl/scripts/vivado-cmod-a7.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | set root [file normalize [file join [file dirname [info script]] ..]] set build_dir [file join $root build vivado cmod-a7] file mkdir $build_dir create_project -force ilo_cmod_a7 $build_dir -part xc7a35tcpg236-1 set_property target_language VHDL [current_project] add_files -norecurse [list \ [file join $root rtl ilo_pkg.vhd] \ [file join $root rtl ilo_core.vhd] \ [file join $root rtl ilo_sram8_controller.vhd] \ [file join $root rtl ilo_byte_fifo.vhd] \ [file join $root rtl ilo_uart_tx.vhd] \ [file join $root rtl ilo_uart_rx.vhd] \ [file join $root rtl boards cmod_a7_top.vhd] \ ] add_files -fileset constrs_1 -norecurse [file join $root constraints cmod_a7.xdc] set_property top cmod_a7_top [current_fileset] update_compile_order -fileset sources_1 synth_design -top cmod_a7_top -part xc7a35tcpg236-1 write_checkpoint -force [file join $build_dir post_synth.dcp] report_utilization -file [file join $build_dir utilization_synth.rpt] report_timing_summary -file [file join $build_dir timing_synth.rpt] opt_design place_design route_design write_checkpoint -force [file join $build_dir post_route.dcp] report_utilization -file [file join $build_dir utilization_route.rpt] report_timing_summary -file [file join $build_dir timing_route.rpt] write_bitstream -force [file join $build_dir ilo_cmod_a7.bit] |
Added ilo-vm/vhdl/sim/cmod_a7_top_tb.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use std.env.all;
entity cmod_a7_top_tb is
end entity;
architecture sim of cmod_a7_top_tb is
constant CLKS_PER_BIT : positive := 4;
signal sysclk : std_logic := '0';
signal btn : std_logic_vector(1 downto 0) := (others => '0');
signal led : std_logic_vector(1 downto 0);
signal led0_b : std_logic;
signal led0_g : std_logic;
signal led0_r : std_logic;
signal uart_rxd_out : std_logic := '1';
signal uart_txd_in : std_logic;
signal sram_addr : unsigned(18 downto 0);
signal sram_data : std_logic_vector(7 downto 0);
signal sram_ce_n : std_logic;
signal sram_oe_n : std_logic;
signal sram_we_n : std_logic;
signal done : boolean := false;
begin
sysclk <= not sysclk after 5 ns;
dut_i : entity work.cmod_a7_top
generic map (
UART_CLKS_PER_BIT => CLKS_PER_BIT,
RESET_CYCLES => 2
)
port map (
sysclk => sysclk,
btn => btn,
led => led,
led0_b => led0_b,
led0_g => led0_g,
led0_r => led0_r,
uart_rxd_out => uart_rxd_out,
uart_txd_in => uart_txd_in,
MemAdr => sram_addr,
MemDB => sram_data,
RamOEn => sram_oe_n,
RamWEn => sram_we_n,
RamCEn => sram_ce_n
);
sram_i : entity work.sram8_model
generic map (
ADDR_WIDTH => 19,
OUTPUT_DELAY_NS => 1
)
port map (
addr => sram_addr,
data => sram_data,
ce_n => sram_ce_n,
oe_n => sram_oe_n,
we_n => sram_we_n
);
process
begin
btn(0) <= '1';
wait for 80 ns;
wait until rising_edge(sysclk);
btn(0) <= '0';
wait;
end process;
process
variable value : std_logic_vector(7 downto 0);
variable l : line;
begin
wait until uart_txd_in = '0';
wait for 5 ns * CLKS_PER_BIT;
assert uart_txd_in = '0' report "UART start bit not stable" severity failure;
for i in 0 to 7 loop
wait for 10 ns * CLKS_PER_BIT;
value(i) := uart_txd_in;
end loop;
wait for 10 ns * CLKS_PER_BIT;
assert uart_txd_in = '1' report "UART stop bit not high" severity failure;
assert value = x"41" report "unexpected UART byte" severity failure;
wait until led(0) = '1';
assert led(1) = '0' report "core errored during Cmod smoke test" severity failure;
write(l, string'("CMOD_A7_SMOKE_TX: "));
write(l, to_integer(unsigned(value)));
writeline(output, l);
done <= true;
stop;
end process;
process
begin
wait for 100 us;
assert done report "Cmod A7 top smoke test timeout" severity failure;
wait;
end process;
end architecture;
|
Added ilo-vm/vhdl/sim/icepi_zero_sdram_top_tb.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use std.env.all;
entity icepi_zero_sdram_top_tb is
generic (
PROFILE : string := "FAST";
TEST : string := "SMOKE";
BOOT_MEM_FILE : string := ""
);
end entity;
architecture sim of icepi_zero_sdram_top_tb is
function profile_time(
constant fast_value : time;
constant icepi_value : time
) return time is
begin
if PROFILE = "ICEPI" then
return icepi_value;
end if;
return fast_value;
end function;
function profile_natural(
constant fast_value : natural;
constant icepi_value : natural
) return natural is
begin
if PROFILE = "ICEPI" then
return icepi_value;
end if;
return fast_value;
end function;
constant CLK_PERIOD : time := profile_time(10 ns, 20 ns);
constant CLKS_PER_BIT : positive := profile_natural(4, 434);
constant RESET_CYCLES : natural := profile_natural(2, 16);
constant SDRAM_INIT_WAIT_CYCLES : natural := profile_natural(4, 10000);
constant SDRAM_REFRESH_INTERVAL_CYCLES : natural := profile_natural(64, 390);
constant SDRAM_TRCD_CYCLES : natural := 1;
constant SDRAM_TRP_CYCLES : natural := 1;
constant SDRAM_TRFC_CYCLES : natural := profile_natural(2, 4);
constant SDRAM_TMRD_CYCLES : natural := profile_natural(1, 2);
constant SDRAM_READ_WAIT_CYCLES : natural := 3;
constant SDRAM_WRITE_RECOVERY_CYCLES : natural := profile_natural(1, 2);
constant TIMEOUT : time := profile_time(2 ms, 13 ms);
constant UART_STRESS_TX_COUNT : natural := 20;
constant UART_STRESS_RX_BYTE : natural := 122;
constant PRELOADED_TX_COUNT : natural := 4;
function expected_tx_count return natural is
begin
if TEST = "PRELOADED" then
return PRELOADED_TX_COUNT;
end if;
if TEST = "UART_STRESS" then
return UART_STRESS_TX_COUNT + 1;
end if;
return 1;
end function;
function expected_uart_byte(index : natural) return std_logic_vector is
begin
if TEST = "PRELOADED" then
case index is
when 0 => return x"42";
when 1 => return x"4F";
when 2 => return x"4F";
when others => return x"54";
end case;
end if;
if TEST = "UART_STRESS" then
if index < UART_STRESS_TX_COUNT then
return std_logic_vector(to_unsigned(65 + index, 8));
end if;
return std_logic_vector(to_unsigned(UART_STRESS_RX_BYTE, 8));
end if;
return x"41";
end function;
procedure uart_send_byte(
signal rx : out std_logic;
constant value : std_logic_vector(7 downto 0)
) is
begin
rx <= '0';
wait for CLK_PERIOD * CLKS_PER_BIT;
for i in 0 to 7 loop
rx <= value(i);
wait for CLK_PERIOD * CLKS_PER_BIT;
end loop;
rx <= '1';
wait for CLK_PERIOD * CLKS_PER_BIT;
end procedure;
procedure uart_recv_byte(
signal tx : in std_logic;
variable value : out std_logic_vector(7 downto 0)
) is
begin
wait until tx = '0';
wait for (CLK_PERIOD * CLKS_PER_BIT) / 2;
assert tx = '0' report "UART start bit not stable" severity failure;
for i in 0 to 7 loop
wait for CLK_PERIOD * CLKS_PER_BIT;
value(i) := tx;
end loop;
wait for CLK_PERIOD * CLKS_PER_BIT;
assert tx = '1' report "UART stop bit not high" severity failure;
end procedure;
signal clk : std_logic := '0';
signal button : std_logic_vector(1 downto 0) := (others => '1');
signal led : std_logic_vector(4 downto 0);
signal usb_rx : std_logic := '1';
signal usb_tx : std_logic;
signal sdram_a : unsigned(12 downto 0);
signal sdram_ba : unsigned(1 downto 0);
signal sdram_dq : std_logic_vector(15 downto 0);
signal sdram_dqm : std_logic_vector(1 downto 0);
signal sdram_csn : std_logic;
signal sdram_cke : std_logic;
signal sdram_clk : std_logic;
signal sdram_wen : std_logic;
signal sdram_casn : std_logic;
signal sdram_rasn : std_logic;
begin
clk <= not clk after CLK_PERIOD / 2;
dut_i : entity work.icepi_zero_sdram_top
generic map (
BOOT_IMAGE => TEST,
UART_CLKS_PER_BIT => CLKS_PER_BIT,
RESET_CYCLES => RESET_CYCLES,
SDRAM_INIT_WAIT_CYCLES => SDRAM_INIT_WAIT_CYCLES,
SDRAM_REFRESH_INTERVAL_CYCLES => SDRAM_REFRESH_INTERVAL_CYCLES,
SDRAM_TRCD_CYCLES => SDRAM_TRCD_CYCLES,
SDRAM_TRP_CYCLES => SDRAM_TRP_CYCLES,
SDRAM_TRFC_CYCLES => SDRAM_TRFC_CYCLES,
SDRAM_TMRD_CYCLES => SDRAM_TMRD_CYCLES,
SDRAM_READ_WAIT_CYCLES => SDRAM_READ_WAIT_CYCLES,
SDRAM_WRITE_RECOVERY_CYCLES => SDRAM_WRITE_RECOVERY_CYCLES
)
port map (
clk => clk,
button => button,
led => led,
usb_rx => usb_rx,
usb_tx => usb_tx,
sdram_a => sdram_a,
sdram_ba => sdram_ba,
sdram_dq => sdram_dq,
sdram_dqm => sdram_dqm,
sdram_csn => sdram_csn,
sdram_cke => sdram_cke,
sdram_clk => sdram_clk,
sdram_wen => sdram_wen,
sdram_casn => sdram_casn,
sdram_rasn => sdram_rasn
);
sdram_i : entity work.sdram_model
generic map (
TRCD_CYCLES => SDRAM_TRCD_CYCLES,
TRP_CYCLES => SDRAM_TRP_CYCLES,
TRFC_CYCLES => SDRAM_TRFC_CYCLES,
TMRD_CYCLES => SDRAM_TMRD_CYCLES,
WRITE_RECOVERY_CYCLES => SDRAM_WRITE_RECOVERY_CYCLES,
INIT_WAIT_CYCLES => SDRAM_INIT_WAIT_CYCLES,
MAX_REFRESH_INTERVAL_CYCLES => SDRAM_REFRESH_INTERVAL_CYCLES * 2,
MEM_FILE => BOOT_MEM_FILE
)
port map (
clk => sdram_clk,
a => sdram_a,
ba => sdram_ba,
dq => sdram_dq,
dqm => sdram_dqm,
csn => sdram_csn,
cke => sdram_cke,
wen => sdram_wen,
casn => sdram_casn,
rasn => sdram_rasn
);
process
begin
button(0) <= '0';
wait for 80 ns;
wait until rising_edge(clk);
button(0) <= '1';
wait;
end process;
process
begin
if TEST = "UART_STRESS" then
wait until led(4) = '1';
wait for CLK_PERIOD * CLKS_PER_BIT * 3;
uart_send_byte(usb_rx, std_logic_vector(to_unsigned(UART_STRESS_RX_BYTE, 8)));
end if;
wait;
end process;
process
variable value : std_logic_vector(7 downto 0);
variable l : line;
begin
for i in 0 to expected_tx_count - 1 loop
uart_recv_byte(usb_tx, value);
assert value = expected_uart_byte(i) report "unexpected UART byte" severity failure;
end loop;
if led(0) /= '1' then
wait until led(0) = '1';
end if;
assert led(1) = '0' report "core errored during ICEPI Zero SDRAM UART test" severity failure;
if TEST = "PRELOADED" then
write(l, string'("ICEPI_ZERO_SDRAM_PRELOADED_BOOT_TX: "));
write(l, expected_tx_count);
elsif TEST = "UART_STRESS" then
write(l, string'("ICEPI_ZERO_SDRAM_UART_STRESS_TX: "));
write(l, expected_tx_count);
else
write(l, string'("ICEPI_ZERO_SDRAM_SMOKE_TX: "));
write(l, to_integer(unsigned(value)));
end if;
writeline(output, l);
stop;
end process;
process
begin
wait for TIMEOUT;
assert false report "ICEPI Zero SDRAM top smoke test timeout" severity failure;
end process;
end architecture;
|
Added ilo-vm/vhdl/sim/icepi_zero_top_tb.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use std.env.all;
entity icepi_zero_top_tb is
end entity;
architecture sim of icepi_zero_top_tb is
constant CLKS_PER_BIT : positive := 4;
signal clk : std_logic := '0';
signal button : std_logic_vector(1 downto 0) := (others => '1');
signal led : std_logic_vector(4 downto 0);
signal usb_rx : std_logic := '1';
signal usb_tx : std_logic;
begin
clk <= not clk after 5 ns;
dut_i : entity work.icepi_zero_top
generic map (
UART_CLKS_PER_BIT => CLKS_PER_BIT,
RESET_CYCLES => 2
)
port map (
clk => clk,
button => button,
led => led,
usb_rx => usb_rx,
usb_tx => usb_tx
);
process
begin
button(0) <= '0';
wait for 80 ns;
wait until rising_edge(clk);
button(0) <= '1';
wait;
end process;
process
variable value : std_logic_vector(7 downto 0);
variable l : line;
begin
wait until usb_tx = '0';
wait for 5 ns * CLKS_PER_BIT;
assert usb_tx = '0' report "UART start bit not stable" severity failure;
for i in 0 to 7 loop
wait for 10 ns * CLKS_PER_BIT;
value(i) := usb_tx;
end loop;
wait for 10 ns * CLKS_PER_BIT;
assert usb_tx = '1' report "UART stop bit not high" severity failure;
assert value = x"41" report "unexpected UART byte" severity failure;
if led(0) /= '1' then
wait until led(0) = '1';
end if;
assert led(1) = '0' report "core errored during ICEPI Zero smoke test" severity failure;
write(l, string'("ICEPI_ZERO_SMOKE_TX: "));
write(l, to_integer(unsigned(value)));
writeline(output, l);
stop;
end process;
process
begin
wait for 100 us;
assert false report "ICEPI Zero top smoke test timeout" severity failure;
end process;
end architecture;
|
Added ilo-vm/vhdl/sim/ilo_reload_tb.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.env.all;
use work.ilo_pkg.all;
entity ilo_reload_tb is
generic (
ROM_FILE : string := "";
MEM_READ_WAIT_CYCLES : natural := 0;
MEM_WRITE_WAIT_CYCLES : natural := 0;
POISON_UNINITIALIZED : boolean := false;
MAX_CYCLES : natural := 10000
);
end entity;
architecture sim of ilo_reload_tb is
signal clk : std_logic := '0';
signal reset : std_logic := '1';
signal mem_req : std_logic;
signal mem_we : std_logic;
signal mem_addr : addr_t;
signal mem_wdata : cell_t;
signal mem_rdata : cell_t;
signal mem_ready : std_logic;
signal reload_req : std_logic;
signal reload_ready : std_logic;
signal serial_tx_valid : std_logic;
signal serial_tx_data : std_logic_vector(7 downto 0);
signal serial_rx_req : std_logic;
signal block_req : std_logic;
signal block_we : std_logic;
signal block_addr : unsigned(31 downto 0);
signal block_wdata : cell_t;
signal halted : std_logic;
signal errored : std_logic;
signal error_code : unsigned(7 downto 0);
begin
clk <= not clk after 5 ns;
mem_i : entity work.ilo_memory
generic map (
ROM_FILE => ROM_FILE,
READ_WAIT_CYCLES => MEM_READ_WAIT_CYCLES,
WRITE_WAIT_CYCLES => MEM_WRITE_WAIT_CYCLES,
POISON_UNINITIALIZED => POISON_UNINITIALIZED
)
port map (
clk => clk,
req => mem_req,
we => mem_we,
addr => mem_addr,
wdata => mem_wdata,
rdata => mem_rdata,
ready => mem_ready,
reload_req => reload_req,
reload_ready => reload_ready
);
core_i : entity work.ilo_core
port map (
clk => clk,
reset => reset,
mem_req => mem_req,
mem_we => mem_we,
mem_addr => mem_addr,
mem_wdata => mem_wdata,
mem_rdata => mem_rdata,
mem_ready => mem_ready,
serial_tx_valid => serial_tx_valid,
serial_tx_data => serial_tx_data,
serial_tx_ready => '1',
serial_rx_req => serial_rx_req,
serial_rx_valid => '0',
serial_rx_data => (others => '0'),
block_req => block_req,
block_we => block_we,
block_addr => block_addr,
block_wdata => block_wdata,
block_rdata => CELL_ZERO,
block_ready => '0',
reload_req => reload_req,
reload_ready => reload_ready,
halted => halted,
errored => errored,
error_code => error_code
);
process
begin
reset <= '1';
wait for 50 ns;
wait until rising_edge(clk);
reset <= '0';
wait;
end process;
process
variable reloads : natural := 0;
begin
for cycle in 0 to MAX_CYCLES loop
wait until rising_edge(clk);
if reload_ready = '1' then
reloads := reloads + 1;
if reloads = 2 then
assert sim_debug.get_sp = 0 report "reload did not clear data stack" severity failure;
assert sim_debug.get_rp = 0 report "reload did not clear return stack" severity failure;
report "RELOAD PASS";
stop;
wait;
end if;
end if;
assert halted = '0' report "reload test halted before second reload" severity failure;
assert errored = '0' report "reload test errored: " & integer'image(to_integer(error_code)) severity failure;
end loop;
assert false report "reload test timeout" severity failure;
end process;
end architecture;
|
Added ilo-vm/vhdl/sim/ilo_sdram_controller_tb.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.env.all;
use work.ilo_pkg.all;
entity ilo_sdram_controller_tb is
end entity;
architecture sim of ilo_sdram_controller_tb is
type init_monitor_state_t is (
MON_WAIT_CKE,
MON_PRECHARGE,
MON_REFRESH_1,
MON_REFRESH_2,
MON_MODE,
MON_DONE
);
signal clk : std_logic := '0';
signal reset : std_logic := '1';
signal req : std_logic := '0';
signal we : std_logic := '0';
signal addr : addr_t := (others => '0');
signal wdata : cell_t := CELL_ZERO;
signal rdata : cell_t;
signal ready : std_logic;
signal reload_req : std_logic := '0';
signal reload_ready : std_logic;
signal sdram_a : unsigned(12 downto 0);
signal sdram_ba : unsigned(1 downto 0);
signal sdram_dq : std_logic_vector(15 downto 0);
signal sdram_dqm : std_logic_vector(1 downto 0);
signal sdram_csn : std_logic;
signal sdram_cke : std_logic;
signal sdram_clk : std_logic;
signal sdram_wen : std_logic;
signal sdram_casn : std_logic;
signal sdram_rasn : std_logic;
signal init_sequence_seen : std_logic := '0';
procedure write_cell(
signal req_s : out std_logic;
signal we_s : out std_logic;
signal addr_s : out addr_t;
signal wdata_s : out cell_t;
signal ready_s : in std_logic;
constant a : natural;
constant v : cell_t
) is
begin
wait until rising_edge(clk);
addr_s <= to_unsigned(a, MEM_ADDR_WIDTH);
wdata_s <= v;
we_s <= '1';
req_s <= '1';
wait until ready_s = '1';
wait until rising_edge(clk);
req_s <= '0';
we_s <= '0';
end procedure;
procedure read_cell(
signal req_s : out std_logic;
signal we_s : out std_logic;
signal addr_s : out addr_t;
signal ready_s : in std_logic;
signal rdata_s : in cell_t;
constant a : natural;
constant expected : cell_t
) is
begin
wait until rising_edge(clk);
addr_s <= to_unsigned(a, MEM_ADDR_WIDTH);
we_s <= '0';
req_s <= '1';
wait until ready_s = '1';
assert rdata_s = expected
report "unexpected SDRAM read data"
severity failure;
wait until rising_edge(clk);
req_s <= '0';
end procedure;
procedure wait_cycles(constant count : natural) is
begin
for i in 1 to count loop
wait until rising_edge(clk);
end loop;
end procedure;
procedure assert_reset_idle is
begin
wait for 1 ns;
assert ready = '0'
report "SDRAM controller asserted ready during reset"
severity failure;
assert reload_ready = '0'
report "SDRAM controller asserted reload_ready during reset"
severity failure;
assert sdram_cke = '0'
report "SDRAM controller kept CKE high during reset"
severity failure;
end procedure;
procedure release_and_wait_for_init(signal reset_s : out std_logic) is
begin
wait until rising_edge(clk);
reset_s <= '0';
wait until init_sequence_seen = '1';
wait_cycles(4);
assert ready = '0'
report "SDRAM controller produced stale ready after initialization"
severity failure;
assert reload_ready = '0'
report "SDRAM controller produced stale reload_ready after initialization"
severity failure;
end procedure;
begin
clk <= not clk after 5 ns;
dut_i : entity work.ilo_sdram_controller
generic map (
INIT_WAIT_CYCLES => 4,
REFRESH_INTERVAL_CYCLES => 32,
TRCD_CYCLES => 1,
TRP_CYCLES => 1,
TRFC_CYCLES => 2,
TMRD_CYCLES => 1,
READ_WAIT_CYCLES => 3,
WRITE_RECOVERY_CYCLES => 1
)
port map (
clk => clk,
reset => reset,
req => req,
we => we,
addr => addr,
wdata => wdata,
rdata => rdata,
ready => ready,
reload_req => reload_req,
reload_ready => reload_ready,
sdram_a => sdram_a,
sdram_ba => sdram_ba,
sdram_dq => sdram_dq,
sdram_dqm => sdram_dqm,
sdram_csn => sdram_csn,
sdram_cke => sdram_cke,
sdram_clk => sdram_clk,
sdram_wen => sdram_wen,
sdram_casn => sdram_casn,
sdram_rasn => sdram_rasn
);
sdram_i : entity work.sdram_model
generic map (
HALFWORD_ADDR_WIDTH => 17,
CAS_LATENCY => 2,
TRCD_CYCLES => 1,
TRP_CYCLES => 1,
TRFC_CYCLES => 2,
TMRD_CYCLES => 1,
WRITE_RECOVERY_CYCLES => 1,
INIT_WAIT_CYCLES => 4,
MAX_REFRESH_INTERVAL_CYCLES => 64
)
port map (
clk => sdram_clk,
a => sdram_a,
ba => sdram_ba,
dq => sdram_dq,
dqm => sdram_dqm,
csn => sdram_csn,
cke => sdram_cke,
wen => sdram_wen,
casn => sdram_casn,
rasn => sdram_rasn
);
process(sdram_clk)
variable state : init_monitor_state_t := MON_WAIT_CKE;
begin
if rising_edge(sdram_clk) then
if reset = '1' then
state := MON_WAIT_CKE;
init_sequence_seen <= '0';
else
if state = MON_WAIT_CKE and sdram_cke = '1' then
state := MON_PRECHARGE;
end if;
if sdram_cke = '1' and sdram_csn = '0' then
if sdram_rasn = '0' and sdram_casn = '1' and sdram_wen = '0' then
assert state = MON_PRECHARGE or state = MON_DONE
report "controller issued PRECHARGE outside SDRAM init precharge step"
severity failure;
if state = MON_PRECHARGE then
assert sdram_a(10) = '1'
report "controller SDRAM init did not use PRECHARGE ALL"
severity failure;
state := MON_REFRESH_1;
end if;
elsif sdram_rasn = '0' and sdram_casn = '0' and sdram_wen = '1' then
assert state = MON_REFRESH_1 or state = MON_REFRESH_2 or state = MON_DONE
report "controller issued REFRESH outside expected SDRAM init step"
severity failure;
if state = MON_REFRESH_1 then
state := MON_REFRESH_2;
elsif state = MON_REFRESH_2 then
state := MON_MODE;
end if;
elsif sdram_rasn = '0' and sdram_casn = '0' and sdram_wen = '0' then
assert state = MON_MODE or state = MON_DONE
report "controller issued MODE REGISTER SET outside expected SDRAM init step"
severity failure;
if state = MON_MODE then
assert to_integer(unsigned(sdram_a(6 downto 4))) = 2
report "controller SDRAM init programmed unexpected CAS latency"
severity failure;
state := MON_DONE;
init_sequence_seen <= '1';
end if;
elsif not (sdram_rasn = '1' and sdram_casn = '1' and sdram_wen = '1') then
assert state = MON_DONE
report "controller issued normal SDRAM command before init sequence completed"
severity failure;
end if;
end if;
end if;
end if;
end process;
process
begin
reset <= '1';
wait_cycles(2);
assert_reset_idle;
reset <= '0';
wait_cycles(2);
reset <= '1';
wait_cycles(1);
assert_reset_idle;
release_and_wait_for_init(reset);
assert init_sequence_seen = '1'
report "controller did not complete expected SDRAM init sequence"
severity failure;
write_cell(req, we, addr, wdata, ready, 0, signed'(x"12345678"));
write_cell(req, we, addr, wdata, ready, 1, signed'(x"89ABCDEF"));
write_cell(req, we, addr, wdata, ready, 512, signed'(x"0BADCAFE"));
read_cell(req, we, addr, ready, rdata, 0, signed'(x"12345678"));
read_cell(req, we, addr, ready, rdata, 1, signed'(x"89ABCDEF"));
wait for 1 us;
read_cell(req, we, addr, ready, rdata, 512, signed'(x"0BADCAFE"));
wait until rising_edge(clk);
addr <= to_unsigned(1024, MEM_ADDR_WIDTH);
wdata <= signed'(x"55AA33CC");
we <= '1';
req <= '1';
wait_cycles(3);
assert ready = '0'
report "SDRAM controller completed transaction before reset stress point"
severity failure;
reset <= '1';
wait_cycles(1);
req <= '0';
we <= '0';
reload_req <= '0';
assert_reset_idle;
wait_cycles(3);
assert ready = '0'
report "SDRAM controller produced stale ready after transaction reset"
severity failure;
assert reload_ready = '0'
report "SDRAM controller produced stale reload_ready after transaction reset"
severity failure;
release_and_wait_for_init(reset);
wait until rising_edge(clk);
reload_req <= '1';
wait until sdram_csn = '0' and sdram_rasn = '0' and sdram_casn = '0' and sdram_wen = '1';
assert reload_ready = '0'
report "SDRAM controller acknowledged reload during refresh command"
severity failure;
wait until reload_ready = '1';
wait until rising_edge(clk);
reload_req <= '0';
write_cell(req, we, addr, wdata, ready, 2048, signed'(x"13579BDF"));
wait until rising_edge(clk);
addr <= to_unsigned(2048, MEM_ADDR_WIDTH);
we <= '0';
req <= '1';
wait_cycles(2);
reload_req <= '1';
wait_cycles(2);
assert reload_ready = '0'
report "SDRAM controller acknowledged reload while transaction was active"
severity failure;
wait until ready = '1';
assert rdata = signed'(x"13579BDF")
report "unexpected read data during reload stress"
severity failure;
wait until rising_edge(clk);
req <= '0';
wait until reload_ready = '1';
wait until rising_edge(clk);
reload_req <= '0';
wait until rising_edge(clk);
reload_req <= '1';
wait until reload_ready = '1';
wait until rising_edge(clk);
reload_req <= '0';
report "ILO_SDRAM_CONTROLLER_OK";
stop;
end process;
process
begin
wait for 100 us;
assert false report "SDRAM controller test timeout" severity failure;
end process;
end architecture;
|
Added ilo-vm/vhdl/sim/ilo_sdram_tb.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use work.ilo_pkg.all;
entity ilo_sdram_tb is
generic (
ROM_FILE : string := "";
BLOCK_FILE : string := "";
BLOCK_CELLS : natural := 1024;
INIT_WAIT_CYCLES : natural := 4;
REFRESH_INTERVAL_CYCLES : natural := 64;
BLOCK_READ_WAIT_CYCLES : natural := 0;
BLOCK_WRITE_WAIT_CYCLES : natural := 0;
POISON_UNINITIALIZED : boolean := false;
MAX_CYCLES : natural := 1000000;
RX_TEXT : string := ""
);
end entity;
architecture sim of ilo_sdram_tb is
signal clk : std_logic := '0';
signal reset : std_logic := '1';
signal mem_req : std_logic;
signal mem_we : std_logic;
signal mem_addr : addr_t;
signal mem_wdata : cell_t;
signal mem_rdata : cell_t;
signal mem_ready : std_logic;
signal serial_tx_valid : std_logic;
signal serial_tx_data : std_logic_vector(7 downto 0);
signal serial_rx_req : std_logic;
signal serial_rx_valid : std_logic := '0';
signal serial_rx_data : std_logic_vector(7 downto 0) := (others => '0');
signal block_req : std_logic;
signal block_we : std_logic;
signal block_addr : unsigned(31 downto 0);
signal block_wdata : cell_t;
signal block_rdata : cell_t;
signal block_ready : std_logic;
signal reload_req : std_logic;
signal reload_ready : std_logic;
signal halted : std_logic;
signal errored : std_logic;
signal error_code : unsigned(7 downto 0);
signal sdram_a : unsigned(12 downto 0);
signal sdram_ba : unsigned(1 downto 0);
signal sdram_dq : std_logic_vector(15 downto 0);
signal sdram_dqm : std_logic_vector(1 downto 0);
signal sdram_csn : std_logic;
signal sdram_cke : std_logic;
signal sdram_clk : std_logic;
signal sdram_wen : std_logic;
signal sdram_casn : std_logic;
signal sdram_rasn : std_logic;
begin
clk <= not clk after 5 ns;
mem_i : entity work.ilo_sdram_controller
generic map (
INIT_WAIT_CYCLES => INIT_WAIT_CYCLES,
REFRESH_INTERVAL_CYCLES => REFRESH_INTERVAL_CYCLES
)
port map (
clk => clk,
reset => reset,
req => mem_req,
we => mem_we,
addr => mem_addr,
wdata => mem_wdata,
rdata => mem_rdata,
ready => mem_ready,
reload_req => reload_req,
reload_ready => reload_ready,
sdram_a => sdram_a,
sdram_ba => sdram_ba,
sdram_dq => sdram_dq,
sdram_dqm => sdram_dqm,
sdram_csn => sdram_csn,
sdram_cke => sdram_cke,
sdram_clk => sdram_clk,
sdram_wen => sdram_wen,
sdram_casn => sdram_casn,
sdram_rasn => sdram_rasn
);
sdram_i : entity work.sdram_model
generic map (
MEM_FILE => ROM_FILE
)
port map (
clk => sdram_clk,
a => sdram_a,
ba => sdram_ba,
dq => sdram_dq,
dqm => sdram_dqm,
csn => sdram_csn,
cke => sdram_cke,
wen => sdram_wen,
casn => sdram_casn,
rasn => sdram_rasn
);
block_i : entity work.ilo_block_store
generic map (
BLOCK_FILE => BLOCK_FILE,
BLOCK_CELLS => BLOCK_CELLS,
READ_WAIT_CYCLES => BLOCK_READ_WAIT_CYCLES,
WRITE_WAIT_CYCLES => BLOCK_WRITE_WAIT_CYCLES,
POISON_UNINITIALIZED => POISON_UNINITIALIZED
)
port map (
clk => clk,
req => block_req,
we => block_we,
addr => block_addr,
wdata => block_wdata,
rdata => block_rdata,
ready => block_ready
);
core_i : entity work.ilo_core
port map (
clk => clk,
reset => reset,
mem_req => mem_req,
mem_we => mem_we,
mem_addr => mem_addr,
mem_wdata => mem_wdata,
mem_rdata => mem_rdata,
mem_ready => mem_ready,
serial_tx_valid => serial_tx_valid,
serial_tx_data => serial_tx_data,
serial_tx_ready => '1',
serial_rx_req => serial_rx_req,
serial_rx_valid => serial_rx_valid,
serial_rx_data => serial_rx_data,
block_req => block_req,
block_we => block_we,
block_addr => block_addr,
block_wdata => block_wdata,
block_rdata => block_rdata,
block_ready => block_ready,
reload_req => reload_req,
reload_ready => reload_ready,
halted => halted,
errored => errored,
error_code => error_code
);
process
begin
reset <= '1';
wait for 50 ns;
wait until rising_edge(clk);
reset <= '0';
wait;
end process;
process(clk)
variable rx_index : natural := 1;
variable rx_served : boolean := false;
begin
if rising_edge(clk) then
serial_rx_valid <= '0';
if reset = '1' then
rx_index := 1;
rx_served := false;
serial_rx_data <= (others => '0');
elsif serial_rx_req = '0' then
rx_served := false;
elsif not rx_served then
if rx_index <= RX_TEXT'length then
serial_rx_data <= std_logic_vector(to_unsigned(character'pos(RX_TEXT(rx_index)), 8));
serial_rx_valid <= '1';
rx_index := rx_index + 1;
rx_served := true;
end if;
end if;
end if;
end process;
process(clk)
variable l : line;
begin
if rising_edge(clk) then
if serial_tx_valid = '1' then
write(l, string'("SERIAL_TX: "));
write(l, to_integer(unsigned(serial_tx_data)));
writeline(output, l);
end if;
end if;
end process;
process
variable l : line;
begin
for cycle in 0 to MAX_CYCLES loop
wait until rising_edge(clk);
if halted = '1' then
write(l, string'("FINAL_STACK:"));
for i in DS_DEPTH downto 1 loop
if i <= sim_debug.get_sp then
write(l, string'(" "));
write(l, to_integer(sim_debug.get_ds(i)));
end if;
end loop;
writeline(output, l);
assert false report "HALT" severity failure;
elsif errored = '1' then
write(l, string'("ERROR: "));
write(l, to_integer(error_code));
writeline(output, l);
assert false report "ERROR" severity failure;
end if;
end loop;
assert false report "TIMEOUT" severity failure;
end process;
end architecture;
|
Added ilo-vm/vhdl/sim/ilo_sdram_terminal_tb.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use work.ilo_pkg.all;
entity ilo_sdram_terminal_tb is
generic (
ROM_FILE : string := "";
BLOCK_FILE : string := "";
BLOCK_CELLS : natural := 1024;
INIT_WAIT_CYCLES : natural := 10000;
REFRESH_INTERVAL_CYCLES : natural := 390;
BLOCK_READ_WAIT_CYCLES : natural := 0;
BLOCK_WRITE_WAIT_CYCLES : natural := 0;
POISON_UNINITIALIZED : boolean := false;
RX_FIFO : string := "ilo-vhdl/build/terminal.rx";
TX_FIFO : string := "ilo-vhdl/build/terminal.tx";
MAX_CYCLES : natural := 0;
CLOCK_PERIOD_NS : positive := 10
);
end entity;
architecture sim of ilo_sdram_terminal_tb is
constant CLK_HALF_PERIOD : time := (CLOCK_PERIOD_NS * 1 ns) / 2;
signal clk : std_logic := '0';
signal reset : std_logic := '1';
signal mem_req : std_logic;
signal mem_we : std_logic;
signal mem_addr : addr_t;
signal mem_wdata : cell_t;
signal mem_rdata : cell_t;
signal mem_ready : std_logic;
signal serial_tx_valid : std_logic;
signal serial_tx_data : std_logic_vector(7 downto 0);
signal serial_rx_req : std_logic;
signal serial_rx_valid : std_logic := '0';
signal serial_rx_data : std_logic_vector(7 downto 0) := (others => '0');
signal block_req : std_logic;
signal block_we : std_logic;
signal block_addr : unsigned(31 downto 0);
signal block_wdata : cell_t;
signal block_rdata : cell_t;
signal block_ready : std_logic;
signal reload_req : std_logic;
signal reload_ready : std_logic;
signal halted : std_logic;
signal errored : std_logic;
signal error_code : unsigned(7 downto 0);
signal sdram_a : unsigned(12 downto 0);
signal sdram_ba : unsigned(1 downto 0);
signal sdram_dq : std_logic_vector(15 downto 0);
signal sdram_dqm : std_logic_vector(1 downto 0);
signal sdram_csn : std_logic;
signal sdram_cke : std_logic;
signal sdram_clk : std_logic;
signal sdram_wen : std_logic;
signal sdram_casn : std_logic;
signal sdram_rasn : std_logic;
file rx_file : text open read_mode is RX_FIFO;
file tx_file : text open write_mode is TX_FIFO;
begin
clk <= not clk after CLK_HALF_PERIOD;
mem_i : entity work.ilo_sdram_controller
generic map (
INIT_WAIT_CYCLES => INIT_WAIT_CYCLES,
REFRESH_INTERVAL_CYCLES => REFRESH_INTERVAL_CYCLES
)
port map (
clk => clk,
reset => reset,
req => mem_req,
we => mem_we,
addr => mem_addr,
wdata => mem_wdata,
rdata => mem_rdata,
ready => mem_ready,
reload_req => reload_req,
reload_ready => reload_ready,
sdram_a => sdram_a,
sdram_ba => sdram_ba,
sdram_dq => sdram_dq,
sdram_dqm => sdram_dqm,
sdram_csn => sdram_csn,
sdram_cke => sdram_cke,
sdram_clk => sdram_clk,
sdram_wen => sdram_wen,
sdram_casn => sdram_casn,
sdram_rasn => sdram_rasn
);
sdram_i : entity work.sdram_model
generic map (
MEM_FILE => ROM_FILE
)
port map (
clk => sdram_clk,
a => sdram_a,
ba => sdram_ba,
dq => sdram_dq,
dqm => sdram_dqm,
csn => sdram_csn,
cke => sdram_cke,
wen => sdram_wen,
casn => sdram_casn,
rasn => sdram_rasn
);
block_i : entity work.ilo_block_store
generic map (
BLOCK_FILE => BLOCK_FILE,
BLOCK_CELLS => BLOCK_CELLS,
READ_WAIT_CYCLES => BLOCK_READ_WAIT_CYCLES,
WRITE_WAIT_CYCLES => BLOCK_WRITE_WAIT_CYCLES,
POISON_UNINITIALIZED => POISON_UNINITIALIZED
)
port map (
clk => clk,
req => block_req,
we => block_we,
addr => block_addr,
wdata => block_wdata,
rdata => block_rdata,
ready => block_ready
);
core_i : entity work.ilo_core
port map (
clk => clk,
reset => reset,
mem_req => mem_req,
mem_we => mem_we,
mem_addr => mem_addr,
mem_wdata => mem_wdata,
mem_rdata => mem_rdata,
mem_ready => mem_ready,
serial_tx_valid => serial_tx_valid,
serial_tx_data => serial_tx_data,
serial_tx_ready => '1',
serial_rx_req => serial_rx_req,
serial_rx_valid => serial_rx_valid,
serial_rx_data => serial_rx_data,
block_req => block_req,
block_we => block_we,
block_addr => block_addr,
block_wdata => block_wdata,
block_rdata => block_rdata,
block_ready => block_ready,
reload_req => reload_req,
reload_ready => reload_ready,
halted => halted,
errored => errored,
error_code => error_code
);
process
begin
reset <= '1';
wait for 50 ns;
wait until rising_edge(clk);
reset <= '0';
wait;
end process;
process(clk)
variable l : line;
variable byte_value : integer;
variable rx_served : boolean := false;
begin
if rising_edge(clk) then
serial_rx_valid <= '0';
if reset = '1' then
rx_served := false;
serial_rx_data <= (others => '0');
elsif serial_rx_req = '0' then
rx_served := false;
elsif not rx_served then
readline(rx_file, l);
read(l, byte_value);
if byte_value < 0 then
byte_value := 0;
elsif byte_value > 255 then
byte_value := 255;
end if;
serial_rx_data <= std_logic_vector(to_unsigned(byte_value, 8));
serial_rx_valid <= '1';
rx_served := true;
end if;
end if;
end process;
process(clk)
variable prev_valid : std_logic := '0';
variable prev_data : std_logic_vector(7 downto 0) := (others => '0');
begin
if rising_edge(clk) then
if reset = '1' then
prev_valid := '0';
prev_data := (others => '0');
else
if serial_rx_valid = '1' then
assert not is_x(serial_rx_data)
report "serial_rx_data is invalid while serial_rx_valid is asserted"
severity failure;
if prev_valid = '1' then
assert serial_rx_data = prev_data
report "serial_rx_data changed while serial_rx_valid remained asserted"
severity failure;
end if;
end if;
prev_valid := serial_rx_valid;
prev_data := serial_rx_data;
end if;
end if;
end process;
process(clk)
variable l : line;
begin
if rising_edge(clk) then
if serial_tx_valid = '1' then
write(l, to_integer(unsigned(serial_tx_data)));
writeline(tx_file, l);
flush(tx_file);
end if;
end if;
end process;
process
variable l : line;
begin
if MAX_CYCLES = 0 then
loop
wait until rising_edge(clk);
if halted = '1' then
write(l, string'("HALT"));
writeline(output, l);
wait;
elsif errored = '1' then
write(l, string'("ERROR: "));
write(l, to_integer(error_code));
writeline(output, l);
assert false report "ERROR" severity failure;
end if;
end loop;
else
for cycle in 0 to MAX_CYCLES loop
wait until rising_edge(clk);
if halted = '1' then
write(l, string'("HALT"));
writeline(output, l);
wait;
elsif errored = '1' then
write(l, string'("ERROR: "));
write(l, to_integer(error_code));
writeline(output, l);
assert false report "ERROR" severity failure;
end if;
end loop;
assert false report "TIMEOUT" severity failure;
end if;
end process;
end architecture;
|
Added ilo-vm/vhdl/sim/ilo_sram8_tb.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use work.ilo_pkg.all;
entity ilo_sram8_tb is
generic (
ROM_FILE : string := "";
BLOCK_FILE : string := "";
BLOCK_CELLS : natural := 1024;
READ_WAIT_CYCLES : natural := 1;
WRITE_WAIT_CYCLES : natural := 1;
SRAM_OUTPUT_DELAY_NS : natural := 1;
BLOCK_READ_WAIT_CYCLES : natural := 0;
BLOCK_WRITE_WAIT_CYCLES : natural := 0;
POISON_UNINITIALIZED : boolean := false;
MAX_CYCLES : natural := 1000000;
RX_TEXT : string := ""
);
end entity;
architecture sim of ilo_sram8_tb is
signal clk : std_logic := '0';
signal reset : std_logic := '1';
signal mem_req : std_logic;
signal mem_we : std_logic;
signal mem_addr : addr_t;
signal mem_wdata : cell_t;
signal mem_rdata : cell_t;
signal mem_ready : std_logic;
signal serial_tx_valid : std_logic;
signal serial_tx_data : std_logic_vector(7 downto 0);
signal serial_rx_req : std_logic;
signal serial_rx_valid : std_logic := '0';
signal serial_rx_data : std_logic_vector(7 downto 0) := (others => '0');
signal block_req : std_logic;
signal block_we : std_logic;
signal block_addr : unsigned(31 downto 0);
signal block_wdata : cell_t;
signal block_rdata : cell_t;
signal block_ready : std_logic;
signal reload_req : std_logic;
signal reload_ready : std_logic;
signal halted : std_logic;
signal errored : std_logic;
signal error_code : unsigned(7 downto 0);
signal sram_addr : unsigned(18 downto 0);
signal sram_data : std_logic_vector(7 downto 0);
signal sram_ce_n : std_logic;
signal sram_oe_n : std_logic;
signal sram_we_n : std_logic;
begin
clk <= not clk after 5 ns;
mem_i : entity work.ilo_sram8_controller
generic map (
SRAM_ADDR_WIDTH => 19,
READ_WAIT_CYCLES => READ_WAIT_CYCLES,
WRITE_WAIT_CYCLES => WRITE_WAIT_CYCLES
)
port map (
clk => clk,
reset => reset,
req => mem_req,
we => mem_we,
addr => mem_addr,
wdata => mem_wdata,
rdata => mem_rdata,
ready => mem_ready,
reload_req => reload_req,
reload_ready => reload_ready,
sram_addr => sram_addr,
sram_data => sram_data,
sram_ce_n => sram_ce_n,
sram_oe_n => sram_oe_n,
sram_we_n => sram_we_n
);
sram_i : entity work.sram8_model
generic map (
MEM_FILE => ROM_FILE,
ADDR_WIDTH => 19,
OUTPUT_DELAY_NS => SRAM_OUTPUT_DELAY_NS,
POISON_UNINITIALIZED => POISON_UNINITIALIZED
)
port map (
addr => sram_addr,
data => sram_data,
ce_n => sram_ce_n,
oe_n => sram_oe_n,
we_n => sram_we_n
);
block_i : entity work.ilo_block_store
generic map (
BLOCK_FILE => BLOCK_FILE,
BLOCK_CELLS => BLOCK_CELLS,
READ_WAIT_CYCLES => BLOCK_READ_WAIT_CYCLES,
WRITE_WAIT_CYCLES => BLOCK_WRITE_WAIT_CYCLES,
POISON_UNINITIALIZED => POISON_UNINITIALIZED
)
port map (
clk => clk,
req => block_req,
we => block_we,
addr => block_addr,
wdata => block_wdata,
rdata => block_rdata,
ready => block_ready
);
core_i : entity work.ilo_core
port map (
clk => clk,
reset => reset,
mem_req => mem_req,
mem_we => mem_we,
mem_addr => mem_addr,
mem_wdata => mem_wdata,
mem_rdata => mem_rdata,
mem_ready => mem_ready,
serial_tx_valid => serial_tx_valid,
serial_tx_data => serial_tx_data,
serial_tx_ready => '1',
serial_rx_req => serial_rx_req,
serial_rx_valid => serial_rx_valid,
serial_rx_data => serial_rx_data,
block_req => block_req,
block_we => block_we,
block_addr => block_addr,
block_wdata => block_wdata,
block_rdata => block_rdata,
block_ready => block_ready,
reload_req => reload_req,
reload_ready => reload_ready,
halted => halted,
errored => errored,
error_code => error_code
);
process
begin
reset <= '1';
wait for 50 ns;
wait until rising_edge(clk);
reset <= '0';
wait;
end process;
process(clk)
variable rx_index : natural := 1;
variable rx_served : boolean := false;
begin
if rising_edge(clk) then
serial_rx_valid <= '0';
if reset = '1' then
rx_index := 1;
rx_served := false;
serial_rx_data <= (others => '0');
elsif serial_rx_req = '0' then
rx_served := false;
elsif not rx_served then
if rx_index <= RX_TEXT'length then
serial_rx_data <= std_logic_vector(to_unsigned(character'pos(RX_TEXT(rx_index)), 8));
serial_rx_valid <= '1';
rx_index := rx_index + 1;
rx_served := true;
end if;
end if;
end if;
end process;
process(clk)
variable prev_valid : std_logic := '0';
variable prev_data : std_logic_vector(7 downto 0) := (others => '0');
begin
if rising_edge(clk) then
if reset = '1' then
prev_valid := '0';
prev_data := (others => '0');
else
if serial_rx_valid = '1' then
assert not is_x(serial_rx_data)
report "serial_rx_data is invalid while serial_rx_valid is asserted"
severity failure;
if prev_valid = '1' then
assert serial_rx_data = prev_data
report "serial_rx_data changed while serial_rx_valid remained asserted"
severity failure;
end if;
end if;
prev_valid := serial_rx_valid;
prev_data := serial_rx_data;
end if;
end if;
end process;
process(clk)
variable l : line;
begin
if rising_edge(clk) then
if serial_tx_valid = '1' then
write(l, string'("SERIAL_TX: "));
write(l, to_integer(unsigned(serial_tx_data)));
writeline(output, l);
end if;
end if;
end process;
process
variable l : line;
begin
for cycle in 0 to MAX_CYCLES loop
wait until rising_edge(clk);
if halted = '1' then
write(l, string'("FINAL_STACK:"));
for i in DS_DEPTH downto 1 loop
if i <= sim_debug.get_sp then
write(l, string'(" "));
write(l, to_integer(sim_debug.get_ds(i)));
end if;
end loop;
writeline(output, l);
assert false report "HALT" severity failure;
elsif errored = '1' then
write(l, string'("ERROR: "));
write(l, to_integer(error_code));
writeline(output, l);
assert false report "ERROR" severity failure;
end if;
end loop;
assert false report "TIMEOUT" severity failure;
end process;
end architecture;
|
Added ilo-vm/vhdl/sim/ilo_sram8_terminal_tb.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use work.ilo_pkg.all;
entity ilo_sram8_terminal_tb is
generic (
ROM_FILE : string := "";
BLOCK_FILE : string := "";
BLOCK_CELLS : natural := 1024;
SRAM_ADDR_WIDTH : natural := 19;
READ_WAIT_CYCLES : natural := 1;
WRITE_WAIT_CYCLES : natural := 1;
SRAM_OUTPUT_DELAY_NS : natural := 1;
BLOCK_READ_WAIT_CYCLES : natural := 0;
BLOCK_WRITE_WAIT_CYCLES : natural := 0;
POISON_UNINITIALIZED : boolean := false;
RX_FIFO : string := "ilo-vhdl/build/terminal.rx";
TX_FIFO : string := "ilo-vhdl/build/terminal.tx";
MAX_CYCLES : natural := 0;
CLOCK_PERIOD_NS : positive := 10
);
end entity;
architecture sim of ilo_sram8_terminal_tb is
constant CLK_HALF_PERIOD : time := (CLOCK_PERIOD_NS * 1 ns) / 2;
signal clk : std_logic := '0';
signal reset : std_logic := '1';
signal mem_req : std_logic;
signal mem_we : std_logic;
signal mem_addr : addr_t;
signal mem_wdata : cell_t;
signal mem_rdata : cell_t;
signal mem_ready : std_logic;
signal serial_tx_valid : std_logic;
signal serial_tx_data : std_logic_vector(7 downto 0);
signal serial_rx_req : std_logic;
signal serial_rx_valid : std_logic := '0';
signal serial_rx_data : std_logic_vector(7 downto 0) := (others => '0');
signal block_req : std_logic;
signal block_we : std_logic;
signal block_addr : unsigned(31 downto 0);
signal block_wdata : cell_t;
signal block_rdata : cell_t;
signal block_ready : std_logic;
signal reload_req : std_logic;
signal reload_ready : std_logic;
signal halted : std_logic;
signal errored : std_logic;
signal error_code : unsigned(7 downto 0);
signal sram_addr : unsigned(SRAM_ADDR_WIDTH - 1 downto 0);
signal sram_data : std_logic_vector(7 downto 0);
signal sram_ce_n : std_logic;
signal sram_oe_n : std_logic;
signal sram_we_n : std_logic;
file rx_file : text open read_mode is RX_FIFO;
file tx_file : text open write_mode is TX_FIFO;
begin
clk <= not clk after CLK_HALF_PERIOD;
mem_i : entity work.ilo_sram8_controller
generic map (
SRAM_ADDR_WIDTH => SRAM_ADDR_WIDTH,
READ_WAIT_CYCLES => READ_WAIT_CYCLES,
WRITE_WAIT_CYCLES => WRITE_WAIT_CYCLES
)
port map (
clk => clk,
reset => reset,
req => mem_req,
we => mem_we,
addr => mem_addr,
wdata => mem_wdata,
rdata => mem_rdata,
ready => mem_ready,
reload_req => reload_req,
reload_ready => reload_ready,
sram_addr => sram_addr,
sram_data => sram_data,
sram_ce_n => sram_ce_n,
sram_oe_n => sram_oe_n,
sram_we_n => sram_we_n
);
sram_i : entity work.sram8_model
generic map (
MEM_FILE => ROM_FILE,
ADDR_WIDTH => SRAM_ADDR_WIDTH,
OUTPUT_DELAY_NS => SRAM_OUTPUT_DELAY_NS,
POISON_UNINITIALIZED => POISON_UNINITIALIZED
)
port map (
addr => sram_addr,
data => sram_data,
ce_n => sram_ce_n,
oe_n => sram_oe_n,
we_n => sram_we_n
);
block_i : entity work.ilo_block_store
generic map (
BLOCK_FILE => BLOCK_FILE,
BLOCK_CELLS => BLOCK_CELLS,
READ_WAIT_CYCLES => BLOCK_READ_WAIT_CYCLES,
WRITE_WAIT_CYCLES => BLOCK_WRITE_WAIT_CYCLES,
POISON_UNINITIALIZED => POISON_UNINITIALIZED
)
port map (
clk => clk,
req => block_req,
we => block_we,
addr => block_addr,
wdata => block_wdata,
rdata => block_rdata,
ready => block_ready
);
core_i : entity work.ilo_core
port map (
clk => clk,
reset => reset,
mem_req => mem_req,
mem_we => mem_we,
mem_addr => mem_addr,
mem_wdata => mem_wdata,
mem_rdata => mem_rdata,
mem_ready => mem_ready,
serial_tx_valid => serial_tx_valid,
serial_tx_data => serial_tx_data,
serial_tx_ready => '1',
serial_rx_req => serial_rx_req,
serial_rx_valid => serial_rx_valid,
serial_rx_data => serial_rx_data,
block_req => block_req,
block_we => block_we,
block_addr => block_addr,
block_wdata => block_wdata,
block_rdata => block_rdata,
block_ready => block_ready,
reload_req => reload_req,
reload_ready => reload_ready,
halted => halted,
errored => errored,
error_code => error_code
);
process
begin
reset <= '1';
wait for 50 ns;
wait until rising_edge(clk);
reset <= '0';
wait;
end process;
process(clk)
variable l : line;
variable byte_value : integer;
variable rx_served : boolean := false;
begin
if rising_edge(clk) then
serial_rx_valid <= '0';
if reset = '1' then
rx_served := false;
serial_rx_data <= (others => '0');
elsif serial_rx_req = '0' then
rx_served := false;
elsif not rx_served then
readline(rx_file, l);
read(l, byte_value);
if byte_value < 0 then
byte_value := 0;
elsif byte_value > 255 then
byte_value := 255;
end if;
serial_rx_data <= std_logic_vector(to_unsigned(byte_value, 8));
serial_rx_valid <= '1';
rx_served := true;
end if;
end if;
end process;
process(clk)
variable prev_valid : std_logic := '0';
variable prev_data : std_logic_vector(7 downto 0) := (others => '0');
begin
if rising_edge(clk) then
if reset = '1' then
prev_valid := '0';
prev_data := (others => '0');
else
if serial_rx_valid = '1' then
assert not is_x(serial_rx_data)
report "serial_rx_data is invalid while serial_rx_valid is asserted"
severity failure;
if prev_valid = '1' then
assert serial_rx_data = prev_data
report "serial_rx_data changed while serial_rx_valid remained asserted"
severity failure;
end if;
end if;
prev_valid := serial_rx_valid;
prev_data := serial_rx_data;
end if;
end if;
end process;
process(clk)
variable l : line;
begin
if rising_edge(clk) then
if serial_tx_valid = '1' then
write(l, to_integer(unsigned(serial_tx_data)));
writeline(tx_file, l);
flush(tx_file);
end if;
end if;
end process;
process
variable l : line;
begin
if MAX_CYCLES = 0 then
loop
wait until rising_edge(clk);
if halted = '1' then
write(l, string'("HALT"));
writeline(output, l);
wait;
elsif errored = '1' then
write(l, string'("ERROR: "));
write(l, to_integer(error_code));
writeline(output, l);
assert false report "ERROR" severity failure;
end if;
end loop;
else
for cycle in 0 to MAX_CYCLES loop
wait until rising_edge(clk);
if halted = '1' then
write(l, string'("HALT"));
writeline(output, l);
wait;
elsif errored = '1' then
write(l, string'("ERROR: "));
write(l, to_integer(error_code));
writeline(output, l);
assert false report "ERROR" severity failure;
end if;
end loop;
assert false report "TIMEOUT" severity failure;
end if;
end process;
end architecture;
|
Added ilo-vm/vhdl/sim/ilo_system_tb.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use work.ilo_pkg.all;
entity ilo_system_tb is
generic (
ROM_FILE : string := "";
BLOCK_FILE : string := "";
BLOCK_CELLS : natural := 1024;
MEM_READ_WAIT_CYCLES : natural := 0;
MEM_WRITE_WAIT_CYCLES : natural := 0;
BLOCK_READ_WAIT_CYCLES : natural := 0;
BLOCK_WRITE_WAIT_CYCLES : natural := 0;
RESET_CYCLES : natural := 4;
POISON_UNINITIALIZED : boolean := false;
MAX_CYCLES : natural := 1000000;
RX_TEXT : string := ""
);
end entity;
architecture sim of ilo_system_tb is
signal clk : std_logic := '0';
signal reset : std_logic := '1';
signal serial_tx_valid : std_logic;
signal serial_tx_data : std_logic_vector(7 downto 0);
signal serial_rx_req : std_logic;
signal serial_rx_valid : std_logic := '0';
signal serial_rx_data : std_logic_vector(7 downto 0) := (others => '0');
signal halted : std_logic;
signal errored : std_logic;
signal error_code : unsigned(7 downto 0);
begin
clk <= not clk after 5 ns;
system_i : entity work.ilo_system
generic map (
ROM_FILE => ROM_FILE,
BLOCK_FILE => BLOCK_FILE,
BLOCK_CELLS => BLOCK_CELLS,
MEM_READ_WAIT_CYCLES => MEM_READ_WAIT_CYCLES,
MEM_WRITE_WAIT_CYCLES => MEM_WRITE_WAIT_CYCLES,
BLOCK_READ_WAIT_CYCLES => BLOCK_READ_WAIT_CYCLES,
BLOCK_WRITE_WAIT_CYCLES => BLOCK_WRITE_WAIT_CYCLES,
RESET_CYCLES => RESET_CYCLES,
POISON_UNINITIALIZED => POISON_UNINITIALIZED
)
port map (
clk => clk,
reset => reset,
serial_tx_valid => serial_tx_valid,
serial_tx_data => serial_tx_data,
serial_rx_req => serial_rx_req,
serial_rx_valid => serial_rx_valid,
serial_rx_data => serial_rx_data,
halted => halted,
errored => errored,
error_code => error_code
);
process
begin
reset <= '1';
wait for 50 ns;
wait until rising_edge(clk);
reset <= '0';
wait;
end process;
process(clk)
variable rx_index : natural := 1;
variable rx_served : boolean := false;
begin
if rising_edge(clk) then
serial_rx_valid <= '0';
if reset = '1' then
rx_index := 1;
rx_served := false;
serial_rx_data <= (others => '0');
elsif serial_rx_req = '0' then
rx_served := false;
elsif not rx_served then
if rx_index <= RX_TEXT'length then
serial_rx_data <= std_logic_vector(to_unsigned(character'pos(RX_TEXT(rx_index)), 8));
serial_rx_valid <= '1';
rx_index := rx_index + 1;
rx_served := true;
end if;
end if;
end if;
end process;
process(clk)
variable prev_valid : std_logic := '0';
variable prev_data : std_logic_vector(7 downto 0) := (others => '0');
begin
if rising_edge(clk) then
if reset = '1' then
prev_valid := '0';
prev_data := (others => '0');
else
if serial_rx_valid = '1' then
assert not is_x(serial_rx_data)
report "serial_rx_data is invalid while serial_rx_valid is asserted"
severity failure;
if prev_valid = '1' then
assert serial_rx_data = prev_data
report "serial_rx_data changed while serial_rx_valid remained asserted"
severity failure;
end if;
end if;
prev_valid := serial_rx_valid;
prev_data := serial_rx_data;
end if;
end if;
end process;
process(clk)
variable l : line;
begin
if rising_edge(clk) then
if serial_tx_valid = '1' then
write(l, string'("SERIAL_TX: "));
write(l, to_integer(unsigned(serial_tx_data)));
writeline(output, l);
end if;
end if;
end process;
process
variable l : line;
begin
for cycle in 0 to MAX_CYCLES loop
wait until rising_edge(clk);
if halted = '1' then
write(l, string'("FINAL_STACK:"));
for i in DS_DEPTH downto 1 loop
if i <= sim_debug.get_sp then
write(l, string'(" "));
write(l, to_integer(sim_debug.get_ds(i)));
end if;
end loop;
writeline(output, l);
assert false report "HALT" severity failure;
elsif errored = '1' then
write(l, string'("ERROR: "));
write(l, to_integer(error_code));
writeline(output, l);
assert false report "ERROR" severity failure;
end if;
end loop;
assert false report "TIMEOUT" severity failure;
end process;
end architecture;
|
Added ilo-vm/vhdl/sim/ilo_tb.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use work.ilo_pkg.all;
entity ilo_tb is
generic (
ROM_FILE : string := "";
BLOCK_FILE : string := "";
BLOCK_CELLS : natural := 1024;
MEM_READ_WAIT_CYCLES : natural := 0;
MEM_WRITE_WAIT_CYCLES : natural := 0;
BLOCK_READ_WAIT_CYCLES : natural := 0;
BLOCK_WRITE_WAIT_CYCLES : natural := 0;
POISON_UNINITIALIZED : boolean := false;
MAX_CYCLES : natural := 1000000;
TX_READY_DELAY_CYCLES : natural := 0;
RX_TEXT : string := ""
);
end entity;
architecture sim of ilo_tb is
signal clk : std_logic := '0';
signal reset : std_logic := '1';
signal mem_req : std_logic;
signal mem_we : std_logic;
signal mem_addr : addr_t;
signal mem_wdata : cell_t;
signal mem_rdata : cell_t;
signal mem_ready : std_logic;
signal serial_tx_valid : std_logic;
signal serial_tx_data : std_logic_vector(7 downto 0);
signal serial_tx_ready : std_logic := '1';
signal serial_rx_req : std_logic;
signal serial_rx_valid : std_logic := '0';
signal serial_rx_data : std_logic_vector(7 downto 0) := (others => '0');
signal block_req : std_logic;
signal block_we : std_logic;
signal block_addr : unsigned(31 downto 0);
signal block_wdata : cell_t;
signal block_rdata : cell_t;
signal block_ready : std_logic;
signal reload_req : std_logic;
signal reload_ready : std_logic;
signal halted : std_logic;
signal errored : std_logic;
signal error_code : unsigned(7 downto 0);
begin
clk <= not clk after 5 ns;
mem_i : entity work.ilo_memory
generic map (
ROM_FILE => ROM_FILE,
READ_WAIT_CYCLES => MEM_READ_WAIT_CYCLES,
WRITE_WAIT_CYCLES => MEM_WRITE_WAIT_CYCLES,
POISON_UNINITIALIZED => POISON_UNINITIALIZED
)
port map (
clk => clk,
req => mem_req,
we => mem_we,
addr => mem_addr,
wdata => mem_wdata,
rdata => mem_rdata,
ready => mem_ready,
reload_req => reload_req,
reload_ready => reload_ready
);
block_i : entity work.ilo_block_store
generic map (
BLOCK_FILE => BLOCK_FILE,
BLOCK_CELLS => BLOCK_CELLS,
READ_WAIT_CYCLES => BLOCK_READ_WAIT_CYCLES,
WRITE_WAIT_CYCLES => BLOCK_WRITE_WAIT_CYCLES,
POISON_UNINITIALIZED => POISON_UNINITIALIZED
)
port map (
clk => clk,
req => block_req,
we => block_we,
addr => block_addr,
wdata => block_wdata,
rdata => block_rdata,
ready => block_ready
);
core_i : entity work.ilo_core
port map (
clk => clk,
reset => reset,
mem_req => mem_req,
mem_we => mem_we,
mem_addr => mem_addr,
mem_wdata => mem_wdata,
mem_rdata => mem_rdata,
mem_ready => mem_ready,
serial_tx_valid => serial_tx_valid,
serial_tx_data => serial_tx_data,
serial_tx_ready => serial_tx_ready,
serial_rx_req => serial_rx_req,
serial_rx_valid => serial_rx_valid,
serial_rx_data => serial_rx_data,
block_req => block_req,
block_we => block_we,
block_addr => block_addr,
block_wdata => block_wdata,
block_rdata => block_rdata,
block_ready => block_ready,
reload_req => reload_req,
reload_ready => reload_ready,
halted => halted,
errored => errored,
error_code => error_code
);
process
begin
reset <= '1';
wait for 50 ns;
wait until rising_edge(clk);
reset <= '0';
wait;
end process;
process(clk)
variable cycles : natural := 0;
begin
if rising_edge(clk) then
if reset = '1' then
cycles := 0;
if TX_READY_DELAY_CYCLES = 0 then
serial_tx_ready <= '1';
else
serial_tx_ready <= '0';
end if;
elsif cycles >= TX_READY_DELAY_CYCLES then
serial_tx_ready <= '1';
else
cycles := cycles + 1;
serial_tx_ready <= '0';
end if;
end if;
end process;
process(clk)
variable rx_index : natural := 1;
variable rx_served : boolean := false;
begin
if rising_edge(clk) then
serial_rx_valid <= '0';
if reset = '1' then
rx_index := 1;
rx_served := false;
serial_rx_data <= (others => '0');
elsif serial_rx_req = '0' then
rx_served := false;
elsif not rx_served then
if rx_index <= RX_TEXT'length then
serial_rx_data <= std_logic_vector(to_unsigned(character'pos(RX_TEXT(rx_index)), 8));
serial_rx_valid <= '1';
rx_index := rx_index + 1;
rx_served := true;
end if;
end if;
end if;
end process;
process(clk)
variable prev_valid : std_logic := '0';
variable prev_data : std_logic_vector(7 downto 0) := (others => '0');
begin
if rising_edge(clk) then
if reset = '1' then
prev_valid := '0';
prev_data := (others => '0');
else
if serial_rx_valid = '1' then
assert not is_x(serial_rx_data)
report "serial_rx_data is invalid while serial_rx_valid is asserted"
severity failure;
if prev_valid = '1' then
assert serial_rx_data = prev_data
report "serial_rx_data changed while serial_rx_valid remained asserted"
severity failure;
end if;
end if;
prev_valid := serial_rx_valid;
prev_data := serial_rx_data;
end if;
end if;
end process;
process(clk)
variable l : line;
begin
if rising_edge(clk) then
assert not (serial_tx_valid = '1' and serial_tx_ready = '0')
report "serial_tx_valid asserted while serial_tx_ready was low"
severity failure;
if serial_tx_valid = '1' then
write(l, string'("SERIAL_TX: "));
write(l, to_integer(unsigned(serial_tx_data)));
writeline(output, l);
end if;
end if;
end process;
process
variable l : line;
begin
for cycle in 0 to MAX_CYCLES loop
wait until rising_edge(clk);
if halted = '1' then
write(l, string'("FINAL_STACK:"));
for i in DS_DEPTH downto 1 loop
if i <= sim_debug.get_sp then
write(l, string'(" "));
write(l, to_integer(sim_debug.get_ds(i)));
end if;
end loop;
writeline(output, l);
assert false report "HALT" severity failure;
elsif errored = '1' then
write(l, string'("ERROR: "));
write(l, to_integer(error_code));
writeline(output, l);
assert false report "ERROR" severity failure;
end if;
end loop;
assert false report "TIMEOUT" severity failure;
end process;
end architecture;
|
Added ilo-vm/vhdl/sim/ilo_terminal_tb.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use work.ilo_pkg.all;
entity ilo_terminal_tb is
generic (
ROM_FILE : string := "";
BLOCK_FILE : string := "";
BLOCK_CELLS : natural := 1024;
MEM_READ_WAIT_CYCLES : natural := 0;
MEM_WRITE_WAIT_CYCLES : natural := 0;
BLOCK_READ_WAIT_CYCLES : natural := 0;
BLOCK_WRITE_WAIT_CYCLES : natural := 0;
POISON_UNINITIALIZED : boolean := false;
RX_FIFO : string := "ilo-vhdl/build/terminal.rx";
TX_FIFO : string := "ilo-vhdl/build/terminal.tx";
MAX_CYCLES : natural := 0;
CLOCK_PERIOD_NS : positive := 10
);
end entity;
architecture sim of ilo_terminal_tb is
constant CLK_HALF_PERIOD : time := (CLOCK_PERIOD_NS * 1 ns) / 2;
signal clk : std_logic := '0';
signal reset : std_logic := '1';
signal mem_req : std_logic;
signal mem_we : std_logic;
signal mem_addr : addr_t;
signal mem_wdata : cell_t;
signal mem_rdata : cell_t;
signal mem_ready : std_logic;
signal serial_tx_valid : std_logic;
signal serial_tx_data : std_logic_vector(7 downto 0);
signal serial_rx_req : std_logic;
signal serial_rx_valid : std_logic := '0';
signal serial_rx_data : std_logic_vector(7 downto 0) := (others => '0');
signal block_req : std_logic;
signal block_we : std_logic;
signal block_addr : unsigned(31 downto 0);
signal block_wdata : cell_t;
signal block_rdata : cell_t;
signal block_ready : std_logic;
signal reload_req : std_logic;
signal reload_ready : std_logic;
signal halted : std_logic;
signal errored : std_logic;
signal error_code : unsigned(7 downto 0);
file rx_file : text open read_mode is RX_FIFO;
file tx_file : text open write_mode is TX_FIFO;
begin
clk <= not clk after CLK_HALF_PERIOD;
mem_i : entity work.ilo_memory
generic map (
ROM_FILE => ROM_FILE,
READ_WAIT_CYCLES => MEM_READ_WAIT_CYCLES,
WRITE_WAIT_CYCLES => MEM_WRITE_WAIT_CYCLES,
POISON_UNINITIALIZED => POISON_UNINITIALIZED
)
port map (
clk => clk,
req => mem_req,
we => mem_we,
addr => mem_addr,
wdata => mem_wdata,
rdata => mem_rdata,
ready => mem_ready,
reload_req => reload_req,
reload_ready => reload_ready
);
block_i : entity work.ilo_block_store
generic map (
BLOCK_FILE => BLOCK_FILE,
BLOCK_CELLS => BLOCK_CELLS,
READ_WAIT_CYCLES => BLOCK_READ_WAIT_CYCLES,
WRITE_WAIT_CYCLES => BLOCK_WRITE_WAIT_CYCLES,
POISON_UNINITIALIZED => POISON_UNINITIALIZED
)
port map (
clk => clk,
req => block_req,
we => block_we,
addr => block_addr,
wdata => block_wdata,
rdata => block_rdata,
ready => block_ready
);
core_i : entity work.ilo_core
port map (
clk => clk,
reset => reset,
mem_req => mem_req,
mem_we => mem_we,
mem_addr => mem_addr,
mem_wdata => mem_wdata,
mem_rdata => mem_rdata,
mem_ready => mem_ready,
serial_tx_valid => serial_tx_valid,
serial_tx_data => serial_tx_data,
serial_tx_ready => '1',
serial_rx_req => serial_rx_req,
serial_rx_valid => serial_rx_valid,
serial_rx_data => serial_rx_data,
block_req => block_req,
block_we => block_we,
block_addr => block_addr,
block_wdata => block_wdata,
block_rdata => block_rdata,
block_ready => block_ready,
reload_req => reload_req,
reload_ready => reload_ready,
halted => halted,
errored => errored,
error_code => error_code
);
process
begin
reset <= '1';
wait for 50 ns;
wait until rising_edge(clk);
reset <= '0';
wait;
end process;
process(clk)
variable l : line;
variable byte_value : integer;
variable rx_served : boolean := false;
begin
if rising_edge(clk) then
serial_rx_valid <= '0';
if reset = '1' then
rx_served := false;
serial_rx_data <= (others => '0');
elsif serial_rx_req = '0' then
rx_served := false;
elsif not rx_served then
readline(rx_file, l);
read(l, byte_value);
if byte_value < 0 then
byte_value := 0;
elsif byte_value > 255 then
byte_value := 255;
end if;
serial_rx_data <= std_logic_vector(to_unsigned(byte_value, 8));
serial_rx_valid <= '1';
rx_served := true;
end if;
end if;
end process;
process(clk)
variable prev_valid : std_logic := '0';
variable prev_data : std_logic_vector(7 downto 0) := (others => '0');
begin
if rising_edge(clk) then
if reset = '1' then
prev_valid := '0';
prev_data := (others => '0');
else
if serial_rx_valid = '1' then
assert not is_x(serial_rx_data)
report "serial_rx_data is invalid while serial_rx_valid is asserted"
severity failure;
if prev_valid = '1' then
assert serial_rx_data = prev_data
report "serial_rx_data changed while serial_rx_valid remained asserted"
severity failure;
end if;
end if;
prev_valid := serial_rx_valid;
prev_data := serial_rx_data;
end if;
end if;
end process;
process(clk)
variable l : line;
begin
if rising_edge(clk) then
if serial_tx_valid = '1' then
write(l, to_integer(unsigned(serial_tx_data)));
writeline(tx_file, l);
flush(tx_file);
end if;
end if;
end process;
process
variable l : line;
begin
if MAX_CYCLES = 0 then
loop
wait until rising_edge(clk);
if halted = '1' then
write(l, string'("HALT"));
writeline(output, l);
wait;
elsif errored = '1' then
write(l, string'("ERROR: "));
write(l, to_integer(error_code));
writeline(output, l);
assert false report "ERROR" severity failure;
end if;
end loop;
else
for cycle in 0 to MAX_CYCLES loop
wait until rising_edge(clk);
if halted = '1' then
write(l, string'("HALT"));
writeline(output, l);
wait;
elsif errored = '1' then
write(l, string'("ERROR: "));
write(l, to_integer(error_code));
writeline(output, l);
assert false report "ERROR" severity failure;
end if;
end loop;
assert false report "TIMEOUT" severity failure;
end if;
end process;
end architecture;
|
Added ilo-vm/vhdl/sim/sdram_model.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use work.ilo_pkg.all;
entity sdram_model is
generic (
MEM_FILE : string := "";
HALFWORD_ADDR_WIDTH : natural := 17;
CAS_LATENCY : natural := 2;
TRCD_CYCLES : natural := 1;
TRP_CYCLES : natural := 1;
TRFC_CYCLES : natural := 4;
TMRD_CYCLES : natural := 2;
WRITE_RECOVERY_CYCLES : natural := 2;
INIT_WAIT_CYCLES : natural := 0;
MAX_REFRESH_INTERVAL_CYCLES : natural := 0
);
port (
clk : in std_logic;
a : in unsigned(12 downto 0);
ba : in unsigned(1 downto 0);
dq : inout std_logic_vector(15 downto 0);
dqm : in std_logic_vector(1 downto 0);
csn : in std_logic;
cke : in std_logic;
wen : in std_logic;
casn : in std_logic;
rasn : in std_logic
);
end entity;
architecture sim of sdram_model is
constant DEPTH : natural := 2 ** HALFWORD_ADDR_WIDTH;
type ram_t is array (0 to DEPTH - 1) of std_logic_vector(15 downto 0);
type bank_rows_t is array (0 to 3) of unsigned(12 downto 0);
type bank_open_t is array (0 to 3) of boolean;
type bank_timing_t is array (0 to 3) of natural;
type init_state_t is (
INIT_NEED_CKE,
INIT_NEED_PRECHARGE_ALL,
INIT_NEED_REFRESH_1,
INIT_NEED_REFRESH_2,
INIT_NEED_MODE,
INIT_MODE_WAIT,
INIT_DONE
);
signal dq_out : std_logic_vector(15 downto 0) := (others => '0');
signal dq_drive : std_logic := '0';
function mem_index(row : unsigned(12 downto 0); bank : unsigned(1 downto 0); col : unsigned(8 downto 0)) return natural is
variable raw : unsigned(HALFWORD_ADDR_WIDTH - 1 downto 0) := (others => '0');
begin
raw(8 downto 0) := col;
if HALFWORD_ADDR_WIDTH > 9 then
raw(10 downto 9) := bank;
end if;
if HALFWORD_ADDR_WIDTH > 11 then
raw(HALFWORD_ADDR_WIDTH - 1 downto 11) := row(HALFWORD_ADDR_WIDTH - 12 downto 0);
end if;
return to_integer(raw);
end function;
begin
dq <= dq_out when dq_drive = '1' else (others => 'Z');
process(clk)
file f : text;
variable l : line;
variable v : integer;
variable ram : ram_t := (others => (others => '0'));
variable active_row : bank_rows_t := (others => (others => '0'));
variable bank_open : bank_open_t := (others => false);
variable trcd_wait : bank_timing_t := (others => 0);
variable trp_wait : bank_timing_t := (others => 0);
variable write_recovery_wait : bank_timing_t := (others => 0);
variable trfc_wait : natural := 0;
variable tmrd_wait : natural := 0;
variable cycles_since_refresh : natural := 0;
variable have_refresh : boolean := false;
variable memory_loaded : boolean := false;
variable init_state : init_state_t := INIT_NEED_CKE;
variable cke_high_cycles : natural := 0;
variable word_index : natural;
variable half_index : natural;
variable raw : std_logic_vector(CELL_WIDTH - 1 downto 0);
variable read_delay : natural := 0;
variable read_pending : boolean := false;
variable read_data : std_logic_vector(15 downto 0) := (others => '0');
variable b : natural;
variable idx : natural;
begin
if rising_edge(clk) then
for bank in 0 to 3 loop
if trcd_wait(bank) > 0 then
trcd_wait(bank) := trcd_wait(bank) - 1;
end if;
if trp_wait(bank) > 0 then
trp_wait(bank) := trp_wait(bank) - 1;
end if;
if write_recovery_wait(bank) > 0 then
write_recovery_wait(bank) := write_recovery_wait(bank) - 1;
end if;
end loop;
if trfc_wait > 0 then
trfc_wait := trfc_wait - 1;
end if;
if tmrd_wait > 0 then
tmrd_wait := tmrd_wait - 1;
end if;
if have_refresh and MAX_REFRESH_INTERVAL_CYCLES > 0 then
cycles_since_refresh := cycles_since_refresh + 1;
assert cycles_since_refresh <= MAX_REFRESH_INTERVAL_CYCLES
report "sdram_model: maximum refresh interval exceeded"
severity failure;
end if;
if not memory_loaded then
if MEM_FILE /= "" then
file_open(f, MEM_FILE, read_mode);
word_index := 0;
while not endfile(f) and (word_index * 2 + 1) < DEPTH loop
readline(f, l);
read(l, v);
raw := std_logic_vector(to_signed(v, CELL_WIDTH));
half_index := word_index * 2;
ram(half_index) := raw(15 downto 0);
ram(half_index + 1) := raw(31 downto 16);
word_index := word_index + 1;
end loop;
file_close(f);
end if;
memory_loaded := true;
end if;
dq_drive <= '0';
if read_pending then
if read_delay = 0 then
dq_out <= read_data;
dq_drive <= '1';
read_pending := false;
else
read_delay := read_delay - 1;
end if;
end if;
if cke = '0' then
cke_high_cycles := 0;
init_state := INIT_NEED_CKE;
have_refresh := false;
cycles_since_refresh := 0;
trfc_wait := 0;
tmrd_wait := 0;
trcd_wait := (others => 0);
trp_wait := (others => 0);
write_recovery_wait := (others => 0);
bank_open := (others => false);
else
cke_high_cycles := cke_high_cycles + 1;
if init_state = INIT_NEED_CKE and cke_high_cycles >= INIT_WAIT_CYCLES then
init_state := INIT_NEED_PRECHARGE_ALL;
end if;
end if;
if init_state = INIT_MODE_WAIT and tmrd_wait = 0 then
init_state := INIT_DONE;
end if;
if cke = '1' and csn = '0' then
b := to_integer(ba);
if rasn = '0' and casn = '1' and wen = '1' then
assert init_state = INIT_DONE
report "sdram_model: ACTIVE before initialization complete"
severity failure;
assert trfc_wait = 0
report "sdram_model: ACTIVE violates tRFC"
severity failure;
assert trp_wait(b) = 0
report "sdram_model: ACTIVE violates tRP"
severity failure;
assert write_recovery_wait(b) = 0
report "sdram_model: ACTIVE violates write recovery"
severity failure;
active_row(b) := a;
bank_open(b) := true;
trcd_wait(b) := TRCD_CYCLES;
elsif rasn = '1' and casn = '0' and wen = '1' then
assert init_state = INIT_DONE
report "sdram_model: READ before initialization complete"
severity failure;
assert trfc_wait = 0
report "sdram_model: READ violates tRFC"
severity failure;
assert bank_open(b)
report "sdram_model: read from inactive bank"
severity failure;
assert trcd_wait(b) = 0
report "sdram_model: READ violates tRCD"
severity failure;
assert not read_pending
report "sdram_model: overlapping READ before CAS data"
severity failure;
idx := mem_index(active_row(b), ba, a(8 downto 0));
read_data := ram(idx);
read_delay := CAS_LATENCY;
read_pending := true;
if a(10) = '1' then
bank_open(b) := false;
trp_wait(b) := TRP_CYCLES;
end if;
elsif rasn = '1' and casn = '0' and wen = '0' then
assert init_state = INIT_DONE
report "sdram_model: WRITE before initialization complete"
severity failure;
assert trfc_wait = 0
report "sdram_model: WRITE violates tRFC"
severity failure;
assert bank_open(b)
report "sdram_model: write to inactive bank"
severity failure;
assert trcd_wait(b) = 0
report "sdram_model: WRITE violates tRCD"
severity failure;
assert dqm = "00"
report "sdram_model: byte-masked writes are not modeled"
severity failure;
assert not is_x(dq)
report "sdram_model: invalid or undriven data during write"
severity failure;
idx := mem_index(active_row(b), ba, a(8 downto 0));
ram(idx) := dq;
write_recovery_wait(b) := WRITE_RECOVERY_CYCLES;
if a(10) = '1' then
bank_open(b) := false;
trp_wait(b) := TRP_CYCLES;
end if;
elsif rasn = '0' and casn = '1' and wen = '0' then
assert init_state = INIT_DONE or init_state = INIT_NEED_PRECHARGE_ALL
report "sdram_model: PRECHARGE before expected init step"
severity failure;
assert trfc_wait = 0
report "sdram_model: PRECHARGE violates tRFC"
severity failure;
if init_state = INIT_NEED_PRECHARGE_ALL then
assert a(10) = '1'
report "sdram_model: initialization requires PRECHARGE ALL"
severity failure;
init_state := INIT_NEED_REFRESH_1;
end if;
if a(10) = '1' then
for bank in 0 to 3 loop
assert write_recovery_wait(bank) = 0
report "sdram_model: PRECHARGE ALL violates write recovery"
severity failure;
end loop;
bank_open := (others => false);
trp_wait := (others => TRP_CYCLES);
else
assert write_recovery_wait(b) = 0
report "sdram_model: PRECHARGE violates write recovery"
severity failure;
bank_open(b) := false;
trp_wait(b) := TRP_CYCLES;
end if;
elsif rasn = '0' and casn = '0' and wen = '1' then
assert init_state = INIT_DONE or init_state = INIT_NEED_REFRESH_1 or init_state = INIT_NEED_REFRESH_2
report "sdram_model: REFRESH before expected init step"
severity failure;
assert trfc_wait = 0
report "sdram_model: REFRESH violates tRFC"
severity failure;
if init_state = INIT_NEED_REFRESH_1 then
init_state := INIT_NEED_REFRESH_2;
elsif init_state = INIT_NEED_REFRESH_2 then
init_state := INIT_NEED_MODE;
end if;
trfc_wait := TRFC_CYCLES;
cycles_since_refresh := 0;
have_refresh := true;
elsif rasn = '0' and casn = '0' and wen = '0' then
assert init_state = INIT_DONE or init_state = INIT_NEED_MODE
report "sdram_model: MODE REGISTER SET before expected init step"
severity failure;
assert trfc_wait = 0
report "sdram_model: MODE REGISTER SET violates tRFC"
severity failure;
assert to_integer(unsigned(a(6 downto 4))) = CAS_LATENCY
report "sdram_model: mode register CAS latency does not match model CAS_LATENCY"
severity failure;
if init_state = INIT_NEED_MODE then
init_state := INIT_MODE_WAIT;
tmrd_wait := TMRD_CYCLES;
end if;
end if;
end if;
end if;
end process;
end architecture;
|
Added ilo-vm/vhdl/sim/sdram_model_timing_tb.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.env.all;
entity sdram_model_timing_tb is
generic (
VIOLATION : string := "TRCD"
);
end entity;
architecture sim of sdram_model_timing_tb is
function timing_for(
constant selector : string;
constant target : string;
constant enabled_value : natural;
constant disabled_value : natural
) return natural is
begin
if selector = target then
return enabled_value;
end if;
return disabled_value;
end function;
signal clk : std_logic := '0';
signal a : unsigned(12 downto 0) := (others => '0');
signal ba : unsigned(1 downto 0) := (others => '0');
signal dq : std_logic_vector(15 downto 0);
signal dqm : std_logic_vector(1 downto 0) := "00";
signal csn : std_logic := '1';
signal cke : std_logic := '1';
signal wen : std_logic := '1';
signal casn : std_logic := '1';
signal rasn : std_logic := '1';
signal dq_out : std_logic_vector(15 downto 0) := x"1234";
signal dq_drive : std_logic := '0';
procedure nop(
signal csn_s : out std_logic;
signal rasn_s : out std_logic;
signal casn_s : out std_logic;
signal wen_s : out std_logic
) is
begin
csn_s <= '0';
rasn_s <= '1';
casn_s <= '1';
wen_s <= '1';
end procedure;
procedure issue(
signal csn_s : out std_logic;
signal rasn_s : out std_logic;
signal casn_s : out std_logic;
signal wen_s : out std_logic;
constant ras_v : std_logic;
constant cas_v : std_logic;
constant we_v : std_logic
) is
begin
csn_s <= '0';
rasn_s <= ras_v;
casn_s <= cas_v;
wen_s <= we_v;
wait until rising_edge(clk);
nop(csn_s, rasn_s, casn_s, wen_s);
wait for 1 ns;
end procedure;
procedure wait_cycles(constant cycles : natural) is
begin
for i in 1 to cycles loop
wait until rising_edge(clk);
end loop;
wait for 1 ns;
end procedure;
procedure initialize_sdram(
signal a_s : out unsigned(12 downto 0);
signal csn_s : out std_logic;
signal rasn_s : out std_logic;
signal casn_s : out std_logic;
signal wen_s : out std_logic;
constant cas_bits : unsigned(2 downto 0)
) is
begin
a_s <= (others => '0');
a_s(10) <= '1';
issue(csn_s, rasn_s, casn_s, wen_s, '0', '1', '0'); -- PRECHARGE ALL
wait_cycles(4);
issue(csn_s, rasn_s, casn_s, wen_s, '0', '0', '1'); -- REFRESH 1
wait_cycles(4);
issue(csn_s, rasn_s, casn_s, wen_s, '0', '0', '1'); -- REFRESH 2
wait_cycles(4);
a_s <= (others => '0');
a_s(6 downto 4) <= cas_bits;
issue(csn_s, rasn_s, casn_s, wen_s, '0', '0', '0'); -- MODE
wait_cycles(2);
end procedure;
begin
clk <= not clk after 5 ns;
dq <= dq_out when dq_drive = '1' else (others => 'Z');
sdram_i : entity work.sdram_model
generic map (
CAS_LATENCY => 2,
TRCD_CYCLES => timing_for(VIOLATION, "TRCD", 3, 0),
TRP_CYCLES => timing_for(VIOLATION, "TRP", 3, 0),
TRFC_CYCLES => timing_for(VIOLATION, "TRFC", 3, 0),
WRITE_RECOVERY_CYCLES => timing_for(VIOLATION, "WRITE_RECOVERY", 3, 0),
MAX_REFRESH_INTERVAL_CYCLES => timing_for(VIOLATION, "REFRESH_INTERVAL", 2, 0)
)
port map (
clk => clk,
a => a,
ba => ba,
dq => dq,
dqm => dqm,
csn => csn,
cke => cke,
wen => wen,
casn => casn,
rasn => rasn
);
process
begin
nop(csn, rasn, casn, wen);
wait until rising_edge(clk);
wait for 1 ns;
if VIOLATION = "INIT_READ" then
a <= (others => '0');
issue(csn, rasn, casn, wen, '1', '0', '1'); -- READ before init
elsif VIOLATION = "INIT_WRITE" then
a <= (others => '0');
dq_drive <= '1';
issue(csn, rasn, casn, wen, '1', '0', '0'); -- WRITE before init
elsif VIOLATION = "INIT_PRECHARGE_BANK" then
a <= (others => '0');
issue(csn, rasn, casn, wen, '0', '1', '0'); -- PRECHARGE bank during init
elsif VIOLATION = "INIT_REFRESH_EARLY" then
issue(csn, rasn, casn, wen, '0', '0', '1'); -- REFRESH before PRECHARGE ALL
elsif VIOLATION = "INIT_MODE_EARLY" then
a <= (others => '0');
a(6 downto 4) <= "010";
issue(csn, rasn, casn, wen, '0', '0', '0'); -- MODE before refreshes
elsif VIOLATION = "CAS" then
initialize_sdram(a, csn, rasn, casn, wen, "011");
else
initialize_sdram(a, csn, rasn, casn, wen, "010");
end if;
if VIOLATION = "INIT_READ" or VIOLATION = "INIT_WRITE" or
VIOLATION = "INIT_PRECHARGE_BANK" or VIOLATION = "INIT_REFRESH_EARLY" or
VIOLATION = "INIT_MODE_EARLY" then
null;
elsif VIOLATION = "TRCD" then
a <= (others => '0');
issue(csn, rasn, casn, wen, '0', '1', '1'); -- ACTIVE
a <= (others => '0');
issue(csn, rasn, casn, wen, '1', '0', '1'); -- READ too soon
elsif VIOLATION = "TRP" then
a <= (others => '0');
a(10) <= '1';
issue(csn, rasn, casn, wen, '0', '1', '0'); -- PRECHARGE ALL
a <= (others => '0');
issue(csn, rasn, casn, wen, '0', '1', '1'); -- ACTIVE too soon
elsif VIOLATION = "TRFC" then
issue(csn, rasn, casn, wen, '0', '0', '1'); -- REFRESH
a <= (others => '0');
issue(csn, rasn, casn, wen, '0', '1', '1'); -- ACTIVE too soon
elsif VIOLATION = "CAS" then
null;
elsif VIOLATION = "WRITE_RECOVERY" then
a <= (others => '0');
issue(csn, rasn, casn, wen, '0', '1', '1'); -- ACTIVE
wait until rising_edge(clk);
wait until rising_edge(clk);
wait until rising_edge(clk);
wait for 1 ns;
a <= (others => '0');
a(10) <= '1';
dq_drive <= '1';
issue(csn, rasn, casn, wen, '1', '0', '0'); -- WRITE with auto-precharge
dq_drive <= '0';
a <= (others => '0');
issue(csn, rasn, casn, wen, '0', '1', '1'); -- ACTIVE before recovery
elsif VIOLATION = "REFRESH_INTERVAL" then
issue(csn, rasn, casn, wen, '0', '0', '1'); -- REFRESH
wait until rising_edge(clk);
wait until rising_edge(clk);
wait until rising_edge(clk);
wait until rising_edge(clk);
else
assert false report "unknown SDRAM timing violation selector" severity failure;
end if;
assert false report "SDRAM timing violation did not fail" severity failure;
stop;
end process;
end architecture;
|
Added ilo-vm/vhdl/sim/sram8_model.vhd.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use work.ilo_pkg.all;
entity sram8_model is
generic (
MEM_FILE : string := "";
ADDR_WIDTH : natural := 19;
OUTPUT_DELAY_NS : natural := 1;
POISON_UNINITIALIZED : boolean := false
);
port (
addr : in unsigned(ADDR_WIDTH - 1 downto 0);
data : inout std_logic_vector(7 downto 0);
ce_n : in std_logic;
oe_n : in std_logic;
we_n : in std_logic
);
end entity;
architecture sim of sram8_model is
constant BYTE_DEPTH : natural := 2 ** ADDR_WIDTH;
type byte_array_t is array (0 to BYTE_DEPTH - 1) of std_logic_vector(7 downto 0);
type byte_valid_array_t is array (0 to BYTE_DEPTH - 1) of boolean;
signal data_out : std_logic_vector(7 downto 0) := (others => '0');
begin
data <= data_out after OUTPUT_DELAY_NS * 1 ns
when ce_n = '0' and oe_n = '0' and we_n = '1' else
(others => 'Z') after OUTPUT_DELAY_NS * 1 ns;
process(addr, data, ce_n, oe_n, we_n)
file f : text;
variable l : line;
variable v : integer;
variable word_index : natural;
variable byte_index : natural;
variable raw : std_logic_vector(CELL_WIDTH - 1 downto 0);
variable ram : byte_array_t := (others => (others => '0'));
variable valid : byte_valid_array_t := (others => false);
variable initialized : boolean := false;
variable a : natural;
begin
if not initialized then
if MEM_FILE /= "" then
file_open(f, MEM_FILE, read_mode);
word_index := 0;
while not endfile(f) and (word_index * 4 + 3) < BYTE_DEPTH loop
readline(f, l);
read(l, v);
raw := std_logic_vector(to_signed(v, CELL_WIDTH));
byte_index := word_index * 4;
ram(byte_index) := raw(7 downto 0);
ram(byte_index + 1) := raw(15 downto 8);
ram(byte_index + 2) := raw(23 downto 16);
ram(byte_index + 3) := raw(31 downto 24);
valid(byte_index) := true;
valid(byte_index + 1) := true;
valid(byte_index + 2) := true;
valid(byte_index + 3) := true;
word_index := word_index + 1;
end loop;
file_close(f);
end if;
initialized := true;
end if;
if is_x(std_logic_vector(addr)) then
data_out <= (others => 'X');
else
a := to_integer(addr);
if ce_n = '0' then
assert not (oe_n = '0' and we_n = '0')
report "sram8_model: OE and WE active at the same time"
severity failure;
end if;
if ce_n = '0' and we_n = '0' then
assert not is_x(data)
report "sram8_model: invalid or undriven data during write"
severity failure;
ram(a) := data;
valid(a) := true;
end if;
if POISON_UNINITIALIZED and not valid(a) then
case a mod 4 is
when 0 => data_out <= x"EF";
when 1 => data_out <= x"BE";
when 2 => data_out <= x"AD";
when others => data_out <= x"DE";
end case;
else
data_out <= ram(a);
end if;
end if;
end process;
end architecture;
|
Added ilo-vm/vhdl/testdata/block-read.blocks.mem.
> | 1 | 123 |
Added ilo-vm/vhdl/testdata/test-board-boot-preloaded.pali.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | c Larger board-level SDRAM boot image for simulation preload. c Stores bytes in SDRAM-backed VM memory, fetches them, emits "BOOT", then halts. ~~~ : entry i liju.... r main : main i lilist.. d 66 d 4096 i lilist.. d 79 d 4097 i lilist.. d 79 d 4098 i lilist.. d 84 d 4099 i lifeliio d 4096 d 0 i lifeliio d 4097 d 0 i lifeliio d 4098 d 0 i lifeliio d 4099 d 0 i liio.... d 6 ~~~ |
Added ilo-vm/vhdl/testdata/test-io-block-read.pali.
> > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 | c Test io 2 block read c Reads block 0 to address 1000 and fetches the first cell. ~~~ i lililiio d 0 d 1000 d 2 i lifeliio d 1000 d 6 ~~~ |
Added ilo-vm/vhdl/testdata/test-io-block-write.pali.
> > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | c Test io 3 block write by writing block 0, reading it back, and fetching cell 0. ~~~ i lilist.. d 77 d 1000 i lililiio d 0 d 1000 d 3 i lililiio d 0 d 2000 d 2 i lifeliio d 2000 d 6 ~~~ |
Added ilo-vm/vhdl/testdata/test-io-emit.pali.
> > > > > > > > > | 1 2 3 4 5 6 7 8 9 |
c Test serial-style io 0 output
c Emits ASCII 65 ('A') and halts with an empty stack.
~~~
i liliio..
d 65
d 0
i liio....
d 6
~~~
|
Added ilo-vm/vhdl/testdata/test-io-read.pali.
> > > > > > > > | 1 2 3 4 5 6 7 8 | c Test serial-style io 1 input c Reads one byte from RX_TEXT and leaves it on the stack. ~~~ i liio.... d 1 i liio.... d 6 ~~~ |
Added ilo-vm/vhdl/testdata/test-io-reload.pali.
> > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | c Test I/O device 5 (reload image) c The first run changes memory at main/main_device so a non-reloaded restart c would halt. A correct reload restores the original image and reloads again. ~~~ : entry i liju.... r main : main i lilistli : main_device d 7425 r main d 6 i listliio r main_device d 5 ~~~ |
Added ilo-vm/vhdl/testdata/test-sdram-address-boundaries.pali.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | c Exercise SDRAM-backed VM stores/fetches across controller address boundaries. c Expected final stack: 501 402 401 302 301 202 201 102 101 ~~~ : entry i liju.... r main : main c adjacent cells i lilist.. d 101 d 2048 i lilist.. d 102 d 2049 c column/bank transition at a 256-cell boundary i lilist.. d 201 d 2303 i lilist.. d 202 d 2304 c another bank transition in the same row i lilist.. d 301 d 2559 i lilist.. d 302 d 2560 c row transition at a 1024-cell boundary i lilist.. d 401 d 3071 i lilist.. d 402 d 3072 c high modeled SDRAM address i lilist.. d 501 d 60000 c fetch back in write order; final stack is reported top-first i life.... d 2048 i life.... d 2049 i life.... d 2303 i life.... d 2304 i life.... d 2559 i life.... d 2560 i life.... d 3071 i life.... d 3072 i life.... d 60000 i liio.... d 6 ~~~ |
Added ilo-vm/vhdl/testdata/test-uninitialized-read.pali.
> > > > > > | 1 2 3 4 5 6 | c Fetch an unloaded memory cell to verify strict simulation poison mode. ~~~ i lifeliio d 60000 d 6 ~~~ |
Added ilo-vm/vhdl/testdata/test-uninitialized-read.partial.mem.
> > > | 1 2 3 | 486608897 60000 6 |