Initial work on reading instructions from bootROM

This commit is contained in:
Koray Yanik 2021-02-15 22:55:09 +00:00
parent e56afb8c9e
commit 3191a19f7e
9 changed files with 166 additions and 11 deletions

View File

@ -1,5 +1,8 @@
TB = tb_top
SOURCES = gb.sv tb_top.sv
PATH_SRC = ../rtl:../sim/tbench
SOURCES = gb.sv cpu.sv registers.sv control.sv rom.sv tb_top.sv clkgen.sv
PATH_SRC = ../rtl:../rtl/cpu:../rtl/shared:../sim/tbench:../sim/shared
gb.sdb: cpu.sdb rom.sdb
cpu.sdb: control.sdb fetch.sdb registers.sdb
include ../synthflow/vivado/Makefile.rules

49
rtl/cpu/control.sv Normal file
View File

@ -0,0 +1,49 @@
`include "cpu_pkg.svh"
import cpu_pkg::*;
module control (
input logic clk_i,
input logic nreset_i,
output state_t state_o,
output logic [15:0] pc_o
);
state_t state_r;
state_t state_next;
logic pc_we;
logic [15:0] pc_r;
logic [15:0] pc_next;
always_ff @(posedge clk_i or negedge nreset_i) begin
if (~nreset_i)
state_r <= ST0_ADDR;
else
state_r <= state_next;
end
always_ff @(posedge clk_i or negedge nreset_i) begin
if (~nreset_i)
pc_r <= '0;
else if (pc_we)
pc_r <= pc_next;
end
assign pc_we = (state_r == ST0_ADDR);
assign pc_next = (pc_r + 16'b1);
always_comb begin
case (state_r)
ST0_ADDR: state_next = ST1_DEC;
ST1_DEC: state_next = ST2_EXEC;
ST2_EXEC: state_next = ST3_INC_ADDR;
ST3_INC_ADDR: state_next = ST0_ADDR;
endcase
end
assign state_o = state_r;
assign pc_o = pc_r;
endmodule : control

31
rtl/cpu/cpu.sv Normal file
View File

@ -0,0 +1,31 @@
`include "cpu_pkg.svh"
import cpu_pkg::*;
module cpu (
input logic clk_i,
input logic nreset_i,
output logic [15:0] address_o,
input logic [ 7:0] rdata_i
);
state_t state;
logic [15:0] pc;
control control_inst (
.clk_i (clk_i),
.nreset_i(nreset_i),
.state_o (state),
.pc_o (pc)
);
registers registers_inst (
.clk_i (clk_i),
.nreset_i(nreset_i)
);
assign address_o = pc;
endmodule : cpu

10
rtl/cpu/cpu_pkg.svh Normal file
View File

@ -0,0 +1,10 @@
package cpu_pkg;
typedef enum {
ST0_ADDR,
ST1_DEC,
ST2_EXEC,
ST3_INC_ADDR
} state_t;
endpackage

6
rtl/cpu/registers.sv Normal file
View File

@ -0,0 +1,6 @@
module registers (
input logic clk_i,
input logic nreset_i
);
endmodule : registers

View File

@ -3,6 +3,24 @@ module gb (
input logic nreset_i
);
logic [15:0] address;
logic [ 7:0] rdata;
cpu cpu_inst (
.clk_i (clk_i),
.nreset_i (nreset_i),
.address_o(address),
.rdata_i (rdata)
);
rom #(
.FILE_NAME("DMG_ROM.bin"),
.ADDR_W (8),
.DATA_W (8)
) rom_inst (
.clk_i (clk_i),
.address_i(address[7:0]),
.rdata_o (rdata)
);
endmodule : gb

24
rtl/shared/rom.sv Normal file
View File

@ -0,0 +1,24 @@
module rom #(
parameter string FILE_NAME = "",
parameter integer unsigned ADDR_W = 8,
parameter integer unsigned DATA_W = 8
) (
input logic clk_i,
input logic [ADDR_W-1:0] address_i,
output logic [DATA_W-1:0] rdata_o
);
localparam ROM_SIZE = 2**ADDR_W;
logic [DATA_W-1:0] rom [ROM_SIZE-1:0];
always_ff @(posedge clk_i)
rdata_o <= rom[address_i];
initial begin
static integer fd = $fopen(FILE_NAME, "rb");
void'($fread(rom, fd));
end
endmodule : rom

18
sim/shared/clkgen.sv Normal file
View File

@ -0,0 +1,18 @@
module clkgen #(
PERIOD_NS = 10,
RESET_DELAY_NS = 100
) (
output logic clk_o,
output logic nreset_o
);
initial begin
clk_o <= 1'b0;
nreset_o <= 1'b0;
#RESET_DELAY_NS nreset_o <= 1'b1;
end
always
#(PERIOD_NS/2) clk_o <= ~clk_o;
endmodule

View File

@ -3,19 +3,15 @@ module tb_top ();
logic clk;
logic nreset;
clkgen clkgen_inst (
.clk_o (clk),
.nreset_o(nreset)
);
gb gb_inst (
.clk_i (clk),
.nreset_i(nreset)
);
initial begin
clk = 1'b0;
nreset = 1'b1;
#1 nreset = 1'b0;
#24 nreset = 1'b1;
end // initial
always #5 clk = ~clk;
endmodule : tb_top