added v2.0
This commit is contained in:
BIN
06_IO_Devices/01_UartTX/ICE40PGM.jpg
Normal file
BIN
06_IO_Devices/01_UartTX/ICE40PGM.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 77 KiB |
40
06_IO_Devices/01_UartTX/Include.v
Normal file
40
06_IO_Devices/01_UartTX/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/01_UartTX/Makefile
Normal file
12
06_IO_Devices/01_UartTX/Makefile
Normal file
@@ -0,0 +1,12 @@
|
||||
NAME = hello
|
||||
|
||||
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
|
111
06_IO_Devices/01_UartTX/Readme.md
Normal file
111
06_IO_Devices/01_UartTX/Readme.md
Normal file
@@ -0,0 +1,111 @@
|
||||
## 01 UartTX
|
||||
|
||||
The special function register `UartTX` mapped to memory address 4098 enables HACK to send chars to the outer world over UART with 115200 baud 8N1. The timing diagramm for the TX wire should look like:
|
||||
|
||||

|
||||
|
||||
During idle TX line is high (logic 1). Transmission of a byte (8 bits) is initiated by the so called start bit, which always is low (logic 0), followed by the 8 data bits, starting with the least significant bit. The transmission is finished by sending the stop bit, which always is high (logic 1).
|
||||
This protocoll is refered as 8N1 meaning (8 data bits, no parity bit, 1 stop bit). We use a transmission speed of 115200 baud (bits per second), meaning that each bit takes 1s/115200 = 8.68us or 217 cycles of the internal 25MHz clock clk.
|
||||
|
||||
### Chip specification
|
||||
|
||||
| IN/OUT | wire | function |
|
||||
| ------ | ------- | --------------------------------------------------- |
|
||||
| IN | in[7:0] | byte to be sent. |
|
||||
| IN | load | =1 initiates the transmission |
|
||||
| OUT | out[15] | =1 chip is busy, =0 chip is ready to send next byte |
|
||||
| OUT | TX | transmission wire |
|
||||
|
||||
When load = 1 the chip starts serial transmission of the byte in[7:0] to the TX line according to the protocoll 8N1 with 115200 baud. During transmission out[15] is set to high (busy). The transmission is finished after 2170 clock cycles (10 byte a 217 cycle each). When transmission completes out[15] goes low again (ready).
|
||||
|
||||
### Proposed Implementation
|
||||
|
||||
Use a `Bit` to store the state (0 = ready, 1 = busy). Use a counter `PC` to count from 0 to 216. When clocked at 25MHz, this counter will produce the baudrate of 115200 bits per second. A second counter `PC` counts from 0 to 9 (the 10 bits to send). Finally we need a `BitShift9R`. This will be loaded with the bit pattern to be send (startbit, 8 data bits).
|
||||
|
||||

|
||||
|
||||
### memory map
|
||||
|
||||
The special function register `UartTX` is mapped to memory map of HACK according to:
|
||||
|
||||
| address | I/O device | R/W | function |
|
||||
| ------- | ---------- | --- | ------------------------------------- |
|
||||
| 4098 | UART_TX | R | out[15]=1 if busy, out[15]=0 if ready |
|
||||
| 4098 | UART_TX | W | send char in[7:0] to TX |
|
||||
|
||||
### hello.asm
|
||||
|
||||
To test HACK with `UartTX` we need a little machine language programm `hello.asm`, which sends the String "Hi" to UART.
|
||||
|
||||
**Attention:** Use a loop to wait until UartTX is ready to send the next byte.
|
||||
|
||||
### UartTX in real hardware
|
||||
|
||||
The programmer Olimexino 32u4 can also be used as bridge to connect the PC to iCE40HX1K-EVB over UART. This can be done with the 10 wire UEXT cable which goes into the PGM1 connector of iCE40HX1K-EVB.
|
||||
|
||||

|
||||
|
||||
**Note:** To connect RX and TX lines of UEXT-connector with iCE40-chip on iCE40-HX1K-EVB find the solder-jumper-pads RxD_E1 and TxD_E1 near the UEXT connector (refer to [datasheets/iCE40HX1K-EVB](../datasheets/iCE40HX1K-EVB_Rev_B.pdf)) and solder them together as in the foto below.
|
||||
|
||||

|
||||
|
||||
The programmer olimexino 32u4 works in two different mode:
|
||||
|
||||
- Mode 1 (yellow led on): programmer of iCE40-board. Used with iceprogduino.
|
||||
- Mode 2 (green led on): UART Bridge to iCE40 chip. Use with terminal programm (e.g. tio or screen on linux).
|
||||
|
||||
To switch between the modes press the hardware button on olimexino 32u4 (HWB).
|
||||
|
||||
Now iCE40HX1K is connected to RX,TX of olimexino 32u4 according to `iCE40HX1K-EVB.pcf`. (Check by comparing the schematic of iCE40HX1K-EVB).
|
||||
|
||||
```
|
||||
set_io UART_RX 36 # PIO2_8/RxD connected to pin 3 of UEXT (PGM)
|
||||
set_io UART_TX 37 # PIO2_9/TxD connected to pin 4 of UEXT (PGM)
|
||||
```
|
||||
|
||||
***
|
||||
|
||||
### Project
|
||||
|
||||
* Implement `UartTX` and simulate with testbench.
|
||||
|
||||
```
|
||||
$ cd 01_UartTX
|
||||
$ apio clean
|
||||
$ apio sim
|
||||
```
|
||||
|
||||
* Compare with CMP:
|
||||
|
||||

|
||||
|
||||
* Edit `HACK` and add the special function register `UartTX` to the memory address 4098.
|
||||
|
||||
* Implement `hello.asm` and run in simulation:
|
||||
|
||||
```
|
||||
$ cd 01_UartTX
|
||||
$ make
|
||||
$ cd ../00_HACK
|
||||
$ apio clean
|
||||
$ apio sim
|
||||
```
|
||||
|
||||
* Check the TX wire of the simulation and look for the transmission of "Hi".
|
||||
|
||||

|
||||
|
||||
* build and upload HACK with `hello.asm` in ROM.BIN to iCE40HX1K-EVB.
|
||||
|
||||
* switch olimexino 32u4 to UART-Bridge
|
||||
|
||||
* open Terminal on your computer
|
||||
|
||||
* press reset button on iCE40HX1K-EVB and see if wou can recieve "Hi" on your Computer.
|
||||
|
||||
```
|
||||
$ cd 00_HACK
|
||||
$ apio clean
|
||||
$ apio upload
|
||||
$ tio /dev/ttyACM0
|
||||
```
|
BIN
06_IO_Devices/01_UartTX/UARTJumper.jpg
Normal file
BIN
06_IO_Devices/01_UartTX/UARTJumper.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 908 KiB |
BIN
06_IO_Devices/01_UartTX/UartTX.dia
Normal file
BIN
06_IO_Devices/01_UartTX/UartTX.dia
Normal file
Binary file not shown.
BIN
06_IO_Devices/01_UartTX/UartTX.png
Normal file
BIN
06_IO_Devices/01_UartTX/UartTX.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
43
06_IO_Devices/01_UartTX/UartTX_tb.gtkw
Normal file
43
06_IO_Devices/01_UartTX/UartTX_tb.gtkw
Normal file
@@ -0,0 +1,43 @@
|
||||
[*]
|
||||
[*] GTKWave Analyzer v3.3.104 (w)1999-2020 BSI
|
||||
[*] Fri Dec 23 15:04:28 2022
|
||||
[*]
|
||||
[dumpfile] "/home/micha/gitlab/nand2tetris/06_IO_Devices/01_UartTX/UartTX_tb.vcd"
|
||||
[dumpfile_mtime] "Fri Dec 23 15:03:47 2022"
|
||||
[dumpfile_size] 3855989
|
||||
[savefile] "/home/micha/gitlab/nand2tetris/06_IO_Devices/01_UartTX/UartTX_tb.gtkw"
|
||||
[timestart] 0
|
||||
[size] 1659 507
|
||||
[pos] 165 50
|
||||
*-26.000000 0 -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
|
||||
[treeopen] UartTX_tb.
|
||||
[sst_width] 281
|
||||
[signals_width] 170
|
||||
[sst_expanded] 1
|
||||
[sst_vpaned_height] 108
|
||||
@28
|
||||
UartTX_tb.clk
|
||||
@200
|
||||
-IN
|
||||
@28
|
||||
UartTX_tb.load
|
||||
@22
|
||||
UartTX_tb.in[15:0]
|
||||
@200
|
||||
-OUT
|
||||
@22
|
||||
UartTX_tb.out[15:0]
|
||||
@28
|
||||
UartTX_tb.TX
|
||||
@200
|
||||
-CMP
|
||||
@23
|
||||
UartTX_tb.out_cmp[15:0]
|
||||
@28
|
||||
UartTX_tb.TX_cmp
|
||||
@200
|
||||
-Test
|
||||
@28
|
||||
UartTX_tb.fail
|
||||
[pattern_trace] 1
|
||||
[pattern_trace] 0
|
BIN
06_IO_Devices/01_UartTX/UartTX_tb.png
Normal file
BIN
06_IO_Devices/01_UartTX/UartTX_tb.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 56 KiB |
74
06_IO_Devices/01_UartTX/UartTX_tb.v
Normal file
74
06_IO_Devices/01_UartTX/UartTX_tb.v
Normal file
@@ -0,0 +1,74 @@
|
||||
`timescale 10ns/1ns
|
||||
`default_nettype none
|
||||
|
||||
module UartTX_tb();
|
||||
|
||||
// IN,OUT
|
||||
reg clk = 0;
|
||||
reg load = 0;
|
||||
reg [15:0] in = 0;
|
||||
wire TX;
|
||||
wire [15:0] out;
|
||||
|
||||
// Part
|
||||
UartTX UartTX(
|
||||
.clk(clk),
|
||||
.load(load),
|
||||
.in(in),
|
||||
.TX(TX),
|
||||
.out(out)
|
||||
);
|
||||
|
||||
// Simulate
|
||||
always #2 clk=~clk;
|
||||
wire trigger;
|
||||
assign trigger = (n==1000) || (n==5000) || (n==9000);
|
||||
always @(posedge clk) begin
|
||||
in <= trigger?$random:in;
|
||||
load <= trigger;
|
||||
end
|
||||
|
||||
// Compare
|
||||
reg [9:0] uart=10'b1111111111;
|
||||
reg [15:0] baudrate = 0;
|
||||
reg [15:0] bits = 0;
|
||||
wire is216=(baudrate==216);
|
||||
reg [15:0] out_cmp=0;
|
||||
always @(posedge clk)
|
||||
out_cmp <=load?16'h8000:(bits==9)&is216?16'd0:out_cmp;
|
||||
always @(posedge clk)
|
||||
bits <= (load)?0:is216?bits+1:bits;
|
||||
always @(posedge clk)
|
||||
baudrate <= (is216?0:out_cmp?baudrate+1:baudrate);
|
||||
always @(posedge clk)
|
||||
uart <= (load)?((in<<2)|1):(is216?{1'b1,uart[9:1]}:uart);
|
||||
wire TX_cmp;
|
||||
assign TX_cmp = uart[1];
|
||||
|
||||
reg fail = 0;
|
||||
reg [31:0] n = 0;
|
||||
task check;
|
||||
#4
|
||||
if ((TX != TX_cmp) ||(out != out_cmp))
|
||||
begin
|
||||
$display("FAIL: clk=%1b, load=%1b, in=%16b, out=%16b, TX=%1b",clk,load,in,out,TX);
|
||||
fail=1;
|
||||
end
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
$dumpfile("UartTX_tb.vcd");
|
||||
$dumpvars(0, UartTX_tb);
|
||||
|
||||
$display("------------------------");
|
||||
$display("Testbench: UartTX");
|
||||
|
||||
for (n=0; n<13000;n=n+1)
|
||||
check();
|
||||
|
||||
if (fail==0) $display("passed");
|
||||
$display("------------------------");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
3
06_IO_Devices/01_UartTX/apio.ini
Normal file
3
06_IO_Devices/01_UartTX/apio.ini
Normal file
@@ -0,0 +1,3 @@
|
||||
[env]
|
||||
board = iCE40-HX1K-EVB
|
||||
|
4
06_IO_Devices/01_UartTX/hello.asm
Normal file
4
06_IO_Devices/01_UartTX/hello.asm
Normal file
@@ -0,0 +1,4 @@
|
||||
// hello.asm
|
||||
// this little assembler programm outputs "Hi" on UART_TX
|
||||
//
|
||||
// Put your code here:
|
BIN
06_IO_Devices/01_UartTX/hi.png
Normal file
BIN
06_IO_Devices/01_UartTX/hi.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 45 KiB |
BIN
06_IO_Devices/01_UartTX/timing.jpg
Normal file
BIN
06_IO_Devices/01_UartTX/timing.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
Reference in New Issue
Block a user