added v2.0
This commit is contained in:
40
06_IO_Devices/04_SRAM/Include.v
Normal file
40
06_IO_Devices/04_SRAM/Include.v
Normal file
@@ -0,0 +1,40 @@
|
||||
`include "../../01_Boolean_Logic/Nand.v"
|
||||
`include "../../01_Boolean_Logic/Not.v"
|
||||
`include "../../01_Boolean_Logic/Buffer.v"
|
||||
`include "../../01_Boolean_Logic/And.v"
|
||||
`include "../../01_Boolean_Logic/Or.v"
|
||||
`include "../../01_Boolean_Logic/Xor.v"
|
||||
`include "../../01_Boolean_Logic/Mux.v"
|
||||
`include "../../01_Boolean_Logic/DMux.v"
|
||||
`include "../../01_Boolean_Logic/Not16.v"
|
||||
`include "../../01_Boolean_Logic/Buffer16.v"
|
||||
`include "../../01_Boolean_Logic/And16.v"
|
||||
`include "../../01_Boolean_Logic/Or16.v"
|
||||
`include "../../01_Boolean_Logic/Mux16.v"
|
||||
`include "../../01_Boolean_Logic/Or8Way.v"
|
||||
`include "../../01_Boolean_Logic/Mux4Way16.v"
|
||||
`include "../../01_Boolean_Logic/Mux8Way16.v"
|
||||
`include "../../01_Boolean_Logic/DMux4Way.v"
|
||||
`include "../../01_Boolean_Logic/DMux8Way.v"
|
||||
|
||||
`include "../../02_Boolean_Arithmetic/HalfAdder.v"
|
||||
`include "../../02_Boolean_Arithmetic/FullAdder.v"
|
||||
`include "../../02_Boolean_Arithmetic/Add16.v"
|
||||
`include "../../02_Boolean_Arithmetic/Inc16.v"
|
||||
`include "../../02_Boolean_Arithmetic/ALU.v"
|
||||
|
||||
`include "../../03_Sequential_Logic/DFF.v"
|
||||
`include "../../03_Sequential_Logic/Bit.v"
|
||||
`include "../../03_Sequential_Logic/Register.v"
|
||||
`include "../../03_Sequential_Logic/PC.v"
|
||||
`include "../../03_Sequential_Logic/BitShift9R.v"
|
||||
`include "../../03_Sequential_Logic/BitShift8L.v"
|
||||
|
||||
`include "../../06_IO_Devices/UartTX.v"
|
||||
`include "../../06_IO_Devices/UartRX.v"
|
||||
`include "../../06_IO_Devices/SPI.v"
|
||||
`include "../../06_IO_Devices/InOut.v"
|
||||
`include "../../06_IO_Devices/SRAM_D.v"
|
||||
`include "../../06_IO_Devices/GO.v"
|
||||
`include "../../06_IO_Devices/LCD.v"
|
||||
`include "../../06_IO_Devices/RTP.v"
|
12
06_IO_Devices/04_SRAM/Makefile
Normal file
12
06_IO_Devices/04_SRAM/Makefile
Normal file
@@ -0,0 +1,12 @@
|
||||
NAME = buffer
|
||||
|
||||
all: asm install
|
||||
|
||||
asm:
|
||||
../../tools/Assembler/assembler.pyc $(NAME).asm
|
||||
install:
|
||||
cp $(NAME).hack ../00_HACK/ROM.hack
|
||||
clean:
|
||||
rm -f *.hack *~
|
||||
|
||||
.PHONY: all clean
|
168
06_IO_Devices/04_SRAM/Readme.md
Normal file
168
06_IO_Devices/04_SRAM/Readme.md
Normal file
@@ -0,0 +1,168 @@
|
||||
## 04 SRAM
|
||||
|
||||
The evaluation board iCE40HX1K-EVB includes an 512kbyte static ram chip K6R4016V1D. The SRAM chip connects to iCE40HX1K with 37 wires;
|
||||
|
||||
- SRAM_ADDR 18 bit
|
||||
- SRAM_DATA 16 bit (bidiretional inout)
|
||||
- SRAM_CSX (chip select not)
|
||||
- SRAM_OEX (output enable not)
|
||||
- SRAM_WEX (write enable not)
|
||||
|
||||
To read and write to the SRAM chip we will add two special function register to HACK:
|
||||
|
||||
1. SRAM_A is a 16 bit register mapped at memory location 4104. SRAM_ADDR controls the 16 lower bits of the 18 bit address bus. The two most significant bits are allways 0, so we can only access 64k x 16 bit words of SRAM chip.
|
||||
|
||||
2. SRAM_D is a special function register mapped at memory location 4105. SRAM_D controls the bidirectional data bus and the control wires CSX, OEX and WEX.
|
||||
|
||||
**Note:** the 16 bit data bus is bidirectional and has therefore to be connected over a tristate buffer. This is done with `InOut.v` which is considered primitive and must not be implemented.
|
||||
|
||||
### Chip specification SRAM_A
|
||||
|
||||
SRAM_A is a simple `Register` that stores the lower 16 bit of the 18 bit address of the SRAM chip.
|
||||
|
||||
### Chip specification SRAM_D
|
||||
|
||||
| IN/OUT | wire | function |
|
||||
| ------ | --------------- | -------------------------- |
|
||||
| IN | clk | system clock (25MHz) |
|
||||
| IN | load | initiate a write operation |
|
||||
| IN | in[15:0] | data to write to SRAM |
|
||||
| OUT | out[15:0] | data read from SRAM |
|
||||
| INOUT | SRAM_DATA[15:0] | bidirectional data bus |
|
||||
| OUT | SRAM_CSX | chip select not |
|
||||
| OUT | SRAM_OEX | output enable not |
|
||||
| OUT | SRAM_WEX | write enable not |
|
||||
|
||||
When load[t]=1 transmission of word in[15:0] is initiated. The word is send to SRAM over the bidirectional wires SRAM_DATA (direction out) and a write pulse will be triggered for one cycle at t+1:
|
||||
|
||||
* SRAM_OEX=1
|
||||
|
||||
* SRAM_WEX=0
|
||||
|
||||
When load=0 SRAM_DATA will be used as input and the data of the SRAM chip will be presented at out[15:0]
|
||||
|
||||
- SRAM_OEX=0
|
||||
|
||||
- SRAM_WEX=1
|
||||
|
||||
SRAM_CSX can be set to low all the time.
|
||||
|
||||
### Proposed Implementation ADDR_A
|
||||
|
||||
Use a `Register` to store the lower 16 bit of SRAM_ADDR (The two most significant bits are hardwired to 0).
|
||||
|
||||
### Proposed Implementation ADDR_D
|
||||
|
||||
Use a `DFF` to delay the load signal. Use a `Register` to store the data in[15:0] to be stored. Use a tristate buffer `InOut.v` to control the direction of the bidirectional SRAM_DATA data bus.
|
||||
|
||||
### Memory map
|
||||
|
||||
The special function register `SRAM_A` and `SRAM_D` are mapped to memory map of HACK according to:
|
||||
|
||||
| address | I/O device | R/W | function |
|
||||
| ------- | ---------- | --- | ------------------------------ |
|
||||
| 4101 | SRAM_A | R | address of SRAM |
|
||||
| 4102 | SRAM_D | R | read data from SRAM |
|
||||
| 4102 | SRAM_D | W | initiate a write cylce to SRAM |
|
||||
|
||||
### buffer.asm
|
||||
|
||||
To test HACK with SRAM we need a little machine language programm `buffer.asm`, which reads the first four bytes of an ASCII file previosuly stored to the SPI flash memory chip W25Q16BV of iCE40HX1K-EVB, starting at address 0x040000 (256k) and stores the four bytes to SRAM. Finally we read the four bytes from SRAM and write them to UART.
|
||||
|
||||
### SRAM in real hardware
|
||||
|
||||
The board iCE40HX1K-EVB comes with a static ram chip K6R4016V1D. The chip is already connected to iCE40HX1K according `iCE40HX1K-EVB.pcf` (Compare with schematic [iCE40HX1K_EVB](../../doc/iCE40HX1K-EVB_Rev_B.pdf).
|
||||
|
||||
```
|
||||
set_io SRAM_ADDR[0] 79 # SA0
|
||||
set_io SRAM_ADDR[1] 80 # SA1
|
||||
set_io SRAM_ADDR[2] 81 # SA2
|
||||
set_io SRAM_ADDR[3] 82 # SA3
|
||||
set_io SRAM_ADDR[4] 83 # SA4
|
||||
set_io SRAM_ADDR[5] 85 # SA5
|
||||
set_io SRAM_ADDR[6] 86 # SA6
|
||||
set_io SRAM_ADDR[7] 87 # SA7
|
||||
set_io SRAM_ADDR[8] 89 # SA8
|
||||
set_io SRAM_ADDR[9] 90 # SA9
|
||||
set_io SRAM_ADDR[10] 91 # SA10
|
||||
set_io SRAM_ADDR[11] 93 # SA11
|
||||
set_io SRAM_ADDR[12] 94 # SA12
|
||||
set_io SRAM_ADDR[13] 95 # SA13
|
||||
set_io SRAM_ADDR[14] 96 # SA14
|
||||
set_io SRAM_ADDR[15] 97 # SA15
|
||||
set_io SRAM_ADDR[16] 99 # SA16
|
||||
set_io SRAM_ADDR[17] 100 # SA17
|
||||
set_io SRAM_CSX 78 # SRAM_#CS
|
||||
set_io SRAM_OEX 74 # SRAM_#OE
|
||||
set_io SRAM_WEX 73 # SRAM_#WE
|
||||
set_io SRAM_DATA[0] 62 # SD0
|
||||
set_io SRAM_DATA[1] 63 # SD1
|
||||
set_io SRAM_DATA[2] 64 # SD2
|
||||
set_io SRAM_DATA[3] 65 # SD3
|
||||
set_io SRAM_DATA[4] 66 # SD4
|
||||
set_io SRAM_DATA[5] 68 # SD5
|
||||
set_io SRAM_DATA[6] 69 # SD6
|
||||
set_io SRAM_DATA[7] 71 # SD7
|
||||
set_io SRAM_DATA[8] 72 # SD8
|
||||
set_io SRAM_DATA[9] 60 # SD9
|
||||
set_io SRAM_DATA[10] 59 # SD10
|
||||
set_io SRAM_DATA[11] 57 # SD11
|
||||
set_io SRAM_DATA[12] 56 # SD12
|
||||
set_io SRAM_DATA[13] 54 # SD13
|
||||
set_io SRAM_DATA[14] 53 # SD14
|
||||
set_io SRAM_DATA[15] 52 # SD15
|
||||
```
|
||||
|
||||
***
|
||||
|
||||
### Project
|
||||
|
||||
* Implement `SRAM_D.v` and simulate with testbench:
|
||||
|
||||
```
|
||||
$ cd 04_SRAM_D
|
||||
$ apio clean
|
||||
$ apio sim
|
||||
```
|
||||
|
||||
* Compare output of your chip `OUT` with `CMP`.
|
||||
|
||||

|
||||
|
||||
* Edit `HACK.v` and add a `Register` for SRAM_A memory mapped to 4101.
|
||||
|
||||
* Edit `HACK.v` and add a special function register `SRAM_D` to memory address 4102.
|
||||
|
||||
* Implement `buffer.asm` and test with the testbench:
|
||||
|
||||
```
|
||||
$ cd 04_SRAM_D
|
||||
$ make
|
||||
$ cd ../00_HACK
|
||||
$ apio clean
|
||||
$ apio sim
|
||||
```
|
||||
|
||||
* Check the SRAM wires of the simulation and look for the storing of "SPI!" (which was preloaded in SPI chip at memory address 0x040000 of the testbench).
|
||||
|
||||

|
||||
|
||||
* Check the output at UART_TX in the long run. You should see the string "SPI!" output to UART_TX:
|
||||
|
||||

|
||||
|
||||
* preload the SPI memory chip with some text file at address 0x040000.
|
||||
|
||||
* build and upload HACK with `buffer.asm` in ROM.BIN to iCE40HX1K-EVB.
|
||||
- press reset button on iCE40HX1K-EVB and see if wou can receive the preloaded text file on your Computer.
|
||||
|
||||
```
|
||||
$ echo SPI! > spi.txt
|
||||
$ iceprogduino -o 256k -w spi.txt
|
||||
$ cd 04_SRAM_D
|
||||
$ make
|
||||
$ cd ../00_HACK
|
||||
$ apio clean
|
||||
$ apio upload
|
||||
$ tio /dev/ttyACM0
|
||||
```
|
44
06_IO_Devices/04_SRAM/SRAM_D_tb.gtkw
Normal file
44
06_IO_Devices/04_SRAM/SRAM_D_tb.gtkw
Normal file
@@ -0,0 +1,44 @@
|
||||
[*]
|
||||
[*] GTKWave Analyzer v3.3.104 (w)1999-2020 BSI
|
||||
[*] Wed Dec 28 09:52:04 2022
|
||||
[*]
|
||||
[dumpfile] "/home/micha/gitlab/nand2tetris-fpga/06_IO_Devices/04_SRAM/SRAM_D_tb.vcd"
|
||||
[dumpfile_mtime] "Wed Dec 28 09:50:13 2022"
|
||||
[dumpfile_size] 42940
|
||||
[savefile] "/home/micha/gitlab/nand2tetris-fpga/06_IO_Devices/04_SRAM/SRAM_D_tb.gtkw"
|
||||
[timestart] 0
|
||||
[size] 1920 963
|
||||
[pos] -51 -51
|
||||
*-18.000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
|
||||
[sst_width] 281
|
||||
[signals_width] 160
|
||||
[sst_expanded] 1
|
||||
[sst_vpaned_height] 259
|
||||
@200
|
||||
-IN
|
||||
@28
|
||||
SRAM_D_tb.load
|
||||
@22
|
||||
SRAM_D_tb.in[15:0]
|
||||
@200
|
||||
-OUT
|
||||
@28
|
||||
SRAM_D_tb.CSX
|
||||
SRAM_D_tb.OEX
|
||||
SRAM_D_tb.WEX
|
||||
@22
|
||||
SRAM_D_tb.out[15:0]
|
||||
@200
|
||||
-CMP
|
||||
@28
|
||||
SRAM_D_tb.CSX_cmp
|
||||
SRAM_D_tb.OEX_cmp
|
||||
SRAM_D_tb.WEX_cmp
|
||||
@22
|
||||
SRAM_D_tb.out_cmp[15:0]
|
||||
@200
|
||||
-Test
|
||||
@29
|
||||
SRAM_D_tb.fail
|
||||
[pattern_trace] 1
|
||||
[pattern_trace] 0
|
72
06_IO_Devices/04_SRAM/SRAM_D_tb.v
Normal file
72
06_IO_Devices/04_SRAM/SRAM_D_tb.v
Normal file
@@ -0,0 +1,72 @@
|
||||
`timescale 10ns/1ns
|
||||
`default_nettype none
|
||||
|
||||
module SRAM_D_tb();
|
||||
|
||||
// IN,OUT
|
||||
reg clk = 0;
|
||||
reg load = 0;
|
||||
reg [15:0] in=0;
|
||||
wire [15:0] out;
|
||||
wire CSX;
|
||||
wire OEX;
|
||||
wire WEX;
|
||||
wire [15:0] DATA;
|
||||
|
||||
// Part
|
||||
SRAM_D SRAM_D(
|
||||
.clk(clk),
|
||||
.load(load),
|
||||
.in(in),
|
||||
.out(out),
|
||||
.CSX(CSX),
|
||||
.OEX(OEX),
|
||||
.WEX(WEX),
|
||||
.DATA(DATA)
|
||||
);
|
||||
|
||||
// Simulate
|
||||
always #2 clk=~clk;
|
||||
wire trigger;
|
||||
reg write;
|
||||
assign trigger = (n==4) || (n==8) || (n==12) || (n==16) || (n==20);
|
||||
always @(posedge clk) begin
|
||||
in <= $random;
|
||||
load <= trigger;
|
||||
write <= load;
|
||||
end
|
||||
reg [15:0] data;
|
||||
always @(posedge clk)
|
||||
if (load) data <= in;
|
||||
// Compare
|
||||
wire CSX_cmp = 0;
|
||||
wire OEX_cmp = write;
|
||||
wire WEX_cmp = ~write;
|
||||
wire [15:0] out_cmp = (~CSX_cmp&~OEX_cmp)?16'bzzzzzzzzzzzzzzzz:data;
|
||||
reg fail = 0;
|
||||
reg [31:0] n = 0;
|
||||
task check;
|
||||
#4
|
||||
if ((out!=out_cmp)||(CSX!=CSX_cmp)||(OEX!=OEX_cmp)||(WEX!=WEX_cmp))
|
||||
begin
|
||||
$display("FAIL: clk=%1b, load=%1b, in=%16b, out=%16b, CSX=%1b, OEX=%1b, SEX=%1b, DATA=%16b",clk,load,in,out,CSX,OEX,WEX,DATA);
|
||||
fail=1;
|
||||
end
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
$dumpfile("SRAM_D_tb.vcd");
|
||||
$dumpvars(0, SRAM_D_tb);
|
||||
|
||||
$display("------------------------");
|
||||
$display("Testbench: SRAM_D");
|
||||
|
||||
for (n=0; n<24;n=n+1)
|
||||
check();
|
||||
|
||||
if (fail==0) $display("passed");
|
||||
$display("------------------------");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
3
06_IO_Devices/04_SRAM/apio.ini
Normal file
3
06_IO_Devices/04_SRAM/apio.ini
Normal file
@@ -0,0 +1,3 @@
|
||||
[env]
|
||||
board = iCE40-HX1K-EVB
|
||||
|
7
06_IO_Devices/04_SRAM/buffer.asm
Normal file
7
06_IO_Devices/04_SRAM/buffer.asm
Normal file
@@ -0,0 +1,7 @@
|
||||
// buffer.asm
|
||||
//
|
||||
// read 4 bytes of textfile from SPI starting at address 0x040000 and write
|
||||
// the string to SRAM. Finally read the string from SRAM and send
|
||||
// the string to UART_TX
|
||||
//
|
||||
// Put your code here:
|
BIN
06_IO_Devices/04_SRAM/buffer.png
Normal file
BIN
06_IO_Devices/04_SRAM/buffer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 88 KiB |
BIN
06_IO_Devices/04_SRAM/buffer1.png
Normal file
BIN
06_IO_Devices/04_SRAM/buffer1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 104 KiB |
BIN
06_IO_Devices/04_SRAM/sram_tb.png
Normal file
BIN
06_IO_Devices/04_SRAM/sram_tb.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 74 KiB |
Reference in New Issue
Block a user