the rest of LI, ADD and ADDI
This commit is contained in:
parent
00eadf1b64
commit
53d08b6c04
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,5 +1,5 @@
|
|||
impl/
|
||||
**/*.gprj*
|
||||
tests/*.vcd
|
||||
tests/out
|
||||
tests/**/*.vcd
|
||||
tests/**/out
|
||||
src/gowin_*/
|
22
src/beepo.v
22
src/beepo.v
|
@ -1,4 +1,4 @@
|
|||
`include "instructions.v"
|
||||
// `include "instructions.v"
|
||||
|
||||
module Beepo #(
|
||||
parameter FREQ = 27_000_000,
|
||||
|
@ -24,7 +24,7 @@ module Beepo #(
|
|||
localparam [3:0] ARG_B = 3; // Byte, 8 bit
|
||||
localparam [3:0] ARG_H = 4; // Half-word, 16 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_N = 8; // No argument
|
||||
|
||||
|
@ -45,7 +45,7 @@ module Beepo #(
|
|||
// Registers
|
||||
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_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_arg_regs [0:3]; // register arguments
|
||||
reg [63:0] r_arg_imm = 0; // immediate argument
|
||||
|
@ -63,7 +63,7 @@ module Beepo #(
|
|||
genvar i;
|
||||
|
||||
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;
|
||||
end
|
||||
endgenerate
|
||||
|
@ -90,9 +90,16 @@ module Beepo #(
|
|||
`NOP: r_arg_types_packed = `NOP_ARGS;
|
||||
`ADD8: r_arg_types_packed = `ADD8_ARGS;
|
||||
`ADD16: r_arg_types_packed = `ADD16_ARGS;
|
||||
`ADD32: r_arg_types_packed = `ADD32_ARGS;
|
||||
`ADD64: r_arg_types_packed = `ADD64_ARGS;
|
||||
`ADDI8: r_arg_types_packed = `ADDI8_ARGS;
|
||||
`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
|
||||
|
||||
|
@ -170,9 +177,16 @@ module Beepo #(
|
|||
`NOP: ;
|
||||
`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]);
|
||||
`ADD32: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_registers[r_arg_regs[2]][31:0]);
|
||||
`ADD64: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_registers[r_arg_regs[2]][63:0]);
|
||||
`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
|
||||
|
||||
// r_tx_send_ctrl[0] <= ~r_tx_send_ctrl[0];
|
||||
|
|
|
@ -13,6 +13,10 @@
|
|||
`define ADD8_ARGS {ARG_R, ARG_R, ARG_R, ARG_N}
|
||||
`define ADD16 'h04
|
||||
`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
|
||||
`define DIRU8 'h20
|
||||
|
@ -24,6 +28,12 @@
|
|||
// Binary register-immediate operations
|
||||
`define ADDI8 'h2D
|
||||
`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
|
||||
`define SLUI8 'h38
|
||||
|
@ -36,6 +46,10 @@
|
|||
`define LI8_ARGS {ARG_R, ARG_B, ARG_N, ARG_N}
|
||||
`define LI16 'h49
|
||||
`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
|
||||
`define JEQ 'h56
|
|
@ -2,9 +2,9 @@ ICARUS_FILES = inputs.txt
|
|||
ICARUS_OUT = out
|
||||
|
||||
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}
|
||||
|
||||
wave: vvp
|
42
tests/adding/adding.v
Normal file
42
tests/adding/adding.v
Normal 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
5
tests/adding/inputs.txt
Normal 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
35
tests/adding/spmem.v
Normal 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
|
|
@ -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
|
|
@ -1,5 +0,0 @@
|
|||
../src/instructions.v
|
||||
beepo.v
|
||||
../src/uart_tx.v
|
||||
../src/multi7.v
|
||||
spmem.v
|
|
@ -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
|
Loading…
Reference in a new issue