Compare commits
7 Commits
05c950a0f8
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
a7870b87eb
|
|||
|
0361dcc161
|
|||
|
ceba9d6fd5
|
|||
|
0198e8be41
|
|||
|
507fa2e863
|
|||
|
b651f04748
|
|||
|
2ffd8c9424
|
@@ -1,13 +1,13 @@
|
|||||||
// 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
|
||||||
00000000
|
00000020
|
||||||
00000000
|
00000020
|
||||||
00000000
|
00000010
|
||||||
00000000
|
00000010
|
||||||
00000000
|
00000009
|
||||||
00000000
|
00000008
|
||||||
00000000
|
00000008
|
||||||
00000000
|
00000005
|
||||||
00000000
|
00000004
|
||||||
00000000
|
00000002
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
// 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
|
||||||
00000000
|
00000001
|
||||||
00000000
|
00000004
|
||||||
00000000
|
00000004
|
||||||
00000000
|
00000010
|
||||||
00000000
|
00000010
|
||||||
00000000
|
00000000
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
// 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
|
||||||
00000000
|
00000000
|
||||||
00000000
|
00000020
|
||||||
00000000
|
00000008
|
||||||
00000000
|
00000008
|
||||||
00000000
|
00000002
|
||||||
00000000
|
00000002
|
||||||
|
|||||||
@@ -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
|
||||||
0000000a
|
00000015
|
||||||
0000000b
|
00000017
|
||||||
0000000c
|
00000019
|
||||||
0000000d
|
0000001b
|
||||||
0000000e
|
0000001d
|
||||||
0000000f
|
0000001f
|
||||||
00000010
|
00000021
|
||||||
00000011
|
00000023
|
||||||
00000012
|
00000025
|
||||||
00000013
|
00000025
|
||||||
00000000
|
00000000
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
// 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
|
||||||
|
ffffffc9
|
||||||
|
00000022
|
||||||
|
ffffffeb
|
||||||
|
0000000d
|
||||||
|
fffffff8
|
||||||
|
00000005
|
||||||
|
fffffffd
|
||||||
|
00000002
|
||||||
|
ffffffff
|
||||||
|
00000001
|
||||||
00000000
|
00000000
|
||||||
00000000
|
00000001
|
||||||
00000000
|
00000001
|
||||||
00000000
|
00000002
|
||||||
00000000
|
00000003
|
||||||
00000000
|
00000005
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
|
|||||||
21
OUTPUT/all_test_mem_dump_01.dat
Normal file
21
OUTPUT/all_test_mem_dump_01.dat
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
// 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
|
||||||
|
00001337
|
||||||
|
000039a5
|
||||||
|
00002024
|
||||||
|
0000335b
|
||||||
|
fffff313
|
||||||
|
00000ced
|
||||||
|
026993bc
|
||||||
|
00000024
|
||||||
|
00003337
|
||||||
|
ffffccc8
|
||||||
|
00000001
|
||||||
|
00000000
|
||||||
|
00013370
|
||||||
|
00000133
|
||||||
|
000039a5
|
||||||
|
00000005
|
||||||
|
00000005
|
||||||
|
fffff313
|
||||||
9
OUTPUT/all_test_mem_dump_02.dat
Normal file
9
OUTPUT/all_test_mem_dump_02.dat
Normal 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
|
||||||
|
00001337
|
||||||
@@ -2,18 +2,18 @@
|
|||||||
// 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
|
||||||
00000000
|
00000000
|
||||||
00000000
|
00000001
|
||||||
00000000
|
00000001
|
||||||
00000000
|
00000002
|
||||||
00000000
|
00000003
|
||||||
00000000
|
00000005
|
||||||
00000000
|
00000008
|
||||||
00000000
|
0000000d
|
||||||
00000000
|
00000015
|
||||||
00000000
|
00000022
|
||||||
00000000
|
00000037
|
||||||
00000000
|
00000059
|
||||||
00000000
|
00000090
|
||||||
00000000
|
000000e9
|
||||||
00000000
|
00000179
|
||||||
00000000
|
00000262
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ wire [`DATA_INDEX_LIMIT:0] MEM_DATA_OUT, MEM_DATA_IN;
|
|||||||
|
|
||||||
// reset
|
// reset
|
||||||
reg RST;
|
reg RST;
|
||||||
integer t1=1, t2=1, t3=1, t4=1, t5=1;
|
integer t1=1, t2=1, t3=1, t4=1, t5=1, t6=1;
|
||||||
|
//integer t1=0, t2=0, t3=0, t4=0, t5=0, t6=1;
|
||||||
|
|
||||||
// Clock generator instance
|
// Clock generator instance
|
||||||
CLK_GENERATOR clk_gen_inst(.CLK(CLK));
|
CLK_GENERATOR clk_gen_inst(.CLK(CLK));
|
||||||
@@ -62,7 +63,7 @@ begin
|
|||||||
#5000 $write("\n");
|
#5000 $write("\n");
|
||||||
$write("===> Done simulating fibonacci.dat\n", "");
|
$write("===> Done simulating fibonacci.dat\n", "");
|
||||||
$write("\n");
|
$write("\n");
|
||||||
$writememh("./OUTPUT/fibonacci_mem_dump.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h01000000, 'h0100000f);
|
$writememh("./OUTPUT/fibonacci_mem_dump.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h00040000, 'h0004000f);
|
||||||
/* END : test 1*/
|
/* END : test 1*/
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -78,7 +79,7 @@ begin
|
|||||||
#5000 $write("\n");
|
#5000 $write("\n");
|
||||||
$write("===> Done simulating RevFib.dat\n", "");
|
$write("===> Done simulating RevFib.dat\n", "");
|
||||||
$write("\n");
|
$write("\n");
|
||||||
$writememh("./OUTPUT/RevFib_mem_dump.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h03fffff0, 'h03ffffff);
|
$writememh("./OUTPUT/RevFib_mem_dump.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, `INIT_STACK_POINTER - 'h0f, `INIT_STACK_POINTER);
|
||||||
/* END : test 2*/
|
/* END : test 2*/
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -94,7 +95,7 @@ begin
|
|||||||
#5000 $write("\n");
|
#5000 $write("\n");
|
||||||
$write("===> Done simulating CS147_SP17_HW01_02.dat\n", "");
|
$write("===> Done simulating CS147_SP17_HW01_02.dat\n", "");
|
||||||
$write("\n");
|
$write("\n");
|
||||||
$writememh("./OUTPUT/CS147_SP17_HW01_02_mem_dump.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h01008000, 'h0100800A);
|
$writememh("./OUTPUT/CS147_SP17_HW01_02_mem_dump.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h00048000, 'h0004800A);
|
||||||
/* END : test 3*/
|
/* END : test 3*/
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -110,7 +111,7 @@ begin
|
|||||||
#6000 $write("\n");
|
#6000 $write("\n");
|
||||||
$write("===> Done simulating CS147_FL15_HW01_02.dat\n", "");
|
$write("===> Done simulating CS147_FL15_HW01_02.dat\n", "");
|
||||||
$write("\n");
|
$write("\n");
|
||||||
$writememh("./OUTPUT/CS147_FL15_HW01_02_mem_dump.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h03fffff6, 'h03ffffff);
|
$writememh("./OUTPUT/CS147_FL15_HW01_02_mem_dump.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, `INIT_STACK_POINTER - 9, `INIT_STACK_POINTER);
|
||||||
/* END : test 4*/
|
/* END : test 4*/
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -126,9 +127,26 @@ begin
|
|||||||
#5000 $write("\n");
|
#5000 $write("\n");
|
||||||
$write("===> Done simulating CS147_SP15_HW01_02.dat\n", "");
|
$write("===> Done simulating CS147_SP15_HW01_02.dat\n", "");
|
||||||
$write("\n");
|
$write("\n");
|
||||||
$writememh("./OUTPUT/CS147_SP15_HW01_02_mem_dump_01.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h01008000, 'h01008005);
|
$writememh("./OUTPUT/CS147_SP15_HW01_02_mem_dump_01.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h00048000, 'h00048005);
|
||||||
$writememh("./OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h03fffffA, 'h03ffffff);
|
$writememh("./OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, `INIT_STACK_POINTER - 5, `INIT_STACK_POINTER);
|
||||||
/* END : test 5*/
|
/* END : test 5*/
|
||||||
|
end
|
||||||
|
|
||||||
|
if (t6 === 1)
|
||||||
|
begin
|
||||||
|
/* START : test 6*/
|
||||||
|
#5 RST=1'b0;
|
||||||
|
#5 RST=1'b1;
|
||||||
|
$write("\n");
|
||||||
|
$write("===> Simulating all_test.dat\n", "");
|
||||||
|
$write("\n");
|
||||||
|
$readmemh("./TESTPROGRAM/all_test.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m);
|
||||||
|
#5000 $write("\n");
|
||||||
|
$write("===> Done simulating all_test.dat\n", "");
|
||||||
|
$write("\n");
|
||||||
|
$writememh("./OUTPUT/all_test_mem_dump_01.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h00048000, 'h00048011);
|
||||||
|
$writememh("./OUTPUT/all_test_mem_dump_02.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, `INIT_STACK_POINTER - 5, `INIT_STACK_POINTER);
|
||||||
|
/* END : test 6*/
|
||||||
end
|
end
|
||||||
$stop;
|
$stop;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// ------ Program Part ----
|
// ------ Program Part ----
|
||||||
@0001000
|
@0001000
|
||||||
2021000A // addi r1, r1, 0xA;
|
2021000A // addi r1, r1, 0xA;
|
||||||
20421008 // addi r2, r2, 0x1008;
|
20420048 // addi r2, r2, 0x0048;
|
||||||
00401301 // sll r2, r2, 0xC;
|
00401301 // sll r2, r2, 0xC;
|
||||||
00411820 // add r3, r2, r1;
|
00411820 // add r3, r2, r1;
|
||||||
3C848000 // lui r4, r4, 0x8000;
|
3C848000 // lui r4, r4, 0x8000;
|
||||||
@@ -21,25 +21,25 @@
|
|||||||
|
|
||||||
|
|
||||||
// ------ Data Part ----
|
// ------ Data Part ----
|
||||||
@01008000
|
@00048000
|
||||||
005 // 01008000
|
005 // 0004 8000
|
||||||
008 // 01008001
|
008 // 0004 8001
|
||||||
009 // 01008002
|
009 // 0004 8002
|
||||||
010 // 01008003
|
010 // 0004 8003
|
||||||
020 // 01008004
|
020 // 0004 8004
|
||||||
029 // 01008005
|
029 // 0004 8005
|
||||||
02D // 01008006
|
02D // 0004 8006
|
||||||
02F // 01008007
|
02F // 0004 8007
|
||||||
032 // 01008008
|
032 // 0004 8008
|
||||||
037 // 01008009
|
037 // 0004 8009
|
||||||
002 // 0100800A
|
002 // 0004 800A
|
||||||
004 // 0100800B
|
004 // 0004 800B
|
||||||
008 // 0100800C
|
008 // 0004 800C
|
||||||
010 // 0100800D
|
010 // 0004 800D
|
||||||
020 // 0100800E
|
020 // 0004 800E
|
||||||
040 // 0100800F
|
040 // 0004 800F
|
||||||
080 // 01008010
|
080 // 0004 8010
|
||||||
100 // 01008011
|
100 // 0004 8011
|
||||||
200 // 01008012
|
200 // 0004 8012
|
||||||
400 // 01008013
|
400 // 0004 8013
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
20000001 // addi r0, r0, 0x1;
|
20000001 // addi r0, r0, 0x1;
|
||||||
20210002 // addi r1, r1, 0x2;
|
20210002 // addi r1, r1, 0x2;
|
||||||
20420000 // addi r2, r2, 0x0;
|
20420000 // addi r2, r2, 0x0;
|
||||||
3C630100 // lui r3, 0x100;
|
3C630004 // lui r3, 0x0004;
|
||||||
34638000 // ori r3, r3, 0x8000;
|
34638000 // ori r3, r3, 0x8000;
|
||||||
20840005 // addi r4, r4, 0x5;
|
20840005 // addi r4, r4, 0x5;
|
||||||
00010020 // LOOP: add r0, r0, r1;
|
00010020 // LOOP: add r0, r0, r1;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// ------ Program Part ----
|
// ------ Program Part ----
|
||||||
@0001000
|
@0001000
|
||||||
20001008 // addi r0, r0, 0x1008
|
20000048 // addi r0, r0, 0x0048
|
||||||
00000301 // sll r0, r0, 0xC
|
00000301 // sll r0, r0, 0xC
|
||||||
20420009 // addi r2, r2, 0x9
|
20420009 // addi r2, r2, 0x9
|
||||||
10410007 // LOOP: beq r1, r2, END
|
10410007 // LOOP: beq r1, r2, END
|
||||||
@@ -14,15 +14,15 @@ AC050000 // sw r5, r0, 0x0
|
|||||||
AC050000 // END: sw r5, r0, 0x0
|
AC050000 // END: sw r5, r0, 0x0
|
||||||
|
|
||||||
// ------ Data Part ----
|
// ------ Data Part ----
|
||||||
@01008000
|
@00048000
|
||||||
0A // 0100 8000
|
0A // 0004 8000
|
||||||
0B // 0100 8001
|
0B // 0004 8001
|
||||||
0C // 0100 8002
|
0C // 0004 8002
|
||||||
0D // 0100 8003
|
0D // 0004 8003
|
||||||
0E // 0100 8004
|
0E // 0004 8004
|
||||||
0F // 0100 8005
|
0F // 0004 8005
|
||||||
10 // 0100 8006
|
10 // 0004 8006
|
||||||
11 // 0100 8007
|
11 // 0004 8007
|
||||||
12 // 0100 8008
|
12 // 0004 8008
|
||||||
13 // 0100 8008
|
13 // 0004 8008
|
||||||
|
|
||||||
|
|||||||
49
TESTPROGRAM/all_test.dat
Normal file
49
TESTPROGRAM/all_test.dat
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
@0001000
|
||||||
|
20001337 // addi r0, r0, 0x1337
|
||||||
|
6c000000 // push
|
||||||
|
3c1e0004 // lui r30, 0x0004
|
||||||
|
37de8000 // ori r30, r30 0x00008000
|
||||||
|
afc00000 // sw r0, r30, 0x0
|
||||||
|
0c001014 // jal 0x00001014
|
||||||
|
70000000 // pop
|
||||||
|
20212024 // addi r1, r1, 0x2024
|
||||||
|
00011020 // add r2, r0, r1
|
||||||
|
00011822 // sub r3, r0, r1
|
||||||
|
00202022 // sub r4, r1, r0
|
||||||
|
0001282c // mul r5, r0, r1
|
||||||
|
00013024 // and r6, r0, r1
|
||||||
|
00013825 // or r7, r0, r1
|
||||||
|
00014027 // nor r8, r0, r1
|
||||||
|
0001482a // slt r9, r0, r1
|
||||||
|
0020502a // slt r10, r1, r0
|
||||||
|
00005901 // sll r11, r0, 4
|
||||||
|
00006102 // srl r12, r0, 4
|
||||||
|
08001017 // jmp 0x00001017
|
||||||
|
74000003 // muli r0, r0, 3
|
||||||
|
afc00001 // sw r0, r30, 0x1
|
||||||
|
03e00008 // jr r31
|
||||||
|
8fcd0001 // lw r13, r30, 0x1
|
||||||
|
29ae1338 // slti r14, r13, 0x1338
|
||||||
|
302f0000 // andi r15, r1, 0x0
|
||||||
|
21ef0005 // addi r15, r15, 0x5
|
||||||
|
11ee0002 // beq r14, r15, 0x2
|
||||||
|
21ce0001 // addi r14, r14, 0x1
|
||||||
|
0800101b // jmp 0x0000101b
|
||||||
|
afc10002 // sw r1, r30, 0x2
|
||||||
|
afc20003 // sw r2, r30, 0x3
|
||||||
|
afc30004 // sw r3, r30, 0x4
|
||||||
|
afc40005 // sw r4, r30, 0x5
|
||||||
|
afc50006 // sw r5, r30, 0x6
|
||||||
|
afc60007 // sw r6, r30, 0x7
|
||||||
|
afc70008 // sw r7, r30, 0x8
|
||||||
|
afc80009 // sw r8, r30, 0x9
|
||||||
|
afc9000a // sw r9, r30, 0x0a
|
||||||
|
afca000b // sw r10, r30, 0x0b
|
||||||
|
afcb000c // sw r11, r30, 0x0c
|
||||||
|
afcc000d // sw r12, r30, 0x0d
|
||||||
|
afcd000e // sw r13, r30, 0x0e
|
||||||
|
afce000f // sw r14, r30, 0x0f
|
||||||
|
afcf0010 // sw r15, r30, 0x10
|
||||||
|
2210fbb1 // addi r16, r16, 0xfbb1
|
||||||
|
1470fffe // bne r16, r3, 0xfffe
|
||||||
|
afd00011 // sw r16, r30, 0x11
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
@0001000
|
@0001000
|
||||||
20420001 // addi r2, r2, 0x0001;
|
20420001 // addi r2, r2, 0x0001;
|
||||||
3C000100 // lui r0, 0x0100;
|
3C000004 // lui r0, 0x0004;
|
||||||
AC010000 // sw r1, r0, 0x0000;
|
AC010000 // sw r1, r0, 0x0000;
|
||||||
20000001 // loop: addi r0, r0, 0x0001;
|
20000001 // loop: addi r0, r0, 0x0001;
|
||||||
AC020000 // sw r2, r0, 0x0000;
|
AC020000 // sw r2, r0, 0x0000;
|
||||||
|
|||||||
236
control_unit.v
236
control_unit.v
@@ -19,7 +19,7 @@
|
|||||||
//------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------
|
||||||
`include "prj_definition.v"
|
`include "prj_definition.v"
|
||||||
|
|
||||||
// Control signals, same as in data_path.v
|
// Control signals, referenced in data_path.v
|
||||||
`define pc_load 0
|
`define pc_load 0
|
||||||
`define pc_sel_1 1
|
`define pc_sel_1 1
|
||||||
`define pc_sel_2 2
|
`define pc_sel_2 2
|
||||||
@@ -105,68 +105,65 @@ output READ, WRITE;
|
|||||||
input ZERO, CLK, RST;
|
input ZERO, CLK, RST;
|
||||||
input [`DATA_INDEX_LIMIT:0] INSTRUCTION;
|
input [`DATA_INDEX_LIMIT:0] INSTRUCTION;
|
||||||
|
|
||||||
|
// Task to print 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
|
`OP_RTYPE: case(funct)
|
||||||
case(funct2)
|
`FN_ADD: $write("add r[%02d], r[%02d], r[%02d];", rd, rs, rt);
|
||||||
6'h20: $write("add r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
|
`FN_SUB: $write("sub r[%02d], r[%02d], r[%02d];", rd, rs, rt);
|
||||||
6'h22: $write("sub r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
|
`FN_MUL: $write("mul r[%02d], r[%02d], r[%02d];", rd, rs, rt);
|
||||||
6'h2c: $write("mul r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
|
`FN_AND: $write("and r[%02d], r[%02d], r[%02d];", rd, rs, rt);
|
||||||
6'h24: $write("and r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
|
`FN_OR: $write("or r[%02d], r[%02d], r[%02d];", rd, rs, rt);
|
||||||
6'h25: $write("or r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
|
`FN_NOR: $write("nor r[%02d], r[%02d], r[%02d];", rd, rs, rt);
|
||||||
6'h27: $write("nor r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
|
`FN_SLT: $write("slt r[%02d], r[%02d], r[%02d];", rd, rs, rt);
|
||||||
6'h2a: $write("slt r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2);
|
`FN_SLL: $write("sll r[%02d], r[%02d], %2d;", rd, rs, shamt);
|
||||||
6'h01: $write("sll r[%02d], r[%02d], %2d;", rd2, rs2, shamt2);
|
`FN_SRL: $write("srl r[%02d], 0X%02h, r[%02d];", rd, rs, shamt);
|
||||||
6'h02: $write("srl r[%02d], 0X%02h, r[%02d];", rd2, rs2, shamt2);
|
`FN_JR: $write("jr r[%02d];", rs);
|
||||||
6'h08: $write("jr r[%02d];", rs2);
|
|
||||||
default: $write("");
|
default: $write("");
|
||||||
endcase
|
endcase
|
||||||
end
|
|
||||||
// I-type
|
// I-type
|
||||||
6'h08 : $write("addi r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
|
`OP_ADDI: $write("addi r[%02d], r[%02d], 0X%04h;", rt, rs, imm);
|
||||||
6'h1d : $write("muli r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
|
`OP_MULI: $write("muli r[%02d], r[%02d], 0X%04h;", rt, rs, imm);
|
||||||
6'h0c : $write("andi r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
|
`OP_ANDI: $write("andi r[%02d], r[%02d], 0X%04h;", rt, rs, imm);
|
||||||
6'h0d : $write("ori r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
|
`OP_ORI: $write("ori r[%02d], r[%02d], 0X%04h;", rt, rs, imm);
|
||||||
6'h0f : $write("lui r[%02d], 0X%04h;", rt2, immediate2);
|
`OP_LUI: $write("lui r[%02d], 0X%04h;", rt, imm);
|
||||||
6'h0a : $write("slti r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
|
`OP_SLTI: $write("slti r[%02d], r[%02d], 0X%04h;", rt, rs, imm);
|
||||||
6'h04 : $write("beq r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
|
`OP_BEQ: $write("beq r[%02d], r[%02d], 0X%04h;", rt, rs, imm);
|
||||||
6'h05 : $write("bne r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
|
`OP_BNE: $write("bne r[%02d], r[%02d], 0X%04h;", rt, rs, imm);
|
||||||
6'h23 : $write("lw r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
|
`OP_LW: $write("lw r[%02d], r[%02d], 0X%04h;", rt, rs, imm);
|
||||||
6'h2b : $write("sw r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2);
|
`OP_SW: $write("sw r[%02d], r[%02d], 0X%04h;", rt, rs, imm);
|
||||||
// J-Type
|
// J-Type
|
||||||
6'h02 : $write("jmp 0X%07h;", address2);
|
`OP_JMP: $write("jmp 0X%07h;", addr);
|
||||||
6'h03 : $write("jal 0X%07h;", address2);
|
`OP_JAL: $write("jal 0X%07h;", addr);
|
||||||
6'h1b : $write("push;");
|
`OP_PUSH: $write("push;");
|
||||||
6'h1c : $write("pop;");
|
`OP_POP: $write("pop;");
|
||||||
default: $write("");
|
default: $write("");
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
$write("\n");
|
$write("\n");
|
||||||
end
|
end
|
||||||
endtask
|
endtask
|
||||||
//------------------------------------- END ---------------------------------------//
|
|
||||||
|
|
||||||
|
|
||||||
reg read, write;
|
reg read, write;
|
||||||
buf (READ, read);
|
buf (READ, read);
|
||||||
@@ -190,7 +187,7 @@ reg [25:0] addr;
|
|||||||
wire [2:0] state;
|
wire [2:0] state;
|
||||||
PROC_SM proc_sm(state, CLK, RST);
|
PROC_SM proc_sm(state, CLK, RST);
|
||||||
|
|
||||||
// TBD - take action on each +ve edge of clock
|
// take action on each +ve edge of clock
|
||||||
always @ (state) begin
|
always @ (state) begin
|
||||||
// R-type
|
// R-type
|
||||||
{opcode, rs, rt, rd, shamt, funct} = INSTRUCTION;
|
{opcode, rs, rt, rd, shamt, funct} = INSTRUCTION;
|
||||||
@@ -199,19 +196,6 @@ always @ (state) begin
|
|||||||
// J-type
|
// J-type
|
||||||
{opcode, addr} = INSTRUCTION;
|
{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("\n");
|
|
||||||
|
|
||||||
case (state)
|
case (state)
|
||||||
// fetch - next instruction from memory at PC
|
// fetch - next instruction from memory at PC
|
||||||
`PROC_FETCH: begin
|
`PROC_FETCH: begin
|
||||||
@@ -220,12 +204,13 @@ always @ (state) begin
|
|||||||
// memory
|
// memory
|
||||||
read = 1'b1;
|
read = 1'b1;
|
||||||
write = 1'b0;
|
write = 1'b0;
|
||||||
// selections
|
// ma_sel_2: load data from mem[PC]
|
||||||
C[`ma_sel_2] = 1'b1; // load data from mem[PC]
|
C[`ma_sel_2] = 1'b1;
|
||||||
end
|
end
|
||||||
// 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;
|
||||||
@@ -236,27 +221,30 @@ always @ (state) begin
|
|||||||
print_instruction(INSTRUCTION);
|
print_instruction(INSTRUCTION);
|
||||||
// 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
|
// load now - sp is incremented before pop
|
||||||
// r1_sel_1: push - store value of r0 at stack pointer
|
C[`sp_load] = opcode == `OP_POP;
|
||||||
C[`r1_sel_1] = opcode != 6'h1b ? 1'b0 : 1'b1;
|
|
||||||
// wa_sel_1: R-type - write to rd, I-type - write to rt
|
// r1_sel_1: rs by default (0), push - r1 (1)
|
||||||
C[`wa_sel_1] = opcode == 6'h00 ? 1'b0 : 1'b1;
|
C[`r1_sel_1] = opcode == `OP_PUSH;
|
||||||
// wa_sel_2: jal - write to r31, pop - write to r0
|
|
||||||
C[`wa_sel_2] = opcode == 6'h03 ? 1'b1 : 1'b0;
|
// wa_sel_1: R-type - write to rd (0), I-type - write to rt (1)
|
||||||
// wa_sel_3: push or pop - wa_sel_2, else wa_sel_1
|
C[`wa_sel_1] = opcode != `OP_RTYPE;
|
||||||
C[`wa_sel_3] = opcode == 6'h03 || opcode == 6'h1c ? 1'b0 : 1'b1;
|
// wa_sel_2: pop - write to r0 (0), jal - write to r31 (1)
|
||||||
// jr - jump to address in register
|
C[`wa_sel_2] = opcode == `OP_JAL;
|
||||||
C[`pc_sel_1] = opcode == 6'h00 && funct == 6'h08 ? 1'b0 : 1'b1;
|
// wa_sel_3: wa_sel_2 if push or pop or jal (0), else wa_sel_1 (1)
|
||||||
// beq, bne - branch if equal or not equal
|
C[`wa_sel_3] = ~(opcode == `OP_PUSH || opcode == `OP_POP || opcode == `OP_JAL);
|
||||||
// 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_1: jr - jump to address in rs (0), else pc_inc (1)
|
||||||
// jmp, jal - jump to address
|
C[`pc_sel_1] = ~(opcode == `OP_RTYPE && funct == `FN_JR);
|
||||||
C[`pc_sel_3] = opcode == `OP_JMP || opcode == `OP_JAL ? 1'b0 : 1'b1;
|
// pc_sel_2: pc_sel_1 by default (0), beq, bne - branch if equal or not equal (1)
|
||||||
|
// pc_sel_2 is set after EXE because it depends on ZERO
|
||||||
|
// 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);
|
||||||
|
|
||||||
// alu_oprn - operation to be performed by ALU
|
// alu_oprn - operation to be performed by ALU
|
||||||
|
case (opcode)
|
||||||
// R-type
|
// R-type
|
||||||
if (opcode == `OP_RTYPE) begin
|
`OP_RTYPE: case (funct)
|
||||||
case (funct)
|
|
||||||
`FN_ADD: C[`alu_oprn] = `ALU_ADD;
|
`FN_ADD: C[`alu_oprn] = `ALU_ADD;
|
||||||
`FN_SUB: C[`alu_oprn] = `ALU_SUB;
|
`FN_SUB: C[`alu_oprn] = `ALU_SUB;
|
||||||
`FN_MUL: C[`alu_oprn] = `ALU_MUL;
|
`FN_MUL: C[`alu_oprn] = `ALU_MUL;
|
||||||
@@ -268,10 +256,6 @@ always @ (state) begin
|
|||||||
`FN_SLT: C[`alu_oprn] = `ALU_SLT;
|
`FN_SLT: C[`alu_oprn] = `ALU_SLT;
|
||||||
default: C[`alu_oprn] = `ALU_NOP;
|
default: C[`alu_oprn] = `ALU_NOP;
|
||||||
endcase
|
endcase
|
||||||
end
|
|
||||||
// I-type and J-type
|
|
||||||
else begin
|
|
||||||
case (opcode)
|
|
||||||
// I-type
|
// I-type
|
||||||
`OP_ADDI: C[`alu_oprn] = `ALU_ADD; // addi
|
`OP_ADDI: C[`alu_oprn] = `ALU_ADD; // addi
|
||||||
`OP_MULI: C[`alu_oprn] = `ALU_MUL; // muli
|
`OP_MULI: C[`alu_oprn] = `ALU_MUL; // muli
|
||||||
@@ -287,64 +271,64 @@ always @ (state) begin
|
|||||||
`OP_POP: C[`alu_oprn] = `ALU_ADD; // pop - add
|
`OP_POP: C[`alu_oprn] = `ALU_ADD; // pop - add
|
||||||
default: C[`alu_oprn] = `ALU_NOP;
|
default: C[`alu_oprn] = `ALU_NOP;
|
||||||
endcase
|
endcase
|
||||||
end
|
|
||||||
// op1_sel_1 - select r1 or sp based on opcode
|
|
||||||
// push or pop - sp, else r1
|
|
||||||
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)
|
|
||||||
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)
|
|
||||||
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
|
|
||||||
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
|
|
||||||
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
|
// op1_sel_1: r1 by default (0), push or pop - sp (1)
|
||||||
C[`wd_sel_1] = 1'b0;
|
C[`op1_sel_1] = opcode == `OP_PUSH || opcode == `OP_POP;
|
||||||
// wd_sel_2 - wd_sel_1 or imm_zx_lsb
|
|
||||||
// lui - imm_zx_lsb, else wd_sel_1
|
// op2_sel_1: const 1 (for inc/dec) (0), shamt for sll/srl (1)
|
||||||
C[`wd_sel_2] = opcode == 6'h0f ? 1'b1 : 1'b0;
|
C[`op2_sel_1] = opcode == `OP_RTYPE && (funct == `FN_SLL || funct == `FN_SRL);
|
||||||
// wd_sel_3 - pc_inc or wd_sel_2
|
// op2_sel_2: imm_zx for logical and/or (0), imm_sx otherise (1)
|
||||||
// jal - pc_inc, else wd_sel_2
|
// ('nor' not availble in I-type)
|
||||||
C[`wd_sel_3] = opcode == 6'h03 ? 1'b0 : 1'b1;
|
C[`op2_sel_2] = ~(opcode == `OP_ANDI || opcode == `OP_ORI);
|
||||||
// md_sel_1 - r1 for push, r2 for sw
|
// op2_sel_3: op2_sel_2 for I-type (0), op2_sel_1 for R-type shift or inc/dec (1)
|
||||||
C[`md_sel_1] = opcode == 6'h1b ? 1'b1 : 1'b0;
|
// (inc/dec is for sp with pop or push)
|
||||||
|
C[`op2_sel_3] = opcode == `OP_RTYPE || opcode == `OP_PUSH || opcode == `OP_POP;
|
||||||
|
// op2_sel_4: op2_sel_3 for I-type (except beq, bne) or R-type shift or inc/dec (0), else r2 (1)
|
||||||
|
// i.e. r2 if R-type (except sll/srl), or bne/beq
|
||||||
|
C[`op2_sel_4] = opcode == `OP_RTYPE && ~(funct == `FN_SLL || funct == `FN_SRL)
|
||||||
|
|| opcode == `OP_BEQ || opcode == `OP_BNE;
|
||||||
|
|
||||||
|
// wd_sel_1: alu_out by default (0), DATA_IN for lw or pop (1)
|
||||||
|
C[`wd_sel_1] = opcode == `OP_LW || opcode == `OP_POP;
|
||||||
|
// wd_sel_2: wd_sel_1 by default (0), imm_zx_lsb for lui (1)
|
||||||
|
C[`wd_sel_2] = opcode == `OP_LUI;
|
||||||
|
// wd_sel_3: pc_inc for jal (0), else wd_sel_2 (1)
|
||||||
|
C[`wd_sel_3] = ~(opcode == `OP_JAL);
|
||||||
|
|
||||||
|
// ma_sel_1: alu_out for lw or sw (0), sp for push or pop (1)
|
||||||
|
C[`ma_sel_1] = opcode == `OP_PUSH || opcode == `OP_POP;
|
||||||
|
// ma_sel_2: 0 for every memory access instruction (lw, sw, push, pop), 1 for fetch
|
||||||
|
C[`ma_sel_2] = 1'b0;
|
||||||
|
|
||||||
|
// md_sel_1: r2 for sw (0), r1 for push (1)
|
||||||
|
C[`md_sel_1] = opcode == `OP_PUSH;
|
||||||
end
|
end
|
||||||
`PROC_MEM: begin
|
`PROC_MEM: begin
|
||||||
// load now
|
// loaded in previous state, set to 0
|
||||||
|
C[`sp_load] = 1'b0;
|
||||||
// push or sw - write to memory
|
// push or sw - write to memory
|
||||||
if (opcode == 6'h1b || opcode == 6'h2b) begin
|
write = opcode == `OP_PUSH || opcode == `OP_SW;
|
||||||
read = 1'b0;
|
// pop or lw - read from memory
|
||||||
write = 1'b1;
|
read = opcode == `OP_POP || opcode == `OP_LW;
|
||||||
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
|
||||||
read = 1'b0;
|
read = 1'b0;
|
||||||
write = 1'b0;
|
write = 1'b0;
|
||||||
// load now
|
// load now
|
||||||
|
// pc gets next instruction address
|
||||||
C[`pc_load] = 1'b1;
|
C[`pc_load] = 1'b1;
|
||||||
|
// sp is decremented after push
|
||||||
|
C[`sp_load] = opcode == `OP_PUSH;
|
||||||
// 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
|
// pc_sel_2: branch if equal or not equal
|
||||||
// pc_sel_2 - branch if equal or not equal
|
C[`pc_sel_2] = ((opcode == `OP_BEQ) && ZERO) || ((opcode == `OP_BNE) && ~ZERO);
|
||||||
C[`pc_sel_2] = (opcode == 6'h04 && ZERO) || (opcode == 6'h05 && ~ZERO) ? 1'b1 : 1'b0;
|
|
||||||
|
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
@@ -382,7 +366,7 @@ always @ (negedge RST) begin
|
|||||||
state_sel = 3'bxxx;
|
state_sel = 3'bxxx;
|
||||||
end
|
end
|
||||||
|
|
||||||
// TBD - take action on each +ve edge of clock
|
// take action on each +ve edge of clock
|
||||||
always @ (posedge CLK) begin
|
always @ (posedge CLK) begin
|
||||||
case (state_sel)
|
case (state_sel)
|
||||||
`PROC_FETCH: state_sel = `PROC_DECODE;
|
`PROC_FETCH: state_sel = `PROC_DECODE;
|
||||||
|
|||||||
105
data_path.v
105
data_path.v
@@ -17,6 +17,7 @@
|
|||||||
//------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
`include "prj_definition.v"
|
`include "prj_definition.v"
|
||||||
|
`include "control_unit.v" // for control signal index macros
|
||||||
module DATA_PATH(DATA_OUT, ADDR, ZERO, INSTRUCTION, DATA_IN, CTRL, CLK, RST);
|
module DATA_PATH(DATA_OUT, ADDR, ZERO, INSTRUCTION, DATA_IN, CTRL, CLK, RST);
|
||||||
|
|
||||||
// output list
|
// output list
|
||||||
@@ -29,53 +30,6 @@ input [`CTRL_WIDTH_INDEX_LIMIT:0] CTRL;
|
|||||||
input CLK, RST;
|
input CLK, RST;
|
||||||
input [`DATA_INDEX_LIMIT:0] DATA_IN;
|
input [`DATA_INDEX_LIMIT:0] DATA_IN;
|
||||||
|
|
||||||
wire 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,
|
|
||||||
|
|
||||||
sp_load, op1_sel_1,
|
|
||||||
op2_sel_1, op2_sel_2, op2_sel_3, op2_sel_4,
|
|
||||||
|
|
||||||
wd_sel_1, wd_sel_2, wd_sel_3,
|
|
||||||
ma_sel_1, ma_sel_2,
|
|
||||||
md_sel_1;
|
|
||||||
|
|
||||||
wire [5:0] alu_oprn;
|
|
||||||
|
|
||||||
buf (pc_load, CTRL[0]);
|
|
||||||
buf (pc_sel_1, CTRL[1]);
|
|
||||||
buf (pc_sel_2, CTRL[2]);
|
|
||||||
buf (pc_sel_3, CTRL[3]);
|
|
||||||
|
|
||||||
buf (ir_load, CTRL[4]);
|
|
||||||
|
|
||||||
buf (r1_sel_1, CTRL[5]);
|
|
||||||
buf (reg_r, CTRL[6]);
|
|
||||||
buf (reg_w, CTRL[7]);
|
|
||||||
|
|
||||||
buf (sp_load, CTRL[8]);
|
|
||||||
|
|
||||||
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 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 (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
|
// variables
|
||||||
wire [31:0] ir; // Instruction Register
|
wire [31:0] ir; // Instruction Register
|
||||||
wire [31:0] r1, r2; // Register File
|
wire [31:0] r1, r2; // Register File
|
||||||
@@ -83,7 +37,7 @@ wire [31:0] pc, pc_inc; // Program Counter
|
|||||||
wire [31:0] sp; // Stack Pointer
|
wire [31:0] sp; // Stack Pointer
|
||||||
wire [31:0] alu_out; // ALU output
|
wire [31:0] alu_out; // ALU output
|
||||||
|
|
||||||
// TODO: Why?
|
// instruction sent to control unit
|
||||||
buf ir_buf [31:0] (INSTRUCTION, ir);
|
buf ir_buf [31:0] (INSTRUCTION, ir);
|
||||||
|
|
||||||
// Parse the instruction data
|
// Parse the instruction data
|
||||||
@@ -110,27 +64,26 @@ buf imm_buf [15:0] (imm, ir[15:0]);
|
|||||||
// for J-type
|
// for J-type
|
||||||
buf addr_buf [25:0] (addr, ir[25:0]);
|
buf addr_buf [25:0] (addr, ir[25:0]);
|
||||||
|
|
||||||
|
|
||||||
// Instruction Register input
|
|
||||||
// Instruction Register
|
// Instruction Register
|
||||||
D_LATCH32 ir_inst(.Q(ir), .D(DATA_IN), .LOAD(ir_load), .RESET(RST));
|
D_LATCH32 ir_inst(.Q(ir), .D(DATA_IN), .LOAD(CTRL[`ir_load]), .RESET(RST));
|
||||||
|
|
||||||
// Register File Input
|
// Register File Input
|
||||||
wire [31:0] r1_sel, wa_sel, wd_sel;
|
wire [31:0] r1_sel, wa_sel, wd_sel;
|
||||||
wire [31:0] wa_sel_p1, wa_sel_p2, wd_sel_p1, wd_sel_p2;
|
wire [31:0] wa_sel_p1, wa_sel_p2, wd_sel_p1, wd_sel_p2;
|
||||||
wire [31:0] imm_zx_lsb;
|
wire [31:0] imm_zx_lsb;
|
||||||
buf imm_zx_lsb_buf [31:0] (imm_zx_lsb, {imm, 16'b0});
|
buf imm_zx_lsb_buf [31:0] (imm_zx_lsb, {imm, 16'b0});
|
||||||
MUX32_2x1 mux_r1_sel(r1_sel, {27'b0,rs}, 32'b0, r1_sel_1);
|
MUX32_2x1 mux_r1_sel(r1_sel, {27'b0,rs}, 32'b0, CTRL[`r1_sel_1]);
|
||||||
MUX32_2x1 mux_wa_sel_p1(wa_sel_p1, {27'b0,rd}, {27'b0,rt}, wa_sel_1);
|
MUX32_2x1 mux_wa_sel_p1(wa_sel_p1, {27'b0,rd}, {27'b0,rt}, CTRL[`wa_sel_1]);
|
||||||
// TODO: Why 31?
|
// 0 for push/pop, 31 for jal
|
||||||
MUX32_2x1 mux_wa_sel_p2(wa_sel_p2, 32'b0, 31, wa_sel_2);
|
MUX32_2x1 mux_wa_sel_p2(wa_sel_p2, 32'b0, 31, CTRL[`wa_sel_2]);
|
||||||
MUX32_2x1 mux_wa_sel(wa_sel, wa_sel_p2, wa_sel_p1, wa_sel_3);
|
MUX32_2x1 mux_wa_sel(wa_sel, wa_sel_p2, wa_sel_p1, CTRL[`wa_sel_3]);
|
||||||
MUX32_2x1 mux_wd_sel_p1(wd_sel_p1, alu_out,DATA_IN, wd_sel_1);
|
MUX32_2x1 mux_wd_sel_p1(wd_sel_p1, alu_out,DATA_IN, CTRL[`wd_sel_1]);
|
||||||
MUX32_2x1 mux_wd_sel_p2(wd_sel_p2, wd_sel_p1, imm_zx_lsb, wd_sel_2);
|
MUX32_2x1 mux_wd_sel_p2(wd_sel_p2, wd_sel_p1, imm_zx_lsb, CTRL[`wd_sel_2]);
|
||||||
MUX32_2x1 mux_wd_sel(wd_sel, pc_inc, wd_sel_p2, wd_sel_3);
|
MUX32_2x1 mux_wd_sel(wd_sel, pc_inc, wd_sel_p2, CTRL[`wd_sel_3]);
|
||||||
// Register File
|
// Register File
|
||||||
REGISTER_FILE_32x32 rf_inst(.DATA_R1(r1), .DATA_R2(r2), .ADDR_R1(r1_sel[4:0]), .ADDR_R2(rt),
|
REGISTER_FILE_32x32 rf_inst(.DATA_R1(r1), .DATA_R2(r2), .ADDR_R1(r1_sel[4:0]), .ADDR_R2(rt),
|
||||||
.DATA_W(wd_sel), .ADDR_W(wa_sel[4:0]), .READ(reg_r), .WRITE(reg_w), .CLK(CLK), .RST(RST));
|
.DATA_W(wd_sel), .ADDR_W(wa_sel[4:0]), .READ(CTRL[`reg_r]), .WRITE(CTRL[`reg_w]),
|
||||||
|
.CLK(CLK), .RST(RST));
|
||||||
|
|
||||||
// ALU Input
|
// ALU Input
|
||||||
wire [31:0] op1_sel, op2_sel;
|
wire [31:0] op1_sel, op2_sel;
|
||||||
@@ -139,40 +92,40 @@ wire [31:0] shamt_zx, imm_sx, imm_zx;
|
|||||||
buf shamt_zx_buf [31:0] (shamt_zx, {27'b0, shamt});
|
buf shamt_zx_buf [31:0] (shamt_zx, {27'b0, shamt});
|
||||||
buf imm_sx_buf [31:0] (imm_sx, {{16{imm[15]}}, imm});
|
buf imm_sx_buf [31:0] (imm_sx, {{16{imm[15]}}, imm});
|
||||||
buf imm_zx_buf [31:0] (imm_zx, {16'b0, imm});
|
buf imm_zx_buf [31:0] (imm_zx, {16'b0, imm});
|
||||||
MUX32_2x1 mux_op1_sel(op1_sel, r1, sp, op1_sel_1);
|
MUX32_2x1 mux_op1_sel(op1_sel, r1, sp, CTRL[`op1_sel_1]);
|
||||||
MUX32_2x1 mux_op2_sel_p1(op2_sel_p1, 32'b1, shamt_zx, op2_sel_1);
|
MUX32_2x1 mux_op2_sel_p1(op2_sel_p1, 32'b1, shamt_zx, CTRL[`op2_sel_1]);
|
||||||
MUX32_2x1 mux_op2_sel_p2(op2_sel_p2, imm_zx, imm_sx, op2_sel_2);
|
MUX32_2x1 mux_op2_sel_p2(op2_sel_p2, imm_zx, imm_sx, CTRL[`op2_sel_2]);
|
||||||
MUX32_2x1 mux_op2_sel_p3(op2_sel_p3, op2_sel_p2, op2_sel_p1, op2_sel_3);
|
MUX32_2x1 mux_op2_sel_p3(op2_sel_p3, op2_sel_p2, op2_sel_p1, CTRL[`op2_sel_3]);
|
||||||
MUX32_2x1 mux_op2_sel(op2_sel, op2_sel_p3, r2, op2_sel_4);
|
MUX32_2x1 mux_op2_sel(op2_sel, op2_sel_p3, r2, CTRL[`op2_sel_4]);
|
||||||
// ALU
|
// ALU
|
||||||
ALU alu_inst(.OUT(alu_out), .ZERO(ZERO), .OP1(op1_sel), .OP2(op2_sel), .OPRN(alu_oprn));
|
ALU alu_inst(.OUT(alu_out), .ZERO(ZERO), .OP1(op1_sel), .OP2(op2_sel), .OPRN(CTRL[`alu_oprn]));
|
||||||
|
|
||||||
// Progam Counter Input
|
// Progam Counter Input
|
||||||
wire [31:0] pc_sel;
|
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, CTRL[`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, CTRL[`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, CTRL[`pc_sel_3]);
|
||||||
// Program Counter
|
// Program Counter
|
||||||
defparam pc_inst.PATTERN = `INST_START_ADDR;
|
defparam pc_inst.PATTERN = `INST_START_ADDR;
|
||||||
REG32_PP pc_inst(.Q(pc), .D(pc_sel), .LOAD(pc_load), .CLK(CLK), .RESET(RST));
|
REG32_PP pc_inst(.Q(pc), .D(pc_sel), .LOAD(CTRL[`pc_load]), .CLK(CLK), .RESET(RST));
|
||||||
|
|
||||||
// Stack Pointer
|
// Stack Pointer
|
||||||
defparam sp_inst.PATTERN = `INIT_STACK_POINTER;
|
defparam sp_inst.PATTERN = `INIT_STACK_POINTER;
|
||||||
REG32_PP sp_inst(.Q(sp), .D(alu_out), .LOAD(sp_load), .CLK(CLK), .RESET(RST));
|
REG32_PP sp_inst(.Q(sp), .D(alu_out), .LOAD(CTRL[`sp_load]), .CLK(CLK), .RESET(RST));
|
||||||
|
|
||||||
// Data out
|
// Data out
|
||||||
MUX32_2x1 mux_data_out(DATA_OUT, r2, r1, md_sel_1);
|
MUX32_2x1 mux_data_out(DATA_OUT, r2, r1, CTRL[`md_sel_1]);
|
||||||
|
|
||||||
// Address out
|
// Address out
|
||||||
wire [31:0] ma_sel_p1;
|
wire [31:0] ma_sel_p1;
|
||||||
MUX32_2x1 mux_ma_sel_p1(ma_sel_p1, alu_out, sp, ma_sel_1);
|
MUX32_2x1 mux_ma_sel_p1(ma_sel_p1, alu_out, sp, CTRL[`ma_sel_1]);
|
||||||
// TODO: Check address calculation since it's 26 bit
|
// discard the upper 6 bits of the address since it's only 26 bit addressable
|
||||||
(* keep="soft" *)
|
(* keep="soft" *)
|
||||||
wire [5:0] _addr_ignored;
|
wire [5:0] _addr_ignored;
|
||||||
MUX32_2x1 mux_ma_sel({_addr_ignored,ADDR}, ma_sel_p1, pc, ma_sel_2);
|
MUX32_2x1 mux_ma_sel({_addr_ignored,ADDR}, ma_sel_p1, pc, CTRL[`ma_sel_2]);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
`define ALU_OPRN_INDEX_LIMIT (`ALU_OPRN_WIDTH -1)
|
`define ALU_OPRN_INDEX_LIMIT (`ALU_OPRN_WIDTH -1)
|
||||||
`define ADDRESS_WIDTH 26
|
`define ADDRESS_WIDTH 26
|
||||||
`define ADDRESS_INDEX_LIMIT (`ADDRESS_WIDTH -1)
|
`define ADDRESS_INDEX_LIMIT (`ADDRESS_WIDTH -1)
|
||||||
`define MEM_SIZE (2 ** `ADDRESS_WIDTH)
|
`define MEM_SIZE (2 ** (`ADDRESS_WIDTH - 6))
|
||||||
`define MEM_INDEX_LIMIT (`MEM_SIZE - 1)
|
`define MEM_INDEX_LIMIT (`MEM_SIZE - 1)
|
||||||
`define NUM_OF_REG 32
|
`define NUM_OF_REG 32
|
||||||
`define REG_INDEX_LIMIT (`NUM_OF_REG -1)
|
`define REG_INDEX_LIMIT (`NUM_OF_REG -1)
|
||||||
@@ -41,4 +41,4 @@
|
|||||||
|
|
||||||
// define ISA parameters
|
// define ISA parameters
|
||||||
`define INST_START_ADDR 32'h00001000
|
`define INST_START_ADDR 32'h00001000
|
||||||
`define INIT_STACK_POINTER 32'h03ffffff
|
`define INIT_STACK_POINTER 32'h000fffff
|
||||||
|
|||||||
Reference in New Issue
Block a user