Compare commits

...

6 Commits

21 changed files with 781 additions and 212 deletions

8
OUTPUT/AND32_2x1_TB.out Executable file
View File

@ -0,0 +1,8 @@
// memory data file (do not edit the following line - required for mem load use)
// instance=/AND32_2x1_TB/result
// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress
00000000
00000000
00000000
ffff0000
0000ffff

View File

@ -0,0 +1,9 @@
// 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
// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress
00000000
00000000
00000000
00000000
00000000
00000000

View File

@ -0,0 +1,9 @@
// 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
// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress
00000000
00000000
00000000
00000000
00000000
00000000

8
OUTPUT/INV32_1x1_TB.out Executable file
View File

@ -0,0 +1,8 @@
// memory data file (do not edit the following line - required for mem load use)
// instance=/INV32_1x1_TB/result
// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress
0000ffff
ffffffff
5a5a5a5a
0000ffff
ffff0000

8
OUTPUT/NOR32_2x1_TB.out Executable file
View File

@ -0,0 +1,8 @@
// memory data file (do not edit the following line - required for mem load use)
// instance=/NOR32_2x1_TB/result
// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress
00000000
ffffffff
00000000
0000ffff
ffff0000

8
OUTPUT/OR32_2x1_TB.out Executable file
View File

@ -0,0 +1,8 @@
// memory data file (do not edit the following line - required for mem load use)
// instance=/OR32_2x1_TB/result
// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress
ffffffff
00000000
ffffffff
ffff0000
0000ffff

147
OUTPUT/alu_tb.out Normal file
View File

@ -0,0 +1,147 @@
// memory data file (do not edit the following line - required for mem load use)
// instance=/ALU_TB/result
// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress
00000014
00000001
00000000
00000001
00000064
00000001
00000000
00000001
00002800
00000001
0000000a
00000001
0000000a
00000001
fffffff5
00000000
00000000
00000001
00000000
00000001
ffffffe2
00000001
ffffff1f
00000000
0001ffff
00000000
fff88000
00000001
00000001
00000000
ffffffff
00000000
00000000
00000001
00000001
00000000
00000000
00000001
00000032
00000001
fffffd8f
00000000
00000000
00000001
00000000
00000001
00000001
00000000
ffffffff
00000000
00000000
00000001
00000000
00000001
ffffffc4
00000001
00000000
00000001
00000384
00000001
00000000
00000001
00000000
00000001
ffffffe2
00000001
ffffffe2
00000001
0000001d
00000000
00000000
00000001
00000000
00000001
00000000
00000001
00000000
00000001
00000000
00000001
00000000
00000001
00000000
00000001
00000000
00000001
ffffffff
00000000
00000000
00000001
0000001b
00000000
ffffffc7
00000000
fffffd8a
00000001
00000000
00000001
00000000
00000001
00000020
00000001
fffffffb
00000000
00000004
00000001
00000001
00000000
00000017
00000000
00000017
00000000
00000000
00000001
00000017
00000000
00000017
00000000
00000000
00000001
00000017
00000000
ffffffe8
00000001
00000000
00000001
00000046
00000001
ffffffba
00000001
00000000
00000001
00000000
00000001
00000000
00000001
00000000
00000001
00000046
00000001
ffffffb9
00000000
00000001
00000000

View File

@ -0,0 +1,129 @@
// memory data file (do not edit the following line - required for mem load use)
// instance=/BARREL_SHIFTER32_TB/result
// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress
4b4b4b4a
96969694
2d2d2d28
5a5a5a50
b4b4b4a0
69696940
d2d2d280
a5a5a500
4b4b4a00
96969400
2d2d2800
5a5a5000
b4b4a000
69694000
d2d28000
a5a50000
4b4a0000
96940000
2d280000
5a500000
b4a00000
69400000
d2800000
a5000000
4a000000
94000000
28000000
50000000
a0000000
40000000
80000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
52d2d2d2
29696969
14b4b4b4
0a5a5a5a
052d2d2d
02969696
014b4b4b
00a5a5a5
0052d2d2
00296969
0014b4b4
000a5a5a
00052d2d
00029696
00014b4b
0000a5a5
000052d2
00002969
000014b4
00000a5a
0000052d
00000296
0000014b
000000a5
00000052
00000029
00000014
0000000a
00000005
00000002
00000001
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
xxxxxxxx
xxxxxxxx

10
OUTPUT/d_ff_tb.out Normal file
View File

@ -0,0 +1,10 @@
// memory data file (do not edit the following line - required for mem load use)
// instance=/D_FF_TB/result
// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress
00000012
00000013
0000000b
00000017
0000000d
0000000f
00000017

11
OUTPUT/d_latch_tb.out Normal file
View File

@ -0,0 +1,11 @@
// memory data file (do not edit the following line - required for mem load use)
// instance=/D_LATCH_TB/result
// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress
00000022
00000023
00000027
00000011
00000013
00000017
0000002f
0000001b

10
OUTPUT/d_reg1_tb.out Normal file
View File

@ -0,0 +1,10 @@
// memory data file (do not edit the following line - required for mem load use)
// instance=/REG1_TB/result
// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress
00000022
00000023
0000000b
0000002f
0000001d
0000001f
00000023

11
OUTPUT/d_reg32_tb.out Normal file
View File

@ -0,0 +1,11 @@
// memory data file (do not edit the following line - required for mem load use)
// instance=/REG32_TB/result
// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress
00000000
00000000
a5a5a5a5
ffff0000
00000000
00000000
0000ffff
0000ffff

View File

@ -0,0 +1,35 @@
// memory data file (do not edit the following line - required for mem load use)
// instance=/DECODER_5x32_TB/result
// format=bin addressradix=h dataradix=b version=1.0 wordsperline=1 noaddress
00000000000000000000000000000001
00000000000000000000000000000010
00000000000000000000000000000100
00000000000000000000000000001000
00000000000000000000000000010000
00000000000000000000000000100000
00000000000000000000000001000000
00000000000000000000000010000000
00000000000000000000000100000000
00000000000000000000001000000000
00000000000000000000010000000000
00000000000000000000100000000000
00000000000000000001000000000000
00000000000000000010000000000000
00000000000000000100000000000000
00000000000000001000000000000000
00000000000000010000000000000000
00000000000000100000000000000000
00000000000001000000000000000000
00000000000010000000000000000000
00000000000100000000000000000000
00000000001000000000000000000000
00000000010000000000000000000000
00000000100000000000000000000000
00000001000000000000000000000000
00000010000000000000000000000000
00000100000000000000000000000000
00001000000000000000000000000000
00010000000000000000000000000000
00100000000000000000000000000000
01000000000000000000000000000000
10000000000000000000000000000000

19
OUTPUT/mux32_16x1_tb.out Normal file
View File

@ -0,0 +1,19 @@
// memory data file (do not edit the following line - required for mem load use)
// instance=/MUX32_16x1_TB/result
// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress
00000000
00000001
00000002
00000003
00000004
00000005
00000006
00000007
00000008
00000009
0000000a
0000000b
0000000c
0000000d
0000000e
0000000f

5
OUTPUT/mux32_2x1_tb.out Normal file
View File

@ -0,0 +1,5 @@
// memory data file (do not edit the following line - required for mem load use)
// instance=/MUX32_2x1_TB/result
// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress
a5a5a5a5
5a5a5a5a

35
OUTPUT/mux32_32x1_tb.out Normal file
View File

@ -0,0 +1,35 @@
// memory data file (do not edit the following line - required for mem load use)
// instance=/MUX32_32x1_TB/result
// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress
00000000
00000001
00000002
00000003
00000004
00000005
00000006
00000007
00000008
00000009
0000000a
0000000b
0000000c
0000000d
0000000e
0000000f
00000010
00000011
00000012
00000013
00000014
00000015
00000016
00000017
00000018
00000019
0000001a
0000001b
0000001c
0000001d
0000001e
0000001f

67
OUTPUT/rf_tb.out Normal file
View File

@ -0,0 +1,67 @@
// memory data file (do not edit the following line - required for mem load use)
// instance=/RF_TB/result
// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress
00000000
0000000a
00000014
0000001e
00000028
00000032
0000003c
00000046
00000050
0000005a
00000064
0000006e
00000078
00000082
0000008c
00000096
000000a0
000000aa
000000b4
000000be
000000c8
000000d2
000000dc
000000e6
000000f0
000000fa
00000104
0000010e
00000118
00000122
0000012c
00000136
00000014
00000014
00000014
00000014
00000014
00000014
00000014
00000014
00000014
00000014
00000014
00000014
00000014
00000014
xxxxxxxx
xxxxxxxx
xxxxxxxx
xxxxxxxx
xxxxxxxx
xxxxxxxx
xxxxxxxx
xxxxxxxx
xxxxxxxx
xxxxxxxx
xxxxxxxx
xxxxxxxx
xxxxxxxx
xxxxxxxx
xxxxxxxx
xxxxxxxx
xxxxxxxx
xxxxxxxx

17
OUTPUT/sr_latch_tb.out Normal file
View File

@ -0,0 +1,17 @@
// memory data file (do not edit the following line - required for mem load use)
// instance=/SR_LATCH_TB/result
// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress
00000042
00000043
00000047
0000004b
0000004f
00000021
00000023
00000027
0000002b
0000002f
0000005b
00000053
00000037
00000033

View File

@ -18,6 +18,84 @@
// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation
//------------------------------------------------------------------------------------------
`include "prj_definition.v"
// Control signals, same as in data_path.v
`define pc_load 0
`define pc_sel_1 1
`define pc_sel_2 2
`define pc_sel_3 3
`define ir_load 4
`define r1_sel_1 5
`define reg_r 6
`define reg_w 7
`define sp_load 8
`define op1_sel_1 9
`define op2_sel_1 10
`define op2_sel_2 11
`define op2_sel_3 12
`define op2_sel_4 13
`define alu_oprn 19:14
`define ma_sel_1 20
`define ma_sel_2 21
`define md_sel_1 22
`define wd_sel_1 23
`define wd_sel_2 24
`define wd_sel_3 25
`define wa_sel_1 26
`define wa_sel_2 27
`define wa_sel_3 28
// ALU operation codes
`define ALU_NOP 6'h00
`define ALU_ADD 6'h01
`define ALU_SUB 6'h02
`define ALU_MUL 6'h03
`define ALU_SRL 6'h04
`define ALU_SLL 6'h05
`define ALU_AND 6'h06
`define ALU_OR 6'h07
`define ALU_NOR 6'h08
`define ALU_SLT 6'h09
// Instruction opcodes
// R-type
`define OP_RTYPE 6'h00
`define FN_ADD 6'h20
`define FN_SUB 6'h22
`define FN_MUL 6'h2c
`define FN_AND 6'h24
`define FN_OR 6'h25
`define FN_NOR 6'h27
`define FN_SLT 6'h2a
`define FN_SLL 6'h01
`define FN_SRL 6'h02
`define FN_JR 6'h08
// I-type
`define OP_ADDI 6'h08
`define OP_MULI 6'h1d
`define OP_ANDI 6'h0c
`define OP_ORI 6'h0d
`define OP_LUI 6'h0f
`define OP_SLTI 6'h0a
`define OP_BEQ 6'h04
`define OP_BNE 6'h05
`define OP_LW 6'h23
`define OP_SW 6'h2b
// J-type
`define OP_JMP 6'h02
`define OP_JAL 6'h03
`define OP_PUSH 6'h1b
`define OP_POP 6'h1c
module CONTROL_UNIT(CTRL, READ, WRITE, ZERO, INSTRUCTION, CLK, RST);
// Output signals
output [`CTRL_WIDTH_INDEX_LIMIT:0] CTRL;
@ -50,39 +128,38 @@ $write("@ %6dns -> [0X%08h] ", $time, inst);
case(opcode2)
// R-Type
6'h00 : begin
case(funct2)
6'h20: $write("add r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
6'h22: $write("sub r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
6'h2c: $write("mul r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
6'h24: $write("and r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
6'h25: $write("or r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
6'h27: $write("nor r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
6'h2a: $write("slt r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
6'h01: $write("sll r[%02d], r[%02d], %2d;", rd2, rs2, shamt2);
6'h02: $write("srl r[%02d], 0X%02h, r[%02d];", rd2, rs2, shamt2);
6'h08: $write("jr r[%02d];", rs2);
default: begin $write("");
end
endcase
end
// I-type
6'h08 : $write("addi r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
6'h1d : $write("muli r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
6'h0c : $write("andi r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
6'h0d : $write("ori r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
6'h0f : $write("lui r[%02d], 0X%04h;", rt2, immediate2);
6'h0a : $write("slti r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
6'h04 : $write("beq r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
6'h05 : $write("bne r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
6'h23 : $write("lw r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
6'h2b : $write("sw r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
// J-Type
6'h02 : $write("jmp 0X%07h;", address2);
6'h03 : $write("jal 0X%07h;", address2);
6'h1b : $write("push;");
6'h1c : $write("pop;");
default: $write("");
6'h00 : begin
case(funct2)
6'h20: $write("add r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
6'h22: $write("sub r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
6'h2c: $write("mul r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
6'h24: $write("and r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
6'h25: $write("or r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
6'h27: $write("nor r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
6'h2a: $write("slt r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
6'h01: $write("sll r[%02d], r[%02d], %2d;", rd2, rs2, shamt2);
6'h02: $write("srl r[%02d], 0X%02h, r[%02d];", rd2, rs2, shamt2);
6'h08: $write("jr r[%02d];", rs2);
default: $write("");
endcase
end
// I-type
6'h08 : $write("addi r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
6'h1d : $write("muli r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
6'h0c : $write("andi r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
6'h0d : $write("ori r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
6'h0f : $write("lui r[%02d], 0X%04h;", rt2, immediate2);
6'h0a : $write("slti r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
6'h04 : $write("beq r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
6'h05 : $write("bne r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
6'h23 : $write("lw r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
6'h2b : $write("sw r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
// J-Type
6'h02 : $write("jmp 0X%07h;", address2);
6'h03 : $write("jal 0X%07h;", address2);
6'h1b : $write("push;");
6'h1c : $write("pop;");
default: $write("");
endcase
$write("\n");
@ -92,79 +169,22 @@ endtask
reg read, write;
assign READ = read;
assign WRITE = write;
buf (READ, read);
buf (WRITE, write);
// Control signals, same as in data_path.v
reg pc_load, pc_sel_1, pc_sel_2, pc_sel_3,
ir_load, reg_r, reg_w,
r1_sel_1, wa_sel_1, wa_sel_2, wa_sel_3,
reg [31:0] C;
sp_load, op1_sel_1,
op2_sel_1, op2_sel_2, op2_sel_3, op2_sel_4,
buf ctrl_buf [31:0] (CTRL, C);
wd_sel_1, wd_sel_2, wd_sel_3,
ma_sel_1, ma_sel_2,
md_sel_1;
reg [5:0] alu_oprn;
buf (CTRL[0], pc_load);
buf (CTRL[1], pc_sel_1);
buf (CTRL[2], pc_sel_2);
buf (CTRL[3], pc_sel_3);
buf (CTRL[4], ir_load);
buf (CTRL[5], reg_r);
buf (CTRL[6], reg_w);
buf (CTRL[7], r1_sel_1);
buf (CTRL[8], wa_sel_1);
buf (CTRL[9], wa_sel_2);
buf (CTRL[10], wa_sel_3);
buf (CTRL[11], sp_load);
buf (CTRL[12], op1_sel_1);
buf (CTRL[13], op2_sel_1);
buf (CTRL[14], op2_sel_2);
buf (CTRL[15], op2_sel_3);
buf (CTRL[16], op2_sel_4);
buf (CTRL[17], wd_sel_1);
buf (CTRL[18], wd_sel_2);
buf (CTRL[19], wd_sel_3);
buf (CTRL[20], ma_sel_1);
buf (CTRL[21], ma_sel_2);
buf (CTRL[22], md_sel_1);
buf alu_oprn_buf [5:0] (CTRL[28:23], alu_oprn);
// Parse the instruction data, same as in data_path.v
wire [5:0] opcode;
wire [4:0] rs;
wire [4:0] rt;
wire [4:0] rd;
wire [4:0] shamt;
wire [5:0] funct;
wire [15:0] imm;
wire [25:0] addr;
// common for all
buf opcode_buf [5:0] (opcode, INSTRUCTION[31:26]);
// common for R-type, I-type
buf rs_buf [4:0] (rs, INSTRUCTION[25:21]);
buf rt_buf [4:0] (rt, INSTRUCTION[20:16]);
// for R-type
buf rd_buf [4:0] (rd, INSTRUCTION[15:11]);
buf shamt_buf [4:0] (shamt, INSTRUCTION[10:6]);
buf funct_buf [5:0] (funct, INSTRUCTION[5:0]);
// for I-type
buf imm_buf [15:0] (imm, INSTRUCTION[15:0]);
// for J-type
buf addr_buf [25:0] (addr, INSTRUCTION[25:0]);
// Parse the instruction data
reg [5:0] opcode;
reg [4:0] rs;
reg [4:0] rt;
reg [4:0] rd;
reg [4:0] shamt;
reg [5:0] funct;
reg [15:0] imm;
reg [25:0] addr;
// State machine
wire [2:0] state;
@ -172,124 +192,129 @@ PROC_SM proc_sm(state, CLK, RST);
// TBD - take action on each +ve edge of clock
always @ (state) begin
// R-type
{opcode, rs, rt, rd, shamt, funct} = INSTRUCTION;
// I-type
{opcode, rs, rt, imm} = INSTRUCTION;
// J-type
{opcode, addr} = INSTRUCTION;
// Print current state
$write("@ %6dns -> ", $time);
$write("STATE ", state, ": ");
case (state)
`PROC_FETCH: $write("FETCH");
`PROC_DECODE: $write("DECODE");
`PROC_EXE: $write("EXECUTE");
`PROC_MEM: $write("MEMORY");
`PROC_WB: $write("WRITE BACK");
default: $write("INVALID");
endcase
// $write("@ %6dns -> ", $time);
// $write("STATE ", state, ": ");
// case (state)
// `PROC_FETCH: $write("FETCH");
// `PROC_DECODE: $write("DECODE");
// `PROC_EXE: $write("EXECUTE");
// `PROC_MEM: $write("MEMORY");
// `PROC_WB: $write("WRITE BACK");
// default: $write("INVALID");
// endcase
// $write("\n");
case (state)
// fetch - next instruction from memory at PC
`PROC_FETCH: begin
// loaded in previous state, set to 0
pc_load = 1'b0;
reg_r = 1'b0;
reg_w = 1'b0;
// load now
ir_load = 1'b1;
// set everything in ctrl to 0
C = 32'b0;
// memory
read = 1'b1;
write = 1'b0;
// selections
// ma_sel_2 - load data from mem[PC]
ma_sel_2 = 1'b1;
C[`ma_sel_2] = 1'b1; // load data from mem[PC]
end
// decode - parse instruction and read values from register file
`PROC_DECODE: begin
// loaded in previous state, set to 0
ir_load = 1'b0;
sp_load = 1'b0;
read = 1'b0;
// load now
reg_r = 1'b1;
reg_w = 1'b0;
C[`ir_load] = 1'b1;
C[`reg_r] = 1'b1;
end
// execute - perform operation based on instruction
`PROC_EXE: begin
print_instruction(INSTRUCTION);
// loaded in previous state, set to 0
C[`ir_load] = 1'b0;
// selections
// r1_sel_1: push - store value of r0 at stack pointer
r1_sel_1 = opcode != 6'h1b ? 1'b0 : 1'b1;
C[`r1_sel_1] = opcode != 6'h1b ? 1'b0 : 1'b1;
// wa_sel_1: R-type - write to rd, I-type - write to rt
wa_sel_1 = opcode == 6'h00 ? 1'b0 : 1'b1;
C[`wa_sel_1] = opcode == 6'h00 ? 1'b0 : 1'b1;
// wa_sel_2: jal - write to r31, pop - write to r0
wa_sel_2 = opcode == 6'h03 ? 1'b1 : 1'b0;
C[`wa_sel_2] = opcode == 6'h03 ? 1'b1 : 1'b0;
// wa_sel_3: push or pop - wa_sel_2, else wa_sel_1
wa_sel_3 = opcode == 6'h03 || opcode == 6'h1c ? 1'b0 : 1'b1;
C[`wa_sel_3] = opcode == 6'h03 || opcode == 6'h1c ? 1'b0 : 1'b1;
// jr - jump to address in register
pc_sel_1 = opcode == 6'h00 && funct == 6'h08 ? 1'b0 : 1'b1;
C[`pc_sel_1] = opcode == 6'h00 && funct == 6'h08 ? 1'b0 : 1'b1;
// beq, bne - branch if equal or not equal
// TODO: this should only be selected if the condition is met
// pc_sel_2 = opcode == 6'h04 || opcode == 6'h05 ? 1'b1 : 1'b0;
// jmp, jal - jump to address
pc_sel_3 = opcode == 6'h02 || opcode == 6'h03 ? 1'b0 : 1'b1;
C[`pc_sel_3] = opcode == `OP_JMP || opcode == `OP_JAL ? 1'b0 : 1'b1;
// alu_oprn - operation to be performed by ALU
// R-type
if (opcode == 6'h00) begin
if (opcode == `OP_RTYPE) begin
case (funct)
6'h20: alu_oprn = 6'h01; // add
6'h22: alu_oprn = 6'h02; // sub
6'h2c: alu_oprn = 6'h03; // mul
6'h02: alu_oprn = 6'h04; // srl
6'h01: alu_oprn = 6'h05; // sll
6'h24: alu_oprn = 6'h06; // and
6'h25: alu_oprn = 6'h07; // or
6'h27: alu_oprn = 6'h08; // nor
6'h2a: alu_oprn = 6'h09; // slt
default: alu_oprn = 6'hxx;
`FN_ADD: C[`alu_oprn] = `ALU_ADD;
`FN_SUB: C[`alu_oprn] = `ALU_SUB;
`FN_MUL: C[`alu_oprn] = `ALU_MUL;
`FN_SRL: C[`alu_oprn] = `ALU_SRL;
`FN_SLL: C[`alu_oprn] = `ALU_SLL;
`FN_AND: C[`alu_oprn] = `ALU_AND;
`FN_OR: C[`alu_oprn] = `ALU_OR;
`FN_NOR: C[`alu_oprn] = `ALU_NOR;
`FN_SLT: C[`alu_oprn] = `ALU_SLT;
default: C[`alu_oprn] = `ALU_NOP;
endcase
end
// I-type and J-type
else begin
case (opcode)
// I-type
6'h08: alu_oprn = 6'h01; // addi
6'h1d: alu_oprn = 6'h03; // muli
6'h0c: alu_oprn = 6'h06; // andi
6'h0d: alu_oprn = 6'h07; // ori
6'h0a: alu_oprn = 6'h09; // slti
6'h04: alu_oprn = 6'h02; // beq - sub
6'h05: alu_oprn = 6'h02; // bne - sub
6'h23: alu_oprn = 6'h01; // lw - add
6'h2b: alu_oprn = 6'h01; // sw - add
`OP_ADDI: C[`alu_oprn] = `ALU_ADD; // addi
`OP_MULI: C[`alu_oprn] = `ALU_MUL; // muli
`OP_ANDI: C[`alu_oprn] = `ALU_AND; // andi
`OP_ORI: C[`alu_oprn] = `ALU_OR; // ori
`OP_SLTI: C[`alu_oprn] = `ALU_SLT; // slti
`OP_BEQ: C[`alu_oprn] = `ALU_SUB; // beq - sub
`OP_BNE: C[`alu_oprn] = `ALU_SUB; // bne - sub
`OP_LW: C[`alu_oprn] = `ALU_ADD; // lw - add
`OP_SW: C[`alu_oprn] = `ALU_ADD; // sw - add
// J-type
6'h1b: alu_oprn = 6'h02; // push - sub
6'h1c: alu_oprn = 6'h01; // pop - add
default: alu_oprn = 6'hxx;
`OP_PUSH: C[`alu_oprn] = `ALU_SUB; // push - sub
`OP_POP: C[`alu_oprn] = `ALU_ADD; // pop - add
default: C[`alu_oprn] = `ALU_NOP;
endcase
end
// op1_sel_1 - select r1 or sp based on opcode
// push or pop - sp, else r1
op1_sel_1 = opcode == 6'h1b || opcode == 6'h1c ? 1'b1 : 1'b0;
C[`op1_sel_1] = opcode == 6'h1b || opcode == 6'h1c ? 1'b1 : 1'b0;
// op2_sel_1 - select 1 or shamt based on alu_oprn
// sll or srl - shamt, else 1 (for increments/decrements)
op2_sel_1 = alu_oprn == 6'h04 || alu_oprn == 6'h05 ? 1'b1 : 1'b0;
C[`op2_sel_1] = C[`alu_oprn] == 6'h04 || C[`alu_oprn] == 6'h05 ? 1'b1 : 1'b0;
// op2_sel_2 - select imm_zx or imm_sx based on alu_oprn
// logical (and, or) - imm_zx, else imm_sx; ('nor' not availble in I-type)
op2_sel_2 = alu_oprn == 6'h06 || alu_oprn == 6'h07 ? 1'b0 : 1'b1;
C[`op2_sel_2] = C[`alu_oprn] == 6'h06 || C[`alu_oprn] == 6'h07 ? 1'b0 : 1'b1;
// op2_sel_3 - select op2_sel_2 or op2_sel_1 based on alu_oprn
// R-type - op2_sel_1, I-type - op2_sel_2
op2_sel_3 = opcode == 6'h00 ? 1'b1 : 1'b0;
C[`op2_sel_3] = opcode == 6'h00 ? 1'b1 : 1'b0;
// op2_sel_4 - select op2_sel_3 or r2
// I-type or shift or inc/dec - op2_sel_3, else r2
// i.e. r2 only if R-type and not shift
op2_sel_4 = opcode != 6'h00 || alu_oprn == 6'h04 || alu_oprn == 6'h05 ? 1'b0 : 1'b1;
end
// execute - perform operation based on instruction
`PROC_EXE: begin
// selections
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 = 1'b0;
C[`wd_sel_1] = 1'b0;
// wd_sel_2 - wd_sel_1 or imm_zx_lsb
// lui - imm_zx_lsb, else wd_sel_1
wd_sel_2 = opcode == 6'h0f ? 1'b1 : 1'b0;
C[`wd_sel_2] = opcode == 6'h0f ? 1'b1 : 1'b0;
// wd_sel_3 - pc_inc or wd_sel_2
// jal - pc_inc, else wd_sel_2
wd_sel_3 = opcode == 6'h03 ? 1'b0 : 1'b1;
C[`wd_sel_3] = opcode == 6'h03 ? 1'b0 : 1'b1;
// md_sel_1 - r1 for push, r2 for sw
md_sel_1 = opcode == 6'h1b ? 1'b1 : 1'b0;
C[`md_sel_1] = opcode == 6'h1b ? 1'b1 : 1'b0;
end
`PROC_MEM: begin
// load now
@ -299,8 +324,8 @@ always @ (state) begin
write = 1'b1;
end
else begin
read = 1'b1;
write = 1'b0;
// read = 1'b1;
// write = 1'b0;
end
end
`PROC_WB: begin
@ -308,34 +333,21 @@ always @ (state) begin
read = 1'b0;
write = 1'b0;
// load now
pc_load = 1'b1;
C[`pc_load] = 1'b1;
// write to register file if
// R-type (except jr) or I-type (except beq, bne, sw) or pop or jal
reg_w = (opcode == 6'h00 && funct != 6'h08) // R-type (except jr)
C[`reg_w] = (opcode == 6'h00 && funct != 6'h08) // R-type (except jr)
|| (opcode == 6'h08 || opcode == 6'h1d || opcode == 6'h0c || opcode == 6'h0d
|| opcode == 6'h0f || opcode == 6'h0a || opcode == 6'h23) // I-type (except beq, bne, sw)
|| (opcode == 6'h1c || opcode == 6'h03) // pop or jal
? 1'b1 : 1'b0;
// selections
// ma_sel_2 - load data from mem[PC]
ma_sel_2 = 1'b1;
// pc_sel_2 - branch if equal or not equal
pc_sel_2 = (opcode == 6'h04 && ZERO) || (opcode == 6'h05 && ~ZERO) ? 1'b1 : 1'b0;
C[`pc_sel_2] = (opcode == 6'h04 && ZERO) || (opcode == 6'h05 && ~ZERO) ? 1'b1 : 1'b0;
end
default: begin
$write("@ %6dns -> ", $time);
$write("STATE ", state, ": ");
$write("INVALID");
print_instruction(INSTRUCTION);
end
endcase
// TBD - assign control signals based on instruction
print_instruction(INSTRUCTION);
// TBD - assign READ and WRITE signals based on instruction
end
endmodule
@ -383,5 +395,4 @@ always @ (posedge CLK) begin
end
assign STATE = state_sel;
endmodule

View File

@ -48,32 +48,33 @@ buf (pc_sel_2, CTRL[2]);
buf (pc_sel_3, CTRL[3]);
buf (ir_load, CTRL[4]);
buf (reg_r, CTRL[5]);
buf (reg_w, CTRL[6]);
buf (r1_sel_1, CTRL[7]);
buf (wa_sel_1, CTRL[8]);
buf (wa_sel_2, CTRL[9]);
buf (wa_sel_3, CTRL[10]);
buf (r1_sel_1, CTRL[5]);
buf (reg_r, CTRL[6]);
buf (reg_w, CTRL[7]);
buf (sp_load, CTRL[11]);
buf (op1_sel_1, CTRL[12]);
buf (sp_load, CTRL[8]);
buf (op2_sel_1, CTRL[13]);
buf (op2_sel_2, CTRL[14]);
buf (op2_sel_3, CTRL[15]);
buf (op2_sel_4, CTRL[16]);
buf (op1_sel_1, CTRL[9]);
buf (op2_sel_1, CTRL[10]);
buf (op2_sel_2, CTRL[11]);
buf (op2_sel_3, CTRL[12]);
buf (op2_sel_4, CTRL[13]);
buf (wd_sel_1, CTRL[17]);
buf (wd_sel_2, CTRL[18]);
buf (wd_sel_3, CTRL[19]);
buf alu_oprn_buf [5:0] (alu_oprn, CTRL[19:14]);
buf (ma_sel_1, CTRL[20]);
buf (ma_sel_2, CTRL[21]);
buf (md_sel_1, CTRL[22]);
buf alu_oprn_buf [5:0] (alu_oprn, CTRL[28:23]);
buf (wd_sel_1, CTRL[23]);
buf (wd_sel_2, CTRL[24]);
buf (wd_sel_3, CTRL[25]);
buf (wa_sel_1, CTRL[26]);
buf (wa_sel_2, CTRL[27]);
buf (wa_sel_3, CTRL[28]);
// variables
wire [31:0] ir; // Instruction Register
@ -112,7 +113,7 @@ buf addr_buf [25:0] (addr, ir[25:0]);
// Instruction Register input
// Instruction Register
REG32 ir_inst(.Q(ir), .D(DATA_IN), .LOAD(ir_load), .CLK(CLK), .RESET(RST));
D_LATCH32 ir_inst(.Q(ir), .D(DATA_IN), .LOAD(ir_load), .RESET(RST));
// Register File Input
wire [31:0] r1_sel, wa_sel, wd_sel;
@ -148,11 +149,11 @@ ALU alu_inst(.OUT(alu_out), .ZERO(ZERO), .OP1(op1_sel), .OP2(op2_sel), .OPRN(alu
// Progam Counter Input
wire [31:0] pc_sel;
wire [31:0] pc_offset, 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));
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_offset), .CO(), .A(pc), .B(imm_sx), .SnA(1'b0));
MUX32_2x1 mux_pc_sel_p2(pc_sel_p2, pc_sel_p1, pc_offset, pc_sel_2);
RC_ADD_SUB_32 pc_sel_2_inst(.Y(pc_branch), .CO(), .A(pc), .B(imm_sx), .SnA(1'b0));
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});
MUX32_2x1 mux_pc_sel(pc_sel, pc_jump, pc_sel_p2, pc_sel_3);
// Program Counter

23
logic.v
View File

@ -13,6 +13,23 @@
// 1.0 Sep 02, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation
//------------------------------------------------------------------------------------------
//
// 32-bit D latch
module D_LATCH32(Q, D, LOAD, RESET);
output [31:0] Q;
input LOAD;
input [31:0] D;
input RESET;
genvar i;
generate
for (i = 0; i < 32; i = i + 1) begin : d_latch_gen
D_LATCH d_latch_inst(Q[i], _, D[i], LOAD, 1'b1, RESET);
end
endgenerate
endmodule
// 64-bit two's complement
module TWOSCOMP64(Y,A);
//output list
@ -56,7 +73,6 @@ generate
REG1 reg_inst(.Q(Q[i]), .Qbar(qbar[i]), .D(D[i]), .L(LOAD), .C(CLK), .nP(RESET), .nR(1'b1));
end
endgenerate
endmodule
// 32-bit registere +ve edge, Reset on RESET=0
@ -73,7 +89,6 @@ generate
REG1 r(Q[i], _, D[i], LOAD, CLK, 1'b1, RESET);
end
endgenerate
endmodule
// 1 bit register +ve edge,
@ -164,7 +179,6 @@ generate
and msb1(D[i + 16], I[4], half[i]);
end
endgenerate
endmodule
// 4x16 Line decoder
@ -187,8 +201,6 @@ generate
and msb1(D[i + 8], I[3], half[i]);
end
endgenerate
endmodule
// 3x8 Line decoder
@ -211,7 +223,6 @@ generate
and msb1(D[i + 4], I[2], half[i]);
end
endgenerate
endmodule
// 2x4 Line decoder