mirror of
https://gitlab.com/brendanhaines/cpu.git
synced 2024-12-26 11:06:50 -07:00
fix issue of jumping to address 0
This commit is contained in:
parent
caf9a6f4f7
commit
4a25ca6def
119
hdl/core.v
119
hdl/core.v
|
@ -2,16 +2,30 @@ module core(
|
||||||
input clk,
|
input clk,
|
||||||
input reset,
|
input reset,
|
||||||
|
|
||||||
|
// Memory - instruction
|
||||||
output reg [31:0] mem_inst_addr,
|
output reg [31:0] mem_inst_addr,
|
||||||
input [31:0] mem_inst_data,
|
input [31:0] mem_inst_data,
|
||||||
|
|
||||||
// output reg [31:0] mem_data_addr,
|
// // Memory - data
|
||||||
|
output reg [31:0] mem_data_addr,
|
||||||
|
input [31:0] mem_data_rdata,
|
||||||
|
output reg [31:0] mem_data_wdata,
|
||||||
|
output reg [(32/8)-1:0] mem_data_wmask,
|
||||||
|
output reg mem_data_we,
|
||||||
|
|
||||||
|
// output reg [31:0] mem_data_waddr,
|
||||||
// output reg [31:0] mem_data_wdata,
|
// output reg [31:0] mem_data_wdata,
|
||||||
// input [31:0] mem_data_rdata,
|
// output reg [3:0] mem_data_wmask,
|
||||||
// output reg mem_data_en,
|
// output reg mem_data_wvalid,
|
||||||
// output reg mem_data_we,
|
// input wire mem_data_wready,
|
||||||
// input mem_data_valid,
|
|
||||||
// input mem_data_done
|
// output reg [31:0] mem_data_raddr,
|
||||||
|
// output reg mem_data_raddr_valid,
|
||||||
|
// input wire mem_data_raddr_ready,
|
||||||
|
|
||||||
|
// input wire [31:0] mem_data_rdata,
|
||||||
|
// input wire mem_data_rdata_valid,
|
||||||
|
// output reg mem_data_rdata_ready,
|
||||||
|
|
||||||
|
|
||||||
// // instruction memory
|
// // instruction memory
|
||||||
|
@ -78,21 +92,26 @@ initial begin : init_regfile
|
||||||
end
|
end
|
||||||
|
|
||||||
// Registers
|
// Registers
|
||||||
reg [31:0] r_if_pc = 0, r_id_pc, r_ex_pc, r_mem_pc, r_wb_pc;
|
reg [31:0] r_if_pc = 0, r_id_pc, r_ex_pc, r_mem_pc, r_wb_pc;
|
||||||
reg [31:0] r_id_inst, r_ex_inst, r_mem_inst, r_wb_inst;
|
reg [31:0] r_id_inst, r_ex_inst, r_mem_inst, r_wb_inst;
|
||||||
reg [4:0] r_ex_rd, r_mem_rd, r_wb_rd;
|
reg r_id_valid=0, r_ex_valid=0, r_mem_valid=0, r_wb_valid=0;
|
||||||
reg [3:0] r_ex_aluop;
|
reg [4:0] r_ex_rs1, r_mem_rs1, r_wb_rs1;
|
||||||
reg [31:0] r_ex_s1, r_ex_s2, r_mem_s1, r_mem_s2;
|
reg [4:0] r_ex_rs2, r_mem_rs2, r_wb_rs2;
|
||||||
reg [31:0] r_mem_alu_out, r_wb_alu_out;
|
reg [4:0] r_ex_rd, r_mem_rd, r_wb_rd;
|
||||||
reg r_mem_alu_zero;
|
reg [3:0] r_ex_aluop;
|
||||||
reg r_ex_jump;
|
reg [31:0] r_ex_s1, r_mem_s1;
|
||||||
reg r_ex_store, r_mem_store;
|
reg [31:0] r_ex_s2, r_mem_s2;
|
||||||
reg r_ex_load, r_mem_load;
|
reg [31:0] r_mem_alu_out, r_wb_alu_out;
|
||||||
reg [31:0] r_mem_wdata, r_wb_wdata;
|
reg r_mem_alu_zero;
|
||||||
reg r_id_valid=0, r_ex_valid=0, r_mem_valid=0, r_wb_valid=0;
|
reg r_ex_jump, r_mem_jump, r_wb_jump;
|
||||||
reg r_ex_branch_pol;
|
reg r_ex_store, r_mem_store;
|
||||||
reg r_ex_branch, r_mem_branch, r_wb_branch;
|
reg r_ex_load, r_mem_load, r_wb_load;
|
||||||
reg [31:0] r_ex_immed_btype;
|
reg [31:0] r_mem_wdata, r_wb_wdata;
|
||||||
|
reg r_ex_branch_pol;
|
||||||
|
reg r_ex_branch, r_mem_branch, r_wb_branch;
|
||||||
|
reg [31:0] r_ex_immed_btype;
|
||||||
|
reg [31:0] r_mem_ra, r_wb_ra;
|
||||||
|
reg [31:0] r_wb_load_data;
|
||||||
|
|
||||||
// IF
|
// IF
|
||||||
reg s_if_stall = 0;
|
reg s_if_stall = 0;
|
||||||
|
@ -240,9 +259,12 @@ always @(*) begin
|
||||||
// OP_LOAD: begin
|
// OP_LOAD: begin
|
||||||
|
|
||||||
// end
|
// end
|
||||||
// OP_STORE: begin
|
OP_STORE: begin
|
||||||
|
s_id_store = 1;
|
||||||
// end
|
s_id_s1 = regfile[s_id_rs1];
|
||||||
|
s_id_s2 = s_id_immed_stype;
|
||||||
|
// TODO: finish parsing (byte vs word. For now always assume word)
|
||||||
|
end
|
||||||
OP_IMM: begin
|
OP_IMM: begin
|
||||||
s_id_s1 = regfile[s_id_rs1];
|
s_id_s1 = regfile[s_id_rs1];
|
||||||
s_id_s2 = s_id_immed_itype;
|
s_id_s2 = s_id_immed_itype;
|
||||||
|
@ -309,9 +331,9 @@ reg s_ex_stall = 0;
|
||||||
reg [31:0] s_ex_data1, s_ex_data2;
|
reg [31:0] s_ex_data1, s_ex_data2;
|
||||||
reg [31:0] s_ex_alu_out;
|
reg [31:0] s_ex_alu_out;
|
||||||
reg s_ex_alu_zero;
|
reg s_ex_alu_zero;
|
||||||
reg [31:0] s_ex_wdata;
|
|
||||||
reg s_ex_take_branch;
|
reg s_ex_take_branch;
|
||||||
reg [31:0] s_ex_branch_addr;
|
reg [31:0] s_ex_branch_addr;
|
||||||
|
reg [31:0] s_ex_ra;
|
||||||
|
|
||||||
always @(*) begin
|
always @(*) begin
|
||||||
s_ex_stall = s_mem_stall;
|
s_ex_stall = s_mem_stall;
|
||||||
|
@ -358,11 +380,10 @@ always @(*) begin
|
||||||
s_ex_alu_zero = (s_ex_alu_out == 0);
|
s_ex_alu_zero = (s_ex_alu_out == 0);
|
||||||
|
|
||||||
s_ex_take_branch = r_ex_valid && (r_ex_jump || (r_ex_branch && (s_ex_alu_zero ^ r_ex_branch_pol)));
|
s_ex_take_branch = r_ex_valid && (r_ex_jump || (r_ex_branch && (s_ex_alu_zero ^ r_ex_branch_pol)));
|
||||||
|
s_ex_ra = r_ex_pc + 4;
|
||||||
if (r_ex_jump) begin
|
if (r_ex_jump) begin
|
||||||
s_ex_wdata = r_ex_pc + 4;
|
|
||||||
s_ex_branch_addr = s_ex_alu_out;
|
s_ex_branch_addr = s_ex_alu_out;
|
||||||
end else begin
|
end else begin
|
||||||
s_ex_wdata = s_ex_alu_out;
|
|
||||||
s_ex_branch_addr = r_ex_pc + r_ex_immed_btype;
|
s_ex_branch_addr = r_ex_pc + r_ex_immed_btype;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -370,24 +391,17 @@ end
|
||||||
// MEM
|
// MEM
|
||||||
reg s_mem_stall = 0;
|
reg s_mem_stall = 0;
|
||||||
reg s_mem_bp;
|
reg s_mem_bp;
|
||||||
|
reg [31:0] s_mem_load_data;
|
||||||
|
|
||||||
always @(*) begin
|
always @(*) begin
|
||||||
s_mem_stall = 0; // TODO: add stall logic when actually reading/writing
|
s_mem_stall = 0; // TODO: add stall logic when actually reading/writing
|
||||||
s_mem_bp = 0;
|
s_mem_bp = 0;
|
||||||
|
|
||||||
// if (r_mem_store) begin
|
mem_data_addr = r_mem_alu_out;
|
||||||
// mem_data_en = 1;
|
mem_data_wdata = regfile[r_mem_rs2];
|
||||||
// mem_data_we = 1;
|
mem_data_wmask = 4'b1111; // TODO: implement smaller writes
|
||||||
// s_mem_bp = !mem_data_done;
|
mem_data_we = r_mem_store && r_mem_valid;
|
||||||
// end else if (r_mem_load) begin
|
s_mem_load_data = mem_data_rdata; // TODO: implement smaller reads
|
||||||
// mem_data_en = 1;
|
|
||||||
// mem_data_we = 0;
|
|
||||||
// s_mem_bp = !mem_data_valid;
|
|
||||||
// end else begin
|
|
||||||
// mem_data_en = 0;
|
|
||||||
// mem_data_we = 0;
|
|
||||||
// s_mem_bp = 0;
|
|
||||||
// end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
// WB
|
// WB
|
||||||
|
@ -397,7 +411,13 @@ reg s_wb_write;
|
||||||
always @(*) begin
|
always @(*) begin
|
||||||
|
|
||||||
// load instructions do not use output of alu in wb
|
// load instructions do not use output of alu in wb
|
||||||
s_wb_data = r_wb_wdata;
|
if (r_wb_jump) begin
|
||||||
|
s_wb_data = r_wb_ra;
|
||||||
|
end else if (r_wb_load) begin
|
||||||
|
s_wb_data = r_wb_load_data;
|
||||||
|
end else begin
|
||||||
|
s_wb_data = r_wb_alu_out;
|
||||||
|
end
|
||||||
|
|
||||||
// FIXME: always writes!!!
|
// FIXME: always writes!!!
|
||||||
s_wb_write = (r_wb_branch == 0);
|
s_wb_write = (r_wb_branch == 0);
|
||||||
|
@ -433,13 +453,10 @@ always @(posedge clk) begin: pipeline_update
|
||||||
r_mem_alu_zero <= 0;
|
r_mem_alu_zero <= 0;
|
||||||
r_mem_store <= 0;
|
r_mem_store <= 0;
|
||||||
r_mem_load <= 0;
|
r_mem_load <= 0;
|
||||||
r_mem_wdata <= 0;
|
|
||||||
|
|
||||||
r_wb_pc <= 0;
|
r_wb_pc <= 0;
|
||||||
r_wb_inst <= INST_NOP;
|
r_wb_inst <= INST_NOP;
|
||||||
r_wb_rd <= 0;
|
r_wb_rd <= 0;
|
||||||
r_wb_alu_out <= 0;
|
|
||||||
r_wb_wdata <= 0;
|
|
||||||
|
|
||||||
for (i=1; i<32; i=i+1) begin
|
for (i=1; i<32; i=i+1) begin
|
||||||
regfile[i] <= 0;
|
regfile[i] <= 0;
|
||||||
|
@ -462,6 +479,8 @@ always @(posedge clk) begin: pipeline_update
|
||||||
if (!s_ex_stall) begin
|
if (!s_ex_stall) begin
|
||||||
r_ex_pc <= r_id_pc;
|
r_ex_pc <= r_id_pc;
|
||||||
r_ex_inst <= r_id_inst;
|
r_ex_inst <= r_id_inst;
|
||||||
|
r_ex_rs1 <= s_id_rs1;
|
||||||
|
r_ex_rs2 <= s_id_rs2;
|
||||||
r_ex_rd <= s_id_rd;
|
r_ex_rd <= s_id_rd;
|
||||||
r_ex_s1 <= s_id_s1;
|
r_ex_s1 <= s_id_s1;
|
||||||
r_ex_s2 <= s_id_s2;
|
r_ex_s2 <= s_id_s2;
|
||||||
|
@ -480,6 +499,8 @@ always @(posedge clk) begin: pipeline_update
|
||||||
if (!s_mem_stall) begin
|
if (!s_mem_stall) begin
|
||||||
r_mem_pc <= r_ex_pc;
|
r_mem_pc <= r_ex_pc;
|
||||||
r_mem_inst <= r_ex_inst;
|
r_mem_inst <= r_ex_inst;
|
||||||
|
r_mem_rs1 <= r_ex_rs1;
|
||||||
|
r_mem_rs2 <= r_ex_rs2;
|
||||||
r_mem_rd <= r_ex_rd;
|
r_mem_rd <= r_ex_rd;
|
||||||
r_mem_s1 <= r_ex_s1;
|
r_mem_s1 <= r_ex_s1;
|
||||||
r_mem_s2 <= r_ex_s2;
|
r_mem_s2 <= r_ex_s2;
|
||||||
|
@ -487,20 +508,26 @@ always @(posedge clk) begin: pipeline_update
|
||||||
r_mem_alu_zero <= s_ex_alu_zero;
|
r_mem_alu_zero <= s_ex_alu_zero;
|
||||||
r_mem_store <= r_ex_store;
|
r_mem_store <= r_ex_store;
|
||||||
r_mem_load <= r_ex_load;
|
r_mem_load <= r_ex_load;
|
||||||
r_mem_wdata <= s_ex_wdata;
|
|
||||||
r_mem_valid <= r_ex_valid;
|
r_mem_valid <= r_ex_valid;
|
||||||
r_mem_branch <= r_ex_branch;
|
r_mem_branch <= r_ex_branch;
|
||||||
|
r_mem_ra <= s_ex_ra;
|
||||||
|
r_mem_jump <= r_ex_jump;
|
||||||
end
|
end
|
||||||
|
|
||||||
// WB
|
// WB
|
||||||
if (1) begin
|
if (1) begin
|
||||||
r_wb_pc <= r_mem_pc;
|
r_wb_pc <= r_mem_pc;
|
||||||
r_wb_inst <= r_mem_inst;
|
r_wb_inst <= r_mem_inst;
|
||||||
|
r_wb_rs1 <= r_mem_rs1;
|
||||||
|
r_wb_rs2 <= r_mem_rs2;
|
||||||
r_wb_rd <= r_mem_rd;
|
r_wb_rd <= r_mem_rd;
|
||||||
r_wb_alu_out <= r_mem_alu_out;
|
r_wb_alu_out <= r_mem_alu_out;
|
||||||
r_wb_wdata <= r_mem_wdata;
|
|
||||||
r_wb_valid <= r_mem_valid;
|
r_wb_valid <= r_mem_valid;
|
||||||
r_wb_branch <= r_mem_branch;
|
r_wb_branch <= r_mem_branch;
|
||||||
|
r_wb_ra <= r_mem_ra;
|
||||||
|
r_wb_jump <= r_mem_jump;
|
||||||
|
r_wb_load <= r_mem_load;
|
||||||
|
r_wb_load_data <= s_mem_load_data;
|
||||||
end
|
end
|
||||||
|
|
||||||
// Register File
|
// Register File
|
||||||
|
|
154
hdl/tb/core_tb.v
154
hdl/tb/core_tb.v
|
@ -10,7 +10,8 @@ localparam MEM_INST_LENGTH = 256; // words
|
||||||
localparam MEM_DATA_LENGTH = 256; // words
|
localparam MEM_DATA_LENGTH = 256; // words
|
||||||
|
|
||||||
localparam INST_NOP = 32'h00000013; // nop
|
localparam INST_NOP = 32'h00000013; // nop
|
||||||
localparam DATA_DEFAULT = 32'hdeadbeef;
|
localparam DATA_DEFAULT = 32'h00000000;
|
||||||
|
localparam DATA_INVALID = 32'hdeadbeef;
|
||||||
|
|
||||||
reg clk, reset;
|
reg clk, reset;
|
||||||
|
|
||||||
|
@ -30,13 +31,11 @@ end
|
||||||
|
|
||||||
// Data memory
|
// Data memory
|
||||||
reg [31:0] mem_data [0:MEM_DATA_LENGTH-1];
|
reg [31:0] mem_data [0:MEM_DATA_LENGTH-1];
|
||||||
wire [31:0] mem_data_waddr;
|
wire [31:0] mem_data_addr;
|
||||||
|
reg [31:0] mem_data_rdata;
|
||||||
wire [31:0] mem_data_wdata;
|
wire [31:0] mem_data_wdata;
|
||||||
wire [3:0] mem_data_wmask;
|
wire [3:0] mem_data_wmask;
|
||||||
wire mem_data_we;
|
wire mem_data_we;
|
||||||
wire [31:0] mem_data_raddr;
|
|
||||||
reg [31:0] mem_data_rdata;
|
|
||||||
wire [3:0] mem_data_rmask;
|
|
||||||
|
|
||||||
initial begin: mem_data_init
|
initial begin: mem_data_init
|
||||||
integer i;
|
integer i;
|
||||||
|
@ -54,7 +53,7 @@ initial begin
|
||||||
#10
|
#10
|
||||||
reset = 0;
|
reset = 0;
|
||||||
|
|
||||||
#1000
|
#2000
|
||||||
reset = 1;
|
reset = 1;
|
||||||
$stop;
|
$stop;
|
||||||
end
|
end
|
||||||
|
@ -68,6 +67,12 @@ core dut(
|
||||||
.mem_inst_addr(mem_inst_addr),
|
.mem_inst_addr(mem_inst_addr),
|
||||||
.mem_inst_data(mem_inst_data),
|
.mem_inst_data(mem_inst_data),
|
||||||
|
|
||||||
|
.mem_data_addr(mem_data_addr),
|
||||||
|
.mem_data_rdata(mem_data_rdata),
|
||||||
|
.mem_data_wdata(mem_data_wdata),
|
||||||
|
.mem_data_wmask(mem_data_wmask),
|
||||||
|
.mem_data_we(mem_data_we),
|
||||||
|
|
||||||
// .mem_data_addr(mem_data_addr),
|
// .mem_data_addr(mem_data_addr),
|
||||||
// .mem_data_wdata(mem_data_wdata),
|
// .mem_data_wdata(mem_data_wdata),
|
||||||
// .mem_data_rdata(mem_data_rdata),
|
// .mem_data_rdata(mem_data_rdata),
|
||||||
|
@ -79,81 +84,84 @@ core dut(
|
||||||
.dummy_out(dummy_out)
|
.dummy_out(dummy_out)
|
||||||
);
|
);
|
||||||
|
|
||||||
wire axi_mem_data_awvalid;
|
// wire axi_mem_data_awvalid;
|
||||||
wire [11:0] axi_mem_data_awaddr;
|
// wire [11:0] axi_mem_data_awaddr;
|
||||||
wire [2:0] axi_mem_data_awprot;
|
// wire [2:0] axi_mem_data_awprot;
|
||||||
wire axi_mem_data_awready;
|
// wire axi_mem_data_awready;
|
||||||
wire axi_mem_data_wvalid;
|
// wire axi_mem_data_wvalid;
|
||||||
wire [31:0] axi_mem_data_wdata;
|
// wire [31:0] axi_mem_data_wdata;
|
||||||
wire [3:0] axi_mem_data_wstrb;
|
// wire [3:0] axi_mem_data_wstrb;
|
||||||
wire axi_mem_data_wready;
|
// wire axi_mem_data_wready;
|
||||||
wire axi_mem_data_bvalid;
|
// wire axi_mem_data_bvalid;
|
||||||
wire axi_mem_data_bready;
|
// wire axi_mem_data_bready;
|
||||||
wire [1:0] axi_mem_data_bresp;
|
// wire [1:0] axi_mem_data_bresp;
|
||||||
wire axi_mem_data_arvalid;
|
// wire axi_mem_data_arvalid;
|
||||||
wire [11:0] axi_mem_data_araddr;
|
// wire [11:0] axi_mem_data_araddr;
|
||||||
wire [2:0] axi_mem_data_arprot;
|
// wire [2:0] axi_mem_data_arprot;
|
||||||
wire axi_mem_data_arready;
|
// wire axi_mem_data_arready;
|
||||||
wire axi_mem_data_rvalid;
|
// wire axi_mem_data_rvalid;
|
||||||
wire [31:0] axi_mem_data_rdata;
|
// wire [31:0] axi_mem_data_rdata;
|
||||||
wire [1:0] axi_mem_data_resp;
|
// wire [1:0] axi_mem_data_resp;
|
||||||
wire axi_mem_data_rready;
|
// wire axi_mem_data_rready;
|
||||||
|
|
||||||
axi_lite_memory axi_mem_data(
|
// axi_lite_memory axi_mem_data(
|
||||||
.ACLK(clk),
|
// .ACLK(clk),
|
||||||
.ARESETn(!reset),
|
// .ARESETn(!reset),
|
||||||
.AWVALID(axi_mem_data_awvalid),
|
// .AWVALID(axi_mem_data_awvalid),
|
||||||
.AWADDR(axi_mem_data_awaddr),
|
// .AWADDR(axi_mem_data_awaddr),
|
||||||
.AWPROT(axi_mem_data_awprot),
|
// .AWPROT(axi_mem_data_awprot),
|
||||||
.AWREADY(axi_mem_data_awready),
|
// .AWREADY(axi_mem_data_awready),
|
||||||
.WVALID(axi_mem_data_wvalid),
|
// .WVALID(axi_mem_data_wvalid),
|
||||||
.WDATA(axi_mem_data_wdata),
|
// .WDATA(axi_mem_data_wdata),
|
||||||
.WSTRB(axi_mem_data_wstrb),
|
// .WSTRB(axi_mem_data_wstrb),
|
||||||
.WREADY(axi_mem_data_wready),
|
// .WREADY(axi_mem_data_wready),
|
||||||
.BVALID(axi_mem_data_bvalid),
|
// .BVALID(axi_mem_data_bvalid),
|
||||||
.BREADY(axi_mem_data_bready),
|
// .BREADY(axi_mem_data_bready),
|
||||||
.BRESP(axi_mem_data_bresp),
|
// .BRESP(axi_mem_data_bresp),
|
||||||
.ARVALID(axi_mem_data_arvalid),
|
// .ARVALID(axi_mem_data_arvalid),
|
||||||
.ARADDR(axi_mem_data_araddr),
|
// .ARADDR(axi_mem_data_araddr),
|
||||||
.ARPROT(axi_mem_data_arprot),
|
// .ARPROT(axi_mem_data_arprot),
|
||||||
.ARREADY(axi_mem_data_arready),
|
// .ARREADY(axi_mem_data_arready),
|
||||||
.RVALID(axi_mem_data_rvalid),
|
// .RVALID(axi_mem_data_rvalid),
|
||||||
.RDATA(axi_mem_data_rdata),
|
// .RDATA(axi_mem_data_rdata),
|
||||||
.RRESP(axi_mem_data_resp),
|
// .RRESP(axi_mem_data_resp),
|
||||||
.RREADY(axi_mem_data_rready),
|
// .RREADY(axi_mem_data_rready),
|
||||||
|
|
||||||
.WB_WADDR(mem_data_waddr),
|
// .WB_WADDR(mem_data_waddr),
|
||||||
.WB_WPROT(),
|
// .WB_WPROT(),
|
||||||
.WB_WDATA(mem_data_wdata),
|
// .WB_WDATA(mem_data_wdata),
|
||||||
.WB_WSTRB(mem_data_wmask),
|
// .WB_WSTRB(mem_data_wmask),
|
||||||
.WB_WVALID(mem_data_we),
|
// .WB_WVALID(mem_data_we),
|
||||||
.WB_WREADY(1'b1),
|
// .WB_WREADY(1'b1),
|
||||||
|
|
||||||
.WB_RADDR(mem_data_raddr),
|
// .WB_RADDR(mem_data_raddr),
|
||||||
.WB_RDATA(mem_data_rdata),
|
// .WB_RDATA(mem_data_rdata),
|
||||||
.WB_RVALID(1'b1),
|
// .WB_RVALID(1'b1),
|
||||||
.WB_RREADY()
|
// .WB_RREADY()
|
||||||
);
|
// );
|
||||||
|
|
||||||
wire [31:0] mem_data_widx = mem_data_waddr >> 2;
|
wire [31:0] mem_data_idx = mem_data_addr >> 2;
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (mem_data_we) begin
|
if (mem_data_idx < MEM_DATA_LENGTH) begin
|
||||||
if (mem_data_widx < MEM_DATA_LENGTH) begin
|
mem_data_rdata = mem_data[mem_data_idx];
|
||||||
mem_inst[mem_data_widx] <= (mem_inst[mem_data_widx] & ~{{8{mem_data_wmask[3]}}, {8{mem_data_wmask[2]}}, {8{mem_data_wmask[1]}}, {8{mem_data_wmask[0]}}}) | (mem_data_wdata & {{8{mem_data_wmask[3]}}, {8{mem_data_wmask[2]}}, {8{mem_data_wmask[1]}}, {8{mem_data_wmask[0]}}});
|
if (mem_data_we) begin
|
||||||
|
if (mem_data_wmask[0]) begin
|
||||||
|
mem_data[mem_data_idx][7:0] <= mem_data_wdata[7:0];
|
||||||
|
end
|
||||||
|
if (mem_data_wmask[1]) begin
|
||||||
|
mem_data[mem_data_idx][15:8] <= mem_data_wdata[15:8];
|
||||||
|
end
|
||||||
|
if (mem_data_wmask[2]) begin
|
||||||
|
mem_data[mem_data_idx][23:16] <= mem_data_wdata[23:16];
|
||||||
|
end
|
||||||
|
if (mem_data_wmask[3]) begin
|
||||||
|
mem_data[mem_data_idx][31:24] <= mem_data_wdata[31:24];
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
end else begin
|
||||||
|
mem_data_rdata = DATA_INVALID;
|
||||||
// ignore illegal writes
|
// ignore illegal writes
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
wire [31:0] mem_data_ridx = mem_data_raddr >> 2;
|
|
||||||
always @(*) begin
|
|
||||||
if (mem_data_ridx < MEM_DATA_LENGTH) begin
|
|
||||||
mem_data_rdata = mem_inst[mem_data_ridx] & {{8{mem_data_rmask[3]}}, {8{mem_data_rmask[2]}}, {8{mem_data_rmask[1]}}, {8{mem_data_rmask[0]}}};
|
|
||||||
end else begin
|
|
||||||
mem_data_rdata = 32'h00000000;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
|
@ -10,7 +10,7 @@
|
||||||
</top_modules>
|
</top_modules>
|
||||||
</db_ref>
|
</db_ref>
|
||||||
</db_ref_list>
|
</db_ref_list>
|
||||||
<WVObjectSize size="8" />
|
<WVObjectSize size="9" />
|
||||||
<wvobject fp_name="/core_tb/clk" type="logic" db_ref_id="1">
|
<wvobject fp_name="/core_tb/clk" type="logic" db_ref_id="1">
|
||||||
<obj_property name="ElementShortName">clk</obj_property>
|
<obj_property name="ElementShortName">clk</obj_property>
|
||||||
<obj_property name="ObjectShortName">clk</obj_property>
|
<obj_property name="ObjectShortName">clk</obj_property>
|
||||||
|
@ -19,6 +19,11 @@
|
||||||
<obj_property name="ElementShortName">reset</obj_property>
|
<obj_property name="ElementShortName">reset</obj_property>
|
||||||
<obj_property name="ObjectShortName">reset</obj_property>
|
<obj_property name="ObjectShortName">reset</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
|
<wvobject fp_name="/core_tb/mem_data" type="array" db_ref_id="1">
|
||||||
|
<obj_property name="ElementShortName">mem_data[0:255,31:0]</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">mem_data[0:255,31:0]</obj_property>
|
||||||
|
<obj_property name="Radix">HEXRADIX</obj_property>
|
||||||
|
</wvobject>
|
||||||
<wvobject fp_name="/core_tb/dut/regfile" type="array" db_ref_id="1">
|
<wvobject fp_name="/core_tb/dut/regfile" type="array" db_ref_id="1">
|
||||||
<obj_property name="ElementShortName">regfile[0:31,31:0]</obj_property>
|
<obj_property name="ElementShortName">regfile[0:31,31:0]</obj_property>
|
||||||
<obj_property name="ObjectShortName">regfile[0:31,31:0]</obj_property>
|
<obj_property name="ObjectShortName">regfile[0:31,31:0]</obj_property>
|
||||||
|
@ -432,6 +437,14 @@
|
||||||
<obj_property name="ElementShortName">r_mem_alu_zero</obj_property>
|
<obj_property name="ElementShortName">r_mem_alu_zero</obj_property>
|
||||||
<obj_property name="ObjectShortName">r_mem_alu_zero</obj_property>
|
<obj_property name="ObjectShortName">r_mem_alu_zero</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
|
<wvobject fp_name="/core_tb/dut/r_mem_store" type="logic" db_ref_id="1">
|
||||||
|
<obj_property name="ElementShortName">r_mem_store</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">r_mem_store</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/core_tb/dut/r_mem_load" type="logic" db_ref_id="1">
|
||||||
|
<obj_property name="ElementShortName">r_mem_load</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">r_mem_load</obj_property>
|
||||||
|
</wvobject>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="group8" type="group">
|
<wvobject fp_name="group8" type="group">
|
||||||
<obj_property name="label">WB</obj_property>
|
<obj_property name="label">WB</obj_property>
|
||||||
|
@ -450,16 +463,25 @@
|
||||||
<obj_property name="ObjectShortName">r_wb_inst[31:0]</obj_property>
|
<obj_property name="ObjectShortName">r_wb_inst[31:0]</obj_property>
|
||||||
<obj_property name="Radix">HEXRADIX</obj_property>
|
<obj_property name="Radix">HEXRADIX</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/core_tb/dut/r_wb_alu_out" type="array" db_ref_id="1">
|
|
||||||
<obj_property name="ElementShortName">r_wb_alu_out[31:0]</obj_property>
|
|
||||||
<obj_property name="ObjectShortName">r_wb_alu_out[31:0]</obj_property>
|
|
||||||
<obj_property name="Radix">HEXRADIX</obj_property>
|
|
||||||
</wvobject>
|
|
||||||
<wvobject fp_name="/core_tb/dut/r_wb_rd" type="array" db_ref_id="1">
|
<wvobject fp_name="/core_tb/dut/r_wb_rd" type="array" db_ref_id="1">
|
||||||
<obj_property name="ElementShortName">r_wb_rd[4:0]</obj_property>
|
<obj_property name="ElementShortName">r_wb_rd[4:0]</obj_property>
|
||||||
<obj_property name="ObjectShortName">r_wb_rd[4:0]</obj_property>
|
<obj_property name="ObjectShortName">r_wb_rd[4:0]</obj_property>
|
||||||
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
|
<wvobject fp_name="/core_tb/dut/r_wb_ra" type="logic" db_ref_id="1">
|
||||||
|
<obj_property name="ElementShortName">r_wb_ra</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">r_wb_ra</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/core_tb/dut/r_wb_load_data" type="array" db_ref_id="1">
|
||||||
|
<obj_property name="ElementShortName">r_wb_load_data[31:0]</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">r_wb_load_data[31:0]</obj_property>
|
||||||
|
<obj_property name="Radix">HEXRADIX</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/core_tb/dut/r_wb_alu_out" type="array" db_ref_id="1">
|
||||||
|
<obj_property name="ElementShortName">r_wb_alu_out[31:0]</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">r_wb_alu_out[31:0]</obj_property>
|
||||||
|
<obj_property name="Radix">HEXRADIX</obj_property>
|
||||||
|
</wvobject>
|
||||||
<wvobject fp_name="/core_tb/dut/s_wb_data" type="array" db_ref_id="1">
|
<wvobject fp_name="/core_tb/dut/s_wb_data" type="array" db_ref_id="1">
|
||||||
<obj_property name="ElementShortName">s_wb_data[31:0]</obj_property>
|
<obj_property name="ElementShortName">s_wb_data[31:0]</obj_property>
|
||||||
<obj_property name="ObjectShortName">s_wb_data[31:0]</obj_property>
|
<obj_property name="ObjectShortName">s_wb_data[31:0]</obj_property>
|
||||||
|
|
|
@ -16,8 +16,8 @@ LDFLAGS = -T test.ld
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(CC) $(CFLAGS) $^ -o $@
|
$(CC) $(CFLAGS) $^ -o $@
|
||||||
|
|
||||||
%.elf: %.o
|
%.elf: %.o %.ld
|
||||||
$(LD) $(LDFLAGS) $^ -o $@
|
$(LD) $(LDFLAGS) $< -o $@
|
||||||
|
|
||||||
text.hex: test.elf
|
text.hex: test.elf
|
||||||
riscv64-linux-gnu-objdump -s $^ | sed -n '/.text/,$$p' | tail -n+2 | sed -n '/.data/,$$!p' | cut -f3-6 -d ' ' | sed -e 's/ /\n/g' | sed 's/^\(..\)\(..\)\(..\)\(..\)/\4\3\2\1/' > $@
|
riscv64-linux-gnu-objdump -s $^ | sed -n '/.text/,$$p' | tail -n+2 | sed -n '/.data/,$$!p' | cut -f3-6 -d ' ' | sed -e 's/ /\n/g' | sed 's/^\(..\)\(..\)\(..\)\(..\)/\4\3\2\1/' > $@
|
||||||
|
|
Binary file not shown.
46
test/test.S
46
test/test.S
|
@ -27,7 +27,7 @@ _start:
|
||||||
# or
|
# or
|
||||||
or x9, x1, x2 # x9 = 0xffffffff
|
or x9, x1, x2 # x9 = 0xffffffff
|
||||||
or x10, x1, x0 # x10 = 0xfedcb789
|
or x10, x1, x0 # x10 = 0xfedcb789
|
||||||
or x11, x4, x3 # x11 = 0x0xfedcb79a
|
or x11, x4, x3 # x11 = 0xfedcb79a
|
||||||
|
|
||||||
# xor
|
# xor
|
||||||
xor x12, x1, x2 # x12 = 0x01234876
|
xor x12, x1, x2 # x12 = 0x01234876
|
||||||
|
@ -209,27 +209,29 @@ test9:
|
||||||
j fail
|
j fail
|
||||||
|
|
||||||
test10:
|
test10:
|
||||||
# now for some memory stuff
|
addi x30, x0, 10 # x30 = 10
|
||||||
# # sw
|
# # now for some memory stuff
|
||||||
# la x9, someint # x9 = start of .bss
|
# # sw
|
||||||
# li x10, 0x12345678 # x10 = 0x12345678
|
# la x9, someint # x9 = start of .bss
|
||||||
# nop
|
# lui x10, 0x12345 # x10 = 0x12345000
|
||||||
# nop
|
# addi x10, x10, 0x678 # x10 = 0x12345678
|
||||||
# nop
|
# nop
|
||||||
# nop
|
# nop
|
||||||
# nop
|
# nop
|
||||||
# sw x10, 0(x9) # someint = 0x12345678
|
# nop
|
||||||
# nop
|
# nop
|
||||||
# nop
|
# sw x10, 0(x9) # someint = 0x12345678
|
||||||
# nop
|
# nop
|
||||||
# nop
|
# nop
|
||||||
# nop
|
# nop
|
||||||
# lw x11, 0(x9) # x11 = 0x12345678
|
# nop
|
||||||
# nop
|
# nop
|
||||||
# nop
|
# # lw x11, 0(x9) # x11 = 0x12345678
|
||||||
# nop
|
# nop
|
||||||
# nop
|
# nop
|
||||||
# nop
|
# nop
|
||||||
|
# nop
|
||||||
|
# nop
|
||||||
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
|
10
test/test.ld
10
test/test.ld
|
@ -3,7 +3,7 @@ ENTRY(_start)
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
ROM (rx) : ORIGIN = 0x00000000, LENGTH = 1024
|
ROM (rx) : ORIGIN = 0x00000000, LENGTH = 1024
|
||||||
RAM (rwx) : ORIGIN = 0x10000000, LENGTH = 512
|
RAM (rwx) : ORIGIN = 0x00100000, LENGTH = 1024
|
||||||
/* FLASH (rx) : ORIGIN = 0x00200000, LENGTH = 512 */
|
/* FLASH (rx) : ORIGIN = 0x00200000, LENGTH = 512 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,20 +11,20 @@ SECTIONS
|
||||||
{
|
{
|
||||||
.text :
|
.text :
|
||||||
{
|
{
|
||||||
. = ALIGN(4);
|
/* . = ALIGN(4); */
|
||||||
_text = .;
|
_text = .;
|
||||||
*(.text*)
|
*(.text*)
|
||||||
*(.rodata*)
|
*(.rodata*)
|
||||||
_etext = .;
|
_etext = .;
|
||||||
. = ALIGN(4);
|
/* . = ALIGN(4); */
|
||||||
} > ROM
|
} > ROM
|
||||||
|
|
||||||
.data :
|
.data :
|
||||||
{
|
{
|
||||||
. = ALIGN(4);
|
/* . = ALIGN(4); */
|
||||||
_data = .;
|
_data = .;
|
||||||
*(.data*)
|
*(.data*)
|
||||||
_edata = .;
|
_edata = .;
|
||||||
. = ALIGN(4);
|
/* . = ALIGN(4); */
|
||||||
} > RAM /*AT> FLASH*/
|
} > RAM /*AT> FLASH*/
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user