diff --git a/4-Infrastructure/hardware/Blitter6502OISC_small.v b/4-Infrastructure/hardware/Blitter6502OISC_small.v index 9b16f9bb..c014a141 100644 --- a/4-Infrastructure/hardware/Blitter6502OISC_small.v +++ b/4-Infrastructure/hardware/Blitter6502OISC_small.v @@ -227,11 +227,12 @@ module Blitter6502OISC ( end end - // UART telemetry: when halted, send a_reg as status byte + // UART telemetry: when halted, send a_reg as status byte (once only) reg [3:0] uart_bit_cnt; reg [15:0] uart_div; reg [9:0] uart_shift; reg uart_active; + reg uart_sent; // prevents retransmission localparam UART_DIV = 16'd233; // 115384 baud at 27MHz (matches Lean uartBaudDivisor) @@ -242,13 +243,15 @@ module Blitter6502OISC ( uart_div <= 16'd0; uart_shift <= 10'b0; uart_active <= 1'b0; + uart_sent <= 1'b0; end else begin - if (halted && !uart_active) begin - // Start UART transmission with a_reg as payload - uart_shift <= {1'b1, a_reg, 1'b0}; // stop, data, start + if (halted && !uart_active && !uart_sent) begin + // Send recognizable pattern: 0xAA + a_reg + uart_shift <= {1'b1, 8'hAA, 1'b0}; // stop, 0xAA, start uart_active <= 1'b1; uart_bit_cnt <= 4'd0; uart_div <= 16'd0; + uart_sent <= 1'b1; end if (uart_active) begin @@ -305,11 +308,27 @@ module Blitter6502OISCTop ( end end + // Auto-start: trigger CPU 100ms after reset + reg [31:0] auto_start_cnt; + reg auto_start; + always @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + auto_start_cnt <= 0; + auto_start <= 0; + end else if (!auto_start) begin + if (auto_start_cnt >= 2700000) begin // 100ms at 27MHz + auto_start <= 1; + end else begin + auto_start_cnt <= auto_start_cnt + 1; + end + end + end + // Blitter instance Blitter6502OISC blitter ( .clk(clk), .rst_n(rst_n), - .start(btn_rise), + .start(auto_start), .busy(), .led(led), .uart_tx(uart_tx), diff --git a/4-Infrastructure/hardware/research_stack_top.v b/4-Infrastructure/hardware/research_stack_top.v index 61c89831..58767908 100644 --- a/4-Infrastructure/hardware/research_stack_top.v +++ b/4-Infrastructure/hardware/research_stack_top.v @@ -44,6 +44,22 @@ module research_stack_top ( end assign btn_rise = btn_stable & ~btn_stable_prev; + // Auto-start: trigger CPU 100ms after reset (no button needed) + reg [31:0] auto_start_cnt; + reg auto_start; + always @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + auto_start_cnt <= 0; + auto_start <= 0; + end else if (!auto_start) begin + if (auto_start_cnt >= 2700000) begin // 100ms at 27MHz + auto_start <= 1; + end else begin + auto_start_cnt <= auto_start_cnt + 1; + end + end + end + // ── Blitter CPU Signals ──────────────────────────────────────── wire cpu_busy; wire [5:0] cpu_led; @@ -121,7 +137,7 @@ module research_stack_top ( Blitter6502OISC cpu ( .clk(clk), .rst_n(rst_n), - .start(btn_rise), + .start(auto_start), .busy(cpu_busy), .led(cpu_led), .uart_tx(cpu_uart_tx), @@ -202,11 +218,16 @@ module research_stack_top ( ); // ── LED Output ───────────────────────────────────────────────── - // led[5] = CPU busy - // led[4] = Q16 done - // led[3:2] = voltage mode - // led[1:0] = scale select - assign led = {cpu_busy, q16_done_reg, map_voltage_mode, map_scale_select}; + // When CPU is busy: show running pattern (blinking) + // When CPU is halted: show cpu_led (register values from Blitter) + // Otherwise: show status + reg [24:0] heartbeat; + always @(posedge clk or negedge rst_n) begin + if (!rst_n) heartbeat <= 0; + else heartbeat <= heartbeat + 1; + end + assign led = cpu_busy ? {1'b1, heartbeat[23], 1'b0, heartbeat[21], 1'b0, heartbeat[19]} + : cpu_led; // Blitter's register output after halt // ── UART ─────────────────────────────────────────────────────── assign uart_tx = cpu_uart_tx; diff --git a/4-Infrastructure/hardware/tb_uart_test.v b/4-Infrastructure/hardware/tb_uart_test.v new file mode 100644 index 00000000..e9c77869 --- /dev/null +++ b/4-Infrastructure/hardware/tb_uart_test.v @@ -0,0 +1,97 @@ +module tb_uart_test; + reg clk; + wire uart_tx; + wire [5:0] led; + + uart_test uut ( + .clk(clk), + .uart_tx(uart_tx), + .led(led) + ); + + // 27MHz clock = 37.037ns period + initial clk = 0; + always #18.518 clk = ~clk; + + // UART capture + reg [7:0] rx_byte; + integer bit_idx; + integer baud_ticks; + integer char_count; + + initial begin + $dumpfile("uart_test.vcd"); + $dumpvars(0, tb_uart_test); + + rx_byte = 0; + bit_idx = 0; + baud_ticks = 0; + char_count = 0; + + // Run for 2ms = enough for several UART bytes at 115384 baud + // Each byte = 10 bits * 234 clocks = 2340 clocks = 86.67us + // 2ms / 86.67us = ~23 bytes + #2_000_000; + + $display("=== Simulation complete: received %0d characters ===", char_count); + $finish; + end + + // Monitor UART TX line - capture bytes + // Detect start bit (falling edge) and sample data bits + reg [15:0] clk_count; + reg receiving; + reg [3:0] bit_count; + + initial begin + clk_count = 0; + receiving = 0; + bit_count = 0; + end + + always @(posedge clk) begin + if (!receiving) begin + // Wait for start bit (falling edge on uart_tx) + if (uart_tx == 0) begin + receiving <= 1; + clk_count <= 0; + bit_count <= 0; + rx_byte <= 0; + // Sample at middle of bit: half of baud period = 117 clocks + end + end else begin + clk_count <= clk_count + 1; + if (clk_count == 117) begin + // Middle of first data bit (after start bit) + if (bit_count == 0) begin + // Verify start bit is still low + if (uart_tx != 0) begin + $display("ERROR: start bit not low at sample point"); + receiving <= 0; + end + end + end + if (clk_count == 117 + 234 * bit_count && bit_count < 8) begin + rx_byte[bit_count] <= uart_tx; + bit_count <= bit_count + 1; + end + if (clk_count >= 117 + 234 * 9 + 117) begin + // Past stop bit + char_count <= char_count + 1; + $display("UART byte %0d: 0x%02h = '%c' (time=%0t ns)", + char_count, rx_byte, rx_byte, $time); + receiving <= 0; + clk_count <= 0; + end + end + end + + // Also print LED state + always @(posedge clk) begin + if (led != 6'b101010 && $time > 100_000) begin + // Only print once + if ($time < 200_000) + $display("LED pattern: %06b (time=%0t)", led, $time); + end + end +endmodule diff --git a/4-Infrastructure/hardware/uart_test.v b/4-Infrastructure/hardware/uart_test.v new file mode 100644 index 00000000..b482b5d2 --- /dev/null +++ b/4-Infrastructure/hardware/uart_test.v @@ -0,0 +1,40 @@ +// Minimal UART test: sends 'R' (0x52) continuously at 115200 baud +// Verifies FT2232 channel B ↔ FPGA pin 18 connection + +module uart_test ( + input wire clk, + output wire uart_tx, + output wire [5:0] led +); + + // 27MHz / 234 = 115384 baud + localparam BAUD_DIV = 16'd233; + localparam TEST_BYTE = 8'h52; // 'R' for Research Stack + + assign led = 6'b101010; // Pattern to confirm FPGA is alive + + reg [15:0] baud_cnt = 0; + reg [3:0] bit_cnt = 0; + reg [9:0] shift_reg = 10'b1111111111; + reg tx_out = 1'b1; + assign uart_tx = tx_out; + + always @(posedge clk) begin + if (baud_cnt >= BAUD_DIV) begin + baud_cnt <= 0; + if (bit_cnt == 0) begin + // Load start bit + data + stop bit + shift_reg <= {1'b1, TEST_BYTE, 1'b0}; + bit_cnt <= 10; + tx_out <= 1'b0; // Start bit + end else begin + tx_out <= shift_reg[0]; + shift_reg <= {1'b1, shift_reg[9:1]}; + bit_cnt <= bit_cnt - 1; + end + end else begin + baud_cnt <= baud_cnt + 1; + end + end + +endmodule