Combine the instruction and data buses
This commit is contained in:
parent
7f81e495b3
commit
9b1e27cc0d
7 changed files with 176 additions and 20 deletions
4
Makefile
4
Makefile
|
|
@ -16,7 +16,7 @@ DEVICE = 8k
|
||||||
PACKAGE = ct256
|
PACKAGE = ct256
|
||||||
PCF = ice40hx8k-b-evn.pcf
|
PCF = ice40hx8k-b-evn.pcf
|
||||||
FREQ_OSC = 12
|
FREQ_OSC = 12
|
||||||
FREQ_PLL = 36
|
FREQ_PLL = 32
|
||||||
TARGET = riscv64-unknown-elf
|
TARGET = riscv64-unknown-elf
|
||||||
AS = $(TARGET)-as
|
AS = $(TARGET)-as
|
||||||
ASFLAGS = -march=rv32i -mabi=ilp32
|
ASFLAGS = -march=rv32i -mabi=ilp32
|
||||||
|
|
@ -42,7 +42,7 @@ progmem: progmem.o start.o progmem.lds
|
||||||
$(LD) $(LDFLAGS) -o $@ progmem.o start.o
|
$(LD) $(LDFLAGS) -o $@ progmem.o start.o
|
||||||
|
|
||||||
progmem_syn.hex:
|
progmem_syn.hex:
|
||||||
icebram -g 32 256 > $@
|
icebram -g 32 2048 > $@
|
||||||
|
|
||||||
$(PLL):
|
$(PLL):
|
||||||
icepll $(QUIET) -i $(FREQ_OSC) -o $(FREQ_PLL) -m -f $@
|
icepll $(QUIET) -i $(FREQ_OSC) -o $(FREQ_PLL) -m -f $@
|
||||||
|
|
|
||||||
63
bus_arbiter.sv
Normal file
63
bus_arbiter.sv
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
`ifndef BUS_ARBITER
|
||||||
|
`define BUS_ARBITER
|
||||||
|
|
||||||
|
module bus_arbiter (
|
||||||
|
/* instruction memory bus */
|
||||||
|
input [31:0] instr_address_in,
|
||||||
|
input instr_read_in,
|
||||||
|
output logic [31:0] instr_read_value_out,
|
||||||
|
output logic instr_ready,
|
||||||
|
|
||||||
|
/* data memory bus */
|
||||||
|
input [31:0] data_address_in,
|
||||||
|
input data_read_in,
|
||||||
|
input data_write_in,
|
||||||
|
output logic [31:0] data_read_value_out,
|
||||||
|
input [3:0] data_write_mask_in,
|
||||||
|
input [31:0] data_write_value_in,
|
||||||
|
output logic data_ready,
|
||||||
|
|
||||||
|
/* common memory bus */
|
||||||
|
output logic [31:0] address_out,
|
||||||
|
output logic read_out,
|
||||||
|
output logic write_out,
|
||||||
|
input [31:0] read_value_in,
|
||||||
|
output logic [3:0] write_mask_out,
|
||||||
|
output logic [31:0] write_value_out
|
||||||
|
);
|
||||||
|
always_comb begin
|
||||||
|
if (data_read_in || data_write_in) begin
|
||||||
|
address_out = data_address_in;
|
||||||
|
read_out = data_read_in;
|
||||||
|
write_out = data_write_in;
|
||||||
|
instr_read_value_out = 32'bx;
|
||||||
|
data_read_value_out = read_value_in;
|
||||||
|
write_mask_out = data_write_mask_in;
|
||||||
|
write_value_out = data_write_value_in;
|
||||||
|
instr_ready = 1'b0;
|
||||||
|
data_ready = 1'b1;
|
||||||
|
end else if (instr_read_in) begin
|
||||||
|
address_out = instr_address_in;
|
||||||
|
read_out = instr_read_in;
|
||||||
|
write_out = 1'b0;
|
||||||
|
instr_read_value_out = read_value_in;
|
||||||
|
data_read_value_out = 32'bx;
|
||||||
|
write_mask_out = 4'b0;
|
||||||
|
write_value_out = 32'bx;
|
||||||
|
instr_ready = 1'b1;
|
||||||
|
data_ready = 1'b0;
|
||||||
|
end else begin
|
||||||
|
address_out = 32'bx;
|
||||||
|
read_out = 1'b0;
|
||||||
|
write_out = 1'b0;
|
||||||
|
instr_read_value_out = 32'bx;
|
||||||
|
data_read_value_out = 32'bx;
|
||||||
|
write_mask_out = 4'b0;
|
||||||
|
write_value_out = 32'bx;
|
||||||
|
instr_ready = 1'b0;
|
||||||
|
data_ready = 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
`endif
|
||||||
3
ram.sv
3
ram.sv
|
|
@ -14,6 +14,9 @@ module ram (
|
||||||
logic [31:0] mem [2047:0];
|
logic [31:0] mem [2047:0];
|
||||||
logic [31:0] read_value;
|
logic [31:0] read_value;
|
||||||
|
|
||||||
|
initial
|
||||||
|
$readmemh("progmem_syn.hex", mem);
|
||||||
|
|
||||||
assign read_value_out = sel_in ? read_value : 0;
|
assign read_value_out = sel_in ? read_value : 0;
|
||||||
|
|
||||||
always_ff @(negedge clk) begin
|
always_ff @(negedge clk) begin
|
||||||
|
|
|
||||||
27
rv32.sv
27
rv32.sv
|
|
@ -10,13 +10,20 @@
|
||||||
module rv32 (
|
module rv32 (
|
||||||
input clk,
|
input clk,
|
||||||
|
|
||||||
|
/* instruction memory bus */
|
||||||
|
output logic [31:0] instr_address_out,
|
||||||
|
output logic instr_read_out,
|
||||||
|
input [31:0] instr_read_value_in,
|
||||||
|
input instr_ready_in,
|
||||||
|
|
||||||
/* data memory bus */
|
/* data memory bus */
|
||||||
output logic [31:0] data_address_out,
|
output logic [31:0] data_address_out,
|
||||||
output logic data_read_out,
|
output logic data_read_out,
|
||||||
output logic data_write_out,
|
output logic data_write_out,
|
||||||
input [31:0] data_read_value_in,
|
input [31:0] data_read_value_in,
|
||||||
output logic [3:0] data_write_mask_out,
|
output logic [3:0] data_write_mask_out,
|
||||||
output logic [31:0] data_write_value_out
|
output logic [31:0] data_write_value_out,
|
||||||
|
input data_ready_in
|
||||||
);
|
);
|
||||||
/* hazard -> fetch control */
|
/* hazard -> fetch control */
|
||||||
logic fetch_stall;
|
logic fetch_stall;
|
||||||
|
|
@ -102,6 +109,13 @@ module rv32 (
|
||||||
|
|
||||||
.mem_branch_taken_in(mem_branch_taken),
|
.mem_branch_taken_in(mem_branch_taken),
|
||||||
|
|
||||||
|
.instr_read_in(instr_read_out),
|
||||||
|
.instr_ready_in(instr_ready_in),
|
||||||
|
|
||||||
|
.data_read_in(data_read_out),
|
||||||
|
.data_write_in(data_write_out),
|
||||||
|
.data_ready_in(data_ready_in),
|
||||||
|
|
||||||
/* control out */
|
/* control out */
|
||||||
.fetch_stall_out(fetch_stall),
|
.fetch_stall_out(fetch_stall),
|
||||||
.fetch_flush_out(fetch_flush),
|
.fetch_flush_out(fetch_flush),
|
||||||
|
|
@ -126,12 +140,21 @@ module rv32 (
|
||||||
/* control in (from mem) */
|
/* control in (from mem) */
|
||||||
.branch_taken_in(mem_branch_taken),
|
.branch_taken_in(mem_branch_taken),
|
||||||
|
|
||||||
|
/* control out (to memory bus) */
|
||||||
|
.instr_read_out(instr_read_out),
|
||||||
|
|
||||||
/* data in (from mem) */
|
/* data in (from mem) */
|
||||||
.branch_pc_in(mem_branch_pc),
|
.branch_pc_in(mem_branch_pc),
|
||||||
|
|
||||||
|
/* data in (from memory bus) */
|
||||||
|
.instr_read_value_in(instr_read_value_in),
|
||||||
|
|
||||||
/* data out */
|
/* data out */
|
||||||
.pc_out(fetch_pc),
|
.pc_out(fetch_pc),
|
||||||
.instr_out(fetch_instr)
|
.instr_out(fetch_instr),
|
||||||
|
|
||||||
|
/* data out (to memory bus) */
|
||||||
|
.instr_address_out(instr_address_out)
|
||||||
);
|
);
|
||||||
|
|
||||||
rv32_decode decode (
|
rv32_decode decode (
|
||||||
|
|
|
||||||
|
|
@ -16,23 +16,29 @@ module rv32_fetch (
|
||||||
/* data in (from mem) */
|
/* data in (from mem) */
|
||||||
input [31:0] branch_pc_in,
|
input [31:0] branch_pc_in,
|
||||||
|
|
||||||
|
/* data in (from memory bus) */
|
||||||
|
input [31:0] instr_read_value_in,
|
||||||
|
|
||||||
|
/* control out */
|
||||||
|
output logic instr_read_out,
|
||||||
|
|
||||||
/* data out */
|
/* data out */
|
||||||
output logic [31:0] pc_out,
|
output logic [31:0] pc_out,
|
||||||
output logic [31:0] instr_out
|
output logic [31:0] instr_out,
|
||||||
);
|
|
||||||
logic [31:0] instr_mem [255:0];
|
|
||||||
logic [31:0] next_pc;
|
|
||||||
|
|
||||||
|
/* data out (to memory bus) */
|
||||||
|
output logic [31:0] instr_address_out
|
||||||
|
);
|
||||||
|
logic [31:0] next_pc;
|
||||||
logic [31:0] pc;
|
logic [31:0] pc;
|
||||||
|
|
||||||
initial
|
|
||||||
$readmemh("progmem_syn.hex", instr_mem);
|
|
||||||
|
|
||||||
assign pc = branch_taken_in ? branch_pc_in : next_pc;
|
assign pc = branch_taken_in ? branch_pc_in : next_pc;
|
||||||
|
assign instr_read_out = 1;
|
||||||
|
assign instr_address_out = pc;
|
||||||
|
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
if (!stall_in) begin
|
if (!stall_in) begin
|
||||||
instr_out <= instr_mem[pc[31:2]];
|
instr_out <= instr_read_value_in;
|
||||||
next_pc <= pc + 4;
|
next_pc <= pc + 4;
|
||||||
pc_out <= pc;
|
pc_out <= pc;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,13 @@ module rv32_hazard_unit (
|
||||||
|
|
||||||
input mem_branch_taken_in,
|
input mem_branch_taken_in,
|
||||||
|
|
||||||
|
input instr_read_in,
|
||||||
|
input instr_ready_in,
|
||||||
|
|
||||||
|
input data_read_in,
|
||||||
|
input data_write_in,
|
||||||
|
input data_ready_in,
|
||||||
|
|
||||||
/* control out */
|
/* control out */
|
||||||
output logic fetch_stall_out,
|
output logic fetch_stall_out,
|
||||||
output logic fetch_flush_out,
|
output logic fetch_flush_out,
|
||||||
|
|
@ -25,11 +32,15 @@ module rv32_hazard_unit (
|
||||||
output logic mem_stall_out,
|
output logic mem_stall_out,
|
||||||
output logic mem_flush_out
|
output logic mem_flush_out
|
||||||
);
|
);
|
||||||
|
logic fetch_wait_for_bus;
|
||||||
logic fetch_wait_for_mem_read;
|
logic fetch_wait_for_mem_read;
|
||||||
|
logic mem_wait_for_bus;
|
||||||
|
|
||||||
|
assign fetch_wait_for_bus = instr_read_in && !instr_ready_in;
|
||||||
assign fetch_wait_for_mem_read = (decode_rs1_in == decode_rd_in || decode_rs2_in == decode_rd_in) && |decode_rd_in && decode_mem_read_in && decode_rd_write_in;
|
assign fetch_wait_for_mem_read = (decode_rs1_in == decode_rd_in || decode_rs2_in == decode_rd_in) && |decode_rd_in && decode_mem_read_in && decode_rd_write_in;
|
||||||
|
assign mem_wait_for_bus = (data_read_in || data_write_in) && !data_ready_in;
|
||||||
|
|
||||||
assign fetch_stall_out = decode_stall_out || fetch_wait_for_mem_read;
|
assign fetch_stall_out = decode_stall_out || fetch_wait_for_mem_read || fetch_wait_for_bus;
|
||||||
assign fetch_flush_out = 0;
|
assign fetch_flush_out = 0;
|
||||||
|
|
||||||
assign decode_stall_out = execute_stall_out;
|
assign decode_stall_out = execute_stall_out;
|
||||||
|
|
@ -38,7 +49,7 @@ module rv32_hazard_unit (
|
||||||
assign execute_stall_out = mem_stall_out;
|
assign execute_stall_out = mem_stall_out;
|
||||||
assign execute_flush_out = decode_stall_out || mem_branch_taken_in;
|
assign execute_flush_out = decode_stall_out || mem_branch_taken_in;
|
||||||
|
|
||||||
assign mem_stall_out = 0;
|
assign mem_stall_out = mem_wait_for_bus;
|
||||||
assign mem_flush_out = execute_stall_out;
|
assign mem_flush_out = execute_stall_out;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
|
||||||
62
top.sv
62
top.sv
|
|
@ -1,3 +1,4 @@
|
||||||
|
`include "bus_arbiter.sv"
|
||||||
`include "pll.sv"
|
`include "pll.sv"
|
||||||
`include "ram.sv"
|
`include "ram.sv"
|
||||||
`include "rv32.sv"
|
`include "rv32.sv"
|
||||||
|
|
@ -57,24 +58,73 @@ module top (
|
||||||
.out(pll_locked)
|
.out(pll_locked)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* instruction memory bus */
|
||||||
|
logic [31:0] instr_address;
|
||||||
|
logic instr_read;
|
||||||
|
logic [31:0] instr_read_value;
|
||||||
|
logic instr_ready;
|
||||||
|
|
||||||
|
/* data memory bus */
|
||||||
|
logic [31:0] data_address;
|
||||||
|
logic data_read;
|
||||||
|
logic data_write;
|
||||||
|
logic [31:0] data_read_value;
|
||||||
|
logic [3:0] data_write_mask;
|
||||||
|
logic [31:0] data_write_value;
|
||||||
|
logic data_ready;
|
||||||
|
|
||||||
/* memory bus */
|
/* memory bus */
|
||||||
logic [31:0] mem_address;
|
logic [31:0] mem_address;
|
||||||
logic mem_read;
|
logic mem_read;
|
||||||
|
logic mem_write;
|
||||||
logic [31:0] mem_read_value;
|
logic [31:0] mem_read_value;
|
||||||
logic [3:0] mem_write_mask;
|
logic [3:0] mem_write_mask;
|
||||||
logic [31:0] mem_write_value;
|
logic [31:0] mem_write_value;
|
||||||
|
|
||||||
assign mem_read_value = ram_read_value | leds_read_value | uart_read_value;
|
assign mem_read_value = ram_read_value | leds_read_value | uart_read_value;
|
||||||
|
|
||||||
|
bus_arbiter bus_arbiter (
|
||||||
|
/* instruction memory bus */
|
||||||
|
.instr_address_in(instr_address),
|
||||||
|
.instr_read_in(instr_read),
|
||||||
|
.instr_read_value_out(instr_read_value),
|
||||||
|
.instr_ready(instr_ready),
|
||||||
|
|
||||||
|
/* data memory bus */
|
||||||
|
.data_address_in(data_address),
|
||||||
|
.data_read_in(data_read),
|
||||||
|
.data_write_in(data_write),
|
||||||
|
.data_read_value_out(data_read_value),
|
||||||
|
.data_write_mask_in(data_write_mask),
|
||||||
|
.data_write_value_in(data_write_value),
|
||||||
|
.data_ready(data_ready),
|
||||||
|
|
||||||
|
/* common memory bus */
|
||||||
|
.address_out(mem_address),
|
||||||
|
.read_out(mem_read),
|
||||||
|
.write_out(mem_write),
|
||||||
|
.read_value_in(mem_read_value),
|
||||||
|
.write_mask_out(mem_write_mask),
|
||||||
|
.write_value_out(mem_write_value)
|
||||||
|
);
|
||||||
|
|
||||||
rv32 rv32 (
|
rv32 rv32 (
|
||||||
.clk(pll_clk),
|
.clk(pll_clk),
|
||||||
|
|
||||||
/* memory bus */
|
/* instruction memory bus */
|
||||||
.data_address_out(mem_address),
|
.instr_address_out(instr_address),
|
||||||
.data_read_out(mem_read),
|
.instr_read_out(instr_read),
|
||||||
.data_read_value_in(mem_read_value),
|
.instr_read_value_in(instr_read_value),
|
||||||
.data_write_mask_out(mem_write_mask),
|
.instr_ready_in(instr_ready),
|
||||||
.data_write_value_out(mem_write_value)
|
|
||||||
|
/* data memory bus */
|
||||||
|
.data_address_out(data_address),
|
||||||
|
.data_read_out(data_read),
|
||||||
|
.data_write_out(data_write),
|
||||||
|
.data_read_value_in(data_read_value),
|
||||||
|
.data_write_mask_out(data_write_mask),
|
||||||
|
.data_write_value_out(data_write_value),
|
||||||
|
.data_ready_in(data_ready)
|
||||||
);
|
);
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue