URL
https://opencores.org/ocsvn/mpx/mpx/trunk
Subversion Repositories mpx
Compare Revisions
- This comparison shows the changes necessary to convert path
/mpx
- from Rev 2 to Rev 3
- ↔ Reverse comparison
Rev 2 → Rev 3
/trunk/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 |
/trunk/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 |
/trunk/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 |
/trunk/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) |
/trunk/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 |
/trunk/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 |
/trunk/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 |
/trunk/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 |
/trunk/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 |
|
/trunk/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 |
/trunk/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 |
/trunk/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 |
|