11 Commits
wip ... wip-2

Author SHA1 Message Date
3fd95eff64 wip optimization on SPI/LCD 2025-04-25 23:01:17 +05:30
3157b5306d WIP optimizations on SPI/UART 2025-04-25 21:22:29 +05:30
2fdfe24793 update .gitignore and makefile 2025-04-22 23:56:26 +05:30
33fd9ef6b2 rename files 2025-04-22 23:52:40 +05:30
5ff1b1486a add Makefile, make life easy 2025-04-22 23:47:08 +05:30
c331166dac update apio.ini 2025-04-22 23:46:35 +05:30
48fbd4abed fix bootloader and add docs, minor fix to hello 2025-04-21 23:19:04 +05:30
de1ce5cdac update python path in makefiles 2025-04-21 22:45:06 +05:30
fc63bb9e6a update gitignore 2025-04-21 20:47:49 +05:30
e2fa3ee864 bootloader test dump 2024-11-23 16:56:29 +05:30
5527f9e8b2 spi test dump 2024-10-25 13:47:27 -04:00
41 changed files with 1011 additions and 312 deletions

5
.gitignore vendored
View File

@@ -7,6 +7,9 @@
*.dblite *.dblite
*.hack *.hack
*.vm *.vm
*.img
*.backup
*.history
.*
out.asm out.asm
out.hack out.hack
.*

View File

@@ -14,7 +14,7 @@ module Mux8Way16(
input [15:0] f, input [15:0] f,
input [15:0] g, input [15:0] g,
input [15:0] h, input [15:0] h,
input [2:0] sel, input [2:0] sel,
output [15:0] out output [15:0] out
); );
@@ -35,4 +35,17 @@ module Mux8Way16(
Mux16 MUX16F(outef[15:0], outgh[15:0], sel[1], outefgh[15:0]); Mux16 MUX16F(outef[15:0], outgh[15:0], sel[1], outefgh[15:0]);
Mux16 MUX16(outabcd[15:0], outefgh[15:0], sel[2], out[15:0]); Mux16 MUX16(outabcd[15:0], outefgh[15:0], sel[2], out[15:0]);
// always @(*) begin
// case (sel)
// 0 : out = a;
// 1 : out = b;
// 2 : out = c;
// 3 : out = d;
// 4 : out = e;
// 5 : out = f;
// 6 : out = g;
// 7 : out = h;
// endcase
// end
endmodule endmodule

View File

@@ -30,4 +30,8 @@ module Register(
Bit BITN(clk, in[13], load, out[13]); Bit BITN(clk, in[13], load, out[13]);
Bit BITO(clk, in[14], load, out[14]); Bit BITO(clk, in[14], load, out[14]);
Bit BITP(clk, in[15], load, out[15]); Bit BITP(clk, in[15], load, out[15]);
// reg [15:0] out = 0;
// always @(posedge clk)
// out <= load?in:out;
// initial out = 0;
endmodule endmodule

View File

@@ -1,4 +1,4 @@
PYTHON = /bin/python3.11 PYTHON = ~/.pyenv/shims/python
leds: leds:
$(PYTHON) ../tools/Assembler/assembler.pyc leds.asm $(PYTHON) ../tools/Assembler/assembler.pyc leds.asm

View File

@@ -5,8 +5,8 @@
// Put your code here: // Put your code here:
@BUT @BUT
D=M D=!M
@LED @LED
M=!D M=D
@0 @0
0;JMP 0;JMP

View File

@@ -54,21 +54,16 @@ module CPU(
wire [15:0] fromAorM; wire [15:0] fromAorM;
wire [15:0] fromALU; wire [15:0] fromALU;
reg [15:0] tempM;
reg [15:0] tempPC;
assign is_C = instruction[15] & instruction[14] & instruction[13]; assign is_C = instruction[15] & instruction[14] & instruction[13];
assign is_A = ~is_C; assign is_A = ~is_C;
assign loadD = is_C & instruction[4]; assign loadD = is_C & instruction[4];
assign loadA = (is_C & instruction[5]) || is_A; assign loadA = (is_C & instruction[5]) || is_A;
assign fromAorM = instruction[12] ? inM : fromA; assign fromAorM = instruction[12] ? inM : fromA;
assign toA = is_A ? instruction : outM; assign toA = is_A ? instruction : outM;
// jump if j1 bit set and ng bit set // jump if j1 bit set and ng bit set
// jump if j2 bit set and zr bit set // jump if j2 bit set and zr bit set
// jump if j3 bit set and zr, ng bit not set // jump if j3 bit set and zr, ng bit not set

View File

@@ -13,7 +13,7 @@ module Clock25_Reset20(
// Put your code here: // Put your code here:
reg boot=1; reg boot=1;
reg [3:0] ccount=0; reg [3:0] ccount=0;
reg [12:0] rcount=0; reg [11:0] rcount=0;
always @(posedge CLK) begin always @(posedge CLK) begin
if (boot == 1) begin if (boot == 1) begin

View File

@@ -1,3 +1,3 @@
[env] [env]
board = iCE40-HX1K-EVB board = iCE40-HX1K-EVB
top-module = HACK

View File

@@ -1,5 +1,4 @@
PYTHON = /bin/python3.11 PYTHON = ~/.pyenv/shims/python
NAME = hello NAME = hello
all: asm install all: asm install

View File

@@ -1,32 +0,0 @@
// hello.asm
// this little assembler programm outputs "Hi" on UART_TX
//
// Put your code here:
//check tx status
(START)
@UART_TX
D=M
@SENDH
D;JEQ
@START
0;JMP
(SENDH)
@72
D=A
@UART_TX
M=D
(WAIT)
@UART_TX
D=M
@SENDI
D;JEQ
@WAIT
0;JMP
(SENDI)
@105
D=A
@UART_TX
M=D
(END)
@END
0;JMP

View File

@@ -0,0 +1,119 @@
// hello.asm
// this little assembler programm outputs "Hi" on UART_TX
//
// Put your code here:
// send "Never Graduate!" on UART_TX
// read BUT[1,2] and write to LED[1,2]
@78
D=A
@128
M=D //N
@101
D=A
@129
M=D //e
@118
D=A
@130
M=D //v
@101
D=A
@131
M=D //e
@114
D=A
@132
M=D //r
@32
D=A
@133
M=D // space
@71
D=A
@134
M=D //G
@114
D=A
@135
M=D //r
@97
D=A
@136
M=D //a
@100
D=A
@137
M=D //d
@117
D=A
@138
M=D //u
@97
D=A
@139
M=D //a
@116
D=A
@140
M=D //t
@101
D=A
@141
M=D //e
@33
D=A
@142
M=D //!
@13
D=A
@143
M=D // carriage return
@10
D=A
@144
M=D // line feed
@128
D=A
@CHARBOOT
M=D
@BOOT
0;JEQ
(POLL)
@BUT
D=!M
@LED
M=D
@POLL
0;JMP
(WAITBOOT)
@UART_TX
D=M
@BOOT
D;JEQ
@WAITBOOT
0;JMP
(BOOT)
@CHARBOOT
A=M
D=M
@UART_TX
M=D
@CHARBOOT
M=M+1
@145
D=A
@CHARBOOT
D=D-M
@ENDBOOT
D;JEQ
@WAITBOOT
0;JMP
(ENDBOOT)
@POLL
0;JMP

View File

@@ -1,5 +1,4 @@
PYTHON = /bin/python3.11 PYTHON = ~/.pyenv/shims/python
NAME = echo NAME = echo
all: asm install all: asm install

View File

@@ -4,3 +4,17 @@
// repeat in an endless loop // repeat in an endless loop
// //
// Put your code here: // Put your code here:
// hello.asm
// this little assembler programm outputs "Hi" on UART_TX
//
// Put your code here:
(POLL)
@UART_RX
D=M
@UART_TX
M=D
@UART_RX
M=0
@POLL
0;JMP

View File

@@ -1,5 +1,4 @@
PYTHON = /bin/python3.11 PYTHON = ~/.pyenv/shims/python
NAME = cat NAME = cat
all: asm install all: asm install

View File

@@ -4,3 +4,139 @@
// data to UART_TX // data to UART_TX
// //
// Put your code here: // Put your code here:
// D=M -> 1111110000010000
// M=D -> 1110001100001000
// M=0 -> 1110101010001000
// read data starting at address
// 0x03 0x04 0x00 0x00
@3
D=A
@128
M=D
@4
D=A
@129
M=D
@130
M=0
@131
M=0
// wake up from deep power down and wait 3us
// 0xAB
@171
D=A
@SPI
M=D
@4
D=A
@COUNT
M=D
(DECR1)
@COUNT
DM=M-1
@DECR1
D;JGT
@511
D=A
@SPI
M=D
@21
D=A
@COUNT
M=D
(DECR2)
@COUNT
DM=M-1
@DECR2
D;JGT
//command stack base address
@128
D=A
@CHARREAD
M=D
@READCOUNT
M=0
@WAITREAD
0;JEQ
(WAITREAD)
@SPI
D=M
@WAITREAD
D;JLT
@READ
0;JMP
(READ)
// read
@CHARREAD
A=M
D=M
@SPI
M=D
@CHARREAD
M=M+1
@132
D=A
@CHARREAD
D=D-M
@WAITREAD
D;JGT
@ENDREAD
0;JMP
(ENDREAD)
@WAITBOOT
0;JMP
(WAITBOOT)
@UART_TX
D=M
@BOOT
D;JEQ
@WAITBOOT
0;JMP
(BOOT)
@SPI
M=0
@4
D=A
@COUNT
M=D
(FROMSPI)
@COUNT
DM=M-1
@FROMSPI
D;JGT
@SPI
D=M
@UART_TX
M=D
@READCOUNT
M=M+1
@4
D=A
@READCOUNT
D=D-M
@ENDBOOT
D;JEQ
@WAITBOOT
0;JMP
(ENDBOOT)
@POLL
0;JMP
// LED<->BUT loop
(POLL)
@BUT
D=!M
@LED
M=D
@POLL
0;JMP

View File

@@ -0,0 +1 @@
SPI!

View File

@@ -1,5 +1,4 @@
PYTHON = /bin/python3.11 PYTHON = ~/.pyenv/shims/python
NAME = buffer NAME = buffer
all: asm install all: asm install

View File

@@ -5,3 +5,185 @@
// the string to UART_TX // the string to UART_TX
// //
// Put your code here: // Put your code here:
// cat.asm
//
// load spi flash rom starting at address 0x040000 and write the
// data to UART_TX
//
// Put your code here:
// D=M -> 1111110000010000
// M=D -> 1110001100001000
// M=0 -> 1110101010001000
// read data starting at address
// 0x03 0x04 0x00 0x00
@3
D=A
@128
M=D
@4
D=A
@129
M=D
@130
M=0
@131
M=0
// wake up from deep power down and wait 3us
// 0xAB
@171
D=A
@SPI
M=D
@4
D=A
@COUNT
M=D
(DECR1)
@COUNT
DM=M-1
@DECR1
D;JGT
@511
D=A
@SPI
M=D
@21
D=A
@COUNT
M=D
(DECR2)
@COUNT
DM=M-1
@DECR2
D;JGT
//command stack base address
@128
D=A
@CHARREAD
M=D
@WRITECOUNT
M=0
@SENDCOUNT
M=0
@WAITREAD
0;JEQ
(WAITREAD)
@SPI
D=M
@WAITREAD
D;JLT
@READ
0;JMP
(READ)
// read
@CHARREAD
A=M
D=M
@SPI
M=D
@CHARREAD
M=M+1
@132
D=A
@CHARREAD
D=D-M
@WAITREAD
D;JGT
@ENDREAD
0;JMP
(ENDREAD)
@WAITWRITE
0;JMP
(WAITWRITE)
@SPI
D=M
@WAITWRITE
D;JLT
@WRITE
0;JMP
(WRITE)
@SPI
M=0
@4
D=A
@COUNT
M=D
(FROMSPI)
@COUNT
DM=M-1
@FROMSPI
D;JGT
@WRITECOUNT
D=M
@SRAM_A
M=D
@SPI
D=M
@SRAM_D
M=D
@WRITECOUNT
M=M+1
@8
D=A
@WRITECOUNT
D=D-M
@ENDWRITE
D;JEQ
@WAITWRITE
0;JMP
(ENDWRITE)
@WAITBOOT
0;JMP
(WAITBOOT)
@UART_TX
D=M
@BOOT
D;JEQ
@WAITBOOT
0;JMP
(BOOT)
@SENDCOUNT
D=M
@SRAM_A
M=D
@SRAM_D
D=M
@UART_TX
M=D
@SENDCOUNT
M=M+1
@8
D=A
@SENDCOUNT
D=D-M
@ENDBOOT
D;JEQ
@WAITBOOT
0;JMP
(ENDBOOT)
@POLL
0;JMP
// LED<->BUT loop
(POLL)
@BUT
D=!M
@LED
M=D
@POLL
0;JMP

View File

@@ -1,5 +1,4 @@
PYTHON = /bin/python3.11 PYTHON = ~/.pyenv/shims/python
NAME = boot NAME = boot
all: asm install all: asm install

View File

@@ -1,5 +0,0 @@
//*****************************************************************************
// Boot loader. Load HACK code from SPI address 0x010000 (64k) into SRAM and GO
//*****************************************************************************
//
// Put your code here:

View File

@@ -0,0 +1,207 @@
//*****************************************************************************
// Boot loader. Load HACK code from SPI address 0x010000 (64k) into SRAM and GO
//*****************************************************************************
//
// Put your code here:
// @R0
// D=M
//
// // Shift left by 8 bits by doubling 8 times
// D=D+D // Shift left by 1 bit
// D=D+D // Shift left by another bit
// D=D+D // Shift left by another bit
// D=D+D // Shift left by another bit (4-bit shift so far)
// D=D+D // Shift left by another bit
// D=D+D // Shift left by another bit
// D=D+D // Shift left by another bit
// D=D+D // Shift left by another bit (now D contains 0xEA00)
//
// D=M -> 1111110000010000
// M=D -> 1110001100001000
// M=0 -> 1110101010001000
//
// // Store the result in R1
// @R1
// M=D
//
//
// 00010000 0 -> add 8 times and store to lhs
// 00000001 1 -> add to lhs and store to word
// 0001000000000001 write all the words to sram
//
// 0001000000000001
// 1111110001010000
// 0001000000000000
// 1110001100001000
// 0000000000000000
// 1110101010000111
// read data starting at address
// 0x03 0x01 0x00 0x00
@3
D=A
@100
M=D
@1
D=A
@101
M=D
@102
M=0
@103
M=0
// wake up from deep power down and wait 3us
// 0xAB
@171
D=A
@SPI
M=D
@4
D=A
@COUNT
M=D
(DECR1)
@COUNT
DM=M-1
@DECR1
D;JGT
@511
D=A
@SPI
M=D
@21
D=A
@COUNT
M=D
(DECR2)
@COUNT
DM=M-1
@DECR2
D;JGT
//command stack base address
@100
D=A
@READCOMMAND
M=D
@DIRECTION
M=0
@WORDCOUNT
M=0
@WAITREAD
0;JEQ
(WAITREAD)
@SPI
D=M
@WAITREAD
D;JLT
@READ
0;JMP
(READ)
// read
@READCOMMAND
A=M
D=M
@SPI
M=D
@READCOMMAND
M=M+1
@104
D=A
@READCOMMAND
D=D-M
@WAITREAD
D;JGT
@ENDREAD
0;JMP
(ENDREAD)
@WAITWRITE
0;JMP
(WAITWRITE)
@SPI
D=M
@WAITWRITE
D;JLT
@WRITE
0;JMP
(WRITE)
@SPI
M=0
@4
D=A
@COUNT
M=D
(FROMSPI)
@COUNT
DM=M-1
@FROMSPI
D;JGT
@DIRECTION
D=M
@WESTWORD
D;JEQ
@EASTWORD
D;JGT
(WESTWORD)
@SPI
D=M
@DEBUG0
M=D
DM=D+M
DM=D+M
DM=D+M
DM=D+M
DM=D+M
DM=D+M
DM=D+M
DM=D+M
@DIRECTION
M=1
@WAITWRITE
0;JMP
(EASTWORD)
@WORDCOUNT
D=M
@SRAM_A
M=D
@SPI
D=M
@DEBUG1
M=D
@DEBUG0
D=M
@DEBUG1
D=D+M
@SRAM_D
M=D
@DIRECTION
M=0
@WORDCOUNT
M=M+1
@57343
D=A
@WORDCOUNT
D=D-M
@ENDWRITE
D;JEQ
@WAITWRITE
0;JMP
(ENDWRITE)
@185
D=A
@SPI
M=D
@GO
M=1

View File

@@ -22,5 +22,5 @@ module GO(
end end
assign instruction = (active) ? sram_data : ROM_data; assign instruction = (active) ? sram_data : ROM_data;
assign SRAM_ADDR = (active) ? pc : sram_addr; assign SRAM_ADDR = (active) ? sram_addr: pc;
endmodule endmodule

View File

@@ -12,29 +12,29 @@
`default_nettype none `default_nettype none
module HACK( module HACK(
input CLK, // external clock 100 MHz input CLK, // external clock 100 MHz
input [1:0] BUT, // user button ("pushed down" == 0) ("up" == 1) input [1:0] BUT, // user button ("pushed down" == 0) ("up" == 1)
output [1:0] LED, // leds (0 off, 1 on) output [1:0] LED, // leds (0 off, 1 on)
input UART_RX, // UART recieve input UART_RX, // UART recieve
output UART_TX, // UART transmit output UART_TX, // UART transmit
output SPI_SDO, // SPI data out output SPI_SDO, // SPI data out
input SPI_SDI, // SPI data in input SPI_SDI, // SPI data in
output SPI_SCK, // SPI serial clock output SPI_SCK, // SPI serial clock
output SPI_CSX, // SPI chip select not output SPI_CSX, // SPI chip select not
output [17:0] SRAM_ADDR,// SRAM address 18 Bit = 256K output [17:0] SRAM_ADDR,// SRAM address 18 Bit = 256K
inout [15:0] SRAM_DATA, // SRAM data 16 Bit inout [15:0] SRAM_DATA, // SRAM data 16 Bit
output SRAM_WEX, // SRAM write_enable_not output SRAM_WEX, // SRAM write_enable_not
output SRAM_OEX, // SRAM output_enable_not output SRAM_OEX, // SRAM output_enable_not
output SRAM_CSX, // SRAM chip_select_not output SRAM_CSX, // SRAM chip_select_not
output LCD_DCX, // LCD data/command not output LCD_DCX, // LCD data/command not
output LCD_SDO, // LCD data out output LCD_SDO, // LCD data out
output LCD_SCK, // LCD serial clock output LCD_SCK, // LCD serial clock
output LCD_CSX, // LCD chip select not output LCD_CSX, // LCD chip select not
input RTP_SDI, // RTP data in s input RTP_SDI, // RTP data in s
output RTP_SDO, // RTP data out output RTP_SDO, // RTP data out
output RTP_SCK // RTP serial clock output RTP_SCK // RTP serial clock
); );
// Put your code here: // Put your code here:
wire loadRAM; wire loadRAM;
wire loadIO0; wire loadIO0;
wire loadIO1; wire loadIO1;
@@ -57,18 +57,18 @@ module HACK(
wire [15:0] inIO1; wire [15:0] inIO1;
wire [15:0] inIO2; wire [15:0] inIO2;
wire [15:0] inIO3; wire [15:0] inIO3;
wire [15:0] inIO4=0; wire [15:0] inIO4;
wire [15:0] inIO5=0; wire [15:0] inIO5;
wire [15:0] inIO6=0; wire [15:0] inIO6;
wire [15:0] inIO7=0; wire [15:0] inIO7;
wire [15:0] inIO8=0; wire [15:0] inIO8;
wire [15:0] inIO9=0; wire [15:0] inIO9;
wire [15:0] inIOA=0; wire [15:0] inIOA=0;
wire [15:0] inIOB; wire [15:0] inIOB;
wire [15:0] inIOC; wire [15:0] inIOC;
wire [15:0] inIOD; wire [15:0] inIOD=0;
wire [15:0] inIOE; wire [15:0] inIOE=0;
wire [15:0] inIOF; wire [15:0] inIOF=0;
wire writeM; wire writeM;
wire [15:0] inM; wire [15:0] inM;
@@ -77,23 +77,32 @@ module HACK(
wire [15:0] addressM; wire [15:0] addressM;
wire [15:0] pc; wire [15:0] pc;
wire clk, reset; wire clk, reset, RESET;
wire [15:0] ROM_DATA;
wire [15:0] fromLCD;
wire [15:0] outDEBUG0; wire [15:0] outDEBUG0;
wire [15:0] outDEBUG1; wire [15:0] outDEBUG1;
wire [15:0] outDEBUG2; //wire [15:0] outDEBUG2;
wire loadDEBUG0; wire loadDEBUG0;
wire loadDEBUG1; wire loadDEBUG1;
wire loadDEBUG2; //wire loadDEBUG2;
// Put your code here: // Put your code here:
wire [15:0] fromGO;
assign SRAM_ADDR[17:16]=2'b0;
assign SRAM_ADDR[15:0]=fromGO;
assign LED[1:0] = inIO0[1:0]; assign LED[1:0] = inIO0[1:0];
assign inIO8 = fromLCD;
assign inIO9 = fromLCD;
assign outDEBUG0 = inIOB; assign outDEBUG0 = inIOB;
assign outDEBUG1 = inIOC; assign outDEBUG1 = inIOC;
assign outDEBUG2 = inIOD; //assign outDEBUG2 = inIOD;
assign loadDEBUG0 = loadIOB; //assign loadDEBUG0 = loadIOB;
assign loadDEBUG1 = loadIOC; //assign loadDEBUG1 = loadIOC;
assign loadDEBUG2 = loadIOD; //assign loadDEBUG2 = loadIOD;
Clock25_Reset20 CLKR(CLK, clk, reset); Clock25_Reset20 CLKR(CLK, clk, reset);
CPU CPU(clk, inM, instruction, reset, outM, writeM, addressM, pc); Or OR(reset, loadIO7, RESET);
CPU CPU(clk, inM, instruction, RESET, outM, writeM, addressM, pc);
Memory Memory(addressM, writeM, inM, loadRAM, Memory Memory(addressM, writeM, inM, loadRAM,
loadIO0, loadIO1, loadIO2, loadIO3, loadIO4, loadIO5, loadIO6, loadIO7, loadIO0, loadIO1, loadIO2, loadIO3, loadIO4, loadIO5, loadIO6, loadIO7,
@@ -101,7 +110,7 @@ module HACK(
inRAM, inIO0, inIO1, inIO2, inIO3, inIO4, inIO5, inIO6, inIO7, inRAM, inIO0, inIO1, inIO2, inIO3, inIO4, inIO5, inIO6, inIO7,
inIO8, inIO9, inIOA, inIOB, inIOC, inIOD, inIOE, inIOF); inIO8, inIO9, inIOA, inIOB, inIOC, inIOD, inIOE, inIOF);
ROM ROM(pc, instruction); ROM ROM(pc, ROM_DATA);
RAM3840 RAM(clk, addressM[11:0], outM, loadRAM, inRAM); RAM3840 RAM(clk, addressM[11:0], outM, loadRAM, inRAM);
Register LED12(clk, outM, loadIO0, inIO0); Register LED12(clk, outM, loadIO0, inIO0);
@@ -110,27 +119,42 @@ module HACK(
UartTX UartTX(clk, loadIO2, outM, UART_TX, inIO2); UartTX UartTX(clk, loadIO2, outM, UART_TX, inIO2);
UartRX UartRX(clk, loadIO3, UART_RX, inIO3); UartRX UartRX(clk, loadIO3, UART_RX, inIO3);
//SPI SPI(clk, loadIO4, outM, inIO4, SPI_CSX, SPI_SDO, SPI_SDI, SPI_SCK); SPI SPI(clk, loadIO4, outM, inIO4, SPI_CSX, SPI_SDO, SPI_SDI, SPI_SCK);
//GO GO(clk, loadIO5, pc, sram_addr, SRAM_ADDR, sram_data, ROM_data, instruction);
// if loadIO7=1 then instruction = SRAM_DATA/inIO6 otherwise output ROM_DATA
//GO GO(clk, loadIO7, pc, inIO5, SRAM_ADDR[15:0], inIO6, ROM_DATA, instruction);
reg load_sram=0;
always @(posedge clk) begin
if (loadIO7) begin
load_sram <= 1;
end
end
Mux16 SWITCHA(inIO5, pc, load_sram, fromGO);
Mux16 SWITCHD(ROM_DATA, inIO6, load_sram, instruction);
Register SRAM_A(clk, outM, loadIO5, inIO5);
SRAM_D SRAM_D(clk, loadIO6, outM, inIO6, SRAM_DATA, SRAM_CSX, SRAM_OEX, SRAM_WEX);
LCD LCD(clk, loadIO8, loadIO9, outM, fromLCD, LCD_DCX, LCD_CSX, LCD_SDO, LCD_SCK);
Register DEBUG0(clk, outM, loadIOB, inIOB); Register DEBUG0(clk, outM, loadIOB, inIOB);
Register DEBUG1(clk, outM, loadIOC, inIOC); Register DEBUG1(clk, outM, loadIOC, inIOC);
Register DEBUG2(clk, outM, loadIOD, inIOD); //Register DEBUG2(clk, outM, loadIOD, inIOD);
Register DEBUG3(clk, outM, loadIOE, inIOE); //Register DEBUG3(clk, outM, loadIOE, inIOE);
Register DEBUG4(clk, outM, loadIOF, inIOF); //Register DEBUG4(clk, outM, loadIOF, inIOF);
assign SPI_SDO=0; //assign SPI_SDO=0;
assign SPI_SCK=0; //assign SPI_SCK=0;
assign SPI_CSX=0; //assign SPI_CSX=0;
assign SRAM_ADDR=0;
assign SRAM_DATA=0; //assign SRAM_DATA=0;
assign SRAM_WEX=0; //assign SRAM_WEX=0;
assign SRAM_OEX=0; //assign SRAM_OEX=0;
assign SRAM_CSX=0; //assign SRAM_CSX=0;
assign LCD_DCX=0; // assign LCD_DCX=0;
assign LCD_SDO=0; // assign LCD_SDO=0;
assign LCD_SCK=0; // assign LCD_SCK=0;
assign LCD_CSX=0; // assign LCD_CSX=0;
assign RTP_SDO=0; assign RTP_SDO=0;
assign RTP_SCK=0; assign RTP_SCK=0;
endmodule endmodule

View File

@@ -15,18 +15,65 @@
* After 32 clock cycles transmission is completed and out[15] is set to 0. * After 32 clock cycles transmission is completed and out[15] is set to 0.
*/ */
`default_nettype none `default_nettype none
module LCD(
input clk, //clock 25 MHz module LCD (
input load, //start send command/byte over SPI input wire clk, // 25 MHz clock
input load16, //start send data (16 bits) input wire load, // Start sending 8-bit command/data
input [15:0] in, //data to be send input wire load16, // Start sending 16-bit data
output [15:0] out, //data to be send input wire [15:0] in, // Data to be sent
output DCX, //SPI data/command not output reg [15:0] out, // Status output
output CSX, //SPI chip select not output reg DCX, // Data/Command select (1 = data, 0 = command)
output SDO, //SPI serial data out output reg CSX, // Chip select (active low)
output SCK //SPI serial clock output reg SDO, // Serial data out (MOSI)
output reg SCK // Serial clock
); );
// Put your code here: reg [15:0] shift_reg = 16'b0;
reg [3:0] bit_counter = 0;
reg transmitting = 0;
reg is_16bit = 0;
initial begin
CSX <= 1;
DCX <= 0;
SCK <= 0;
SDO <= 0;
end
always @(posedge clk) begin
// Default signal values
SCK <= 0;
SDO <= transmitting ? SDO : 0;
out <= (transmitting || load || load16) ? 16'h8000 : 16'h0000;
//CSX <= ~transmitting;
// Handle new transmission start
if ((load || load16) && ~transmitting) begin
transmitting <= 1;
bit_counter <= (load16) ? 15 : 7;
shift_reg <= (load16) ? in : {8'b0, in[7:0]};
is_16bit <= load16;
DCX <= (load16) ? 1 : in[9]; // data if load16 or in[9] for load
CSX <= 0;
SDO <= (load16) ? in[15] : in[7]; // First bit to send
end
// Continue shifting out bits
else if (transmitting) begin
SCK <= ~SCK;
if (SCK == 1) begin
// Set next bit on falling edge
SDO <= shift_reg[bit_counter - 1];
bit_counter <= bit_counter - 1;
end
else begin
// Shift on rising edge
if (bit_counter == 0 && SCK == 0) begin
transmitting <= 0;
end
end
end
end
endmodule endmodule

View File

@@ -22,106 +22,63 @@ module SPI(
// Put your code here: // Put your code here:
// 1100 0000 0101 1011 // 1100 0000 0101 1011
// 1000 0000 0101 1011 // 1000 0000 0101 1011
reg temp; reg active;
reg active=0; reg [2:0] bit_index;
reg [7:0] totx; reg [7:0] shift_out;
reg [7:0] torx; reg [7:0] shift_in;
reg [11:0] is216; reg [3:0] count;
wire is_sample_phase = (count >= 1 && count <= 15 && count[0] == 1);
wire is_shift_phase = (count >= 0 && count <= 14 && count[0] == 0);
initial begin
SDO <= 0;
CSX <= 1'b1;
out <= 16'b0;
bit_index <= 3'b0;
end
always @(posedge clk) begin always @(posedge clk) begin
CSX <= 0;
SDO <= 0;
SCK <= 0; SCK <= 0;
out <= (out)? out : 0;
if (load == 1) begin if (load == 1) begin
out[14:8] <= 0; CSX <= 1;
out[7:0] <= in[7:0]; out <= { 8'b0, in[7:0] };
if (in[8]==1) begin
out[15] <= 0; if (!in[8]) begin
CSX <= 1;
end
else if (in[8]==0) begin
out[15] <= 1;
CSX <= 0;
active <= 1; active <= 1;
is216 <= 1; count <= 0;
totx[7:0] <= in[7:0]; bit_index <= 7; // byte order MSB->LSB
CSX <= 0;
out[15] <= 1;
shift_out[7:0] <= in[7:0];
SDO <= in[7]; SDO <= in[7];
//out <= (out<<1);
//out[0] <= SDI;
//torx[7] <= SDI;
end end
end end
else if (active==1) begin else if (active==1) begin
SCK <= ~SCK; SCK <= ~SCK;
if (is216 == 16) begin
if (count == 15) begin
SDO <= 0;
out <= {8'b0, shift_in};
active <= 0; active <= 0;
CSX <= CSX; end else begin
out <= {8'b0, torx[7:0]}; count <= count + 1;
end
else begin if (is_sample_phase) begin
CSX <= 0; bit_index <= bit_index - 1;
is216 <= is216 + 1; out[7:0] <= {out[6:0], shift_in[bit_index]};
//SDO <= totx[7-(is216/2)];
torx[7-(is216/2)] <= SDI; shift_out <= {shift_out[6:0], 1'b0};
case (is216+1) SDO <= shift_out[6]; // next bit
2 : SDO <= totx[7]; end
3 : SDO <= totx[6];
4 : SDO <= totx[6];
5 : SDO <= totx[5];
6 : SDO <= totx[5];
7 : SDO <= totx[4];
8 : SDO <= totx[4];
9 : SDO <= totx[3];
10 : SDO <= totx[3];
11 : SDO <= totx[2];
12 : SDO <= totx[2];
13 : SDO <= totx[1];
14 : SDO <= totx[1];
15 : SDO <= totx[0];
16 : SDO <= totx[0];
endcase
// case (is216) if (is_shift_phase) begin
// 3 : torx[6] <= SDI; shift_in[bit_index] <= SDI;
// 5 : torx[5] <= SDI; end
// 7 : torx[4] <= SDI;
// 9 : torx[3] <= SDI;
// 11 : torx[2] <= SDI;
// 13 : torx[1] <= SDI;
// 15 : torx[0] <= SDI;
// endcase
case (is216)
2 : out <= (out<<1);
4 : out <= (out<<1);
6 : out <= (out<<1);
8 : out <= (out<<1);
10 : out <= (out<<1);
12 : out <= (out<<1);
14 : out <= (out<<1);
endcase
case (is216)
2 : out[0] <= torx[7];
4 : out[0] <= torx[6];
6 : out[0] <= torx[5];
8 : out[0] <= torx[4];
10 : out[0] <= torx[3];
12 : out[0] <= torx[2];
14 : out[0] <= torx[1];
endcase
case (is216)
2 : out[15:8] <= {8'b10000000};
4 : out[15:8] <= {8'b10000000};
6 : out[15:8] <= {8'b10000000};
8 : out[15:8] <= {8'b10000000};
10 : out[15:8] <= {8'b10000000};
12 : out[15:8] <= {8'b10000000};
14 : out[15:8] <= {8'b10000000};
endcase
end end
end else begin
CSX <= CSX;
out <= out? out : 16'b0;
end end
end end
endmodule endmodule

View File

@@ -15,7 +15,7 @@ module SRAM_D(
input [15:0] in, input [15:0] in,
output [15:0] out, output [15:0] out,
inout [15:0] DATA, // SRAM data 16 Bit inout [15:0] DATA, // SRAM data 16 Bit
output CSX, // SRAM chip_enable_not output reg CSX=0, // SRAM chip_enable_not
output reg OEX, // SRAM output_enable_not output reg OEX, // SRAM output_enable_not
output reg WEX // SRAM write_enable_not output reg WEX // SRAM write_enable_not
); );
@@ -32,11 +32,16 @@ module SRAM_D(
WEX <= 1; WEX <= 1;
end end
end end
//DFF DFF(clk, load, LOAD); // wire LOAD;
//Register Register(clk, in, load, to_sram); // wire [15:0] to_sram;
// assign CSX = 0;
// assign OEX = (LOAD) ? 1 : 0; // assign OEX = (LOAD) ? 1 : 0;
// assign WEX = (LOAD) ? 0 : 1; // assign WEX = (LOAD) ? 0 : 1;
assign CSX = 0; // DFF DFF(clk, load, LOAD);
// Register Register(clk, in, load, to_sram);
InOut InOut(DATA, to_sram, out, OEX); InOut InOut(DATA, to_sram, out, OEX);
//if (dir == 0) IN: PIN are set to High-Z, dataR = external PIN
//if (dir == 1) OUTPUT: dataW is output to external PIN, dataR = dataW
endmodule endmodule

View File

@@ -7,45 +7,49 @@
* of byte completes, chip ouputs the received byte to out[7:0]] with out[15]=0. * of byte completes, chip ouputs the received byte to out[7:0]] with out[15]=0.
*/ */
`default_nettype none `default_nettype none
module UartRX( module UartRX (
input clk, input wire clk,
input clear, input wire clear,
input RX, input wire RX,
output reg [15:0] out output reg [15:0] out
); );
// Put your code here: reg [7:0] baud_count;
wire clkdRX; reg [3:0] bit_index;
reg active=0; reg [7:0] rx_shift;
reg [7:0] uart; reg rx_active;
reg [3:0] nthbit;
reg [11:0] is216;
always @(posedge clk) begin
out <= clear ? 16'h8000 : out;
if ((active==0) && (RX == 0)) begin initial begin
active <= 1; out <= 16'b0;
is216 <= 1; rx_active <= 1'b0;
uart <= 0; end
nthbit <= 0;
end
else if (active==1) begin always @(posedge clk) begin
is216 <= (is216 == 216) ? 0 : is216 + 1;
nthbit <= (is216 == 108) ? nthbit + 1 : nthbit; out <= (clear | out[15]) ? 16'h8000 : out;
case (nthbit)
1 : uart[0] <= RX; if (!rx_active && !RX) begin
2 : uart[1] <= RX;
3 : uart[2] <= RX; // RX Falling edge: Start bit detected
4 : uart[3] <= RX; rx_active <= 1;
5 : uart[4] <= RX; rx_shift <= 0;
6 : uart[5] <= RX; baud_count <= 1;
7 : uart[6] <= RX; bit_index <= 0;
8 : uart[7] <= RX; end else if (rx_active) begin
endcase
if (nthbit == 10 && is216 == 216) begin baud_count <= (baud_count == 216) ? 0 : baud_count + 1;
active <= 0; bit_index <= (baud_count == 108) ? bit_index + 1 : bit_index;
out <= {8'b0, uart};
if (bit_index >= 1 && bit_index <= 8 && baud_count == 108) begin
rx_shift <= {RX, rx_shift[7:1]};
end
if (bit_index == 10 && baud_count == 216) begin
rx_active <= 0; // Done receiving 8 bits + stop
out <= {8'b0, rx_shift};
end end
end end
end end
endmodule endmodule

View File

@@ -8,47 +8,50 @@
* low again (ready). * low again (ready).
*/ */
`default_nettype none `default_nettype none
module UartTX( module UartTX (
input clk, input wire clk,
input load, input wire load,
input [15:0] in, input wire [15:0] in,
output TX, output wire TX,
output reg [15:0] out output reg [15:0] out
); );
reg uart=1; reg [9:0] baud_count;
reg active=0; reg [3:0] bit_index;
reg [7:0] to_send; reg [9:0] shift_reg;
reg [3:0] nthbit=0; reg tx_active;
reg [11:0] is216;
always @(posedge clk) begin
out <= (load || active) ? 16'h8000 : 16'h0000;
if ((active==0) && (load == 1)) begin initial begin
active <= 1; tx_active <= 1'b0;
is216 <= 1; shift_reg <= 10'b1;
nthbit <= 0; end
uart <= 0;
to_send <= in[7:0];
end always @(posedge clk) begin
else if (active==1) begin // Output status
is216 <= (is216 == 216) ? 0 : is216 + 1; out <= (load || tx_active) ? 16'h8000 : 16'h0000;
nthbit <= (is216 == 216) ? nthbit + 1 : nthbit;
case (nthbit) if (!tx_active && load) begin
0 : uart <= 0; // Load start bit + data + stop bit into shift register
1 : uart <= to_send[0]; shift_reg <= {1'b1, in[7:0], 1'b0}; // {stop, data[7:0], start}
2 : uart <= to_send[1]; tx_active <= 1;
3 : uart <= to_send[2]; baud_count <= 0;
4 : uart <= to_send[3]; bit_index <= 0;
5 : uart <= to_send[4]; end else if (tx_active) begin
6 : uart <= to_send[5]; if (baud_count == 216) begin
7 : uart <= to_send[6]; baud_count <= 0;
8 : uart <= to_send[7]; bit_index <= bit_index + 1;
9 : uart <= 1; shift_reg <= {1'b1, shift_reg[9:1]}; // shift in stop bit after final bit
10 : begin active <= 0; out <= 16'h0000; end if (bit_index == 9) begin
endcase tx_active <= 0;
out <= 16'h0000;
end
end else begin
baud_count <= baud_count + 1;
end
end end
end end
assign TX = uart;
assign TX = shift_reg[0];
endmodule endmodule

View File

@@ -1,5 +1,4 @@
PYTHON = /bin/python3.11 PYTHON = ~/.pyenv/shims/python
all: jack vm asm bin sim all: jack vm asm bin sim
jack: jack:

View File

@@ -1,5 +1,4 @@
PYTHON = python3.11 PYTHON = ~/.pyenv/shims/python
all: jack vm asm bin sim all: jack vm asm bin sim
jack: jack:

View File

@@ -1,5 +1,4 @@
PYTHON = python3.11 PYTHON = ~/.pyenv/shims/python
all: jack vm asm bin sim all: jack vm asm bin sim
jack: jack:

View File

@@ -1,5 +1,4 @@
PYTHON = python3.11 PYTHON = ~/.pyenv/shims/python
all: jack vm asm bin sim all: jack vm asm bin sim
jack: jack:

View File

@@ -1,5 +1,4 @@
PYTHON = python3.11 PYTHON = ~/.pyenv/shims/python
all: jack vm asm bin sim all: jack vm asm bin sim
jack: jack:

View File

@@ -1,5 +1,4 @@
PYTHON = python3.11 PYTHON = ~/.pyenv/shims/python
all: jack vm asm bin sim all: jack vm asm bin sim
jack: jack:

View File

@@ -1,5 +1,4 @@
PYTHON = python3.11 PYTHON = ~/.pyenv/shims/python
all: jack vm asm bin sim all: jack vm asm bin sim
jack: jack:

View File

@@ -1,5 +1,4 @@
PYTHON = python3.11 PYTHON = ~/.pyenv/shims/python
all: jack vm asm bin sim all: jack vm asm bin sim
jack: jack:

View File

@@ -1,5 +1,4 @@
PYTHON = python3.11 PYTHON = ~/.pyenv/shims/python
all: jack vm asm bin sim all: jack vm asm bin sim
jack: jack:

View File

@@ -1,5 +1,4 @@
PYTHON = python3.11 PYTHON = ~/.pyenv/shims/python
all: jack vm asm bin sim all: jack vm asm bin sim
jack: jack:

View File

@@ -1,5 +1,4 @@
PYTHON = python3.11 PYTHON = ~/.pyenv/shims/python
all: jack vm asm bin sim all: jack vm asm bin sim
jack: jack:

View File

@@ -1,5 +1,4 @@
PYTHON = python3.11 PYTHON = ~/.pyenv/shims/python
all: jack vm asm bin sim all: jack vm asm bin sim
jack: jack:

39
Makefile Normal file
View File

@@ -0,0 +1,39 @@
PYTHON = ~/.pyenv/shims/python
rom = 06_IO_Devices/00_HACK/ROM
bootloader = 06_IO_Devices/05_GO/bootloader
warez = 06_IO_Devices/01_UartTX/motd
bitstream = 06_IO_Devices/00_HACK/hardware
upload = Nand2Tetris.img
download = Nand2Tetris.img.backup
clean:
find . -type f \( -name *.hack -o -name *.bin -o -name *.img \) -delete
read:
flashrom.exe --progress -p buspirate_spi:dev=COM12 -r $(download)
write:
flashrom.exe --progress -p buspirate_spi:dev=COM12 -w $(upload)
build: build-rom build-warez build-bitstream
build-rom:
$(PYTHON) tools/Assembler/assembler.pyc $(bootloader).asm
cp $(bootloader).hack $(rom).hack
build-warez:
$(PYTHON) tools/Assembler/assembler.pyc $(warez).asm
$(PYTHON) tools/AsciiToBin.py $(warez).hack
build-bitstream:
cd 06_IO_Devices/00_HACK; apio clean; apio build -v
dd if=/dev/zero bs=2M count=1 of=$(upload)
dd if=$(warez).bin of=$(upload) seek=128 conv=notrunc
dd if=$(bitstream).bin of=$(upload) conv=notrunc
install: clean build read write
.PHONY: build clean install