the rest of LI, ADD and ADDI

This commit is contained in:
Bee 2023-11-15 20:55:46 -05:00
parent 00eadf1b64
commit 53d08b6c04
10 changed files with 133 additions and 89 deletions

4
.gitignore vendored
View file

@ -1,5 +1,5 @@
impl/ impl/
**/*.gprj* **/*.gprj*
tests/*.vcd tests/**/*.vcd
tests/out tests/**/out
src/gowin_*/ src/gowin_*/

View file

@ -1,4 +1,4 @@
`include "instructions.v" // `include "instructions.v"
module Beepo #( module Beepo #(
parameter FREQ = 27_000_000, parameter FREQ = 27_000_000,
@ -24,7 +24,7 @@ module Beepo #(
localparam [3:0] ARG_B = 3; // Byte, 8 bit localparam [3:0] ARG_B = 3; // Byte, 8 bit
localparam [3:0] ARG_H = 4; // Half-word, 16 bit localparam [3:0] ARG_H = 4; // Half-word, 16 bit
localparam [3:0] ARG_W = 5; // Word, 32 bit localparam [3:0] ARG_W = 5; // Word, 32 bit
localparam [3:0] ARG_D = 6; // D{gtkwave NET OFF} ouble-word, 64 bit localparam [3:0] ARG_D = 6; // Double-word, 64 bit
localparam [3:0] ARG_A = 7; // Absolute address immediate, 64 bit localparam [3:0] ARG_A = 7; // Absolute address immediate, 64 bit
localparam [3:0] ARG_N = 8; // No argument localparam [3:0] ARG_N = 8; // No argument
@ -45,7 +45,7 @@ module Beepo #(
// Registers // Registers
reg [63:0] r_pc = PC_START; // program counter reg [63:0] r_pc = PC_START; // program counter
reg [63:0] r_pc_latch = PC_START; // address input to ROM reg [63:0] r_pc_latch = PC_START; // address input to ROM
reg [63:0] r_registers [0:NUM_REGS-1]; // the 255 modifiable registers 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_instr; // the current instruction
reg [7:0] r_arg_regs [0:3]; // register arguments reg [7:0] r_arg_regs [0:3]; // register arguments
reg [63:0] r_arg_imm = 0; // immediate argument reg [63:0] r_arg_imm = 0; // immediate argument
@ -63,7 +63,7 @@ module Beepo #(
genvar i; genvar i;
generate generate
for (i = 1; i < NUM_REGS-1; i = i + 1) begin for (i = 1; i <= NUM_REGS; i = i + 1) begin
initial r_registers[i] <= 0; initial r_registers[i] <= 0;
end end
endgenerate endgenerate
@ -86,14 +86,21 @@ module Beepo #(
r_arg_bit <= 0; r_arg_bit <= 0;
case (w_mem_fetch) case (w_mem_fetch)
`TX: r_arg_types_packed = `TX_ARGS; `TX: r_arg_types_packed = `TX_ARGS;
`NOP: r_arg_types_packed = `NOP_ARGS; `NOP: r_arg_types_packed = `NOP_ARGS;
`ADD8: r_arg_types_packed = `ADD8_ARGS; `ADD8: r_arg_types_packed = `ADD8_ARGS;
`ADD16: r_arg_types_packed = `ADD16_ARGS; `ADD16: r_arg_types_packed = `ADD16_ARGS;
`ADDI8: r_arg_types_packed = `ADDI8_ARGS; `ADD32: r_arg_types_packed = `ADD32_ARGS;
`LI8: r_arg_types_packed = `LI8_ARGS; `ADD64: r_arg_types_packed = `ADD64_ARGS;
`LI16: r_arg_types_packed = `LI16_ARGS; `ADDI8: r_arg_types_packed = `ADDI8_ARGS;
default: r_arg_types_packed = {ARG_N, ARG_N, ARG_N, ARG_N}; `ADDI16: r_arg_types_packed = `ADDI16_ARGS;
`ADDI32: r_arg_types_packed = `ADDI32_ARGS;
`ADDI64: r_arg_types_packed = `ADDI64_ARGS;
`LI8: r_arg_types_packed = `LI8_ARGS;
`LI16: r_arg_types_packed = `LI16_ARGS;
`LI32: r_arg_types_packed = `LI32_ARGS;
`LI64: r_arg_types_packed = `LI64_ARGS;
default: r_arg_types_packed = {ARG_N, ARG_N, ARG_N, ARG_N};
endcase endcase
if (r_arg_types_packed[15:12] != ARG_N) begin if (r_arg_types_packed[15:12] != ARG_N) begin
@ -166,13 +173,20 @@ module Beepo #(
r_state <= FETCHI; r_state <= FETCHI;
case (r_instr) case (r_instr)
`TX: r_state <= DONE; `TX: r_state <= DONE;
`NOP: ; `NOP: ;
`ADD8: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_registers[r_arg_regs[2]][7:0]); `ADD8: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_registers[r_arg_regs[2]][7:0]);
`ADD16: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_registers[r_arg_regs[2]][15:0]); `ADD16: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_registers[r_arg_regs[2]][15:0]);
`ADDI8: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_arg_imm[7:0]); `ADD32: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_registers[r_arg_regs[2]][31:0]);
`LI8: set_register(r_arg_regs[0], r_arg_imm); `ADD64: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_registers[r_arg_regs[2]][63:0]);
`LI16: set_register(r_arg_regs[0], r_arg_imm); `ADDI8: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_arg_imm[7:0]);
`ADDI16: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_arg_imm[15:0]);
`ADDI32: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_arg_imm[31:0]);
`ADDI64: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_arg_imm[63:0]);
`LI8: set_register(r_arg_regs[0], r_arg_imm);
`LI16: set_register(r_arg_regs[0], r_arg_imm);
`LI32: set_register(r_arg_regs[0], r_arg_imm);
`LI64: set_register(r_arg_regs[0], r_arg_imm);
endcase endcase
// r_tx_send_ctrl[0] <= ~r_tx_send_ctrl[0]; // r_tx_send_ctrl[0] <= ~r_tx_send_ctrl[0];

View file

@ -13,6 +13,10 @@
`define ADD8_ARGS {ARG_R, ARG_R, ARG_R, ARG_N} `define ADD8_ARGS {ARG_R, ARG_R, ARG_R, ARG_N}
`define ADD16 'h04 `define ADD16 'h04
`define ADD16_ARGS {ARG_R, ARG_R, ARG_R, ARG_N} `define ADD16_ARGS {ARG_R, ARG_R, ARG_R, ARG_N}
`define ADD32 'h05
`define ADD32_ARGS {ARG_R, ARG_R, ARG_R, ARG_N}
`define ADD64 'h06
`define ADD64_ARGS {ARG_R, ARG_R, ARG_R, ARG_N}
// Merged divide-remainder // Merged divide-remainder
`define DIRU8 'h20 `define DIRU8 'h20
@ -24,6 +28,12 @@
// Binary register-immediate operations // Binary register-immediate operations
`define ADDI8 'h2D `define ADDI8 'h2D
`define ADDI8_ARGS {ARG_R, ARG_R, ARG_B, ARG_N} `define ADDI8_ARGS {ARG_R, ARG_R, ARG_B, ARG_N}
`define ADDI16 'h2E
`define ADDI16_ARGS {ARG_R, ARG_R, ARG_H, ARG_N}
`define ADDI32 'h2F
`define ADDI32_ARGS {ARG_R, ARG_R, ARG_W, ARG_N}
`define ADDI64 'h30
`define ADDI64_ARGS {ARG_R, ARG_R, ARG_D, ARG_N}
// Register-immediate bitshifts // Register-immediate bitshifts
`define SLUI8 'h38 `define SLUI8 'h38
@ -36,6 +46,10 @@
`define LI8_ARGS {ARG_R, ARG_B, ARG_N, ARG_N} `define LI8_ARGS {ARG_R, ARG_B, ARG_N, ARG_N}
`define LI16 'h49 `define LI16 'h49
`define LI16_ARGS {ARG_R, ARG_H, ARG_N, ARG_N} `define LI16_ARGS {ARG_R, ARG_H, ARG_N, ARG_N}
`define LI32 'h4A
`define LI32_ARGS {ARG_R, ARG_W, ARG_N, ARG_N}
`define LI64 'h4B
`define LI64_ARGS {ARG_R, ARG_D, ARG_N, ARG_N}
// Conditional jump // Conditional jump
`define JEQ 'h56 `define JEQ 'h56

View file

@ -2,9 +2,9 @@ ICARUS_FILES = inputs.txt
ICARUS_OUT = out ICARUS_OUT = out
build: ${ICARUS_FILES} build: ${ICARUS_FILES}
iverilog -o ${ICARUS_OUT} -c $^ -s tb_beepo -g2005-sv iverilog -o ${ICARUS_OUT} -c $^ -s tb_adding
vvp: build run: build
vvp ${ICARUS_OUT} vvp ${ICARUS_OUT}
wave: vvp wave: vvp

42
tests/adding/adding.v Normal file
View file

@ -0,0 +1,42 @@
`include "../../src/beepo.v"
`timescale 100us/10ns
`define assert(signal, value) \
if (signal !== value) begin \
$display("ASSERTION FAILED in %m: signal != value"); \
$finish; \
end
module tb_adding(
output o_uart_tx
);
reg clk = 0;
Beepo #(
.FREQ(1),
.UART_BAUD(1_000_000)
) bep (
.i_clk(clk),
.o_uart_tx(o_uart_tx)
);
localparam CLK_PERIOD = 1.0;
always #(CLK_PERIOD/2) clk=~clk;
initial begin
$dumpfile("dump.vcd");
$dumpvars(0, tb_adding,
bep.r_registers[1], bep.r_registers[2],
bep.r_arg_types[0], bep.r_arg_types[1],
bep.r_arg_types[2], bep.r_arg_types[3],
bep.r_arg_regs[0], bep.r_arg_regs[1],
bep.r_arg_regs[2], bep.r_arg_regs[3]
);
end
// should probably do more tests than just the end
initial #10000 begin
`assert(bep.r_registers[1], 64'h2020202040406090);
$finish;
end
endmodule

5
tests/adding/inputs.txt Normal file
View file

@ -0,0 +1,5 @@
../../src/instructions.v
adding.v
../../src/uart_tx.v
../../src/multi7.v
spmem.v

35
tests/adding/spmem.v Normal file
View file

@ -0,0 +1,35 @@
module spMem(
output [7:0] dout,
input clk,
input oce,
input ce,
input reset,
input wre,
input [15:0] ad,
input [7:0] din
);
reg [0:543] mem = {
8'h0,
8'h48, 8'h01, 8'h10, // r1 <- 0x10
8'h49, 8'h02, 16'h1010, // r2 <- 0x1010
8'h4A, 8'h03, 32'h10101010, // r3 <- 0x10101010
8'h4B, 8'h04, 64'h1010101010101010, // r4 <- 0x1010101010101010
8'h03, 8'h01, 8'h01, 8'h01, // r1 <- r1 + r1 (r1 = 0x20)
8'h04, 8'h01, 8'h01, 8'h02, // r1 <- r1 + r2 (r1 = 0x1030)
8'h05, 8'h01, 8'h01, 8'h03, // r1 <- r1 + r3 (r1 = 0x10102040)
8'h06, 8'h01, 8'h01, 8'h04, // r1 <- r1 + r4 (r1 = 0x1010101020203050)
8'h2D, 8'h01, 8'h01, 8'h10, // r1 <- r1 + 0x10 (r1 = 0x1010101020203060)
8'h2E, 8'h01, 8'h01, 16'h1010, // r1 <- r1 + 0x1010 (r1 = 0x1010101020204070)
8'h2F, 8'h01, 8'h01, 32'h10101010, // r1 <- r1 + 0x10101010 (r1 = 0x1010101030305080)
8'h30, 8'h01, 8'h01, 64'h1010101010101010, // r1 <- r1 + 0x1010101010101010 (r1 = 0x2020202040406090)
8'h01 // die
};
reg [7:0] r_out;
assign dout = r_out;
always @(negedge clk) begin
r_out <= mem[ad*8+:8];
end
endmodule

View file

@ -1,34 +0,0 @@
`include "../src/beepo.v"
`timescale 100us/10ns
module tb_beepo(
output o_uart_tx
);
reg clk = 0;
Beepo #(
.FREQ(1),
.UART_BAUD(1_000_000)
) bep (
.i_clk(clk),
.o_uart_tx(o_uart_tx)
);
localparam CLK_PERIOD = 1.0;
always #(CLK_PERIOD/2) clk=~clk;
initial begin
$dumpfile("dump.vcd");
$dumpvars(0, tb_beepo,
bep.r_registers[1], bep.r_registers[2],
bep.r_arg_types[0], bep.r_arg_types[1],
bep.r_arg_types[2], bep.r_arg_types[3],
bep.r_arg_regs[0], bep.r_arg_regs[1],
bep.r_arg_regs[2], bep.r_arg_regs[3]
);
end
initial #10000 $finish;
endmodule

View file

@ -1,5 +0,0 @@
../src/instructions.v
beepo.v
../src/uart_tx.v
../src/multi7.v
spmem.v

View file

@ -1,27 +0,0 @@
module spMem(
output [7:0] dout,
input clk,
input oce,
input ce,
input reset,
input wre,
input [15:0] ad,
input [7:0] din
);
reg [0:255] mem = {
8'h0,
8'h49, 8'h01, 8'h23, 8'h46,
8'h49, 8'h02, 8'h46, 8'h23,
8'h03, 8'h01, 8'h01, 8'h02,
8'h01,
144'h0
};
reg [7:0] r_out;
assign dout = r_out;
always @(negedge clk) begin
r_out <= mem[ad*8+:8];
end
endmodule