OpenCores
URL https://opencores.org/ocsvn/mpx/mpx/trunk

Subversion Repositories mpx

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /mpx/trunk
    from Rev 2 to Rev 3
    Reverse comparison

Rev 2 → Rev 3

/mpx/mpx_regfile_xil.v
47,48 → 47,48
//-----------------------------------------------------------------
module mpx_regfile_xil
(
clk_i,
rst_i,
en_i,
wr_i,
rs_i,
rt_i,
rd_i,
reg_rs_o,
reg_rt_o,
reg_rd_i
clk_i,
rst_i,
en_i,
wr_i,
rs_i,
rt_i,
rd_i,
reg_rs_o,
reg_rt_o,
reg_rd_i
);
 
//-----------------------------------------------------------------
// I/O
//-----------------------------------------------------------------
input clk_i /*verilator public*/;
input rst_i /*verilator public*/;
input en_i /*verilator public*/;
input wr_i /*verilator public*/;
input [4:0] rs_i /*verilator public*/;
input [4:0] rt_i /*verilator public*/;
input [4:0] rd_i /*verilator public*/;
output [31:0] reg_rs_o /*verilator public*/;
output [31:0] reg_rt_o /*verilator public*/;
input [31:0] reg_rd_i /*verilator public*/;
input clk_i /*verilator public*/;
input rst_i /*verilator public*/;
input en_i /*verilator public*/;
input wr_i /*verilator public*/;
input [4:0] rs_i /*verilator public*/;
input [4:0] rt_i /*verilator public*/;
input [4:0] rd_i /*verilator public*/;
output [31:0] reg_rs_o /*verilator public*/;
output [31:0] reg_rt_o /*verilator public*/;
input [31:0] reg_rd_i /*verilator public*/;
 
//-----------------------------------------------------------------
// Registers
//-----------------------------------------------------------------
reg [4:0] addr_write;
wire [31:0] data_out1;
wire [31:0] data_out2;
reg write_enable;
wire [31:0] data_out1a;
wire [31:0] data_out1b;
wire [31:0] data_out2a;
wire [31:0] data_out2b;
wire wea;
wire web;
reg [4:0] addr_write;
wire [31:0] data_out1;
wire [31:0] data_out2;
reg write_enable;
wire [31:0] data_out1a;
wire [31:0] data_out1b;
wire [31:0] data_out2a;
wire [31:0] data_out2b;
wire wea;
wire web;
 
reg [31:0] reg_rs_o;
reg [31:0] reg_rt_o;
reg [31:0] reg_rs_o;
reg [31:0] reg_rt_o;
 
//-----------------------------------------------------------------
// Async Read Process
95,38 → 95,38
//-----------------------------------------------------------------
always @ (clk_i or rs_i or rt_i or rd_i or reg_rd_i or data_out1 or data_out2 or rst_i or wr_i)
begin
// Read Rs
if (rs_i == 5'b00000)
reg_rs_o <= 32'h00000000;
else
reg_rs_o <= data_out1;
// Read Rs
if (rs_i == 5'b00000)
reg_rs_o <= 32'h00000000;
else
reg_rs_o <= data_out1;
 
// Read Rt
if (rt_i == 5'b00000)
reg_rt_o <= 32'h00000000;
else
reg_rt_o <= data_out2;
// Read Rt
if (rt_i == 5'b00000)
reg_rt_o <= 32'h00000000;
else
reg_rt_o <= data_out2;
 
// Write enabled?
addr_write <= rd_i[4:0];
if ((rd_i != 5'b00000) & (wr_i == 1'b1))
write_enable <= 1'b1;
else
write_enable <= 1'b0;
// Write enabled?
addr_write <= rd_i[4:0];
if ((rd_i != 5'b00000) & (wr_i == 1'b1))
write_enable <= 1'b1;
else
write_enable <= 1'b0;
end
//-----------------------------------------------------------------
// Register File (using RAM16X1D )
//-----------------------------------------------------------------
//-----------------------------------------------------------------
generate
begin
genvar i;
for (i=0;i<32;i=i+1)
begin : reg_loop
RAM16X1D reg_bit1a(.WCLK(clk_i), .WE(wea), .A0(addr_write[0]), .A1(addr_write[1]), .A2(addr_write[2]), .A3(addr_write[3]), .D(reg_rd_i[i]), .DPRA0(rs_i[0]), .DPRA1(rs_i[1]), .DPRA2(rs_i[2]), .DPRA3(rs_i[3]), .DPO(data_out1a[i]), .SPO(/* open */));
RAM16X1D reg_bit1b(.WCLK(clk_i), .WE(web), .A0(addr_write[0]), .A1(addr_write[1]), .A2(addr_write[2]), .A3(addr_write[3]), .D(reg_rd_i[i]), .DPRA0(rs_i[0]), .DPRA1(rs_i[1]), .DPRA2(rs_i[2]), .DPRA3(rs_i[3]), .DPO(data_out1b[i]), .SPO(/* open */));
RAM16X1D reg_bit2a(.WCLK(clk_i), .WE(wea), .A0(addr_write[0]), .A1(addr_write[1]), .A2(addr_write[2]), .A3(addr_write[3]), .D(reg_rd_i[i]), .DPRA0(rt_i[0]), .DPRA1(rt_i[1]), .DPRA2(rt_i[2]), .DPRA3(rt_i[3]), .DPO(data_out2a[i]), .SPO(/* open */));
RAM16X1D reg_bit2b(.WCLK(clk_i), .WE(web), .A0(addr_write[0]), .A1(addr_write[1]), .A2(addr_write[2]), .A3(addr_write[3]), .D(reg_rd_i[i]), .DPRA0(rt_i[0]), .DPRA1(rt_i[1]), .DPRA2(rt_i[2]), .DPRA3(rt_i[3]), .DPO(data_out2b[i]), .SPO(/* open */));
RAM16X1D reg_bit1a(.WCLK(clk_i), .WE(wea), .A0(addr_write[0]), .A1(addr_write[1]), .A2(addr_write[2]), .A3(addr_write[3]), .D(reg_rd_i[i]), .DPRA0(rs_i[0]), .DPRA1(rs_i[1]), .DPRA2(rs_i[2]), .DPRA3(rs_i[3]), .DPO(data_out1a[i]), .SPO(/* open */));
RAM16X1D reg_bit1b(.WCLK(clk_i), .WE(web), .A0(addr_write[0]), .A1(addr_write[1]), .A2(addr_write[2]), .A3(addr_write[3]), .D(reg_rd_i[i]), .DPRA0(rs_i[0]), .DPRA1(rs_i[1]), .DPRA2(rs_i[2]), .DPRA3(rs_i[3]), .DPO(data_out1b[i]), .SPO(/* open */));
RAM16X1D reg_bit2a(.WCLK(clk_i), .WE(wea), .A0(addr_write[0]), .A1(addr_write[1]), .A2(addr_write[2]), .A3(addr_write[3]), .D(reg_rd_i[i]), .DPRA0(rt_i[0]), .DPRA1(rt_i[1]), .DPRA2(rt_i[2]), .DPRA3(rt_i[3]), .DPO(data_out2a[i]), .SPO(/* open */));
RAM16X1D reg_bit2b(.WCLK(clk_i), .WE(web), .A0(addr_write[0]), .A1(addr_write[1]), .A2(addr_write[2]), .A3(addr_write[3]), .D(reg_rd_i[i]), .DPRA0(rt_i[0]), .DPRA1(rt_i[1]), .DPRA2(rt_i[2]), .DPRA3(rt_i[3]), .DPO(data_out2b[i]), .SPO(/* open */));
end
end
endgenerate
134,9 → 134,9
//-----------------------------------------------------------------
// Combinatorial Assignments
//-----------------------------------------------------------------
assign {data_out1} = (rs_i[4] == 1'b0) ? data_out1a : data_out1b;
assign {data_out2} = (rt_i[4] == 1'b0) ? data_out2a : data_out2b;
assign {wea} = (write_enable & ~ (addr_write[4]));
assign {web} = (write_enable & addr_write[4]);
assign data_out1 = (rs_i[4] == 1'b0) ? data_out1a : data_out1b;
assign data_out2 = (rt_i[4] == 1'b0) ? data_out2a : data_out2b;
assign wea = (write_enable & ~ (addr_write[4]));
assign web = (write_enable & addr_write[4]);
 
endmodule
/mpx/mpx_funcs.v
44,13 → 44,13
// Return: x << y
//-----------------------------------------------------------------
function [31:0] shift_left;
input [31:0] x;
input [31:0] y;
reg [31:0] shift1l;
reg [31:0] shift2l;
reg [31:0] shift4l;
reg [31:0] shift8l;
reg [31:0] shift16l;
input [31:0] x;
input [31:0] y;
reg [31:0] shift1l;
reg [31:0] shift2l;
reg [31:0] shift4l;
reg [31:0] shift8l;
reg [31:0] shift16l;
begin
if (y[0] == 1'b1)
shift1l = {x[30:0],1'b0};
80,7 → 80,7
shift_left = shift16l;
end
endfunction
 
//-----------------------------------------------------------------
// shift_right: Shift right by specified amount
// Inputs: x = input, y = shift amount
264,9 → 264,9
input [31:0] x;
begin
if ((x == 32'h00000000) | (x[31] == 1'b1))
less_than_equal_zero = 1'b1;
less_than_equal_zero = 1'b1;
else
less_than_equal_zero = 1'b0;
less_than_equal_zero = 1'b0;
end
endfunction
279,9 → 279,9
input [31:0] x;
begin
if ((x == 32'h00000000) | (x[31] == 1'b0))
more_than_equal_zero = 1'b1;
more_than_equal_zero = 1'b1;
else
more_than_equal_zero = 1'b0;
more_than_equal_zero = 1'b0;
end
endfunction
294,8 → 294,8
input [31:0] x;
begin
if (((x != 32'h00000000) & (x[31] == 1'b0)))
more_than_zero = 1'b1;
more_than_zero = 1'b1;
else
more_than_zero = 1'b0;
more_than_zero = 1'b0;
end
endfunction
/mpx/mpx.v
48,57 → 48,57
//-----------------------------------------------------------------
module mpx
(
// General
clk_i,
rst_i,
en_i,
intr_i,
step_done_o,
fault_o,
// Data Memory
mem_addr_o,
mem_data_out_o,
mem_data_in_i,
mem_wr_o,
mem_rd_o,
mem_pause_i,
// Debug Access
dbg_reg_addr_i,
dbg_reg_out_o,
dbg_pc_o
// General
clk_i,
rst_i,
en_i,
intr_i,
step_done_o,
fault_o,
 
// Data Memory
mem_addr_o,
mem_data_out_o,
mem_data_in_i,
mem_wr_o,
mem_rd_o,
mem_pause_i,
 
// Debug Access
dbg_reg_addr_i,
dbg_reg_out_o,
dbg_pc_o
);
 
//-----------------------------------------------------------------
// Params
//-----------------------------------------------------------------
parameter [31:0] BOOT_VECTOR = 32'h00000000;
parameter [31:0] ISR_VECTOR = 32'h0000003C;
parameter [31:0] BOOT_VECTOR = 32'h00000000;
parameter [31:0] ISR_VECTOR = 32'h0000003C;
 
//-----------------------------------------------------------------
// I/O
//-----------------------------------------------------------------
// General
input clk_i /*verilator public*/;
input rst_i /*verilator public*/;
input en_i /*verilator public*/;
input intr_i /*verilator public*/;
output fault_o /*verilator public*/;
output step_done_o /*verilator public*/;
input clk_i /*verilator public*/;
input rst_i /*verilator public*/;
input en_i /*verilator public*/;
input intr_i /*verilator public*/;
output fault_o /*verilator public*/;
output step_done_o /*verilator public*/;
 
// Data Memory
output [31:0] mem_addr_o /*verilator public*/;
output [31:0] mem_data_out_o /*verilator public*/;
input [31:0] mem_data_in_i /*verilator public*/;
output [3:0] mem_wr_o /*verilator public*/;
output mem_rd_o /*verilator public*/;
input mem_pause_i /*verilator public*/;
output [31:0] mem_addr_o /*verilator public*/;
output [31:0] mem_data_out_o /*verilator public*/;
input [31:0] mem_data_in_i /*verilator public*/;
output [3:0] mem_wr_o /*verilator public*/;
output mem_rd_o /*verilator public*/;
input mem_pause_i /*verilator public*/;
 
// Debug Register Access
input [8:0] dbg_reg_addr_i /*verilator public*/;
output [31:0] dbg_reg_out_o /*verilator public*/;
output [31:0] dbg_pc_o /*verilator public*/;
input [8:0] dbg_reg_addr_i /*verilator public*/;
output [31:0] dbg_reg_out_o /*verilator public*/;
output [31:0] dbg_pc_o /*verilator public*/;
//-----------------------------------------------------------------
// Registers
174,10 → 174,10
mpx_alu alu
(
.input_a(alu_a),
.input_b(alu_b),
.func(alu_func),
.result(alu_result)
.input_a(alu_a),
.input_b(alu_b),
.func(alu_func),
.result(alu_result)
);
 
`ifdef CONF_MPX_TARGET_SIM
187,25 → 187,25
`endif
reg_bank
(
// Clocking
.clk_i(clk_i),
.rst_i(rst_i),
.en_i(1'b1),
.wr_i(r_writeback),
// Tri-port
.rs_i(r_rs_muxed),
.rt_i(r_rt),
.rd_i(d2_rd_wb),
.reg_rs_o(r_reg_rs),
.reg_rt_o(r_reg_rt),
.reg_rd_i(r_reg_rd_out)
// Clocking
.clk_i(clk_i),
.rst_i(rst_i),
.en_i(1'b1),
.wr_i(r_writeback),
// Tri-port
.rs_i(r_rs_muxed),
.rt_i(r_rt),
.rd_i(d2_rd_wb),
.reg_rs_o(r_reg_rs),
.reg_rt_o(r_reg_rt),
.reg_rd_i(r_reg_rd_out)
);
 
// Debug access to register set
assign r_rs_muxed = en_i ? r_rs : dbg_reg_addr_i[4:0];
assign dbg_reg_out_o = r_reg_rs;
assign dbg_pc_o = r_pc;
assign r_rs_muxed = en_i ? r_rs : dbg_reg_addr_i[4:0];
assign dbg_reg_out_o = r_reg_rs;
assign dbg_pc_o = r_pc;
 
//-------------------------------------------------------------------
// Pipeline
214,28 → 214,28
begin
if (rst_i == 1'b1)
begin
d_opcode <= 32'h00000000;
d_rd_wb <= 5'b00000;
d2_rd_wb <= 5'b00000;
d_reg_result <= 32'h00000000;
d_alu_result <= 32'h00000000;
d_alu_func <= 4'b0000;
d_mem_offset <= 2'b00;
d_mem_access <= 1'b0;
d_take_intr <= 1'b0;
mem_addr_last<= 32'h00000000;
d_opcode <= 32'h00000000;
d_rd_wb <= 5'b00000;
d2_rd_wb <= 5'b00000;
d_reg_result <= 32'h00000000;
d_alu_result <= 32'h00000000;
d_alu_func <= 4'b0000;
d_mem_offset <= 2'b00;
d_mem_access <= 1'b0;
d_take_intr <= 1'b0;
mem_addr_last <= 32'h00000000;
end
else if ((en_i == 1'b1) && (mem_pause_i == 1'b0))
begin
d_opcode <= r_opcode;
d_rd_wb <= r_rd_wb;
d2_rd_wb <= d_rd_wb;
d_reg_result <= r_reg_result;
d_alu_result <= alu_result;
d_alu_func <= alu_func;
d_mem_offset <= mem_offset;
d_mem_access <= r_mem_access;
d_take_intr <= r_take_intr;
d_opcode <= r_opcode;
d_rd_wb <= r_rd_wb;
d2_rd_wb <= d_rd_wb;
d_reg_result <= r_reg_result;
d_alu_result <= alu_result;
d_alu_func <= alu_func;
d_mem_offset <= mem_offset;
d_mem_access <= r_mem_access;
d_take_intr <= r_take_intr;
if (r_mem_access == 1'b1)
mem_addr_last <= mem_addr;
287,94 → 287,94
if (rst_i == 1'b1)
begin
// Default to no ALU operation
alu_func <= `ALU_NONE;
// Default to no ALU operation
alu_func <= `ALU_NONE;
r_rd_wb <= 5'b00000;
r_pc <= BOOT_VECTOR;
r_rd_wb <= 5'b00000;
r_pc <= BOOT_VECTOR;
r_epc <= 32'h00000000;
r_status <= 32'h00000000;
r_cause <= `EXCEPTION_NONE;
r_fault_info <= 32'h00000000;
r_lo <= 32'h00000000;
r_hi <= 32'h00000000;
r_branch_dslot <= 1'b0;
r_pc_branch <= 32'h00000000;
r_take_intr <= 1'b0;
r_epc <= 32'h00000000;
r_status <= 32'h00000000;
r_cause <= `EXCEPTION_NONE;
r_fault_info <= 32'h00000000;
r_lo <= 32'h00000000;
r_hi <= 32'h00000000;
r_branch_dslot <= 1'b0;
r_pc_branch <= 32'h00000000;
r_take_intr <= 1'b0;
r_opcode <= 32'h00000000;
r_opcode <= 32'h00000000;
mem_addr <= 32'h00000000;
mem_data_out <= 32'h00000000;
mem_rd <= 1'b0;
mem_wr <= 4'b0000;
mem_offset <= 2'b00;
mem_addr <= 32'h00000000;
mem_data_out <= 32'h00000000;
mem_rd <= 1'b0;
mem_wr <= 4'b0000;
mem_offset <= 2'b00;
// Default ISR vector address
r_isr_vector <= ISR_VECTOR;
r_isr_vector <= ISR_VECTOR;
fault_o <= 1'b0;
r_mem_access <= 1'b0;
fault_o <= 1'b0;
r_mem_access <= 1'b0;
end
else if ((en_i == 1'b1) && (mem_pause_i == 1'b0))
begin
mem_rd <= 1'b0;
mem_wr <= 4'b0000;
mem_rd <= 1'b0;
mem_wr <= 4'b0000;
v_exception = 1'b0;
v_emulate = 1'b0;
v_branch = 1'b0;
v_jmp = 1'b0;
v_write_rt = 1'b0;
v_write_rd = 1'b0;
v_status = r_status;
v_mem_access = 1'b0;
v_mem_data_in = mem_data_in_i;
v_exception = 1'b0;
v_emulate = 1'b0;
v_branch = 1'b0;
v_jmp = 1'b0;
v_write_rt = 1'b0;
v_write_rd = 1'b0;
v_status = r_status;
v_mem_access = 1'b0;
v_mem_data_in = mem_data_in_i;
// If memory access was done, check for no instruction to process.
// As memory access has a 1 cycle latency, invalid mem_data_in_i is
// aligned with d_mem_access not r_mem_access.
// If memory access was done, check for no instruction to process.
// As memory access has a 1 cycle latency, invalid mem_data_in_i is
// aligned with d_mem_access not r_mem_access.
if (d_mem_access == 1'b1)
v_mem_data_in = `OPCODE_INST_BUBBLE;
// Flush pipeline due to an exception/interrupt?
// NOTE: When d_take_intr=1, mem_data_in_i will be invalid for one more cycle
// Flush pipeline due to an exception/interrupt?
// NOTE: When d_take_intr=1, mem_data_in_i will be invalid for one more cycle
if ((r_take_intr == 1'b1) || (d_take_intr == 1'b1))
v_mem_data_in = `OPCODE_INST_BUBBLE;
r_take_intr <= 1'b0;
r_take_intr <= 1'b0;
// Decode opcode
r_opcode <= v_mem_data_in;
v_inst = {2'b00,v_mem_data_in[31:26]};
v_rs = v_mem_data_in[25:21];
v_rt = v_mem_data_in[20:16];
v_rd = v_mem_data_in[15:11];
v_re = v_mem_data_in[10:6];
v_func = {2'b00,v_mem_data_in[5:0]};
v_imm = v_mem_data_in[15:0];
v_target = v_mem_data_in[25:0];
r_opcode <= v_mem_data_in;
v_inst = {2'b00,v_mem_data_in[31:26]};
v_rs = v_mem_data_in[25:21];
v_rt = v_mem_data_in[20:16];
v_rd = v_mem_data_in[15:11];
v_re = v_mem_data_in[10:6];
v_func = {2'b00,v_mem_data_in[5:0]};
v_imm = v_mem_data_in[15:0];
v_target = v_mem_data_in[25:0];
// Signed & unsigned imm -> 32-bits
v_imm_int32 = sign_extend_imm16(v_imm);
v_imm_uint32 = extend_imm16(v_imm);
v_imm_int32 = sign_extend_imm16(v_imm);
v_imm_uint32 = extend_imm16(v_imm);
// Load register[rs]
v_reg_rs = r_reg_rs;
v_reg_rs = r_reg_rs;
// Load register[rt]
v_reg_rt = r_reg_rt;
v_reg_rt = r_reg_rt;
// Register[rs] hazard detection & forwarding logic
// (higher priority = latest results!)
// Register[rs] hazard detection & forwarding logic
// (higher priority = latest results!)
if (v_rs != 5'b00000)
begin
if (v_rs == r_rd_wb)
begin
// Result from memory / other
// Result from memory / other
if (alu_func == `ALU_NONE)
begin
v_reg_rs = r_reg_result;
387,7 → 387,7
end
else if (v_rs == d_rd_wb)
begin
// Result from memory load?
// Result from memory load?
if (c_load_op == 1'b1)
begin
v_reg_rs = c_mem_forward;
399,36 → 399,36
end
// Result from ALU
else
begin
begin
v_reg_rs = d_alu_result;
end
end
else if (v_rs == d2_rd_wb)
begin
v_reg_rs = r_reg_rd_out;
end
v_reg_rs = r_reg_rd_out;
end
end
// Register[rt] hazard detection & forwarding logic
// (higher priority = latest results!)
// (higher priority = latest results!)
if (v_rt != 5'b00000)
begin
if (v_rt == r_rd_wb)
begin
// Result from memory / other
// Result from memory / other
if (alu_func == `ALU_NONE)
begin
v_reg_rt = r_reg_result;
end
// Result from ALU
v_reg_rt = r_reg_result;
end
// Result from ALU
else
begin
v_reg_rt = alu_result;
end
end
end
else if (v_rt == d_rd_wb)
begin
// Result from memory load?
// Result from memory load?
if (c_load_op == 1'b1)
begin
v_reg_rt = c_mem_forward;
442,17 → 442,17
else
begin
v_reg_rt = d_alu_result;
end
end
end
else if (v_rt == d2_rd_wb)
begin
v_reg_rt = r_reg_rd_out;
end
end
end
// Zero result
v_reg_result = 32'h00000000;
v_reg_result = 32'h00000000;
// Update PC to next value
v_pc = (r_pc + 4);
466,213 → 466,213
// Reset branch delay slot status
r_branch_dslot <= 1'b0;
// Execute instruction
case (v_inst)
8'h00 :
case (v_func)
`INSTR_R_SLL:
begin
alu_func <= `ALU_SHIFTL;
alu_a <= v_reg_rt;
alu_b <= {27'b0, v_re};
v_write_rd = 1'b1;
end
`INSTR_R_SRL:
begin
alu_func <= `ALU_SHIFTR;
alu_a <= v_reg_rt;
alu_b <= {27'b0, v_re};
v_write_rd = 1'b1;
end
`INSTR_R_SRA:
begin
alu_func <= `ALU_SHIRTR_ARITH;
alu_a <= v_reg_rt;
alu_b <= {27'b0, v_re};
v_write_rd = 1'b1;
end
`INSTR_R_SLLV:
begin
alu_func <= `ALU_SHIFTL;
alu_a <= v_reg_rt;
alu_b <= v_reg_rs;
v_write_rd = 1'b1;
end
`INSTR_R_SRLV:
begin
alu_func <= `ALU_SHIFTR;
alu_a <= v_reg_rt;
alu_b <= v_reg_rs;
v_write_rd = 1'b1;
end
`INSTR_R_SRAV:
begin
alu_func <= `ALU_SHIRTR_ARITH;
alu_a <= v_reg_rt;
alu_b <= v_reg_rs;
v_write_rd = 1'b1;
end
`INSTR_R_JR:
begin
v_pc = v_reg_rs;
v_jmp = 1'b1;
end
`INSTR_R_JALR:
begin
v_reg_result = v_pc;
v_write_rd = 1'b1;
v_pc = v_reg_rs;
v_jmp = 1'b1;
end
`INSTR_R_SYSCALL:
begin
v_exception = 1'b1;
r_cause <= `EXCEPTION_SYSCALL;
end
`INSTR_R_BREAK:
begin
v_exception = 1'b1;
r_cause <= `EXCEPTION_BREAK;
end
`INSTR_R_MFHI:
begin
v_reg_result = r_hi;
v_write_rd = 1'b1;
end
`INSTR_R_MTHI:
begin
r_hi <= v_reg_rs;
end
`INSTR_R_MFLO:
begin
v_reg_result = r_lo;
v_write_rd = 1'b1;
end
`INSTR_R_MTLO:
begin
r_lo <= v_reg_rs;
end
`INSTR_R_MULT:
begin
v_exception = 1'b1;
v_emulate = 1'b1;
r_cause <= `EXCEPTION_MULT;
end
`INSTR_R_MULTU:
begin
v_exception = 1'b1;
v_emulate = 1'b1;
r_cause <= `EXCEPTION_UMULT;
end
`INSTR_R_DIV:
begin
v_exception = 1'b1;
v_emulate = 1'b1;
r_cause <= `EXCEPTION_DIV;
end
`INSTR_R_DIVU:
begin
v_exception = 1'b1;
v_emulate = 1'b1;
r_cause <= `EXCEPTION_UDIV;
end
`INSTR_R_ADD:
begin
alu_func <= `ALU_ADD;
alu_a <= v_reg_rs;
alu_b <= v_reg_rt;
v_write_rd = 1'b1;
end
`INSTR_R_ADDU:
begin
alu_func <= `ALU_ADD;
alu_a <= v_reg_rs;
alu_b <= v_reg_rt;
v_write_rd = 1'b1;
end
`INSTR_R_SUB:
begin
alu_func <= `ALU_SUB;
alu_a <= v_reg_rs;
alu_b <= v_reg_rt;
v_write_rd = 1'b1;
end
`INSTR_R_SUBU:
begin
alu_func <= `ALU_SUB;
alu_a <= v_reg_rs;
alu_b <= v_reg_rt;
v_write_rd = 1'b1;
end
`INSTR_R_AND:
begin
alu_func <= `ALU_AND;
alu_a <= v_reg_rs;
alu_b <= v_reg_rt;
v_write_rd = 1'b1;
end
`INSTR_R_OR:
begin
alu_func <= `ALU_OR;
alu_a <= v_reg_rs;
alu_b <= v_reg_rt;
v_write_rd = 1'b1;
end
`INSTR_R_XOR:
begin
alu_func <= `ALU_XOR;
alu_a <= v_reg_rs;
alu_b <= v_reg_rt;
v_write_rd = 1'b1;
end
`INSTR_R_NOR:
begin
alu_func <= `ALU_NOR;
alu_a <= v_reg_rs;
alu_b <= v_reg_rt;
v_write_rd = 1'b1;
end
`INSTR_R_SLT:
begin
alu_func <= `ALU_SLT;
alu_a <= v_reg_rs;
alu_b <= v_reg_rt;
v_write_rd = 1'b1;
end
`INSTR_R_SLTU:
begin
alu_func <= `ALU_SLTU;
alu_a <= v_reg_rs;
alu_b <= v_reg_rt;
v_write_rd = 1'b1;
end
// Execute instruction
case (v_inst)
8'h00 :
case (v_func)
`INSTR_R_SLL:
begin
alu_func <= `ALU_SHIFTL;
alu_a <= v_reg_rt;
alu_b <= {27'b0, v_re};
v_write_rd = 1'b1;
end
`INSTR_R_SRL:
begin
alu_func <= `ALU_SHIFTR;
alu_a <= v_reg_rt;
alu_b <= {27'b0, v_re};
v_write_rd = 1'b1;
end
`INSTR_R_SRA:
begin
alu_func <= `ALU_SHIRTR_ARITH;
alu_a <= v_reg_rt;
alu_b <= {27'b0, v_re};
v_write_rd = 1'b1;
end
`INSTR_R_SLLV:
begin
alu_func <= `ALU_SHIFTL;
alu_a <= v_reg_rt;
alu_b <= v_reg_rs;
v_write_rd = 1'b1;
end
`INSTR_R_SRLV:
begin
alu_func <= `ALU_SHIFTR;
alu_a <= v_reg_rt;
alu_b <= v_reg_rs;
v_write_rd = 1'b1;
end
`INSTR_R_SRAV:
begin
alu_func <= `ALU_SHIRTR_ARITH;
alu_a <= v_reg_rt;
alu_b <= v_reg_rs;
v_write_rd = 1'b1;
end
`INSTR_R_JR:
begin
v_pc = v_reg_rs;
v_jmp = 1'b1;
end
`INSTR_R_JALR:
begin
v_reg_result = v_pc;
v_write_rd = 1'b1;
v_pc = v_reg_rs;
v_jmp = 1'b1;
end
`INSTR_R_SYSCALL:
begin
v_exception = 1'b1;
r_cause <= `EXCEPTION_SYSCALL;
end
`INSTR_R_BREAK:
begin
v_exception = 1'b1;
r_cause <= `EXCEPTION_BREAK;
end
`INSTR_R_MFHI:
begin
v_reg_result = r_hi;
v_write_rd = 1'b1;
end
`INSTR_R_MTHI:
begin
r_hi <= v_reg_rs;
end
`INSTR_R_MFLO:
begin
v_reg_result = r_lo;
v_write_rd = 1'b1;
end
`INSTR_R_MTLO:
begin
r_lo <= v_reg_rs;
end
`INSTR_R_MULT:
begin
v_exception = 1'b1;
v_emulate = 1'b1;
r_cause <= `EXCEPTION_MULT;
end
`INSTR_R_MULTU:
begin
v_exception = 1'b1;
v_emulate = 1'b1;
r_cause <= `EXCEPTION_UMULT;
end
`INSTR_R_DIV:
begin
v_exception = 1'b1;
v_emulate = 1'b1;
r_cause <= `EXCEPTION_DIV;
end
`INSTR_R_DIVU:
begin
v_exception = 1'b1;
v_emulate = 1'b1;
r_cause <= `EXCEPTION_UDIV;
end
`INSTR_R_ADD:
begin
alu_func <= `ALU_ADD;
alu_a <= v_reg_rs;
alu_b <= v_reg_rt;
v_write_rd = 1'b1;
end
`INSTR_R_ADDU:
begin
alu_func <= `ALU_ADD;
alu_a <= v_reg_rs;
alu_b <= v_reg_rt;
v_write_rd = 1'b1;
end
`INSTR_R_SUB:
begin
alu_func <= `ALU_SUB;
alu_a <= v_reg_rs;
alu_b <= v_reg_rt;
v_write_rd = 1'b1;
end
`INSTR_R_SUBU:
begin
alu_func <= `ALU_SUB;
alu_a <= v_reg_rs;
alu_b <= v_reg_rt;
v_write_rd = 1'b1;
end
`INSTR_R_AND:
begin
alu_func <= `ALU_AND;
alu_a <= v_reg_rs;
alu_b <= v_reg_rt;
v_write_rd = 1'b1;
end
`INSTR_R_OR:
begin
alu_func <= `ALU_OR;
alu_a <= v_reg_rs;
alu_b <= v_reg_rt;
v_write_rd = 1'b1;
end
`INSTR_R_XOR:
begin
alu_func <= `ALU_XOR;
alu_a <= v_reg_rs;
alu_b <= v_reg_rt;
v_write_rd = 1'b1;
end
`INSTR_R_NOR:
begin
alu_func <= `ALU_NOR;
alu_a <= v_reg_rs;
alu_b <= v_reg_rt;
v_write_rd = 1'b1;
end
`INSTR_R_SLT:
begin
alu_func <= `ALU_SLT;
alu_a <= v_reg_rs;
alu_b <= v_reg_rt;
v_write_rd = 1'b1;
end
`INSTR_R_SLTU:
begin
alu_func <= `ALU_SLTU;
alu_a <= v_reg_rs;
alu_b <= v_reg_rt;
v_write_rd = 1'b1;
end
default :
begin
fault_o <= 1'b1;
682,210 → 682,210
end
endcase
// REGIMM
`INSTR_I_REGIMM :
case (v_rt)
`INSTR_I_COND_BLTZAL : // BLTZAL [ branch = ((int)v_reg_rs < 0) ]
begin
v_reg_result = v_pc;
v_write_rd = 1'b1;
r_rd_wb <= 5'b11111; // Write to $ra
v_branch = less_than_zero(v_reg_rs);
end
`INSTR_I_COND_BLTZ : // BLTZ [ branch = ((int)v_reg_rs < 0) ]
begin
v_branch = less_than_zero(v_reg_rs);
end
`INSTR_I_COND_BGEZAL : // BGEZAL [ branch = ((int)v_reg_rs >= 0) ]
begin
v_reg_result = v_pc;
v_write_rd = 1'b1;
r_rd_wb <= 5'b11111; // Write to $ra
v_branch = more_than_equal_zero(v_reg_rs);
end
`INSTR_I_COND_BGEZ : // BGEZ [ branch = ((int)v_reg_rs >= 0) ]
begin
v_branch = more_than_equal_zero(v_reg_rs);
end
default :
begin
fault_o <= 1'b1;
v_exception = 1'b1;
r_cause <= `EXCEPTION_FAULT;
r_fault_info <= v_mem_data_in;
end
endcase
`INSTR_J_JAL:
begin
v_reg_result = v_pc;
v_write_rd = 1'b1;
r_rd_wb <= 5'b11111; // Write to $ra
v_pc = {{v_pc[31:28],v_target[25:0]},2'b00};
v_jmp = 1'b1;
end
`INSTR_J_J:
begin
v_pc = {{v_pc[31:28],v_target[25:0]},2'b00};
v_jmp = 1'b1;
end
`INSTR_J_BEQ:
begin
if ((v_reg_rs == v_reg_rt))
v_branch = 1'b1;
end
// REGIMM
`INSTR_I_REGIMM :
case (v_rt)
`INSTR_I_COND_BLTZAL : // BLTZAL [ branch = ((int)v_reg_rs < 0) ]
begin
v_reg_result = v_pc;
v_write_rd = 1'b1;
r_rd_wb <= 5'b11111; // Write to $ra
v_branch = less_than_zero(v_reg_rs);
end
`INSTR_J_BNE:
begin
if ((!(v_reg_rs==v_reg_rt)))
v_branch = 1'b1;
end
`INSTR_I_COND_BLTZ : // BLTZ [ branch = ((int)v_reg_rs < 0) ]
begin
v_branch = less_than_zero(v_reg_rs);
end
`INSTR_J_BLEZ : // BLEZ [ branch = (int)v_reg_rs <= 0 ]
v_branch = less_than_equal_zero(v_reg_rs);
`INSTR_J_BGTZ : // BGTZ [ branch = (int)v_reg_rs > 0 ]
v_branch = more_than_zero(v_reg_rs);
`INSTR_I_ADDI:
begin
alu_func <= `ALU_ADD;
alu_a <= v_reg_rs;
alu_b <= v_imm_int32;
v_write_rt = 1'b1;
end
`INSTR_I_ADDIU:
begin
alu_func <= `ALU_ADD;
alu_a <= v_reg_rs;
alu_b <= v_imm_int32;
v_write_rt = 1'b1;
end
`INSTR_I_SLTI:
begin
alu_func <= `ALU_SLT;
alu_a <= v_reg_rs;
alu_b <= v_imm_int32;
v_write_rt = 1'b1;
end
`INSTR_I_SLTIU:
begin
alu_func <= `ALU_SLTU;
alu_a <= v_reg_rs;
alu_b <= v_imm_int32;
v_write_rt = 1'b1;
end
`INSTR_I_ANDI:
begin
alu_func <= `ALU_AND;
alu_a <= v_reg_rs;
alu_b <= v_imm_uint32;
v_write_rt = 1'b1;
end
`INSTR_I_ORI:
begin
alu_func <= `ALU_OR;
alu_a <= v_reg_rs;
alu_b <= v_imm_uint32;
v_write_rt = 1'b1;
end
`INSTR_I_XORI:
begin
alu_func <= `ALU_XOR;
alu_a <= v_reg_rs;
alu_b <= v_imm_uint32;
v_write_rt = 1'b1;
end
`INSTR_I_LUI:
begin
v_reg_result = {v_imm,16'h0000};
v_write_rt = 1'b1;
end
`INSTR_COP0:
begin
// Move from CP0
if (v_rs[2] == 1'b0)
case (v_rd)
`COP0_STATUS:
begin
v_reg_result = r_status;
v_write_rt = 1'b1;
end
`COP0_CAUSE:
begin
v_reg_result = {28'h0000000,r_cause};
v_write_rt = 1'b1;
end
`COP0_EPC:
begin
v_reg_result = r_epc;
v_write_rt = 1'b1;
end
`COP0_ISR_VECT:
begin
v_reg_result = r_isr_vector;
v_write_rt = 1'b1;
end
`COP0_FAULT_INFO:
begin
v_reg_result = r_fault_info;
v_write_rt = 1'b1;
end
default :
begin
end
endcase
// Move to CP0
else
case (v_rd)
`COP0_STATUS:
begin
r_status <= v_reg_rt;
v_status = v_reg_rt;
end
`COP0_CAUSE:
r_cause <= v_reg_rt[3:0];
`COP0_EPC:
r_epc <= v_reg_rt;
`COP0_ISR_VECT:
r_isr_vector <= v_reg_rt;
`COP0_FAULT_INFO:
r_fault_info <= v_reg_rt;
default :
begin
end
endcase
end
`INSTR_I_COND_BGEZAL : // BGEZAL [ branch = ((int)v_reg_rs >= 0) ]
begin
v_reg_result = v_pc;
v_write_rd = 1'b1;
r_rd_wb <= 5'b11111; // Write to $ra
v_branch = more_than_equal_zero(v_reg_rs);
end
// Memory load / store instructions
`INSTR_I_COND_BGEZ : // BGEZ [ branch = ((int)v_reg_rs >= 0) ]
begin
v_branch = more_than_equal_zero(v_reg_rs);
end
default :
begin
fault_o <= 1'b1;
v_exception = 1'b1;
r_cause <= `EXCEPTION_FAULT;
r_fault_info <= v_mem_data_in;
end
endcase
`INSTR_J_JAL:
begin
v_reg_result = v_pc;
v_write_rd = 1'b1;
r_rd_wb <= 5'b11111; // Write to $ra
v_pc = {{v_pc[31:28],v_target[25:0]},2'b00};
v_jmp = 1'b1;
end
`INSTR_J_J:
begin
v_pc = {{v_pc[31:28],v_target[25:0]},2'b00};
v_jmp = 1'b1;
end
`INSTR_J_BEQ:
begin
if (v_reg_rs == v_reg_rt)
v_branch = 1'b1;
end
`INSTR_J_BNE:
begin
if (v_reg_rs != v_reg_rt)
v_branch = 1'b1;
end
`INSTR_J_BLEZ : // BLEZ [ branch = (int)v_reg_rs <= 0 ]
v_branch = less_than_equal_zero(v_reg_rs);
`INSTR_J_BGTZ : // BGTZ [ branch = (int)v_reg_rs > 0 ]
v_branch = more_than_zero(v_reg_rs);
`INSTR_I_ADDI:
begin
alu_func <= `ALU_ADD;
alu_a <= v_reg_rs;
alu_b <= v_imm_int32;
v_write_rt = 1'b1;
end
`INSTR_I_ADDIU:
begin
alu_func <= `ALU_ADD;
alu_a <= v_reg_rs;
alu_b <= v_imm_int32;
v_write_rt = 1'b1;
end
`INSTR_I_SLTI:
begin
alu_func <= `ALU_SLT;
alu_a <= v_reg_rs;
alu_b <= v_imm_int32;
v_write_rt = 1'b1;
end
`INSTR_I_SLTIU:
begin
alu_func <= `ALU_SLTU;
alu_a <= v_reg_rs;
alu_b <= v_imm_int32;
v_write_rt = 1'b1;
end
`INSTR_I_ANDI:
begin
alu_func <= `ALU_AND;
alu_a <= v_reg_rs;
alu_b <= v_imm_uint32;
v_write_rt = 1'b1;
end
`INSTR_I_ORI:
begin
alu_func <= `ALU_OR;
alu_a <= v_reg_rs;
alu_b <= v_imm_uint32;
v_write_rt = 1'b1;
end
`INSTR_I_XORI:
begin
alu_func <= `ALU_XOR;
alu_a <= v_reg_rs;
alu_b <= v_imm_uint32;
v_write_rt = 1'b1;
end
`INSTR_I_LUI:
begin
v_reg_result = {v_imm,16'h0000};
v_write_rt = 1'b1;
end
`INSTR_COP0:
begin
// Move from CP0
if (v_rs[2] == 1'b0)
case (v_rd)
`COP0_STATUS:
begin
v_reg_result = r_status;
v_write_rt = 1'b1;
end
`COP0_CAUSE:
begin
v_reg_result = {28'h0000000,r_cause};
v_write_rt = 1'b1;
end
`COP0_EPC:
begin
v_reg_result = r_epc;
v_write_rt = 1'b1;
end
`COP0_ISR_VECT:
begin
v_reg_result = r_isr_vector;
v_write_rt = 1'b1;
end
`COP0_FAULT_INFO:
begin
v_reg_result = r_fault_info;
v_write_rt = 1'b1;
end
default :
begin
end
endcase
// Move to CP0
else
case (v_rd)
`COP0_STATUS:
begin
r_status <= v_reg_rt;
v_status = v_reg_rt;
end
`COP0_CAUSE:
r_cause <= v_reg_rt[3:0];
`COP0_EPC:
r_epc <= v_reg_rt;
`COP0_ISR_VECT:
r_isr_vector <= v_reg_rt;
`COP0_FAULT_INFO:
r_fault_info <= v_reg_rt;
default :
begin
end
endcase
end
// Memory load / store instructions
`INSTR_I_LB, `INSTR_I_LH, `INSTR_I_LW, `INSTR_I_LBU, `INSTR_I_LHU :
begin
v_mem_addr = (v_reg_rs + v_imm_int32);
984,54 → 984,54
// Handle branches
if (v_branch == 1'b1)
begin
v_offset = v_imm_int32;
v_offset = {v_offset[29:0],2'b00};
v_pc = (r_pc + v_offset);
v_offset = v_imm_int32;
v_offset = {v_offset[29:0],2'b00};
v_pc = (r_pc + v_offset);
// Next instruction is branch delay slot
r_branch_dslot <= 1'b1;
r_pc_branch <= v_pc;
r_branch_dslot <= 1'b1;
r_pc_branch <= v_pc;
end
// If not branching, handle interrupts / exceptions
else if ((v_jmp == 1'b0) && (v_inst != `INSTR_BUBBLE))
begin
// Exception (Fault/Mult/Div/Syscall/Break)
// Exception (Fault/Mult/Div/Syscall/Break)
if (v_exception == 1'b1)
begin
// Schedule interrupt after pipeline flush
r_take_intr <= 1'b1;
// Schedule interrupt after pipeline flush
r_take_intr <= 1'b1;
// Record instruction to continue from
r_epc <= r_pc;
r_epc <= r_pc;
 
// Disable interrupts by shifting left status register
r_status <= {v_status[30:0],1'b0};
// Disable interrupts by shifting left status register
r_status <= {v_status[30:0],1'b0};
end
// External interrupt (and not handling an exception, branch or bubble)?
// NOTE: d_mem_access & r_branch_dslot are exclusive as this would result in a bubble
else if ((intr_i == 1'b1) && (v_status[0] == 1'b1))
begin
// Schedule interrupt after pipeline flush
r_take_intr <= 1'b1;
// Schedule interrupt after pipeline flush
r_take_intr <= 1'b1;
// Interrupt src is external
r_cause <= `EXCEPTION_EXTINT;
r_cause <= `EXCEPTION_EXTINT;
// Record instruction to continue from
r_epc <= r_pc;
r_epc <= r_pc;
// Disable interrupts by shifting left status register
r_status <= {v_status[30:0],1'b0};
r_status <= {v_status[30:0],1'b0};
end
end
// Handle jumps
else if (v_jmp == 1'b1)
begin
// Next instruction is branch delay slot
r_branch_dslot <= 1'b1;
r_pc_branch <= v_pc;
// Next instruction is branch delay slot
r_branch_dslot <= 1'b1;
r_pc_branch <= v_pc;
end
// Update to new PC value only if last cycle wasn't a memory access
1045,7 → 1045,7
// If pipeline flushed due to interrupt request
if (r_take_intr == 1'b1)
begin
// Jump to ISR
// Jump to ISR
r_pc <= r_isr_vector;
end
1056,13 → 1056,13
// Target is Register[rt]
if (v_write_rt == 1'b1)
begin
// Store new value to register[rt] instead of register[rd]
// Store new value to register[rt] instead of register[rd]
r_rd_wb <= r_rt;
end
// No writeback required?
else if ((v_write_rt == 1'b0) && (v_write_rd == 1'b0))
begin
// Target register is $0 which is read-only
// Target register is $0 which is read-only
r_rd_wb <= 5'b00000;
end
end
1168,7 → 1168,7
end
// Result from ALU
else
begin
begin
r_reg_rd_out <= d_alu_result;
end
1178,7 → 1178,7
// If instruction was not bubble, output step done flag
if (wb_v_inst != `INSTR_BUBBLE)
step_done_o <= 1'b1;
step_done_o <= 1'b1;
end
end
end
1188,17 → 1188,17
//-----------------------------------------------------------------//
// Memory access mux
assign mem_data_in = mem_data_in_i;
assign mem_addr_mux = (r_mem_access == 1'b1) ? mem_addr : r_pc;
assign mem_addr_o = (mem_pause_i == 1'b1) ? mem_addr_last : mem_addr_mux;
assign mem_data_out_o = mem_data_out;
assign mem_rd_o = (r_mem_access == 1'b1) ? mem_rd : 1'b1;
assign mem_wr_o = (mem_pause_i == 1'b0) ? mem_wr : 4'b0000;
assign mem_data_in = mem_data_in_i;
assign mem_addr_mux = (r_mem_access == 1'b1) ? mem_addr : r_pc;
assign mem_addr_o = (mem_pause_i == 1'b1) ? mem_addr_last : mem_addr_mux;
assign mem_data_out_o = mem_data_out;
assign mem_rd_o = (r_mem_access == 1'b1) ? mem_rd : 1'b1;
assign mem_wr_o = (mem_pause_i == 1'b0) ? mem_wr : 4'b0000;
 
// Opcode register decoding
assign r_rs = mem_data_in_i[25:21];
assign r_rt = mem_data_in_i[20:16];
assign r_rd = mem_data_in_i[15:11];
assign r_rs = mem_data_in_i[25:21];
assign r_rt = mem_data_in_i[20:16];
assign r_rd = mem_data_in_i[15:11];
//-------------------------------------------------------------------
// Async memory result forwarding
/mpx/mpx_alu.v
48,40 → 48,40
//-----------------------------------------------------------------
module mpx_alu
(
input_a,
input_b,
func,
result
input_a,
input_b,
func,
result
);
 
//-----------------------------------------------------------------
// I/O
//-----------------------------------------------------------------
input [31:0] input_a /*verilator public*/;
input [31:0] input_b /*verilator public*/;
input [3:0] func /*verilator public*/;
output [31:0] result /*verilator public*/;
input [31:0] input_a /*verilator public*/;
input [31:0] input_b /*verilator public*/;
input [3:0] func /*verilator public*/;
output [31:0] result /*verilator public*/;
 
//-----------------------------------------------------------------
// Registers
//-----------------------------------------------------------------
reg [31:0] result;
reg [31:0] result;
 
//-----------------------------------------------------------------
// ALU
//-----------------------------------------------------------------
//-----------------------------------------------------------------
always @ (func or input_a or input_b )
begin
case (func)
`ALU_SHIFTL : result = shift_left(input_a, input_b);
`ALU_SHIFTR : result = shift_right(input_a, input_b);
`ALU_SHIRTR_ARITH: result = shift_right_arith(input_a, input_b);
`ALU_ADD : result = (input_a + input_b);
`ALU_SUB : result = (input_a - input_b);
`ALU_AND : result = (input_a & input_b);
`ALU_OR : result = (input_a | input_b);
`ALU_XOR : result = (input_a ^ input_b);
`ALU_NOR : result = (~(input_a | input_b));
`ALU_SHIFTL : result = shift_left(input_a, input_b);
`ALU_SHIFTR : result = shift_right(input_a, input_b);
`ALU_SHIRTR_ARITH: result = shift_right_arith(input_a, input_b);
`ALU_ADD : result = (input_a + input_b);
`ALU_SUB : result = (input_a - input_b);
`ALU_AND : result = (input_a & input_b);
`ALU_OR : result = (input_a | input_b);
`ALU_XOR : result = (input_a ^ input_b);
`ALU_NOR : result = (~(input_a | input_b));
`ALU_SLT :
begin
if (less_than_signed(input_a, input_b) == 1'b1)
88,14 → 88,14
result = 32'h00000001;
else
result = 32'h00000000;
end
end
`ALU_SLTE :
begin
begin
if ((less_than_signed(input_a, input_b) == 1'b1) || (input_a == input_b))
result = 32'h00000001;
else
result = 32'h00000000;
end
end
`ALU_SLTU :
begin
if (less_than(input_a, input_b) == 1'b1)
/mpx/mpx_defs.v
41,19 → 41,19
//-----------------------------------------------------------------
// ALU Operations
//-----------------------------------------------------------------
`define ALU_NONE 4'b0000
`define ALU_SHIFTL 4'b0001
`define ALU_SHIFTR 4'b0010
`define ALU_SHIRTR_ARITH 4'b0011
`define ALU_ADD 4'b0100
`define ALU_SUB 4'b0101
`define ALU_AND 4'b0110
`define ALU_OR 4'b0111
`define ALU_XOR 4'b1000
`define ALU_NOR 4'b1001
`define ALU_SLT 4'b1010
`define ALU_SLTE 4'b1011
`define ALU_SLTU 4'b1100
`define ALU_NONE 4'b0000
`define ALU_SHIFTL 4'b0001
`define ALU_SHIFTR 4'b0010
`define ALU_SHIRTR_ARITH 4'b0011
`define ALU_ADD 4'b0100
`define ALU_SUB 4'b0101
`define ALU_AND 4'b0110
`define ALU_OR 4'b0111
`define ALU_XOR 4'b1000
`define ALU_NOR 4'b1001
`define ALU_SLT 4'b1010
`define ALU_SLTE 4'b1011
`define ALU_SLTU 4'b1100
//-----------------------------------------------------------------
// Instructions
60,91 → 60,91
//-----------------------------------------------------------------
 
// R Type
`define INSTR_R_SLL 8'h00
`define INSTR_R_SRL 8'h02
`define INSTR_R_SRA 8'h03
`define INSTR_R_SLLV 8'h04
`define INSTR_R_SRLV 8'h06
`define INSTR_R_SRAV 8'h07
`define INSTR_R_JR 8'h08
`define INSTR_R_JALR 8'h09
`define INSTR_R_SYSCALL 8'h0c
`define INSTR_R_BREAK 8'h0d
`define INSTR_R_MFHI 8'h10
`define INSTR_R_MTHI 8'h11
`define INSTR_R_MFLO 8'h12
`define INSTR_R_MTLO 8'h13
`define INSTR_R_MULT 8'h18
`define INSTR_R_MULTU 8'h19
`define INSTR_R_DIV 8'h1a
`define INSTR_R_DIVU 8'h1b
`define INSTR_R_ADD 8'h20
`define INSTR_R_ADDU 8'h21
`define INSTR_R_SUB 8'h22
`define INSTR_R_SUBU 8'h23
`define INSTR_R_AND 8'h24
`define INSTR_R_OR 8'h25
`define INSTR_R_XOR 8'h26
`define INSTR_R_NOR 8'h27
`define INSTR_R_SLT 8'h2a
`define INSTR_R_SLTU 8'h2b
`define INSTR_R_SLL 8'h00
`define INSTR_R_SRL 8'h02
`define INSTR_R_SRA 8'h03
`define INSTR_R_SLLV 8'h04
`define INSTR_R_SRLV 8'h06
`define INSTR_R_SRAV 8'h07
`define INSTR_R_JR 8'h08
`define INSTR_R_JALR 8'h09
`define INSTR_R_SYSCALL 8'h0c
`define INSTR_R_BREAK 8'h0d
`define INSTR_R_MFHI 8'h10
`define INSTR_R_MTHI 8'h11
`define INSTR_R_MFLO 8'h12
`define INSTR_R_MTLO 8'h13
`define INSTR_R_MULT 8'h18
`define INSTR_R_MULTU 8'h19
`define INSTR_R_DIV 8'h1a
`define INSTR_R_DIVU 8'h1b
`define INSTR_R_ADD 8'h20
`define INSTR_R_ADDU 8'h21
`define INSTR_R_SUB 8'h22
`define INSTR_R_SUBU 8'h23
`define INSTR_R_AND 8'h24
`define INSTR_R_OR 8'h25
`define INSTR_R_XOR 8'h26
`define INSTR_R_NOR 8'h27
`define INSTR_R_SLT 8'h2a
`define INSTR_R_SLTU 8'h2b
 
`define INSTR_COP0 8'h10
`define INSTR_COP0 8'h10
 
// J Type
`define INSTR_J_JAL 8'h03
`define INSTR_J_J 8'h02
`define INSTR_J_BEQ 8'h04
`define INSTR_J_BNE 8'h05
`define INSTR_J_BLEZ 8'h06
`define INSTR_J_BGTZ 8'h07
`define INSTR_J_JAL 8'h03
`define INSTR_J_J 8'h02
`define INSTR_J_BEQ 8'h04
`define INSTR_J_BNE 8'h05
`define INSTR_J_BLEZ 8'h06
`define INSTR_J_BGTZ 8'h07
 
// I Type
`define INSTR_I_ADDI 8'h08
`define INSTR_I_ADDIU 8'h09
`define INSTR_I_SLTI 8'h0a
`define INSTR_I_SLTIU 8'h0b
`define INSTR_I_ANDI 8'h0c
`define INSTR_I_ORI 8'h0d
`define INSTR_I_XORI 8'h0e
`define INSTR_I_LUI 8'h0f
`define INSTR_I_LB 8'h20
`define INSTR_I_LH 8'h21
`define INSTR_I_LW 8'h23
`define INSTR_I_LBU 8'h24
`define INSTR_I_LHU 8'h25
`define INSTR_I_SB 8'h28
`define INSTR_I_SH 8'h29
`define INSTR_I_SW 8'h2b
`define INSTR_I_ADDI 8'h08
`define INSTR_I_ADDIU 8'h09
`define INSTR_I_SLTI 8'h0a
`define INSTR_I_SLTIU 8'h0b
`define INSTR_I_ANDI 8'h0c
`define INSTR_I_ORI 8'h0d
`define INSTR_I_XORI 8'h0e
`define INSTR_I_LUI 8'h0f
`define INSTR_I_LB 8'h20
`define INSTR_I_LH 8'h21
`define INSTR_I_LW 8'h23
`define INSTR_I_LBU 8'h24
`define INSTR_I_LHU 8'h25
`define INSTR_I_SB 8'h28
`define INSTR_I_SH 8'h29
`define INSTR_I_SW 8'h2b
 
`define INSTR_I_REGIMM 8'h01
`define INSTR_I_COND_BLTZAL 5'b10000
`define INSTR_I_COND_BLTZ 5'b00000
`define INSTR_I_COND_BGEZAL 5'b10001
`define INSTR_I_COND_BGEZ 5'b00001
`define INSTR_I_REGIMM 8'h01
`define INSTR_I_COND_BLTZAL 5'b10000
`define INSTR_I_COND_BLTZ 5'b00000
`define INSTR_I_COND_BGEZAL 5'b10001
`define INSTR_I_COND_BGEZ 5'b00001
 
`define INSTR_BUBBLE 8'h3F
`define INSTR_BUBBLE 8'h3F
 
`define OPCODE_INST_BUBBLE 32'hFC000000
`define OPCODE_INST_BUBBLE 32'hFC000000
 
//-----------------------------------------------------------------
// COP0
//-----------------------------------------------------------------
`define COP0_STATUS 5'b01100
`define COP0_CAUSE 5'b01101
`define COP0_EPC 5'b01110
`define COP0_ISR_VECT 5'b01111
`define COP0_FAULT_INFO 5'b10000
`define COP0_STATUS 5'b01100
`define COP0_CAUSE 5'b01101
`define COP0_EPC 5'b01110
`define COP0_ISR_VECT 5'b01111
`define COP0_FAULT_INFO 5'b10000
 
//-----------------------------------------------------------------
// Exception Cause (COP0_CAUSE)
//-----------------------------------------------------------------
`define EXCEPTION_NONE 4'b0000
`define EXCEPTION_SYSCALL 4'b0001
`define EXCEPTION_BREAK 4'b0010
`define EXCEPTION_EXTINT 4'b0011
`define EXCEPTION_FAULT 4'b0100
`define EXCEPTION_MULT 4'b0101
`define EXCEPTION_UMULT 4'b0110
`define EXCEPTION_DIV 4'b0111
`define EXCEPTION_UDIV 4'b1000
`define EXCEPTION_NONE 4'b0000
`define EXCEPTION_SYSCALL 4'b0001
`define EXCEPTION_BREAK 4'b0010
`define EXCEPTION_EXTINT 4'b0011
`define EXCEPTION_FAULT 4'b0100
`define EXCEPTION_MULT 4'b0101
`define EXCEPTION_UMULT 4'b0110
`define EXCEPTION_DIV 4'b0111
`define EXCEPTION_UDIV 4'b1000
/mpx/mpx_regfile_sim.v
48,31 → 48,31
//-----------------------------------------------------------------
module mpx_regfile_sim
(
clk_i,
rst_i,
en_i,
wr_i,
rs_i,
rt_i,
rd_i,
reg_rs_o,
reg_rt_o,
reg_rd_i
clk_i,
rst_i,
en_i,
wr_i,
rs_i,
rt_i,
rd_i,
reg_rs_o,
reg_rt_o,
reg_rd_i
);
 
//-----------------------------------------------------------------
// I/O
//-----------------------------------------------------------------
input clk_i /*verilator public*/;
input rst_i /*verilator public*/;
input en_i /*verilator public*/;
input wr_i /*verilator public*/;
input [4:0] rs_i /*verilator public*/;
input [4:0] rt_i /*verilator public*/;
input [4:0] rd_i /*verilator public*/;
output [31:0] reg_rs_o /*verilator public*/;
output [31:0] reg_rt_o /*verilator public*/;
input [31:0] reg_rd_i /*verilator public*/;
input clk_i /*verilator public*/;
input rst_i /*verilator public*/;
input en_i /*verilator public*/;
input wr_i /*verilator public*/;
input [4:0] rs_i /*verilator public*/;
input [4:0] rt_i /*verilator public*/;
input [4:0] rd_i /*verilator public*/;
output [31:0] reg_rs_o /*verilator public*/;
output [31:0] reg_rt_o /*verilator public*/;
input [31:0] reg_rd_i /*verilator public*/;
 
//-----------------------------------------------------------------
// Registers
120,37 → 120,37
begin
if (rst_i)
begin
reg_r1_at <= 32'h00000000;
reg_r2_v0 <= 32'h00000000;
reg_r3_v1 <= 32'h00000000;
reg_r4_a0 <= 32'h00000000;
reg_r5_a1 <= 32'h00000000;
reg_r6_a2 <= 32'h00000000;
reg_r7_a3 <= 32'h00000000;
reg_r8 <= 32'h00000000;
reg_r9 <= 32'h00000000;
reg_r10 <= 32'h00000000;
reg_r11 <= 32'h00000000;
reg_r12 <= 32'h00000000;
reg_r13 <= 32'h00000000;
reg_r14 <= 32'h00000000;
reg_r15 <= 32'h00000000;
reg_r16 <= 32'h00000000;
reg_r17 <= 32'h00000000;
reg_r18 <= 32'h00000000;
reg_r19 <= 32'h00000000;
reg_r20 <= 32'h00000000;
reg_r21 <= 32'h00000000;
reg_r22 <= 32'h00000000;
reg_r23 <= 32'h00000000;
reg_r24 <= 32'h00000000;
reg_r25 <= 32'h00000000;
reg_k0 <= 32'h00000000;
reg_k1 <= 32'h00000000;
reg_gp <= 32'h00000000;
reg_sp <= 32'h00000000;
reg_fp <= 32'h00000000;
reg_ra <= 32'h00000000;
reg_r1_at <= 32'h00000000;
reg_r2_v0 <= 32'h00000000;
reg_r3_v1 <= 32'h00000000;
reg_r4_a0 <= 32'h00000000;
reg_r5_a1 <= 32'h00000000;
reg_r6_a2 <= 32'h00000000;
reg_r7_a3 <= 32'h00000000;
reg_r8 <= 32'h00000000;
reg_r9 <= 32'h00000000;
reg_r10 <= 32'h00000000;
reg_r11 <= 32'h00000000;
reg_r12 <= 32'h00000000;
reg_r13 <= 32'h00000000;
reg_r14 <= 32'h00000000;
reg_r15 <= 32'h00000000;
reg_r16 <= 32'h00000000;
reg_r17 <= 32'h00000000;
reg_r18 <= 32'h00000000;
reg_r19 <= 32'h00000000;
reg_r20 <= 32'h00000000;
reg_r21 <= 32'h00000000;
reg_r22 <= 32'h00000000;
reg_r23 <= 32'h00000000;
reg_r24 <= 32'h00000000;
reg_r25 <= 32'h00000000;
reg_k0 <= 32'h00000000;
reg_k1 <= 32'h00000000;
reg_gp <= 32'h00000000;
reg_sp <= 32'h00000000;
reg_fp <= 32'h00000000;
reg_ra <= 32'h00000000;
end
else if (en_i == 1'b1)
begin
366,4 → 366,4
endcase
end
 
endmodule
endmodule
/soc/uart.v
43,62 → 43,62
//-----------------------------------------------------------------
module uart
(
// Clock & Reset
clk_i,
rst_i,
// Status
tx_busy_o,
rx_ready_o,
// Data
data_i,
wr_i,
data_o,
rd_i,
// UART pins
rxd_i,
txd_o
// Clock & Reset
clk_i,
rst_i,
// Status
tx_busy_o,
rx_ready_o,
// Data
data_i,
wr_i,
data_o,
rd_i,
// UART pins
rxd_i,
txd_o
);
//-----------------------------------------------------------------
// Params
//-----------------------------------------------------------------
parameter [31:0] UART_DIVISOR = 278;
parameter [31:0] UART_DIVISOR = 278;
//-----------------------------------------------------------------
// I/O
//-----------------------------------------------------------------
input clk_i /*verilator public*/;
input rst_i /*verilator public*/;
input [7:0] data_i /*verilator public*/;
output [7:0] data_o /*verilator public*/;
input wr_i /*verilator public*/;
input rd_i /*verilator public*/;
output tx_busy_o /*verilator public*/;
output rx_ready_o /*verilator public*/;
input rxd_i /*verilator public*/;
output txd_o /*verilator public*/;
input clk_i /*verilator public*/;
input rst_i /*verilator public*/;
input [7:0] data_i /*verilator public*/;
output [7:0] data_o /*verilator public*/;
input wr_i /*verilator public*/;
input rd_i /*verilator public*/;
output tx_busy_o /*verilator public*/;
output rx_ready_o /*verilator public*/;
input rxd_i /*verilator public*/;
output txd_o /*verilator public*/;
 
//-----------------------------------------------------------------
// Registers
//-----------------------------------------------------------------
parameter FULL_BIT = UART_DIVISOR;
parameter HALF_BIT = (FULL_BIT / 2);
parameter FULL_BIT = UART_DIVISOR;
parameter HALF_BIT = (FULL_BIT / 2);
 
// TX Signals
reg [7:0] tx_buf;
reg tx_buf_full;
reg tx_busy;
reg [3:0] tx_bits;
integer tx_count;
reg [7:0] tx_shift_reg;
reg txd_o;
reg [7:0] tx_buf;
reg tx_buf_full;
reg tx_busy;
reg [3:0] tx_bits;
integer tx_count;
reg [7:0] tx_shift_reg;
reg txd_o;
 
// RX Signals
reg i_rxd;
reg [7:0] data_o;
reg [3:0] rx_bits;
integer rx_count;
reg [7:0] rx_shift_reg;
reg rx_ready_o;
reg i_rxd;
reg [7:0] data_o;
reg [3:0] rx_bits;
integer rx_count;
reg [7:0] rx_shift_reg;
reg rx_ready_o;
 
//-----------------------------------------------------------------
// Re-sync RXD
118,85 → 118,85
begin
if (rst_i == 1'b1)
begin
rx_bits <= 0;
rx_count <= 0;
rx_ready_o <= 1'b0;
rx_bits <= 0;
rx_count <= 0;
rx_ready_o <= 1'b0;
rx_shift_reg <= 8'h00;
data_o <= 8'h00;
data_o <= 8'h00;
end
else
begin
// If reading data, reset data ready state
// If reading data, reset data ready state
if (rd_i == 1'b1)
rx_ready_o <= 1'b0;
// Rx bit timer
if (rx_count != 0)
rx_count <= (rx_count - 1);
rx_count <= (rx_count - 1);
else
begin
//-------------------------------
// Start bit detection
//-------------------------------
//-------------------------------
// Start bit detection
//-------------------------------
if (rx_bits == 0)
begin
// If RXD low, check again in half bit time
// If RXD low, check again in half bit time
if (i_rxd == 1'b0)
begin
rx_count <= HALF_BIT;
rx_bits <= 1;
rx_count <= HALF_BIT;
rx_bits <= 1;
end
end
//-------------------------------
// Start bit (mid bit time point)
//-------------------------------
//-------------------------------
// Start bit (mid bit time point)
//-------------------------------
else if (rx_bits == 1)
begin
// RXD should still be low at mid point of bit period
// RXD should still be low at mid point of bit period
if (i_rxd == 1'b0)
begin
rx_count <= FULL_BIT;
rx_bits <= (rx_bits + 1);
rx_count <= FULL_BIT;
rx_bits <= (rx_bits + 1);
rx_shift_reg <= 8'h00;
end
// Start bit not still low, reset RX process
else
begin
rx_bits <= 0;
rx_bits <= 0;
end
end
//-------------------------------
// Stop bit
//-------------------------------
//-------------------------------
// Stop bit
//-------------------------------
else if (rx_bits == 10)
begin
// RXD should be still high
// RXD should be still high
if (i_rxd == 1'b1)
begin
rx_count <= 0;
rx_bits <= 0;
data_o <= rx_shift_reg;
rx_ready_o <= 1'b1;
rx_count <= 0;
rx_bits <= 0;
data_o <= rx_shift_reg;
rx_ready_o <= 1'b1;
end
// Bad Stop bit - wait for a full bit period
// before allowing start bit detection again
else
begin
rx_count <= FULL_BIT;
rx_bits <= 0;
rx_count <= FULL_BIT;
rx_bits <= 0;
end
end
//-------------------------------
// Data bits
//-------------------------------
//-------------------------------
// Data bits
//-------------------------------
else
begin
// Receive data LSB first
rx_shift_reg[7] <= i_rxd;
rx_shift_reg[6:0]<= rx_shift_reg[7:1];
rx_count <= FULL_BIT;
rx_bits <= (rx_bits + 1);
// Receive data LSB first
rx_shift_reg[7] <= i_rxd;
rx_shift_reg[6:0]<= rx_shift_reg[7:1];
rx_count <= FULL_BIT;
rx_bits <= (rx_bits + 1);
end
end
end
209,33 → 209,33
begin
if (rst_i == 1'b1)
begin
tx_count <= 0;
tx_bits <= 0;
tx_busy <= 1'b0;
txd_o <= 1'b1;
tx_count <= 0;
tx_bits <= 0;
tx_busy <= 1'b0;
txd_o <= 1'b1;
tx_shift_reg <= 8'h00;
tx_buf <= 8'h00;
tx_buf_full <= 1'b0;
tx_buf <= 8'h00;
tx_buf_full <= 1'b0;
end
else
begin
// Buffer data to transmit
// Buffer data to transmit
if (wr_i == 1'b1)
begin
tx_buf <= data_i;
tx_buf_full <= 1'b1;
tx_buf <= data_i;
tx_buf_full <= 1'b1;
end
// Tx bit timer
// Tx bit timer
if (tx_count != 0)
tx_count <= (tx_count - 1);
tx_count <= (tx_count - 1);
else
begin
//-------------------------------
// Start bit (TXD = L)
//-------------------------------
begin
//-------------------------------
// Start bit (TXD = L)
//-------------------------------
if (tx_bits == 0)
begin
 
244,33 → 244,33
// Data in buffer ready to transmit?
if (tx_buf_full == 1'b1)
begin
tx_shift_reg <= tx_buf;
tx_busy <= 1'b1;
txd_o <= 1'b0;
tx_buf_full <= 1'b0;
tx_bits <= 1;
tx_count <= FULL_BIT;
tx_shift_reg <= tx_buf;
tx_busy <= 1'b1;
txd_o <= 1'b0;
tx_buf_full <= 1'b0;
tx_bits <= 1;
tx_count <= FULL_BIT;
end
end
//-------------------------------
// Stop bit (TXD = H)
//-------------------------------
//-------------------------------
// Stop bit (TXD = H)
//-------------------------------
else if (tx_bits == 9)
begin
txd_o <= 1'b1;
tx_bits <= 0;
tx_count <= FULL_BIT;
txd_o <= 1'b1;
tx_bits <= 0;
tx_count <= FULL_BIT;
end
//-------------------------------
// Data bits
//-------------------------------
//-------------------------------
// Data bits
//-------------------------------
else
begin
// Shift data out LSB first
txd_o <= tx_shift_reg[0];
tx_shift_reg[6:0]<= tx_shift_reg[7:1];
tx_bits <= (tx_bits + 1);
tx_count <= FULL_BIT;
// Shift data out LSB first
txd_o <= tx_shift_reg[0];
tx_shift_reg[6:0]<= tx_shift_reg[7:1];
tx_bits <= (tx_bits + 1);
tx_count <= FULL_BIT;
end
end
end
279,6 → 279,6
//-----------------------------------------------------------------
// Combinatorial
//-----------------------------------------------------------------
assign tx_busy_o = (tx_busy | tx_buf_full | wr_i);
assign tx_busy_o = (tx_busy | tx_buf_full | wr_i);
 
endmodule
/soc/mpx_soc.v
48,132 → 48,131
//-----------------------------------------------------------------
module mpx_soc
(
// General - Clocking & Reset
clk_i,
rst_i,
en_i,
ext_intr_i,
fault_o,
// UART
uart_tx_o,
uart_rx_i,
// Memory
int_mem_addr_o,
int_mem_data_o,
int_mem_data_i,
int_mem_wr_o,
int_mem_rd_o,
// External IO
ext_io_addr_o,
ext_io_data_o,
ext_io_data_i,
ext_io_wr_o,
ext_io_rd_o,
ext_io_pause_i,
// Debug Register Access
dbg_reg_addr_i,
dbg_reg_out_o,
dbg_pc_o,
// Debug UART output
dbg_uart_data_o,
dbg_uart_wr_o
// General - Clocking & Reset
clk_i,
rst_i,
en_i,
ext_intr_i,
fault_o,
// UART
uart_tx_o,
uart_rx_i,
// Memory
int_mem_addr_o,
int_mem_data_o,
int_mem_data_i,
int_mem_wr_o,
int_mem_rd_o,
// External IO
ext_io_addr_o,
ext_io_data_o,
ext_io_data_i,
ext_io_wr_o,
ext_io_rd_o,
ext_io_pause_i,
// Debug Register Access
dbg_reg_addr_i,
dbg_reg_out_o,
dbg_pc_o,
// Debug UART output
dbg_uart_data_o,
dbg_uart_wr_o
);
 
//-----------------------------------------------------------------
// Params
//-----------------------------------------------------------------
parameter [31:0] CLK_KHZ = 12288;
parameter [31:0] UART_BAUD = 115200;
parameter [31:0] EXTERNAL_INTERRUPTS = 1;
parameter CORE_ID = 0;
parameter BOOT_VECTOR = 0;
parameter ISR_VECTOR = 0;
parameter [31:0] CLK_KHZ = 12288;
parameter [31:0] UART_BAUD = 115200;
parameter [31:0] EXTERNAL_INTERRUPTS = 1;
parameter CORE_ID = 0;
parameter BOOT_VECTOR = 0;
parameter ISR_VECTOR = 0;
//-----------------------------------------------------------------
// I/O
//-----------------------------------------------------------------
input clk_i /*verilator public*/;
input rst_i /*verilator public*/;
input en_i /*verilator public*/;
output fault_o /*verilator public*/;
input clk_i /*verilator public*/;
input rst_i /*verilator public*/;
input en_i /*verilator public*/;
output fault_o /*verilator public*/;
input [(EXTERNAL_INTERRUPTS - 1):0] ext_intr_i /*verilator public*/;
output uart_tx_o /*verilator public*/;
input uart_rx_i /*verilator public*/;
output [31:0] int_mem_addr_o /*verilator public*/;
output [31:0] int_mem_data_o /*verilator public*/;
input [31:0] int_mem_data_i /*verilator public*/;
output [3:0] int_mem_wr_o /*verilator public*/;
output int_mem_rd_o /*verilator public*/;
output [31:0] ext_io_addr_o /*verilator public*/;
output [31:0] ext_io_data_o /*verilator public*/;
input [31:0] ext_io_data_i /*verilator public*/;
output [3:0] ext_io_wr_o /*verilator public*/;
output ext_io_rd_o /*verilator public*/;
input ext_io_pause_i /*verilator public*/;
input [8:0] dbg_reg_addr_i /*verilator public*/;
output [31:0] dbg_reg_out_o /*verilator public*/;
output [31:0] dbg_pc_o /*verilator public*/;
output [7:0] dbg_uart_data_o /*verilator public*/;
output dbg_uart_wr_o /*verilator public*/;
output uart_tx_o /*verilator public*/;
input uart_rx_i /*verilator public*/;
output [31:0] int_mem_addr_o /*verilator public*/;
output [31:0] int_mem_data_o /*verilator public*/;
input [31:0] int_mem_data_i /*verilator public*/;
output [3:0] int_mem_wr_o /*verilator public*/;
output int_mem_rd_o /*verilator public*/;
output [31:0] ext_io_addr_o /*verilator public*/;
output [31:0] ext_io_data_o /*verilator public*/;
input [31:0] ext_io_data_i /*verilator public*/;
output [3:0] ext_io_wr_o /*verilator public*/;
output ext_io_rd_o /*verilator public*/;
input ext_io_pause_i /*verilator public*/;
input [8:0] dbg_reg_addr_i /*verilator public*/;
output [31:0] dbg_reg_out_o /*verilator public*/;
output [31:0] dbg_pc_o /*verilator public*/;
output [7:0] dbg_uart_data_o /*verilator public*/;
output dbg_uart_wr_o /*verilator public*/;
 
//-----------------------------------------------------------------
// Registers
//-----------------------------------------------------------------
reg [31:0] v_irq_status;
reg [2:0] r_mem_sel;
reg [31:0] v_irq_status;
reg [2:0] r_mem_sel;
 
wire [31:0] cpu_address;
wire [3:0] cpu_byte_we;
wire cpu_oe;
wire [31:0] cpu_data_w;
reg [31:0] cpu_data_r;
reg cpu_pause;
wire [31:0] cpu_address;
wire [3:0] cpu_byte_we;
wire cpu_oe;
wire [31:0] cpu_data_w;
reg [31:0] cpu_data_r;
reg cpu_pause;
 
reg [31:0] io_address;
reg [31:0] io_data_w;
reg [31:0] io_data_r;
reg [3:0] io_wr;
reg io_rd;
reg [31:0] io_address;
reg [31:0] io_data_w;
reg [31:0] io_data_r;
reg [3:0] io_wr;
reg io_rd;
 
// UART
reg [7:0] uart_tx_data;
wire [7:0] uart_rx_data;
reg uart_wr;
reg uart_rd;
wire uart_tx_busy;
wire uart_rx_avail;
reg [7:0] uart_tx_data;
wire [7:0] uart_rx_data;
reg uart_wr;
reg uart_rd;
wire uart_tx_busy;
wire uart_rx_avail;
 
// Systick Timer
reg systick_intr;
reg [31:0] systick_count;
reg [31:0] systick_clk_count;
reg systick_intr;
reg [31:0] systick_count;
reg [31:0] systick_clk_count;
 
// Hi-res system clock tick counter
reg [31:0] hr_timer_cnt;
reg [31:0] hr_timer_match;
reg [31:0] hr_timer_cnt;
reg [31:0] hr_timer_match;
 
// IRQ Status
wire intr_in;
reg [31:0] irq_status;
reg [31:0] irq_mask;
wire intr_in;
reg [31:0] irq_status;
reg [31:0] irq_mask;
 
// Output Signals
wire uart_tx_o;
reg [31:0] int_mem_addr_o;
reg [31:0] int_mem_data_o;
reg [3:0] int_mem_wr_o;
reg int_mem_rd_o;
reg [31:0] ext_io_addr_o;
reg [31:0] ext_io_data_o;
reg [3:0] ext_io_wr_o;
reg ext_io_rd_o;
wire uart_tx_o;
reg [31:0] int_mem_addr_o;
reg [31:0] int_mem_data_o;
reg [3:0] int_mem_wr_o;
reg int_mem_rd_o;
reg [31:0] ext_io_addr_o;
reg [31:0] ext_io_data_o;
reg [3:0] ext_io_wr_o;
reg ext_io_rd_o;
 
 
//-----------------------------------------------------------------
// Instantiation
//-----------------------------------------------------------------
181,45 → 180,45
// MPX CPU
mpx
#(
.BOOT_VECTOR(BOOT_VECTOR),
.ISR_VECTOR(ISR_VECTOR)
.BOOT_VECTOR(BOOT_VECTOR),
.ISR_VECTOR(ISR_VECTOR)
)
u1_cpu
(
.clk_i(clk_i),
.rst_i(rst_i),
.en_i(en_i),
.intr_i(intr_in),
.step_done_o(/*open */),
.fault_o(fault_o),
.mem_addr_o(cpu_address),
.mem_data_out_o(cpu_data_w),
.mem_data_in_i(cpu_data_r),
.mem_wr_o(cpu_byte_we),
.mem_rd_o(cpu_oe),
.mem_pause_i(cpu_pause),
.dbg_reg_addr_i(dbg_reg_addr_i),
.dbg_reg_out_o(dbg_reg_out_o),
.dbg_pc_o(dbg_pc_o)
.clk_i(clk_i),
.rst_i(rst_i),
.en_i(en_i),
.intr_i(intr_in),
.step_done_o(/*open */),
.fault_o(fault_o),
.mem_addr_o(cpu_address),
.mem_data_out_o(cpu_data_w),
.mem_data_in_i(cpu_data_r),
.mem_wr_o(cpu_byte_we),
.mem_rd_o(cpu_oe),
.mem_pause_i(cpu_pause),
.dbg_reg_addr_i(dbg_reg_addr_i),
.dbg_reg_out_o(dbg_reg_out_o),
.dbg_pc_o(dbg_pc_o)
);
 
// UART
uart
#(
.UART_DIVISOR(((CLK_KHZ * 1000) / UART_BAUD))
.UART_DIVISOR(((CLK_KHZ * 1000) / UART_BAUD))
)
u3_uart
(
.clk_i(clk_i),
.rst_i(rst_i),
.data_i(uart_tx_data),
.data_o(uart_rx_data),
.wr_i(uart_wr),
.rd_i(uart_rd),
.tx_busy_o(uart_tx_busy),
.rx_ready_o(uart_rx_avail),
.rxd_i(uart_rx_i),
.txd_o(uart_tx_o)
.clk_i(clk_i),
.rst_i(rst_i),
.data_i(uart_tx_data),
.data_o(uart_rx_data),
.wr_i(uart_wr),
.rd_i(uart_rd),
.tx_busy_o(uart_tx_busy),
.rx_ready_o(uart_rx_avail),
.rxd_i(uart_rx_i),
.txd_o(uart_tx_o)
);
 
//-----------------------------------------------------------------
229,21 → 228,21
begin
if (rst_i == 1'b1)
begin
// UART
uart_tx_data <= 8'h00;
uart_wr <= 1'b0;
// UART
uart_tx_data <= 8'h00;
uart_wr <= 1'b0;
// Interrupt Status
irq_status <= 32'h00000000;
irq_mask <= 32'h00000000;
hr_timer_cnt <= 32'h00000000;
hr_timer_match <= 32'h00000000;
irq_status <= 32'h00000000;
irq_mask <= 32'h00000000;
hr_timer_cnt <= 32'h00000000;
hr_timer_match <= 32'h00000000;
end
else
begin
uart_wr <= 1'b0;
uart_wr <= 1'b0;
// Get current IRQ status
v_irq_status = irq_status;
309,8 → 308,8
begin
if (rst_i == 1'b1)
begin
io_data_r <= 32'h00000000;
uart_rd <= 1'b0;
io_data_r <= 32'h00000000;
uart_rd <= 1'b0;
end
else
begin
358,18 → 357,18
begin
if (rst_i == 1'b1)
begin
systick_count <= 32'h00000000;
systick_clk_count <= 32'h00000000;
systick_intr <= 1'b0;
systick_count <= 32'h00000000;
systick_clk_count <= 32'h00000000;
systick_intr <= 1'b0;
end
else
begin
systick_intr <= 1'b0;
systick_intr <= 1'b0;
if (systick_clk_count == CLK_KHZ)
begin
systick_count <= (systick_count + 1);
systick_intr <= 1'b1;
systick_count <= (systick_count + 1);
systick_intr <= 1'b1;
systick_clk_count <= 32'h00000000;
end
else
387,76 → 386,76
// Memory
`MEM_REGION_INTERNAL :
begin
int_mem_addr_o = cpu_address;
int_mem_wr_o = cpu_byte_we;
int_mem_rd_o = cpu_oe;
int_mem_data_o = cpu_data_w;
int_mem_addr_o = cpu_address;
int_mem_wr_o = cpu_byte_we;
int_mem_rd_o = cpu_oe;
int_mem_data_o = cpu_data_w;
io_address = 32'h00000000;
io_wr = 4'b0000;
io_rd = 1'b0;
io_data_w = 32'h00000000;
io_address = 32'h00000000;
io_wr = 4'b0000;
io_rd = 1'b0;
io_data_w = 32'h00000000;
ext_io_addr_o = 32'h00000000;
ext_io_wr_o = 4'b0000;
ext_io_rd_o = 1'b0;
ext_io_data_o = 32'h00000000;
ext_io_addr_o = 32'h00000000;
ext_io_wr_o = 4'b0000;
ext_io_rd_o = 1'b0;
ext_io_data_o = 32'h00000000;
end
// Core I/O peripherals
`MEM_REGION_CORE_IO :
begin
io_address = cpu_address;
io_wr = cpu_byte_we;
io_rd = cpu_oe;
io_data_w = cpu_data_w;
io_address = cpu_address;
io_wr = cpu_byte_we;
io_rd = cpu_oe;
io_data_w = cpu_data_w;
int_mem_addr_o = 32'h00000000;
int_mem_wr_o = 4'b0000;
int_mem_rd_o = 1'b0;
int_mem_data_o = 32'h00000000;
int_mem_addr_o = 32'h00000000;
int_mem_wr_o = 4'b0000;
int_mem_rd_o = 1'b0;
int_mem_data_o = 32'h00000000;
ext_io_addr_o = 32'h00000000;
ext_io_wr_o = 4'b0000;
ext_io_rd_o = 1'b0;
ext_io_data_o = 32'h00000000;
ext_io_addr_o = 32'h00000000;
ext_io_wr_o = 4'b0000;
ext_io_rd_o = 1'b0;
ext_io_data_o = 32'h00000000;
end
// Extended I/O peripherals
`MEM_REGION_EXT_IO :
begin
ext_io_addr_o = cpu_address;
ext_io_wr_o = cpu_byte_we;
ext_io_rd_o = cpu_oe;
ext_io_data_o = cpu_data_w;
ext_io_addr_o = cpu_address;
ext_io_wr_o = cpu_byte_we;
ext_io_rd_o = cpu_oe;
ext_io_data_o = cpu_data_w;
int_mem_addr_o = 32'h00000000;
int_mem_wr_o = 4'b0000;
int_mem_rd_o = 1'b0;
int_mem_data_o = 32'h00000000;
int_mem_addr_o = 32'h00000000;
int_mem_wr_o = 4'b0000;
int_mem_rd_o = 1'b0;
int_mem_data_o = 32'h00000000;
io_address = 32'h00000000;
io_wr = 4'b0000;
io_rd = 1'b0;
io_data_w = 32'h00000000;
io_address = 32'h00000000;
io_wr = 4'b0000;
io_rd = 1'b0;
io_data_w = 32'h00000000;
end
default :
begin
io_address = 32'h00000000;
io_wr = 4'b0000;
io_rd = 1'b0;
io_data_w = 32'h00000000;
io_address = 32'h00000000;
io_wr = 4'b0000;
io_rd = 1'b0;
io_data_w = 32'h00000000;
int_mem_addr_o = 32'h00000000;
int_mem_wr_o = 4'b0000;
int_mem_rd_o = 1'b0;
int_mem_data_o = 32'h00000000;
int_mem_addr_o = 32'h00000000;
int_mem_wr_o = 4'b0000;
int_mem_rd_o = 1'b0;
int_mem_data_o = 32'h00000000;
ext_io_addr_o = 32'h00000000;
ext_io_wr_o = 4'b0000;
ext_io_rd_o = 1'b0;
ext_io_data_o = 32'h00000000;
ext_io_addr_o = 32'h00000000;
ext_io_wr_o = 4'b0000;
ext_io_rd_o = 1'b0;
ext_io_data_o = 32'h00000000;
end
endcase
end
471,28 → 470,28
// Memory
`MEM_REGION_INTERNAL :
begin
cpu_data_r = int_mem_data_i;
cpu_pause = 1'b0;
cpu_data_r = int_mem_data_i;
cpu_pause = 1'b0;
end
// Core I/O peripherals
`MEM_REGION_CORE_IO :
begin
cpu_data_r = io_data_r;
cpu_pause = 1'b0;
cpu_data_r = io_data_r;
cpu_pause = 1'b0;
end
// Extended I/O peripherals
`MEM_REGION_EXT_IO :
begin
cpu_data_r = ext_io_data_i;
cpu_pause = 1'b0;
cpu_data_r = ext_io_data_i;
cpu_pause = 1'b0;
end
default :
begin
cpu_data_r = 32'h00000000;
cpu_pause = 1'b0;
cpu_data_r = 32'h00000000;
cpu_pause = 1'b0;
end
endcase
end
516,13 → 515,13
//-----------------------------------------------------------------
// Combinatorial Logic
//-----------------------------------------------------------------
assign intr_in = ((irq_mask & irq_status) != 32'h00000000) ? 1'b1 : 1'b0;
assign intr_in = ((irq_mask & irq_status) != 32'h00000000) ? 1'b1 : 1'b0;
 
//-----------------------------------------------------------------
// External Interface
//-----------------------------------------------------------------
// Debug UART
assign dbg_uart_data_o = uart_tx_data;
assign dbg_uart_wr_o = uart_wr;
assign dbg_uart_data_o = uart_tx_data;
assign dbg_uart_wr_o = uart_wr;
 
endmodule
/soc/mpx_soc_defs.v
41,9 → 41,9
//-----------------------------------------------------------------
// Memory Map
//-----------------------------------------------------------------
`define MEM_REGION_INTERNAL 3'b001
`define MEM_REGION_CORE_IO 3'b010
`define MEM_REGION_EXT_IO 3'b011
`define MEM_REGION_INTERNAL 3'b001
`define MEM_REGION_CORE_IO 3'b010
`define MEM_REGION_EXT_IO 3'b011
 
//-----------------------------------------------------------------
// I/O
50,21 → 50,21
//-----------------------------------------------------------------
 
// General
`define CORE_ID 8'h00
`define CORE_ID 8'h00
 
// Basic Peripherals
`define UART_USR 8'h04
`define UART_UDR 8'h08
`define TIMER_VAL 8'h10
`define IRQ_MASK_SET 8'h14
`define IRQ_MASK_STATUS 8'h14
`define IRQ_MASK_CLR 8'h18
`define IRQ_STATUS 8'h1C
`define IRQ_SYSTICK (0)
`define IRQ_UART_RX_AVAIL (1)
`define IRQ_SW (2)
`define IRQ_PIT (6)
`define IRQ_EXT_FIRST (8)
`define SYS_CLK_COUNT 8'h60
`define UART_USR 8'h04
`define UART_UDR 8'h08
`define TIMER_VAL 8'h10
`define IRQ_MASK_SET 8'h14
`define IRQ_MASK_STATUS 8'h14
`define IRQ_MASK_CLR 8'h18
`define IRQ_STATUS 8'h1C
`define IRQ_SYSTICK (0)
`define IRQ_UART_RX_AVAIL (1)
`define IRQ_SW (2)
`define IRQ_PIT (6)
`define IRQ_EXT_FIRST (8)
`define SYS_CLK_COUNT 8'h60
 
/sim/sram.v
43,48 → 43,48
//-----------------------------------------------------------------
module sram
(
clk_i,
adr_i,
dat_i,
wr_i,
dat_o
clk_i,
adr_i,
dat_i,
wr_i,
dat_o
);
 
//-----------------------------------------------------------------
// Params
//-----------------------------------------------------------------
parameter [31:0] WIDTH = 8;
parameter [31:0] SIZE = 14;
parameter [31:0] WIDTH = 8;
parameter [31:0] SIZE = 14;
 
//-----------------------------------------------------------------
// I/O
//-----------------------------------------------------------------
input clk_i /*verilator public*/;
input clk_i /*verilator public*/;
output [(WIDTH - 1):0] dat_o /*verilator public*/;
input [(WIDTH - 1):0] dat_i /*verilator public*/;
input [(SIZE - 1):0] adr_i /*verilator public*/;
input wr_i /*verilator public*/;
input [(WIDTH - 1):0] dat_i /*verilator public*/;
input [(SIZE - 1):0] adr_i /*verilator public*/;
input wr_i /*verilator public*/;
 
//-----------------------------------------------------------------
// Registers
//-----------------------------------------------------------------
reg [(WIDTH - 1):0] ram [((2<< (SIZE-1)) - 1):0] /*verilator public*/;
reg [(SIZE - 1):0] rd_addr;
wire [(WIDTH - 1):0] dat_o;
reg [(WIDTH - 1):0] ram [((2<< (SIZE-1)) - 1):0] /*verilator public*/;
reg [(SIZE - 1):0] rd_addr;
wire [(WIDTH - 1):0] dat_o;
 
//-----------------------------------------------------------------
// Processes
//-----------------------------------------------------------------
always @ (posedge clk_i)
begin
if (wr_i == 1'b1)
ram[adr_i] <= dat_i;
rd_addr <= adr_i;
if (wr_i == 1'b1)
ram[adr_i] <= dat_i;
rd_addr <= adr_i;
end
 
//-------------------------------------------------------------------
// Combinatorial
//-------------------------------------------------------------------
assign dat_o = ram[rd_addr];
assign dat_o = ram[rd_addr];
 
endmodule
/sim/mpx_top.v
43,56 → 43,56
//-----------------------------------------------------------------
module mpx_top
(
// Clocking & Reset
clk_i,
rst_i,
// Global Enable
en_i,
// Fault Output
fault_o,
// Interrupt Input
intr_i,
// Debug Register Access
dbg_reg_addr_i,
dbg_reg_out_o,
dbg_pc_o,
// UART output
uart_data_o,
uart_wr_o
// Clocking & Reset
clk_i,
rst_i,
// Global Enable
en_i,
// Fault Output
fault_o,
// Interrupt Input
intr_i,
// Debug Register Access
dbg_reg_addr_i,
dbg_reg_out_o,
dbg_pc_o,
// UART output
uart_data_o,
uart_wr_o
);
 
//-----------------------------------------------------------------
// Params
//-----------------------------------------------------------------
parameter CLK_KHZ = (8192*7);
parameter SRAM_ADDR_WIDTH = 19;
parameter CLK_KHZ = (8192*7);
parameter SRAM_ADDR_WIDTH = 19;
 
//-----------------------------------------------------------------
// I/O
//-----------------------------------------------------------------
input clk_i /*verilator public*/;
input rst_i /*verilator public*/;
input en_i /*verilator public*/;
output fault_o /*verilator public*/;
input intr_i /*verilator public*/;
input [8:0] dbg_reg_addr_i /*verilator public*/;
output [31:0] dbg_reg_out_o /*verilator public*/;
output [31:0] dbg_pc_o /*verilator public*/;
output [7:0] uart_data_o /*verilator public*/;
output uart_wr_o /*verilator public*/;
input clk_i /*verilator public*/;
input rst_i /*verilator public*/;
input en_i /*verilator public*/;
output fault_o /*verilator public*/;
input intr_i /*verilator public*/;
input [8:0] dbg_reg_addr_i /*verilator public*/;
output [31:0] dbg_reg_out_o /*verilator public*/;
output [31:0] dbg_pc_o /*verilator public*/;
output [7:0] uart_data_o /*verilator public*/;
output uart_wr_o /*verilator public*/;
 
//-----------------------------------------------------------------
// Registers / Wires
//-----------------------------------------------------------------
wire fault_o;
wire [31:0] dbg_reg_out_o;
wire [31:0] dbg_pc_o;
wire [7:0] uart_data_o;
wire uart_wr_o;
wire [31:0] int_mem_addr_o;
wire [31:0] int_mem_data_o;
wire [31:0] int_mem_data_i;
wire [3:0] int_mem_wr_o;
wire fault_o;
wire [31:0] dbg_reg_out_o;
wire [31:0] dbg_pc_o;
wire [7:0] uart_data_o;
wire uart_wr_o;
wire [31:0] int_mem_addr_o;
wire [31:0] int_mem_data_o;
wire [31:0] int_mem_data_i;
wire [3:0] int_mem_wr_o;
 
//-----------------------------------------------------------------
// Instantiation
100,62 → 100,62
 
sram4
#(
.SRAM_ADDR_WIDTH(SRAM_ADDR_WIDTH)
.SRAM_ADDR_WIDTH(SRAM_ADDR_WIDTH)
)
u1_bram
(
.clk_i(clk_i),
.address_i(int_mem_addr_o),
.data_i(int_mem_data_o),
.data_o(int_mem_data_i),
.wr_i(int_mem_wr_o)
.clk_i(clk_i),
.address_i(int_mem_addr_o),
.data_i(int_mem_data_o),
.data_o(int_mem_data_i),
.wr_i(int_mem_wr_o)
);
 
mpx_soc
#(
.CLK_KHZ(CLK_KHZ),
.UART_BAUD(115200),
.EXTERNAL_INTERRUPTS(1),
.CORE_ID(32'h00000000),
.BOOT_VECTOR(32'h10000000),
.ISR_VECTOR(32'h1000003C)
.CLK_KHZ(CLK_KHZ),
.UART_BAUD(115200),
.EXTERNAL_INTERRUPTS(1),
.CORE_ID(32'h00000000),
.BOOT_VECTOR(32'h10000000),
.ISR_VECTOR(32'h1000003C)
)
u1_cpu
(
// Clock / Status
.clk_i(clk_i),
.rst_i(rst_i),
.en_i(en_i),
.ext_intr_i(intr_i),
.fault_o(fault_o),
// UART
.uart_tx_o(/* open */),
.uart_rx_i(1'b0),
// Internal Memory
.int_mem_addr_o(int_mem_addr_o),
.int_mem_data_o(int_mem_data_o),
.int_mem_data_i(int_mem_data_i),
.int_mem_wr_o(int_mem_wr_o),
.int_mem_rd_o(/*open */),
// External I/O or Memory
.ext_io_addr_o(/*open */),
.ext_io_data_o(/*open */),
.ext_io_data_i(32'h00000000),
.ext_io_wr_o(/*open */),
.ext_io_rd_o(/*open */),
.ext_io_pause_i(1'b0),
// Debug Register Access
.dbg_reg_addr_i(dbg_reg_addr_i),
.dbg_reg_out_o(dbg_reg_out_o),
.dbg_pc_o(dbg_pc_o),
// Debug UART output
.dbg_uart_data_o(uart_data_o),
.dbg_uart_wr_o(uart_wr_o)
// Clock / Status
.clk_i(clk_i),
.rst_i(rst_i),
.en_i(en_i),
.ext_intr_i(intr_i),
.fault_o(fault_o),
// UART
.uart_tx_o(/* open */),
.uart_rx_i(1'b0),
// Internal Memory
.int_mem_addr_o(int_mem_addr_o),
.int_mem_data_o(int_mem_data_o),
.int_mem_data_i(int_mem_data_i),
.int_mem_wr_o(int_mem_wr_o),
.int_mem_rd_o(/*open */),
// External I/O or Memory
.ext_io_addr_o(/*open */),
.ext_io_data_o(/*open */),
.ext_io_data_i(32'h00000000),
.ext_io_wr_o(/*open */),
.ext_io_rd_o(/*open */),
.ext_io_pause_i(1'b0),
// Debug Register Access
.dbg_reg_addr_i(dbg_reg_addr_i),
.dbg_reg_out_o(dbg_reg_out_o),
.dbg_pc_o(dbg_pc_o),
// Debug UART output
.dbg_uart_data_o(uart_data_o),
.dbg_uart_wr_o(uart_wr_o)
);
endmodule
/sim/sram4.v
43,57 → 43,57
//-----------------------------------------------------------------
module sram4
(
clk_i,
address_i,
data_i,
data_o,
wr_i
clk_i,
address_i,
data_i,
data_o,
wr_i
);
 
//-----------------------------------------------------------------
// Params
//-----------------------------------------------------------------
parameter [31:0] SRAM_ADDR_WIDTH = 14;
parameter [31:0] SRAM_ADDR_WIDTH = 14;
//-----------------------------------------------------------------
// I/O
//-----------------------------------------------------------------
input clk_i /*verilator public*/;
input [31:0] address_i /*verilator public*/;
input [31:0] data_i /*verilator public*/;
output [31:0] data_o /*verilator public*/;
input [3:0] wr_i /*verilator public*/;
input clk_i /*verilator public*/;
input [31:0] address_i /*verilator public*/;
input [31:0] data_i /*verilator public*/;
output [31:0] data_o /*verilator public*/;
input [3:0] wr_i /*verilator public*/;
 
//-----------------------------------------------------------------
// Registers
//-----------------------------------------------------------------
wire [31:0] address;
wire [31:0] data_o;
wire [31:0] address;
wire [31:0] data_o;
 
//-----------------------------------------------------------------
// Implementation
//-----------------------------------------------------------------
assign {address} = {2'b00, address_i[31:2]};
assign address = {2'b00, address_i[31:2]};
 
generate
begin : sram_gen
genvar i;
for (i=0;i<4;i=i+1)
begin :sram_loop
sram
#(
.WIDTH(8),
.SIZE(SRAM_ADDR_WIDTH)
)
u1_bram
(
.clk_i(clk_i),
.dat_o(data_o[(((i + 1) * 8) - 1):(i * 8)]),
.dat_i(data_i[(((i + 1) * 8) - 1):(i * 8)]),
.adr_i(address[(SRAM_ADDR_WIDTH - 1):0]),
.wr_i(wr_i[i])
);
end
begin :sram_loop
sram
#(
.WIDTH(8),
.SIZE(SRAM_ADDR_WIDTH)
)
u1_bram
(
.clk_i(clk_i),
.dat_o(data_o[(((i + 1) * 8) - 1):(i * 8)]),
.dat_i(data_i[(((i + 1) * 8) - 1):(i * 8)]),
.adr_i(address[(SRAM_ADDR_WIDTH - 1):0]),
.wr_i(wr_i[i])
);
end
end
endgenerate
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.