From 057ee6cb6165e8b8c3d38753325e01e830803e51 Mon Sep 17 00:00:00 2001 From: Bee Date: Tue, 21 Nov 2023 16:50:58 -0500 Subject: [PATCH] Can change word size --- src/beepo.v | 162 ++++++++++++++++++++++++----------------- src/instructions.v | 2 + tests/mem/program.rhai | 13 +--- tests/mem/top.v | 12 ++- 4 files changed, 108 insertions(+), 81 deletions(-) diff --git a/src/beepo.v b/src/beepo.v index a9620e0..97d3e4a 100644 --- a/src/beepo.v +++ b/src/beepo.v @@ -1,15 +1,17 @@ -// `include "instructions.v" +`include "instructions.v" module Beepo #( - parameter FREQ = 27_000_000, - parameter UART_BAUD = 115200 + parameter FREQ = 27_000_000, + parameter UART_BAUD = 115200, + parameter WORD_SIZE = 16 ) ( input i_clk, input i_button1, input i_resume, output [6:0] o_segments_drive, output [3:0] o_displays_neg, - output o_breakpoint + output o_breakpoint, + output o_uart_tx ); // State values localparam IDLE = 0; // Start fetching instruction @@ -36,22 +38,22 @@ module Beepo #( localparam NUM_REGS = 4; reg [2:0] r_state = IDLE; - reg [63:0] r_tick = 0; + reg [WORD_SIZE-1:0] r_tick = 0; // Registers - reg [63:0] r_pc = PC_START; // program counter - reg [63:0] r_registers [0:NUM_REGS]; // up to 255 modifiable registers - reg [7:0] r_instr; // the current instruction - reg [7:0] r_arg_regs [0:3]; // register arguments - reg [63:0] r_arg_imm = 0; // immediate argument - reg [63:0] r_arg_addr = 0; // relative/absolute address argument + reg [WORD_SIZE-1:0] r_pc = PC_START; // program counter + reg [WORD_SIZE-1:0] r_registers [0:NUM_REGS]; // up to 255 modifiable registers + reg [7:0] r_instr; // the current instruction + reg [7:0] r_arg_regs [0:3]; // register arguments + reg [WORD_SIZE-1:0] r_arg_imm = 0; // immediate argument + reg [WORD_SIZE-1:0] r_arg_addr = 0; // relative/absolute address argument - reg [1:0] r_arg_index = 3; // the instruction index currently being fetched - reg [3:0] r_arg_types [0:3]; // the types of each argument to be fetched + reg [1:0] r_arg_index = 3; // the instruction index currently being fetched + reg [3:0] r_arg_types [0:3]; // the types of each argument to be fetched reg [15:0] r_arg_types_packed = 0; // to be unpacked into r_arg_types - reg [2:0] r_arg_bytes = 0; // the number of bytes left to fetch for the current argument + reg [2:0] r_arg_bytes = 0; // the number of bytes left to fetch for the current argument reg [3:0] r_arg_current_type = 8; // the type of the current argument - reg [5:0] r_arg_bit = 0; // the current lower bit index being fetched for the current argument + reg [5:0] r_arg_bit = 0; // the current lower bit index being fetched for the current argument reg r_mem_wre = 0; reg r_mem_busy = 0; @@ -59,12 +61,19 @@ module Beepo #( reg [7:0] r_mem_in = 0; reg [7:0] r_mem_index = 0; // the index of the byte in transfer reg [7:0] r_mem_reg = 0; // the register currently used in transfer - wire [63:0] w_mem_addr = r_mem_trans ? r_arg_addr : r_pc; + wire [WORD_SIZE-1:0] w_mem_addr = r_mem_trans ? r_arg_addr : r_pc; wire [7:0] w_mem_fetch; reg r_breakpoint = 0; assign o_breakpoint = r_breakpoint; + reg r_uart_rst_n = 0; + reg [7:0] r_uart_data = 0; + reg r_uart_busy = 0; + reg [7:0] r_uart_left = 0; + reg [WORD_SIZE-1:0] r_uart_addr = 0; + wire w_uart_ready; + genvar i; generate @@ -172,46 +181,58 @@ module Beepo #( EXEC: begin r_state <= FETCHI; - case (r_instr) - `TX: r_state <= DONE; - `NOP: ; - `ADD8: set_reg_byte (r_arg_regs[0], r_registers[r_arg_regs[1]][0+:8] + r_registers [r_arg_regs[2]][0+:8]); - `ADD16: set_reg_hword (r_arg_regs[0], r_registers[r_arg_regs[1]][0+:16] + r_registers [r_arg_regs[2]][0+:16]); - `ADD32: set_reg_word (r_arg_regs[0], r_registers[r_arg_regs[1]][0+:32] + r_registers [r_arg_regs[2]][0+:32]); - `ADD64: set_reg_dword (r_arg_regs[0], r_registers[r_arg_regs[1]][0+:64] + r_registers [r_arg_regs[2]][0+:64]); - `ADDI8: set_reg_byte (r_arg_regs[0], r_registers[r_arg_regs[1]][0+:8] + r_arg_imm [0+:8]); - `ADDI16: set_reg_hword (r_arg_regs[0], r_registers[r_arg_regs[1]][0+:16] + r_arg_imm [0+:16]); - `ADDI32: set_reg_word (r_arg_regs[0], r_registers[r_arg_regs[1]][0+:32] + r_arg_imm [0+:32]); - `ADDI64: set_reg_dword (r_arg_regs[0], r_registers[r_arg_regs[1]][0+:64] + r_arg_imm [0+:64]); - `LI8: set_reg_byte (r_arg_regs[0], r_arg_imm); - `LI16: set_reg_hword (r_arg_regs[0], r_arg_imm); - `LI32: set_reg_word (r_arg_regs[0], r_arg_imm); - `LI64: set_reg_dword (r_arg_regs[0], r_arg_imm); - `LD: begin - if (r_arg_imm > 0) begin - r_arg_addr <= r_arg_addr + r_registers[r_arg_regs[1]]; - r_mem_index <= 0; - r_mem_reg <= r_arg_regs[0]; - r_mem_busy <= 1; - r_state <= MEMR; - r_mem_trans <= 1; + if (WORD_SIZE >= 8) + case (r_instr) + `TX: r_state <= DONE; + `NOP: ; + `ADD8: set_reg_byte (r_arg_regs[0], r_registers[r_arg_regs[1]][0+:8] + r_registers [r_arg_regs[2]][0+:8]); + `ADDI8: set_reg_byte (r_arg_regs[0], r_registers[r_arg_regs[1]][0+:8] + r_arg_imm [0+:8]); + `LI8: set_reg_byte (r_arg_regs[0], r_arg_imm); + `LD: begin + if (r_arg_imm > 0) begin + r_arg_addr <= r_arg_addr + r_registers[r_arg_regs[1]]; + r_mem_index <= 0; + r_mem_reg <= r_arg_regs[0]; + r_mem_busy <= 1; + r_state <= MEMR; + r_mem_trans <= 1; + end end - end - `ST: begin - if (r_arg_imm > 0) begin - r_arg_addr <= r_arg_addr + r_registers[r_arg_regs[1]]; - r_mem_index <= 1; - r_mem_reg <= r_arg_regs[0]; - r_mem_wre <= 1; - r_mem_in <= r_registers[r_arg_regs[0]][0+:8]; - r_mem_busy <= 1; - r_state <= MEMR; - r_mem_trans <= 1; + `ST: begin + if (r_arg_imm > 0) begin + r_arg_addr <= r_arg_addr + r_registers[r_arg_regs[1]]; + r_mem_index <= 1; + r_mem_reg <= r_arg_regs[0]; + r_mem_wre <= 1; + r_mem_in <= r_registers[r_arg_regs[0]][0+:8]; + r_mem_busy <= 1; + r_state <= MEMR; + r_mem_trans <= 1; + end + end + `EBP: r_breakpoint = 1; + endcase - end - end - `EBP: r_breakpoint = 1; - endcase + if (WORD_SIZE >= 16) + case (r_instr) + `ADD16: set_reg_hword (r_arg_regs[0], r_registers[r_arg_regs[1]][0+:16] + r_registers [r_arg_regs[2]][0+:16]); + `ADDI16: set_reg_hword (r_arg_regs[0], r_registers[r_arg_regs[1]][0+:16] + r_arg_imm [0+:16]); + `LI16: set_reg_hword (r_arg_regs[0], r_arg_imm); + endcase + + if (WORD_SIZE >= 32) + case (r_instr) + `ADD32: set_reg_word (r_arg_regs[0], r_registers[r_arg_regs[1]][0+:32] + r_registers [r_arg_regs[2]][0+:32]); + `ADDI32: set_reg_word (r_arg_regs[0], r_registers[r_arg_regs[1]][0+:32] + r_arg_imm [0+:32]); + `LI32: set_reg_word (r_arg_regs[0], r_arg_imm); + endcase + + if (WORD_SIZE >= 64) + case (r_instr) + `ADD64: set_reg_dword (r_arg_regs[0], r_registers[r_arg_regs[1]][0+:64] + r_registers [r_arg_regs[2]][0+:64]); + `ADDI64: set_reg_dword (r_arg_regs[0], r_registers[r_arg_regs[1]][0+:64] + r_arg_imm [0+:64]); + `LI64: set_reg_dword (r_arg_regs[0], r_arg_imm); + endcase end MEMR: begin case (r_instr) @@ -229,7 +250,7 @@ module Beepo #( end else begin r_mem_index = r_mem_index + 1; - if (r_mem_index == 8) begin + if (r_mem_index == WORD_SIZE / 8) begin // reached the end of this register r_mem_reg <= r_mem_reg + 1; r_mem_index <= 0; @@ -240,9 +261,9 @@ module Beepo #( end end endcase - end - always @(r_registers[0]) r_registers[0] <= 0; + r_registers[0] <= 0; + end task automatic set_reg_byte( input [7:0] being_set, @@ -267,7 +288,7 @@ module Beepo #( task automatic set_reg_dword( input [7:0] being_set, - input [63:0] setting_to + input [WORD_SIZE-1:0] setting_to ); r_registers[being_set][0+:64] = setting_to; endtask @@ -280,13 +301,24 @@ module Beepo #( if (start_bit <= 56) r_registers[being_set][start_bit+:8] = setting_to; endtask - Multi7 display ( - .i_clk(i_clk), - .i_hex({r_registers[1][15:0]}), - .o_segments_drive(o_segments_drive), - .o_displays_neg(o_displays_neg) - ); - + Multi7 display ( + .i_clk(i_clk), + .i_hex({r_registers[1][15:0]}), + .o_segments_drive(o_segments_drive), + .o_displays_neg(o_displays_neg) + ); + + // uart_tx #( + // .CLK_FRE(FREQ/1_000_000), + // .BAUD_RATE(115200) + // ) serial ( + // .clk(i_clk), + // .rst_n(r_uart_rst_n), + // .tx_data(r_uart_data), + // .tx_data_ready(w_uart_ready), + // .tx_pin(o_uart_tx) + // ); + spMem mem ( .clk(i_clk), .ad(w_mem_addr), diff --git a/src/instructions.v b/src/instructions.v index fd75bec..87dae7a 100644 --- a/src/instructions.v +++ b/src/instructions.v @@ -61,5 +61,7 @@ `define JEQ 'h56 // Environment traps +`define ECA 'h5C +`define ECA_ARGS {ARG_N, ARG_N, ARG_N, ARG_N} `define EBP 'h5D `define EBP_ARGS {ARG_N, ARG_N, ARG_N, ARG_N} \ No newline at end of file diff --git a/tests/mem/program.rhai b/tests/mem/program.rhai index 648080c..62e6c48 100644 --- a/tests/mem/program.rhai +++ b/tests/mem/program.rhai @@ -1,13 +1,2 @@ -li64 (r4, 0x1020304050607080); -st (r4, r0, 0x400, 8); -ld (r1, r0, 0x400, 8); // 0x1020304050607080 -ebp(); - -ld (r2, r0, 0x404, 4); // 0x0000000010203040 -ebp(); - -li64 (r1, 0x1010202030304040); -li64 (r2, 0x5050606070708080); -st (r1, r0, 0x410, 16); -ld (r3, r0, 0x410, 16); +nop(); ebp(); \ No newline at end of file diff --git a/tests/mem/top.v b/tests/mem/top.v index cfcab0b..f65d79b 100644 --- a/tests/mem/top.v +++ b/tests/mem/top.v @@ -46,16 +46,20 @@ module tb_beepo(); $display("BREAK"); case (r_test) T_STLD: begin - `assert(bep.r_registers[1], 64'h1020304050607080); + // `assert(bep.r_registers[1], 64'h1020304050607080); + `assert(bep.r_registers[1], 16'h1020); $display("[MEM] ST/LD test passed"); end T_STLD_HALF: begin - `assert(bep.r_registers[2], 64'h0000000010203040); + // `assert(bep.r_registers[2], 64'h0000000010203040); + `assert(bep.r_registers[2], 16'h10); $display("[MEM] ST/LD Half test passed"); end T_STLD_DOUBLE: begin - `assert(bep.r_registers[3], 64'h1010202030304040); - `assert(bep.r_registers[4], 64'h5050606070708080); + // `assert(bep.r_registers[3], 64'h1010202030304040); + // `assert(bep.r_registers[4], 64'h5050606070708080); + `assert(bep.r_registers[3], 64'h1010); + `assert(bep.r_registers[4], 64'h5050); $display("[MEM] ST/LD Double test passed"); end endcase