Compare commits
2 commits
28e4032687
...
3a2c675613
Author | SHA1 | Date | |
---|---|---|---|
Bee | 3a2c675613 | ||
Bee | cae3afbc55 |
64
src/beepo.v
64
src/beepo.v
|
@ -6,7 +6,6 @@ module Beepo #(
|
||||||
) (
|
) (
|
||||||
input i_clk,
|
input i_clk,
|
||||||
input i_button1,
|
input i_button1,
|
||||||
output o_uart_tx,
|
|
||||||
output [6:0] o_segments_drive,
|
output [6:0] o_segments_drive,
|
||||||
output [3:0] o_displays_neg
|
output [3:0] o_displays_neg
|
||||||
);
|
);
|
||||||
|
@ -37,11 +36,6 @@ module Beepo #(
|
||||||
reg r_fetching = 0; // counter for waiting before reading from memory
|
reg r_fetching = 0; // counter for waiting before reading from memory
|
||||||
reg [63:0] r_tick = 0;
|
reg [63:0] r_tick = 0;
|
||||||
|
|
||||||
// UART tx
|
|
||||||
// reg [7:0] r_tx_data = 0;
|
|
||||||
// reg r_tx_reset_n = 1;
|
|
||||||
// wire w_tx_ready;
|
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -63,13 +57,12 @@ module Beepo #(
|
||||||
genvar i;
|
genvar i;
|
||||||
|
|
||||||
generate
|
generate
|
||||||
for (i = 1; i <= NUM_REGS; i = i + 1) begin
|
for (i = 1; i < NUM_REGS-1; i = i + 1) begin
|
||||||
initial r_registers[i] <= 0;
|
initial r_registers[i] <= 0;
|
||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
always @(posedge i_clk) r_tick <= r_tick + 1;
|
always @(posedge i_clk) r_tick <= r_tick + 1;
|
||||||
// always @(r_registers[1]) r_tx_data <= r_registers[1];
|
|
||||||
|
|
||||||
always @(posedge i_clk) begin
|
always @(posedge i_clk) begin
|
||||||
if (r_fetching) r_fetching <= r_fetching + 1;
|
if (r_fetching) r_fetching <= r_fetching + 1;
|
||||||
|
@ -85,8 +78,23 @@ module Beepo #(
|
||||||
r_arg_index <= 0;
|
r_arg_index <= 0;
|
||||||
r_arg_bit <= 0;
|
r_arg_bit <= 0;
|
||||||
|
|
||||||
// instructions.v
|
case (w_mem_fetch)
|
||||||
`get_args;
|
`TX: r_arg_types_packed = `TX_ARGS;
|
||||||
|
`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
|
||||||
|
|
||||||
if (r_arg_types_packed[15:12] != ARG_N) begin
|
if (r_arg_types_packed[15:12] != ARG_N) begin
|
||||||
r_state <= FETCHA;
|
r_state <= FETCHA;
|
||||||
|
@ -157,18 +165,26 @@ module Beepo #(
|
||||||
EXEC: begin
|
EXEC: begin
|
||||||
r_state <= FETCHI;
|
r_state <= FETCHI;
|
||||||
|
|
||||||
// instructions.v
|
case (r_instr)
|
||||||
`exec;
|
`TX: r_state <= DONE;
|
||||||
|
`NOP: ;
|
||||||
// r_tx_send_ctrl[0] <= ~r_tx_send_ctrl[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]);
|
||||||
|
`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
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
// always @(posedge i_clk) begin
|
|
||||||
// if (w_tx_send && w_tx_ready) r_tx_send_ctrl[1] <= r_tx_send_ctrl[0];
|
|
||||||
// end
|
|
||||||
|
|
||||||
task automatic set_register(
|
task automatic set_register(
|
||||||
input [7:0] being_set,
|
input [7:0] being_set,
|
||||||
input [63:0] setting_to
|
input [63:0] setting_to
|
||||||
|
@ -176,18 +192,6 @@ module Beepo #(
|
||||||
if (being_set != 0) r_registers[being_set] = setting_to;
|
if (being_set != 0) r_registers[being_set] = setting_to;
|
||||||
endtask
|
endtask
|
||||||
|
|
||||||
// uart_tx #(
|
|
||||||
// .CLK_FRE(FREQ / 1_000_000),
|
|
||||||
// .BAUD_RATE(UART_BAUD)
|
|
||||||
// ) tx (
|
|
||||||
// .clk(i_clk),
|
|
||||||
// .rst_n(1),
|
|
||||||
// .tx_data(r_tx_data),
|
|
||||||
// .tx_data_valid(w_tx_send),
|
|
||||||
// .tx_data_ready(w_tx_ready),
|
|
||||||
// .tx_pin(o_uart_tx)
|
|
||||||
// );
|
|
||||||
|
|
||||||
Multi7 display (
|
Multi7 display (
|
||||||
.i_clk(i_clk),
|
.i_clk(i_clk),
|
||||||
.i_hex({r_registers[1][15:0]}),
|
.i_hex({r_registers[1][15:0]}),
|
||||||
|
|
|
@ -1,73 +1,22 @@
|
||||||
// Based on https://git.ablecorp.us/AbleOS/holey-bytes/src/branch/trunk/spec.md
|
// Based on https://git.ablecorp.us/AbleOS/holey-bytes/src/branch/trunk/spec.md
|
||||||
|
|
||||||
`define get_args \
|
|
||||||
case (w_mem_fetch) \
|
|
||||||
`UN: r_arg_types_packed = `UN_ARGS; \
|
|
||||||
`TX: r_arg_types_packed = `TX_ARGS; \
|
|
||||||
`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; \
|
|
||||||
\
|
|
||||||
`ADDI64: r_arg_types_packed = `ADDI64_ARGS; \
|
|
||||||
`ADDI8: r_arg_types_packed = `ADDI8_ARGS; \
|
|
||||||
`ADDI16: r_arg_types_packed = `ADDI16_ARGS; \
|
|
||||||
`ADDI32: r_arg_types_packed = `ADDI32_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
|
|
||||||
|
|
||||||
`define exec \
|
|
||||||
case (r_instr) \
|
|
||||||
`UN: `UN_EXEC; \
|
|
||||||
`TX: `TX_EXEC; \
|
|
||||||
`NOP: `NOP_EXEC; \
|
|
||||||
\
|
|
||||||
`ADD8: `ADD8_EXEC; \
|
|
||||||
`ADD16: `ADD16_EXEC; \
|
|
||||||
`ADD32: `ADD32_EXEC; \
|
|
||||||
`ADD64: `ADD64_EXEC; \
|
|
||||||
\
|
|
||||||
`ADDI8: `ADDI8_EXEC; \
|
|
||||||
`ADDI16: `ADDI16_EXEC; \
|
|
||||||
`ADDI32: `ADDI32_EXEC; \
|
|
||||||
`ADDI64: `ADDI64_EXEC; \
|
|
||||||
\
|
|
||||||
`LI8: `LI8_EXEC; \
|
|
||||||
`LI16: `LI16_EXEC; \
|
|
||||||
`LI32: `LI32_EXEC; \
|
|
||||||
`LI64: `LI64_EXEC; \
|
|
||||||
endcase
|
|
||||||
|
|
||||||
// Program execution control
|
// Program execution control
|
||||||
`define UN 'h00
|
`define UN 'h00
|
||||||
`define UN_ARGS {ARG_N, ARG_N, ARG_N, ARG_N}
|
`define UN_ARGS {ARG_N, ARG_N, ARG_N, ARG_N}
|
||||||
`define UN_EXEC // TODO
|
|
||||||
`define TX 'h01
|
`define TX 'h01
|
||||||
`define TX_ARGS {ARG_N, ARG_N, ARG_N, ARG_N}
|
`define TX_ARGS {ARG_N, ARG_N, ARG_N, ARG_N}
|
||||||
`define TX_EXEC r_state <= DONE
|
|
||||||
`define NOP 'h02
|
`define NOP 'h02
|
||||||
`define NOP_ARGS {ARG_N, ARG_N, ARG_N, ARG_N}
|
`define NOP_ARGS {ARG_N, ARG_N, ARG_N, ARG_N}
|
||||||
`define NOP_EXEC
|
|
||||||
|
|
||||||
// Register-register addition
|
// Binary register-register operations
|
||||||
`define ADD8 'h03
|
`define ADD8 'h03
|
||||||
`define ADD8_ARGS {ARG_R, ARG_R, ARG_R, ARG_N}
|
`define ADD8_ARGS {ARG_R, ARG_R, ARG_R, ARG_N}
|
||||||
`define ADD8_EXEC set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_registers[r_arg_regs[2]][0+:8])
|
|
||||||
`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 ADD16_EXEC set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_registers[r_arg_regs[2]][0+:16])
|
|
||||||
`define ADD32 'h05
|
`define ADD32 'h05
|
||||||
`define ADD32_ARGS {ARG_R, ARG_R, ARG_R, ARG_N}
|
`define ADD32_ARGS {ARG_R, ARG_R, ARG_R, ARG_N}
|
||||||
`define ADD32_EXEC set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_registers[r_arg_regs[2]][0+:32])
|
|
||||||
`define ADD64 'h06
|
`define ADD64 'h06
|
||||||
`define ADD64_ARGS {ARG_R, ARG_R, ARG_R, ARG_N}
|
`define ADD64_ARGS {ARG_R, ARG_R, ARG_R, ARG_N}
|
||||||
`define ADD64_EXEC set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_registers[r_arg_regs[2]][0+:64])
|
|
||||||
|
|
||||||
// Merged divide-remainder
|
// Merged divide-remainder
|
||||||
`define DIRU8 'h20
|
`define DIRU8 'h20
|
||||||
|
@ -76,19 +25,15 @@
|
||||||
`define NEG 'h28
|
`define NEG 'h28
|
||||||
`define NOT 'h29
|
`define NOT 'h29
|
||||||
|
|
||||||
// Register-immediate addition
|
// 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 ADDI8_EXEC set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_arg_imm[0+:8])
|
|
||||||
`define ADDI16 'h2E
|
`define ADDI16 'h2E
|
||||||
`define ADDI16_ARGS {ARG_R, ARG_R, ARG_H, ARG_N}
|
`define ADDI16_ARGS {ARG_R, ARG_R, ARG_H, ARG_N}
|
||||||
`define ADDI16_EXEC set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_arg_imm[0+:16])
|
|
||||||
`define ADDI32 'h2F
|
`define ADDI32 'h2F
|
||||||
`define ADDI32_ARGS {ARG_R, ARG_R, ARG_W, ARG_N}
|
`define ADDI32_ARGS {ARG_R, ARG_R, ARG_W, ARG_N}
|
||||||
`define ADDI32_EXEC set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_arg_imm[0+:32])
|
|
||||||
`define ADDI64 'h30
|
`define ADDI64 'h30
|
||||||
`define ADDI64_ARGS {ARG_R, ARG_R, ARG_D, ARG_N}
|
`define ADDI64_ARGS {ARG_R, ARG_R, ARG_D, ARG_N}
|
||||||
`define ADDI64_EXEC set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_arg_imm[0+:64])
|
|
||||||
|
|
||||||
// Register-immediate bitshifts
|
// Register-immediate bitshifts
|
||||||
`define SLUI8 'h38
|
`define SLUI8 'h38
|
||||||
|
@ -97,20 +42,14 @@
|
||||||
`define CP 'h46
|
`define CP 'h46
|
||||||
|
|
||||||
// Load immediate
|
// Load immediate
|
||||||
`define LI set_register(r_arg_regs[0], r_arg_imm)
|
|
||||||
|
|
||||||
`define LI8 'h48
|
`define LI8 'h48
|
||||||
`define LI8_ARGS {ARG_R, ARG_B, ARG_N, ARG_N}
|
`define LI8_ARGS {ARG_R, ARG_B, ARG_N, ARG_N}
|
||||||
`define LI8_EXEC `LI
|
|
||||||
`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 LI16_EXEC `LI
|
|
||||||
`define LI32 'h4A
|
`define LI32 'h4A
|
||||||
`define LI32_ARGS {ARG_R, ARG_W, ARG_N, ARG_N}
|
`define LI32_ARGS {ARG_R, ARG_W, ARG_N, ARG_N}
|
||||||
`define LI32_EXEC `LI
|
|
||||||
`define LI64 'h4B
|
`define LI64 'h4B
|
||||||
`define LI64_ARGS {ARG_R, ARG_D, ARG_N, ARG_N}
|
`define LI64_ARGS {ARG_R, ARG_D, ARG_N, ARG_N}
|
||||||
`define LI64_EXEC `LI
|
|
||||||
|
|
||||||
// Conditional jump
|
// Conditional jump
|
||||||
`define JEQ 'h56
|
`define JEQ 'h56
|
|
@ -7,19 +7,16 @@
|
||||||
$finish; \
|
$finish; \
|
||||||
end
|
end
|
||||||
|
|
||||||
module tb_adding(
|
module tb_adding();
|
||||||
output o_uart_tx
|
reg clk = 0;
|
||||||
);
|
|
||||||
|
|
||||||
reg clk = 0;
|
Beepo #(
|
||||||
|
.FREQ(1),
|
||||||
|
.UART_BAUD(1_000_000)
|
||||||
|
) bep (
|
||||||
|
.i_clk(clk)
|
||||||
|
);
|
||||||
|
|
||||||
Beepo #(
|
|
||||||
.FREQ(1),
|
|
||||||
.UART_BAUD(1_000_000)
|
|
||||||
) bep (
|
|
||||||
.i_clk(clk),
|
|
||||||
.o_uart_tx(o_uart_tx)
|
|
||||||
);
|
|
||||||
localparam CLK_PERIOD = 1.0;
|
localparam CLK_PERIOD = 1.0;
|
||||||
always #(CLK_PERIOD/2) clk=~clk;
|
always #(CLK_PERIOD/2) clk=~clk;
|
||||||
|
|
||||||
|
@ -34,7 +31,7 @@ Beepo #(
|
||||||
);
|
);
|
||||||
end
|
end
|
||||||
|
|
||||||
// should probably do more tests than just the end
|
// should probably do more granular tests
|
||||||
initial #10000 begin
|
initial #10000 begin
|
||||||
`assert(bep.r_registers[1], 64'h2020202040406090);
|
`assert(bep.r_registers[1], 64'h2020202040406090);
|
||||||
$finish;
|
$finish;
|
||||||
|
|
Loading…
Reference in a new issue