13 Commits

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
2026be6851 build hack with UART TX / RX support 2024-10-21 20:04:09 -04:00
ecacf86e9f wip dump 2024-10-21 20:01:45 -04:00
41 changed files with 1139 additions and 122 deletions

5
.gitignore vendored
View File

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

View File

@@ -14,7 +14,7 @@ module Mux8Way16(
input [15:0] f,
input [15:0] g,
input [15:0] h,
input [2:0] sel,
input [2:0] sel,
output [15:0] out
);
@@ -35,4 +35,17 @@ module Mux8Way16(
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]);
// 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

View File

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

View File

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

View File

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

View File

@@ -54,21 +54,16 @@ module CPU(
wire [15:0] fromAorM;
wire [15:0] fromALU;
reg [15:0] tempM;
reg [15:0] tempPC;
assign is_C = instruction[15] & instruction[14] & instruction[13];
assign is_A = ~is_C;
assign loadD = is_C & instruction[4];
assign loadA = (is_C & instruction[5]) || is_A;
assign fromAorM = instruction[12] ? inM : fromA;
assign toA = is_A ? instruction : outM;
// jump if j1 bit set and ng bit set
// jump if j2 bit set and zr bit 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:
reg boot=1;
reg [3:0] ccount=0;
reg [12:0] rcount=0;
reg [11:0] rcount=0;
always @(posedge CLK) begin
if (boot == 1) begin

View File

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

View File

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

View File

@@ -1,4 +0,0 @@
// hello.asm
// this little assembler programm outputs "Hi" on UART_TX
//
// Put your code here:

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
all: asm install

View File

@@ -4,3 +4,17 @@
// repeat in an endless loop
//
// 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
all: asm install

View File

@@ -4,3 +4,139 @@
// 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
@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
all: asm install

View File

@@ -5,3 +5,185 @@
// the string to UART_TX
//
// 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
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

@@ -14,5 +14,13 @@ module GO(
);
// Put your code here:
reg active=0;
always @(posedge clk) begin
if (load) begin
active = 1;
end
end
assign instruction = (active) ? sram_data : ROM_data;
assign SRAM_ADDR = (active) ? sram_addr: pc;
endmodule

View File

@@ -12,28 +12,149 @@
`default_nettype none
module HACK(
input CLK, // external clock 100 MHz
input [1:0] BUT, // user button ("pushed down" == 0) ("up" == 1)
output [1:0] LED, // leds (0 off, 1 on)
input UART_RX, // UART recieve
output UART_TX, // UART transmit
output SPI_SDO, // SPI data out
input SPI_SDI, // SPI data in
output SPI_SCK, // SPI serial clock
output SPI_CSX, // SPI chip select not
output [17:0] SRAM_ADDR,// SRAM address 18 Bit = 256K
inout [15:0] SRAM_DATA, // SRAM data 16 Bit
output SRAM_WEX, // SRAM write_enable_not
output SRAM_OEX, // SRAM output_enable_not
output SRAM_CSX, // SRAM chip_select_not
output LCD_DCX, // LCD data/command not
output LCD_SDO, // LCD data out
output LCD_SCK, // LCD serial clock
output LCD_CSX, // LCD chip select not
input RTP_SDI, // RTP data in s
output RTP_SDO, // RTP data out
output RTP_SCK // RTP serial clock
input [1:0] BUT, // user button ("pushed down" == 0) ("up" == 1)
output [1:0] LED, // leds (0 off, 1 on)
input UART_RX, // UART recieve
output UART_TX, // UART transmit
output SPI_SDO, // SPI data out
input SPI_SDI, // SPI data in
output SPI_SCK, // SPI serial clock
output SPI_CSX, // SPI chip select not
output [17:0] SRAM_ADDR,// SRAM address 18 Bit = 256K
inout [15:0] SRAM_DATA, // SRAM data 16 Bit
output SRAM_WEX, // SRAM write_enable_not
output SRAM_OEX, // SRAM output_enable_not
output SRAM_CSX, // SRAM chip_select_not
output LCD_DCX, // LCD data/command not
output LCD_SDO, // LCD data out
output LCD_SCK, // LCD serial clock
output LCD_CSX, // LCD chip select not
input RTP_SDI, // RTP data in s
output RTP_SDO, // RTP data out
output RTP_SCK // RTP serial clock
);
// Put your code here:
// Put your code here:
wire loadRAM;
wire loadIO0;
wire loadIO1;
wire loadIO2;
wire loadIO3;
wire loadIO4;
wire loadIO5;
wire loadIO6;
wire loadIO7;
wire loadIO8;
wire loadIO9;
wire loadIOA;
wire loadIOB;
wire loadIOC;
wire loadIOD;
wire loadIOE;
wire loadIOF;
wire [15:0] inRAM;
wire [15:0] inIO0;
wire [15:0] inIO1;
wire [15:0] inIO2;
wire [15:0] inIO3;
wire [15:0] inIO4;
wire [15:0] inIO5;
wire [15:0] inIO6;
wire [15:0] inIO7;
wire [15:0] inIO8;
wire [15:0] inIO9;
wire [15:0] inIOA=0;
wire [15:0] inIOB;
wire [15:0] inIOC;
wire [15:0] inIOD=0;
wire [15:0] inIOE=0;
wire [15:0] inIOF=0;
wire writeM;
wire [15:0] inM;
wire [15:0] instruction;
wire [15:0] outM;
wire [15:0] addressM;
wire [15:0] pc;
wire clk, reset, RESET;
wire [15:0] ROM_DATA;
wire [15:0] fromLCD;
wire [15:0] outDEBUG0;
wire [15:0] outDEBUG1;
//wire [15:0] outDEBUG2;
wire loadDEBUG0;
wire loadDEBUG1;
//wire loadDEBUG2;
// 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 inIO8 = fromLCD;
assign inIO9 = fromLCD;
assign outDEBUG0 = inIOB;
assign outDEBUG1 = inIOC;
//assign outDEBUG2 = inIOD;
//assign loadDEBUG0 = loadIOB;
//assign loadDEBUG1 = loadIOC;
//assign loadDEBUG2 = loadIOD;
Clock25_Reset20 CLKR(CLK, clk, reset);
Or OR(reset, loadIO7, RESET);
CPU CPU(clk, inM, instruction, RESET, outM, writeM, addressM, pc);
Memory Memory(addressM, writeM, inM, loadRAM,
loadIO0, loadIO1, loadIO2, loadIO3, loadIO4, loadIO5, loadIO6, loadIO7,
loadIO8, loadIO9, loadIOA, loadIOB, loadIOC, loadIOD, loadIOE, loadIOF,
inRAM, inIO0, inIO1, inIO2, inIO3, inIO4, inIO5, inIO6, inIO7,
inIO8, inIO9, inIOA, inIOB, inIOC, inIOD, inIOE, inIOF);
ROM ROM(pc, ROM_DATA);
RAM3840 RAM(clk, addressM[11:0], outM, loadRAM, inRAM);
Register LED12(clk, outM, loadIO0, inIO0);
Register BUT12(clk, {14'b0, BUT[1:0]}, 1'b1, inIO1);
UartTX UartTX(clk, loadIO2, outM, UART_TX, inIO2);
UartRX UartRX(clk, loadIO3, UART_RX, inIO3);
SPI SPI(clk, loadIO4, outM, inIO4, SPI_CSX, SPI_SDO, SPI_SDI, SPI_SCK);
// 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 DEBUG1(clk, outM, loadIOC, inIOC);
//Register DEBUG2(clk, outM, loadIOD, inIOD);
//Register DEBUG3(clk, outM, loadIOE, inIOE);
//Register DEBUG4(clk, outM, loadIOF, inIOF);
//assign SPI_SDO=0;
//assign SPI_SCK=0;
//assign SPI_CSX=0;
//assign SRAM_DATA=0;
//assign SRAM_WEX=0;
//assign SRAM_OEX=0;
//assign SRAM_CSX=0;
// assign LCD_DCX=0;
// assign LCD_SDO=0;
// assign LCD_SCK=0;
// assign LCD_CSX=0;
assign RTP_SDO=0;
assign RTP_SCK=0;
endmodule

View File

@@ -15,18 +15,65 @@
* After 32 clock cycles transmission is completed and out[15] is set to 0.
*/
`default_nettype none
module LCD(
input clk, //clock 25 MHz
input load, //start send command/byte over SPI
input load16, //start send data (16 bits)
input [15:0] in, //data to be send
output [15:0] out, //data to be send
output DCX, //SPI data/command not
output CSX, //SPI chip select not
output SDO, //SPI serial data out
output SCK //SPI serial clock
module LCD (
input wire clk, // 25 MHz clock
input wire load, // Start sending 8-bit command/data
input wire load16, // Start sending 16-bit data
input wire [15:0] in, // Data to be sent
output reg [15:0] out, // Status output
output reg DCX, // Data/Command select (1 = data, 0 = command)
output reg CSX, // Chip select (active low)
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

View File

@@ -9,16 +9,77 @@
`default_nettype none
module SPI(
input clk,
input load,
input [15:0] in,
output [15:0] out,
output CSX,
output SDO,
input SDI,
output SCK
input clk,
input load,
input [15:0] in,
output reg [15:0] out,
output reg CSX,
output reg SDO,
input SDI,
output reg SCK
);
// Put your code here:
// Put your code here:
// 1100 0000 0101 1011
// 1000 0000 0101 1011
reg active;
reg [2:0] bit_index;
reg [7:0] shift_out;
reg [7:0] shift_in;
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
SCK <= 0;
if (load == 1) begin
CSX <= 1;
out <= { 8'b0, in[7:0] };
if (!in[8]) begin
active <= 1;
count <= 0;
bit_index <= 7; // byte order MSB->LSB
CSX <= 0;
out[15] <= 1;
shift_out[7:0] <= in[7:0];
SDO <= in[7];
end
end
else if (active==1) begin
SCK <= ~SCK;
if (count == 15) begin
SDO <= 0;
out <= {8'b0, shift_in};
active <= 0;
end else begin
count <= count + 1;
if (is_sample_phase) begin
bit_index <= bit_index - 1;
out[7:0] <= {out[6:0], shift_in[bit_index]};
shift_out <= {shift_out[6:0], 1'b0};
SDO <= shift_out[6]; // next bit
end
if (is_shift_phase) begin
shift_in[bit_index] <= SDI;
end
end
end
end
endmodule

View File

@@ -10,16 +10,38 @@
*/
`default_nettype none
module SRAM_D(
input clk,
input load,
input [15:0] in,
output [15:0] out,
inout [15:0] DATA, // SRAM data 16 Bit
output CSX, // SRAM chip_enable_not
output OEX, // SRAM output_enable_not
output WEX // SRAM write_enable_not
input clk,
input load,
input [15:0] in,
output [15:0] out,
inout [15:0] DATA, // SRAM data 16 Bit
output reg CSX=0, // SRAM chip_enable_not
output reg OEX, // SRAM output_enable_not
output reg WEX // SRAM write_enable_not
);
// Put your code here:
// Put your code here:
reg [15:0] to_sram;
always @(posedge clk) begin
if (load) begin
OEX <= 1;
WEX <= 0;
to_sram <= in;
end else begin
OEX <= 0;
WEX <= 1;
end
end
// wire LOAD;
// wire [15:0] to_sram;
// assign CSX = 0;
// assign OEX = (LOAD) ? 1 : 0;
// assign WEX = (LOAD) ? 0 : 1;
// DFF DFF(clk, load, LOAD);
// Register Register(clk, in, load, to_sram);
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

View File

@@ -7,14 +7,49 @@
* of byte completes, chip ouputs the received byte to out[7:0]] with out[15]=0.
*/
`default_nettype none
module UartRX(
input clk,
input clear,
input RX,
output [15:0] out
module UartRX (
input wire clk,
input wire clear,
input wire RX,
output reg [15:0] out
);
// Put your code here:
reg [7:0] baud_count;
reg [3:0] bit_index;
reg [7:0] rx_shift;
reg rx_active;
initial begin
out <= 16'b0;
rx_active <= 1'b0;
end
always @(posedge clk) begin
out <= (clear | out[15]) ? 16'h8000 : out;
if (!rx_active && !RX) begin
// RX Falling edge: Start bit detected
rx_active <= 1;
rx_shift <= 0;
baud_count <= 1;
bit_index <= 0;
end else if (rx_active) begin
baud_count <= (baud_count == 216) ? 0 : baud_count + 1;
bit_index <= (baud_count == 108) ? bit_index + 1 : bit_index;
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
endmodule

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,4 @@
PYTHON = python3.11
PYTHON = ~/.pyenv/shims/python
all: jack vm asm bin sim
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