control unit: passing SP15 and SP17
This commit is contained in:
parent
b651f04748
commit
507fa2e863
@ -10,4 +10,4 @@
|
|||||||
00000000
|
00000000
|
||||||
00000000
|
00000000
|
||||||
00000000
|
00000000
|
||||||
00000000
|
00000020
|
||||||
|
@ -6,4 +6,4 @@
|
|||||||
00000004
|
00000004
|
||||||
00000010
|
00000010
|
||||||
00000010
|
00000010
|
||||||
00000040
|
00000000
|
||||||
|
@ -6,4 +6,4 @@
|
|||||||
00000000
|
00000000
|
||||||
00000000
|
00000000
|
||||||
00000000
|
00000000
|
||||||
00000200
|
00000020
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
// memory data file (do not edit the following line - required for mem load use)
|
// memory data file (do not edit the following line - required for mem load use)
|
||||||
// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m
|
// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m
|
||||||
// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress
|
// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress
|
||||||
00090001
|
00000015
|
||||||
00090003
|
00000017
|
||||||
00090005
|
00000019
|
||||||
00090007
|
0000001b
|
||||||
00090009
|
0000001d
|
||||||
0009000b
|
0000001f
|
||||||
0009000d
|
00000021
|
||||||
0009000f
|
00000023
|
||||||
00090011
|
00000025
|
||||||
00090013
|
00000025
|
||||||
00090015
|
00000000
|
||||||
|
183
control_unit.v
183
control_unit.v
@ -107,56 +107,56 @@ input [`DATA_INDEX_LIMIT:0] INSTRUCTION;
|
|||||||
|
|
||||||
task print_instruction;
|
task print_instruction;
|
||||||
input [`DATA_INDEX_LIMIT:0] inst;
|
input [`DATA_INDEX_LIMIT:0] inst;
|
||||||
reg [5:0] opcode2;
|
reg [5:0] opcode;
|
||||||
reg [4:0] rs2;
|
reg [4:0] rs;
|
||||||
reg [4:0] rt2;
|
reg [4:0] rt;
|
||||||
reg [4:0] rd2;
|
reg [4:0] rd;
|
||||||
reg [4:0] shamt2;
|
reg [4:0] shamt;
|
||||||
reg [5:0] funct2;
|
reg [5:0] funct;
|
||||||
reg [15:0] immediate2;
|
reg [15:0] imm;
|
||||||
reg [25:0] address2;
|
reg [25:0] addr;
|
||||||
begin
|
begin
|
||||||
// parse the instruction
|
// parse the instruction
|
||||||
// R-type
|
// R-type
|
||||||
{opcode2, rs2, rt2, rd2, shamt2, funct2} = inst;
|
{opcode, rs, rt, rd, shamt, funct} = inst;
|
||||||
// I-type
|
// I-type
|
||||||
{opcode2, rs2, rt2, immediate2 } = inst;
|
{opcode, rs, rt, imm} = inst;
|
||||||
// J-type
|
// J-type
|
||||||
{opcode2, address2} = inst;
|
{opcode, addr} = inst;
|
||||||
|
|
||||||
$write("@ %6dns -> [0X%08h] ", $time, inst);
|
$write("@ %6dns -> [0X%08h] ", $time, inst);
|
||||||
|
|
||||||
case(opcode2)
|
case(opcode)
|
||||||
// R-Type
|
// R-Type
|
||||||
6'h00 : begin
|
6'h00 : begin
|
||||||
case(funct2)
|
case(funct)
|
||||||
6'h20: $write("add r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
|
6'h20: $write("add r[%02d], r[%02d], r[%02d];", rd, rs, rt);
|
||||||
6'h22: $write("sub r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
|
6'h22: $write("sub r[%02d], r[%02d], r[%02d];", rd, rs, rt);
|
||||||
6'h2c: $write("mul r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
|
6'h2c: $write("mul r[%02d], r[%02d], r[%02d];", rd, rs, rt);
|
||||||
6'h24: $write("and r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
|
6'h24: $write("and r[%02d], r[%02d], r[%02d];", rd, rs, rt);
|
||||||
6'h25: $write("or r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
|
6'h25: $write("or r[%02d], r[%02d], r[%02d];", rd, rs, rt);
|
||||||
6'h27: $write("nor r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
|
6'h27: $write("nor r[%02d], r[%02d], r[%02d];", rd, rs, rt);
|
||||||
6'h2a: $write("slt r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
|
6'h2a: $write("slt r[%02d], r[%02d], r[%02d];", rd, rs, rt);
|
||||||
6'h01: $write("sll r[%02d], r[%02d], %2d;", rd2, rs2, shamt2);
|
6'h01: $write("sll r[%02d], r[%02d], %2d;", rd, rs, shamt);
|
||||||
6'h02: $write("srl r[%02d], 0X%02h, r[%02d];", rd2, rs2, shamt2);
|
6'h02: $write("srl r[%02d], 0X%02h, r[%02d];", rd, rs, shamt);
|
||||||
6'h08: $write("jr r[%02d];", rs2);
|
6'h08: $write("jr r[%02d];", rs);
|
||||||
default: $write("");
|
default: $write("");
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
// I-type
|
// I-type
|
||||||
6'h08 : $write("addi r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
|
6'h08 : $write("addi r[%02d], r[%02d], 0X%04h;", rt, rs, imm);
|
||||||
6'h1d : $write("muli r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
|
6'h1d : $write("muli r[%02d], r[%02d], 0X%04h;", rt, rs, imm);
|
||||||
6'h0c : $write("andi r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
|
6'h0c : $write("andi r[%02d], r[%02d], 0X%04h;", rt, rs, imm);
|
||||||
6'h0d : $write("ori r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
|
6'h0d : $write("ori r[%02d], r[%02d], 0X%04h;", rt, rs, imm);
|
||||||
6'h0f : $write("lui r[%02d], 0X%04h;", rt2, immediate2);
|
6'h0f : $write("lui r[%02d], 0X%04h;", rt, imm);
|
||||||
6'h0a : $write("slti r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
|
6'h0a : $write("slti r[%02d], r[%02d], 0X%04h;", rt, rs, imm);
|
||||||
6'h04 : $write("beq r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
|
6'h04 : $write("beq r[%02d], r[%02d], 0X%04h;", rt, rs, imm);
|
||||||
6'h05 : $write("bne r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
|
6'h05 : $write("bne r[%02d], r[%02d], 0X%04h;", rt, rs, imm);
|
||||||
6'h23 : $write("lw r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
|
6'h23 : $write("lw r[%02d], r[%02d], 0X%04h;", rt, rs, imm);
|
||||||
6'h2b : $write("sw r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
|
6'h2b : $write("sw r[%02d], r[%02d], 0X%04h;", rt, rs, imm);
|
||||||
// J-Type
|
// J-Type
|
||||||
6'h02 : $write("jmp 0X%07h;", address2);
|
6'h02 : $write("jmp 0X%07h;", addr);
|
||||||
6'h03 : $write("jal 0X%07h;", address2);
|
6'h03 : $write("jal 0X%07h;", addr);
|
||||||
6'h1b : $write("push;");
|
6'h1b : $write("push;");
|
||||||
6'h1c : $write("pop;");
|
6'h1c : $write("pop;");
|
||||||
default: $write("");
|
default: $write("");
|
||||||
@ -228,6 +228,7 @@ always @ (state) begin
|
|||||||
// decode - parse instruction and read values from register file
|
// decode - parse instruction and read values from register file
|
||||||
`PROC_DECODE: begin
|
`PROC_DECODE: begin
|
||||||
// loaded in previous state, set to 0
|
// loaded in previous state, set to 0
|
||||||
|
C[`ma_sel_2] = 1'b0;
|
||||||
read = 1'b0;
|
read = 1'b0;
|
||||||
// load now
|
// load now
|
||||||
C[`ir_load] = 1'b1;
|
C[`ir_load] = 1'b1;
|
||||||
@ -239,21 +240,22 @@ always @ (state) begin
|
|||||||
// loaded in previous state, set to 0
|
// loaded in previous state, set to 0
|
||||||
C[`ir_load] = 1'b0;
|
C[`ir_load] = 1'b0;
|
||||||
// selections
|
// selections
|
||||||
// r1_sel_1: push - store value of r0 at stack pointer
|
// r1_sel_1: rs by default (0), push - r1 (1)
|
||||||
C[`r1_sel_1] = opcode != 6'h1b ? 1'b0 : 1'b1;
|
C[`r1_sel_1] = opcode == `OP_PUSH;
|
||||||
// wa_sel_1: R-type - write to rd, I-type - write to rt
|
// wa_sel_1: R-type - write to rd (0), I-type - write to rt (1)
|
||||||
C[`wa_sel_1] = opcode == 6'h00 ? 1'b0 : 1'b1;
|
C[`wa_sel_1] = opcode != `OP_RTYPE;
|
||||||
// wa_sel_2: jal - write to r31, pop - write to r0
|
// wa_sel_2: jal - write to r31 (0), pop - write to r0 (1)
|
||||||
C[`wa_sel_2] = opcode == 6'h03 ? 1'b1 : 1'b0;
|
C[`wa_sel_2] = opcode == `OP_POP;
|
||||||
// wa_sel_3: push or pop - wa_sel_2, else wa_sel_1
|
// wa_sel_3: push or pop - wa_sel_2, else wa_sel_1
|
||||||
C[`wa_sel_3] = opcode == 6'h03 || opcode == 6'h1c ? 1'b0 : 1'b1;
|
// wa_sel_3: wa_sel_2 if push or pop (0), else wa_sel_1 (1)
|
||||||
// jr - jump to address in register
|
C[`wa_sel_3] = ~(opcode == `OP_PUSH || opcode == `OP_POP);
|
||||||
C[`pc_sel_1] = opcode == 6'h00 && funct == 6'h08 ? 1'b0 : 1'b1;
|
// pc_sel_1: jr - jump to address in rs (0), else pc_inc (1)
|
||||||
// beq, bne - branch if equal or not equal
|
C[`pc_sel_1] = ~(opcode == `OP_JMP && funct == `FN_JR);
|
||||||
|
// pc_sel_2: pc_sel_1 by default (0), beq, bne - branch if equal or not equal (1)
|
||||||
// TODO: this should only be selected if the condition is met
|
// TODO: this should only be selected if the condition is met
|
||||||
// pc_sel_2 = opcode == 6'h04 || opcode == 6'h05 ? 1'b1 : 1'b0;
|
// pc_sel_2 = opcode == `OP_BEQ || opcode == `OP_BNE;
|
||||||
// jmp, jal - jump to address
|
// pc_sel_3: jmp or jal - jump to address (0), else pc_sel_2 (1)
|
||||||
C[`pc_sel_3] = opcode == `OP_JMP || opcode == `OP_JAL ? 1'b0 : 1'b1;
|
C[`pc_sel_3] = ~(opcode == `OP_JMP || opcode == `OP_JAL);
|
||||||
|
|
||||||
// alu_oprn - operation to be performed by ALU
|
// alu_oprn - operation to be performed by ALU
|
||||||
// R-type
|
// R-type
|
||||||
@ -290,50 +292,40 @@ always @ (state) begin
|
|||||||
default: C[`alu_oprn] = `ALU_NOP;
|
default: C[`alu_oprn] = `ALU_NOP;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
// op1_sel_1 - select r1 or sp based on opcode
|
// op1_sel_1: r1 by default (0), push or pop - sp (1)
|
||||||
// push or pop - sp, else r1
|
C[`op1_sel_1] = opcode == `OP_PUSH || opcode == `OP_POP;
|
||||||
C[`op1_sel_1] = opcode == 6'h1b || opcode == 6'h1c ? 1'b1 : 1'b0;
|
// op2_sel_1: const 1 (for inc/dec) (0), shamnt for sll/srl (1)
|
||||||
// op2_sel_1 - select 1 or shamt based on alu_oprn
|
C[`op2_sel_1] = opcode == `OP_RTYPE && (funct == `FN_SLL || funct == `FN_SRL);
|
||||||
// sll or srl - shamt, else 1 (for increments/decrements)
|
// op2_sel_2: imm_zx for logical and/or (0), imm_sx otherise (1)
|
||||||
C[`op2_sel_1] = C[`alu_oprn] == 6'h04 || C[`alu_oprn] == 6'h05 ? 1'b1 : 1'b0;
|
// ('nor' not availble in I-type)
|
||||||
// op2_sel_2 - select imm_zx or imm_sx based on alu_oprn
|
C[`op2_sel_2] = ~(opcode == `OP_ANDI || opcode == `OP_ORI);
|
||||||
// logical (and, or) - imm_zx, else imm_sx; ('nor' not availble in I-type)
|
// op2_sel_3: op2_sel_2 for I-type (0), op2_sel_1 for R-type shift (1)
|
||||||
C[`op2_sel_2] = C[`alu_oprn] == 6'h06 || C[`alu_oprn] == 6'h07 ? 1'b0 : 1'b1;
|
C[`op2_sel_3] = opcode == `OP_RTYPE;
|
||||||
// op2_sel_3 - select op2_sel_2 or op2_sel_1 based on alu_oprn
|
// op2_sel_4: op2_sel_3 for I-type (except beq, bne) or R-type shift or inc/dec (0), else r2 (1)
|
||||||
// R-type - op2_sel_1, I-type - op2_sel_2
|
// i.e. r2 if R-type (except sll/srl), or bne/beq
|
||||||
C[`op2_sel_3] = opcode == 6'h00 ? 1'b1 : 1'b0;
|
C[`op2_sel_4] = opcode == `OP_RTYPE && ~(funct == `FN_SLL || funct == `FN_SRL)
|
||||||
// op2_sel_4 - select op2_sel_3 or r2
|
|| opcode == `OP_BEQ || opcode == `OP_BNE;
|
||||||
// I-type or shift or inc/dec - op2_sel_3, else r2
|
|
||||||
// i.e. r2 only if R-type and not shift
|
|
||||||
C[`op2_sel_4] = opcode != 6'h00 || C[`alu_oprn] == 6'h04 || C[`alu_oprn] == 6'h05 ? 1'b0 : 1'b1;
|
|
||||||
|
|
||||||
// wd_sel_1 - alu_out or DATA_IN
|
// wd_sel_1: alu_out or DATA_IN
|
||||||
C[`wd_sel_1] = 1'b0;
|
// wd_sel_1: alu_out by default (0), DATA_IN for lw or pop (1)
|
||||||
// wd_sel_2 - wd_sel_1 or imm_zx_lsb
|
C[`wd_sel_1] = opcode == `OP_LW || opcode == `OP_POP;
|
||||||
// lui - imm_zx_lsb, else wd_sel_1
|
// wd_sel_2: wd_sel_1 by default (0), imm_zx_lsb for lui (1)
|
||||||
C[`wd_sel_2] = opcode == 6'h0f ? 1'b1 : 1'b0;
|
C[`wd_sel_2] = opcode == `OP_LUI;
|
||||||
// wd_sel_3 - pc_inc or wd_sel_2
|
// wd_sel_3: pc_inc for jal (0), else wd_sel_2 (1)
|
||||||
// jal - pc_inc, else wd_sel_2
|
C[`wd_sel_3] = ~(opcode == `OP_JAL);
|
||||||
C[`wd_sel_3] = opcode == 6'h03 ? 1'b0 : 1'b1;
|
// ma_sel_1: alu_out for lw or sw, sp for push or pop
|
||||||
// ma_sel_1 - alu_out for lw or sw, sp for push or pop
|
// ma_sel_1: alu_out for lw or sw (0), sp for push or pop (1)
|
||||||
C[`ma_sel_1] = opcode == `OP_LW || opcode == `OP_SW ? 1'b0 : 1'b1;
|
C[`ma_sel_1] = opcode == `OP_PUSH || opcode == `OP_POP;
|
||||||
// ma_sel_2 - 1 for pc, 0 for everything else
|
// ma_sel_2: 0 for every memory access instruction (lw, sw, push, pop), 1 for fetch
|
||||||
C[`ma_sel_2] = opcode == `OP_LW || opcode == `OP_SW || opcode == `OP_PUSH || opcode == `OP_POP ? 1'b0 : 1'b1;
|
C[`ma_sel_2] = 1'b0;
|
||||||
// md_sel_1 - r1 for push, r2 for sw
|
// md_sel_1: r2 for sw (0), r1 for push (1)
|
||||||
C[`md_sel_1] = opcode == 6'h1b ? 1'b1 : 1'b0;
|
C[`md_sel_1] = opcode == `OP_PUSH;
|
||||||
end
|
end
|
||||||
`PROC_MEM: begin
|
`PROC_MEM: begin
|
||||||
// load now
|
|
||||||
// push or sw - write to memory
|
// push or sw - write to memory
|
||||||
if (opcode == `OP_PUSH || opcode == `OP_SW) begin
|
write = opcode == `OP_PUSH || opcode == `OP_SW;
|
||||||
|
// pop or lw - read from memory
|
||||||
read = 1'b0;
|
read = opcode == `OP_POP || opcode == `OP_LW;
|
||||||
write = 1'b1;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
// read = 1'b1;
|
|
||||||
// write = 1'b0;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
`PROC_WB: begin
|
`PROC_WB: begin
|
||||||
// loaded in previous state, set to 0
|
// loaded in previous state, set to 0
|
||||||
@ -343,15 +335,14 @@ always @ (state) begin
|
|||||||
C[`pc_load] = 1'b1;
|
C[`pc_load] = 1'b1;
|
||||||
// write to register file if
|
// write to register file if
|
||||||
// R-type (except jr) or I-type (except beq, bne, sw) or pop or jal
|
// R-type (except jr) or I-type (except beq, bne, sw) or pop or jal
|
||||||
C[`reg_w] = (opcode == 6'h00 && funct != 6'h08) // R-type (except jr)
|
C[`reg_w] = (opcode == `OP_RTYPE && funct != `FN_JR) // R-type (except jr)
|
||||||
|| (opcode == 6'h08 || opcode == 6'h1d || opcode == 6'h0c || opcode == 6'h0d
|
|| (opcode == `OP_ADDI || opcode == `OP_MULI || opcode == `OP_ANDI || opcode == `OP_ORI
|
||||||
|| opcode == 6'h0f || opcode == 6'h0a || opcode == 6'h23) // I-type (except beq, bne, sw)
|
|| opcode == `OP_LUI || opcode == `OP_SLTI || opcode == `OP_LW) // I-type (except beq, bne, sw)
|
||||||
|| (opcode == 6'h1c || opcode == 6'h03) // pop or jal
|
|| (opcode == `OP_POP || opcode == `OP_JAL) // pop or jal
|
||||||
? 1'b1 : 1'b0;
|
;
|
||||||
// selections
|
// selections
|
||||||
// pc_sel_2 - branch if equal or not equal
|
// pc_sel_2: branch if equal or not equal
|
||||||
C[`pc_sel_2] = (opcode == 6'h04 && ZERO) || (opcode == 6'h05 && ~ZERO) ? 1'b1 : 1'b0;
|
C[`pc_sel_2] = ((opcode == `OP_BEQ) && ZERO) || ((opcode == `OP_BNE) && ~ZERO);
|
||||||
|
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
@ -152,7 +152,7 @@ wire [31:0] pc_sel;
|
|||||||
wire [31:0] pc_branch, pc_jump, pc_sel_p1, pc_sel_p2;
|
wire [31:0] pc_branch, pc_jump, pc_sel_p1, pc_sel_p2;
|
||||||
RC_ADD_SUB_32 pc_inc_inst(.Y(pc_inc), .CO(), .A(pc), .B(32'b1), .SnA(1'b0));
|
RC_ADD_SUB_32 pc_inc_inst(.Y(pc_inc), .CO(), .A(pc), .B(32'b1), .SnA(1'b0));
|
||||||
MUX32_2x1 mux_pc_sel_p1(pc_sel_p1, r1, pc_inc, pc_sel_1);
|
MUX32_2x1 mux_pc_sel_p1(pc_sel_p1, r1, pc_inc, pc_sel_1);
|
||||||
RC_ADD_SUB_32 pc_sel_2_inst(.Y(pc_branch), .CO(), .A(pc), .B(imm_sx), .SnA(1'b0));
|
RC_ADD_SUB_32 pc_sel_2_inst(.Y(pc_branch), .CO(), .A(pc_inc), .B(imm_sx), .SnA(1'b0));
|
||||||
MUX32_2x1 mux_pc_sel_p2(pc_sel_p2, pc_sel_p1, pc_branch, pc_sel_2);
|
MUX32_2x1 mux_pc_sel_p2(pc_sel_p2, pc_sel_p1, pc_branch, pc_sel_2);
|
||||||
buf pc_jump_buf [31:0] (pc_jump, {6'b0, addr});
|
buf pc_jump_buf [31:0] (pc_jump, {6'b0, addr});
|
||||||
MUX32_2x1 mux_pc_sel(pc_sel, pc_jump, pc_sel_p2, pc_sel_3);
|
MUX32_2x1 mux_pc_sel(pc_sel, pc_jump, pc_sel_p2, pc_sel_3);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user