This commit is contained in:
2025-08-18 07:18:32 +03:00
commit 12dcc9d232
27 changed files with 1910 additions and 0 deletions

99
chapter2/a.out Executable file
View File

@@ -0,0 +1,99 @@
#! /usr/bin/vvp
:ivl_version "12.0 (stable)";
:ivl_delay_selection "TYPICAL";
:vpi_time_precision + 0;
:vpi_module "/usr/lib64/ivl/system.vpi";
:vpi_module "/usr/lib64/ivl/vhdl_sys.vpi";
:vpi_module "/usr/lib64/ivl/vhdl_textio.vpi";
:vpi_module "/usr/lib64/ivl/v2005_math.vpi";
:vpi_module "/usr/lib64/ivl/va_math.vpi";
S_0x56542d3760c0 .scope module, "fibonacciTB" "fibonacciTB" 2 1;
.timescale 0 0;
v0x56542d388680_0 .var "clk", 0 0;
v0x56542d388750_0 .net "num", 31 0, v0x56542d388390_0; 1 drivers
v0x56542d388820_0 .var "rst", 0 0;
S_0x56542d376250 .scope module, "uut" "fibonacci" 2 6, 3 1 0, S_0x56542d3760c0;
.timescale 0 0;
.port_info 0 /INPUT 1 "clk";
.port_info 1 /INPUT 1 "rst";
.port_info 2 /OUTPUT 32 "num";
v0x56542d3764a0_0 .net "clk", 0 0, v0x56542d388680_0; 1 drivers
v0x56542d388390_0 .var "num", 31 0;
v0x56542d388470 .array "nums", 0 1, 31 0;
v0x56542d388540_0 .net "rst", 0 0, v0x56542d388820_0; 1 drivers
E_0x56542d373800 .event posedge, v0x56542d3764a0_0;
.scope S_0x56542d376250;
T_0 ;
%wait E_0x56542d373800;
%load/vec4 v0x56542d388540_0;
%flag_set/vec4 8;
%jmp/0xz T_0.0, 8;
%pushi/vec4 1, 0, 32;
%assign/vec4 v0x56542d388390_0, 0;
%pushi/vec4 0, 0, 32;
%ix/load 3, 0, 0;
%flag_set/imm 4, 0;
%ix/load 4, 0, 0; Constant delay
%assign/vec4/a/d v0x56542d388470, 0, 4;
%pushi/vec4 0, 0, 32;
%ix/load 3, 1, 0;
%flag_set/imm 4, 0;
%ix/load 4, 0, 0; Constant delay
%assign/vec4/a/d v0x56542d388470, 0, 4;
%jmp T_0.1;
T_0.0 ;
%ix/load 4, 0, 0;
%flag_set/imm 4, 0;
%load/vec4a v0x56542d388470, 4;
%ix/load 4, 1, 0;
%flag_set/imm 4, 0;
%load/vec4a v0x56542d388470, 4;
%add;
%assign/vec4 v0x56542d388390_0, 0;
%ix/load 4, 0, 0;
%flag_set/imm 4, 0;
%load/vec4a v0x56542d388470, 4;
%ix/load 3, 1, 0;
%flag_set/imm 4, 0;
%ix/load 4, 0, 0; Constant delay
%assign/vec4/a/d v0x56542d388470, 0, 4;
%load/vec4 v0x56542d388390_0;
%ix/load 3, 0, 0;
%flag_set/imm 4, 0;
%ix/load 4, 0, 0; Constant delay
%assign/vec4/a/d v0x56542d388470, 0, 4;
T_0.1 ;
%jmp T_0;
.thread T_0;
.scope S_0x56542d3760c0;
T_1 ;
%load/vec4 v0x56542d388680_0;
%inv;
%store/vec4 v0x56542d388680_0, 0, 1;
%delay 1, 0;
%jmp T_1;
.thread T_1;
.scope S_0x56542d3760c0;
T_2 ;
%vpi_call 2 17 "$dumpfile", "fibonacci.vcd" {0 0 0};
%vpi_call 2 18 "$dumpvars" {0 0 0};
%pushi/vec4 0, 0, 1;
%store/vec4 v0x56542d388680_0, 0, 1;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x56542d388820_0, 0, 1;
%delay 1, 0;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x56542d388820_0, 0, 1;
%delay 1, 0;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x56542d388820_0, 0, 1;
%delay 10, 0;
%vpi_call 2 23 "$finish" {0 0 0};
%end;
.thread T_2;
# The file index is used to find the file name in the following table.
:file_names 4;
"N/A";
"<interactive>";
"fibonacciTB.v";
"fibonacci.v";

83
chapter2/calculator Executable file
View File

@@ -0,0 +1,83 @@
#! /usr/bin/vvp
:ivl_version "12.0 (stable)";
:ivl_delay_selection "TYPICAL";
:vpi_time_precision + 0;
:vpi_module "/usr/lib64/ivl/system.vpi";
:vpi_module "/usr/lib64/ivl/vhdl_sys.vpi";
:vpi_module "/usr/lib64/ivl/vhdl_textio.vpi";
:vpi_module "/usr/lib64/ivl/v2005_math.vpi";
:vpi_module "/usr/lib64/ivl/va_math.vpi";
S_0x55fa39636f10 .scope module, "calculator" "calculator" 2 1;
.timescale 0 0;
.port_info 0 /INPUT 32 "A";
.port_info 1 /INPUT 32 "B";
.port_info 2 /INPUT 2 "op";
.port_info 3 /OUTPUT 32 "Y";
L_0x7feabdea7018 .functor BUFT 1, C4<0000000000000000000000000000zzzz>, C4<0>, C4<0>, C4<0>;
v0x55fa39635140_0 .net "A", 31 0, L_0x7feabdea7018; 1 drivers
o0x7feabdef0048 .functor BUFZ 4, C4<zzzz>; HiZ drive
v0x55fa39610eb0_0 .net "A_rand", 3 0, o0x7feabdef0048; 0 drivers
L_0x7feabdea7060 .functor BUFT 1, C4<00000000000000000000000000zzzzzz>, C4<0>, C4<0>, C4<0>;
v0x55fa3965a2a0_0 .net "B", 31 0, L_0x7feabdea7060; 1 drivers
o0x7feabdef00a8 .functor BUFZ 6, C4<zzzzzz>; HiZ drive
v0x55fa3965a360_0 .net "B_rand", 5 0, o0x7feabdef00a8; 0 drivers
v0x55fa3965a440_0 .var "Y", 31 0;
o0x7feabdef0108 .functor BUFZ 2, C4<zz>; HiZ drive
v0x55fa3965a570_0 .net "op", 1 0, o0x7feabdef0108; 0 drivers
E_0x55fa39647e70 .event anyedge, v0x55fa3965a570_0, v0x55fa39635140_0, v0x55fa3965a2a0_0;
.scope S_0x55fa39636f10;
T_0 ;
%wait E_0x55fa39647e70;
%load/vec4 v0x55fa3965a570_0;
%dup/vec4;
%pushi/vec4 0, 0, 2;
%cmp/u;
%jmp/1 T_0.0, 6;
%dup/vec4;
%pushi/vec4 1, 0, 2;
%cmp/u;
%jmp/1 T_0.1, 6;
%dup/vec4;
%pushi/vec4 2, 0, 2;
%cmp/u;
%jmp/1 T_0.2, 6;
%dup/vec4;
%pushi/vec4 3, 0, 2;
%cmp/u;
%jmp/1 T_0.3, 6;
%pushi/vec4 0, 0, 32;
%store/vec4 v0x55fa3965a440_0, 0, 32;
%jmp T_0.5;
T_0.0 ;
%load/vec4 v0x55fa39635140_0;
%load/vec4 v0x55fa3965a2a0_0;
%add;
%store/vec4 v0x55fa3965a440_0, 0, 32;
%jmp T_0.5;
T_0.1 ;
%load/vec4 v0x55fa39635140_0;
%load/vec4 v0x55fa3965a2a0_0;
%sub;
%store/vec4 v0x55fa3965a440_0, 0, 32;
%jmp T_0.5;
T_0.2 ;
%load/vec4 v0x55fa39635140_0;
%load/vec4 v0x55fa3965a2a0_0;
%mul;
%store/vec4 v0x55fa3965a440_0, 0, 32;
%jmp T_0.5;
T_0.3 ;
%load/vec4 v0x55fa39635140_0;
%load/vec4 v0x55fa3965a2a0_0;
%div;
%store/vec4 v0x55fa3965a440_0, 0, 32;
%jmp T_0.5;
T_0.5 ;
%pop/vec4 1;
%jmp T_0;
.thread T_0, $push;
# The file index is used to find the file name in the following table.
:file_names 3;
"N/A";
"<interactive>";
"calculator.v";

45
chapter2/calculator.v Normal file
View File

@@ -0,0 +1,45 @@
module calculator (
input [1:0] op,
input clk,
input rst,
output reg [31:0] Y
);
reg [31:0] A;
reg [31:0] B;
wire [5:0] B_rand;
wire [3:0] A_rand;
reg [31:0] Y_prev;
assign A = {{28{1'b0}}, A_rand[5:0]};
assign B = {{26{1'b0}}, B_rand[3:0]};
always @(*) begin
if(!rst) begin
case(op)
2'b00 :Y = A + B;
2'b01 :Y = A - B;
2'b10 :Y = A * B;
2'b11 :Y = A / B;
default: Y = 0;
endcase
end
else begin
Y = 0;
end
end
always @(posedge clk) begin
if (rst) begin
Y_prev <= 32'd0;
A <= 32'd0;
B <= 32'd0;
end
else begin
Y_prev <= Y;
A <= Y_prev;
end
end
endmodule

96
chapter2/fibonacci Executable file
View File

@@ -0,0 +1,96 @@
#! /usr/bin/vvp
:ivl_version "12.0 (stable)";
:ivl_delay_selection "TYPICAL";
:vpi_time_precision + 0;
:vpi_module "/usr/lib64/ivl/system.vpi";
:vpi_module "/usr/lib64/ivl/vhdl_sys.vpi";
:vpi_module "/usr/lib64/ivl/vhdl_textio.vpi";
:vpi_module "/usr/lib64/ivl/v2005_math.vpi";
:vpi_module "/usr/lib64/ivl/va_math.vpi";
S_0x562127b680c0 .scope module, "fibonacciTB" "fibonacciTB" 2 1;
.timescale 0 0;
v0x562127b7a290_0 .var "clk", 0 0;
v0x562127b7a360_0 .net "num", 31 0, v0x562127b79fa0_0; 1 drivers
v0x562127b7a430_0 .var "rst", 0 0;
S_0x562127b68250 .scope module, "uut" "fibonacci" 2 6, 3 1 0, S_0x562127b680c0;
.timescale 0 0;
.port_info 0 /INPUT 1 "clk";
.port_info 1 /INPUT 1 "rst";
.port_info 2 /OUTPUT 32 "num";
v0x562127b68480_0 .net "clk", 0 0, v0x562127b7a290_0; 1 drivers
v0x562127b79fa0_0 .var "num", 31 0;
v0x562127b7a080 .array "nums", 0 1, 31 0;
v0x562127b7a150_0 .net "rst", 0 0, v0x562127b7a430_0; 1 drivers
E_0x562127b65800 .event posedge, v0x562127b68480_0;
.scope S_0x562127b68250;
T_0 ;
%wait E_0x562127b65800;
%load/vec4 v0x562127b7a150_0;
%flag_set/vec4 8;
%jmp/0xz T_0.0, 8;
%pushi/vec4 1, 0, 32;
%assign/vec4 v0x562127b79fa0_0, 0;
%pushi/vec4 0, 0, 32;
%ix/load 3, 0, 0;
%flag_set/imm 4, 0;
%ix/load 4, 0, 0; Constant delay
%assign/vec4/a/d v0x562127b7a080, 0, 4;
%pushi/vec4 0, 0, 32;
%ix/load 3, 1, 0;
%flag_set/imm 4, 0;
%ix/load 4, 0, 0; Constant delay
%assign/vec4/a/d v0x562127b7a080, 0, 4;
%jmp T_0.1;
T_0.0 ;
%ix/load 4, 0, 0;
%flag_set/imm 4, 0;
%load/vec4a v0x562127b7a080, 4;
%ix/load 3, 1, 0;
%flag_set/imm 4, 0;
%ix/load 4, 0, 0; Constant delay
%assign/vec4/a/d v0x562127b7a080, 0, 4;
%load/vec4 v0x562127b79fa0_0;
%ix/load 3, 0, 0;
%flag_set/imm 4, 0;
%ix/load 4, 0, 0; Constant delay
%assign/vec4/a/d v0x562127b7a080, 0, 4;
%ix/load 4, 0, 0;
%flag_set/imm 4, 0;
%load/vec4a v0x562127b7a080, 4;
%ix/load 4, 1, 0;
%flag_set/imm 4, 0;
%load/vec4a v0x562127b7a080, 4;
%add;
%assign/vec4 v0x562127b79fa0_0, 0;
T_0.1 ;
%jmp T_0;
.thread T_0;
.scope S_0x562127b680c0;
T_1 ;
%load/vec4 v0x562127b7a290_0;
%inv;
%store/vec4 v0x562127b7a290_0, 0, 1;
%delay 1, 0;
%jmp T_1;
.thread T_1;
.scope S_0x562127b680c0;
T_2 ;
%vpi_call 2 17 "$dumpfile", "fibonacci.vcd" {0 0 0};
%vpi_call 2 18 "$dumpvars" {0 0 0};
%pushi/vec4 0, 0, 1;
%store/vec4 v0x562127b7a290_0, 0, 1;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x562127b7a430_0, 0, 1;
%delay 4, 0;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x562127b7a430_0, 0, 1;
%delay 40, 0;
%vpi_call 2 21 "$finish" {0 0 0};
%end;
.thread T_2;
# The file index is used to find the file name in the following table.
:file_names 4;
"N/A";
"<interactive>";
"fibonacciTB.v";
"fibonacci.v";

22
chapter2/fibonacci.v Normal file
View File

@@ -0,0 +1,22 @@
module fibonacci (
input clk,
input rst,
output reg [31:0] num
);
reg [31:0] nums [1:0];
always @(posedge clk) begin
if (rst) begin
num <= 32'd1;
nums[0] <= 32'd0;
nums[1] <= 32'd0;
end
else begin
nums[1] <= nums[0];
nums[0] <= num;
num <= nums[0] + nums[1];
end
end
endmodule

155
chapter2/fibonacci.vcd Normal file
View File

@@ -0,0 +1,155 @@
$date
Sun Aug 17 18:49:30 2025
$end
$version
Icarus Verilog
$end
$timescale
1s
$end
$scope module fibonacciTB $end
$var wire 32 ! num [31:0] $end
$var reg 1 " clk $end
$var reg 1 # rst $end
$scope module uut $end
$var wire 1 " clk $end
$var wire 1 # rst $end
$var reg 32 $ num [31:0] $end
$upscope $end
$upscope $end
$enddefinitions $end
$comment Show the parameter values. $end
$dumpall
$end
#0
$dumpvars
bx $
1#
0"
bx !
$end
#1
b1 !
b1 $
1"
#2
0"
#3
1"
#4
0"
0#
#5
b0 !
b0 $
1"
#6
0"
#7
b1 !
b1 $
1"
#8
0"
#9
1"
#10
0"
#11
1"
#12
0"
#13
b10 !
b10 $
1"
#14
0"
#15
1"
#16
0"
#17
b11 !
b11 $
1"
#18
0"
#19
b100 !
b100 $
1"
#20
0"
#21
b101 !
b101 $
1"
#22
0"
#23
b111 !
b111 $
1"
#24
0"
#25
b1001 !
b1001 $
1"
#26
0"
#27
b1100 !
b1100 $
1"
#28
0"
#29
b10000 !
b10000 $
1"
#30
0"
#31
b10101 !
b10101 $
1"
#32
0"
#33
b11100 !
b11100 $
1"
#34
0"
#35
b100101 !
b100101 $
1"
#36
0"
#37
b110001 !
b110001 $
1"
#38
0"
#39
b1000001 !
b1000001 $
1"
#40
0"
#41
b1010110 !
b1010110 $
1"
#42
0"
#43
b1110010 !
b1110010 $
1"
#44
0"

23
chapter2/fibonacciTB.v Normal file
View File

@@ -0,0 +1,23 @@
module fibonacciTB();
reg clk, rst;
wire [31:0] num;
fibonacci uut (
.clk(clk),
.rst(rst),
.num(num)
);
always begin
clk = ~clk; #1;
end
initial begin
$dumpfile("fibonacci.vcd");
$dumpvars;
clk = 1'b0; rst = 1'b1; #4;
rst = 1'b0; #40;
$finish;
end
endmodule

19
chapter2/fullAdder.v Normal file
View File

@@ -0,0 +1,19 @@
module fulladder (
input in1,
input in2,
input carryIn,
output sum,
output carryO
);
wire xor1, and1, and2;
xor x1 (xor1, in1, in2);
xor x2 (sum, xor1, carryIn);
and a1 (and1, xor1, carryIn);
and a2 (and2, in1, in2);
or o1 (carryO, and1, and2);
endmodule

39
chapter2/invGate Executable file
View File

@@ -0,0 +1,39 @@
#! /usr/bin/vvp
:ivl_version "12.0 (stable)";
:ivl_delay_selection "TYPICAL";
:vpi_time_precision + 0;
:vpi_module "/usr/lib64/ivl/system.vpi";
:vpi_module "/usr/lib64/ivl/vhdl_sys.vpi";
:vpi_module "/usr/lib64/ivl/vhdl_textio.vpi";
:vpi_module "/usr/lib64/ivl/v2005_math.vpi";
:vpi_module "/usr/lib64/ivl/va_math.vpi";
S_0x56122ac89ed0 .scope module, "invGateTB" "invGateTB" 2 1;
.timescale 0 0;
v0x56122ac99480_0 .var "A", 0 0;
v0x56122ac99520_0 .net "B", 0 0, L_0x56122ac995f0; 1 drivers
S_0x56122ac8a060 .scope module, "uut" "invGate" 2 6, 3 1 0, S_0x56122ac89ed0;
.timescale 0 0;
.port_info 0 /INPUT 1 "A";
.port_info 1 /OUTPUT 1 "B";
L_0x56122ac995f0 .functor NOT 1, v0x56122ac99480_0, C4<0>, C4<0>, C4<0>;
v0x56122ac77570_0 .net "A", 0 0, v0x56122ac99480_0; 1 drivers
v0x56122ac99360_0 .net "B", 0 0, L_0x56122ac995f0; alias, 1 drivers
.scope S_0x56122ac89ed0;
T_0 ;
%vpi_call 2 12 "$dumpfile", "invGate.vcd" {0 0 0};
%vpi_call 2 13 "$dumpvars" {0 0 0};
%pushi/vec4 1, 0, 1;
%store/vec4 v0x56122ac99480_0, 0, 1;
%delay 10, 0;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x56122ac99480_0, 0, 1;
%delay 10, 0;
%vpi_call 2 16 "$finish" {0 0 0};
%end;
.thread T_0;
# The file index is used to find the file name in the following table.
:file_names 4;
"N/A";
"<interactive>";
"invGateTB.v";
"invGate.v";

8
chapter2/invGate.v Normal file
View File

@@ -0,0 +1,8 @@
module invGate (
input A,
output B
);
not a1 (B, A);
endmodule

30
chapter2/invGate.vcd Normal file
View File

@@ -0,0 +1,30 @@
$date
Sun Aug 17 06:21:41 2025
$end
$version
Icarus Verilog
$end
$timescale
1s
$end
$scope module invGateTB $end
$var wire 1 ! B $end
$var reg 1 " A $end
$scope module uut $end
$var wire 1 " A $end
$var wire 1 ! B $end
$upscope $end
$upscope $end
$enddefinitions $end
$comment Show the parameter values. $end
$dumpall
$end
#0
$dumpvars
1"
0!
$end
#10
1!
0"
#20

19
chapter2/invGateTB.v Normal file
View File

@@ -0,0 +1,19 @@
module invGateTB();
reg A;
wire B;
invGate uut (
.A(A),
.B(B)
);
initial begin
$dumpfile("invGate.vcd");
$dumpvars;
A = 1'b1; #10;
A = 1'b0; #10;
$finish;
end
endmodule

14
chapter2/mux.v Normal file
View File

@@ -0,0 +1,14 @@
module mux (
input [1:0] A,
input S,
output Y
);
wire and1, and2;
and a1 (and1, A[0], S);
and a2 (and2, A[1], ~S);
or o1 (Y, and1, and2);
endmodule

21
chapter4/cpu.txt Normal file
View File

@@ -0,0 +1,21 @@
1. PC Logic
This logic is responsible for the program counter (PC). The PC identifies the instruction our CPU will execute next. Most instructions execute sequentially, meaning the default behavior of the PC is to increment to the following instruction each clock cycle. Branch and jump instructions, however, are non-sequential. They specify a target instruction to execute next, and the PC logic must update the PC accordingly.
2. Fetch
The instruction memory (IMem) holds the instructions to execute. To read the IMem, or "fetch", we simply pull out the instruction pointed to by the PC.
Decode Logic
Now that we have an instruction to execute, we must interpret, or decode, it. We must break it into fields based on its type. These fields would tell us which registers to read, which operation to perform, etc.
3. Register File Read
The register file is a small local storage of values the program is actively working with. We decoded the instruction to determine which registers we need to operate on. Now, we need to read those registers from the register file.
4. Arithmetic Logic Unit (ALU)
Now that we have the register values, its time to operate on them. This is the job of the ALU. It will add, subtract, multiply, shift, etc, based on the operation specified in the instruction.
5. Register File Write
Now the result value from the ALU can be written back to the destination register specified in the instruction.
6. DMem
Our test program executes entirely out of the register file and does not require a data memory (DMem). But no CPU is complete without one. The DMem is written to by store instructions and read from by load instructions.

73
chapter4/pc Executable file
View File

@@ -0,0 +1,73 @@
#! /usr/bin/vvp
:ivl_version "12.0 (stable)";
:ivl_delay_selection "TYPICAL";
:vpi_time_precision + 0;
:vpi_module "/usr/lib64/ivl/system.vpi";
:vpi_module "/usr/lib64/ivl/vhdl_sys.vpi";
:vpi_module "/usr/lib64/ivl/vhdl_textio.vpi";
:vpi_module "/usr/lib64/ivl/v2005_math.vpi";
:vpi_module "/usr/lib64/ivl/va_math.vpi";
S_0x56486b9b1530 .scope module, "pcTB" "pcTB" 2 1;
.timescale 0 0;
v0x56486b9c2f90_0 .var "clk", 0 0;
v0x56486b9c3050_0 .net "next_pc", 31 0, v0x56486b9c2c50_0; 1 drivers
v0x56486b9c3120_0 .net "pc", 31 0, v0x56486b9c2d30_0; 1 drivers
v0x56486b9c3220_0 .var "rst", 0 0;
S_0x56486b9b16c0 .scope module, "uut" "pc" 2 8, 3 1 0, S_0x56486b9b1530;
.timescale 0 0;
.port_info 0 /INPUT 1 "rst";
.port_info 1 /INPUT 1 "clk";
.port_info 2 /OUTPUT 32 "pc";
.port_info 3 /OUTPUT 32 "next_pc";
v0x56486b99e730_0 .net "clk", 0 0, v0x56486b9c2f90_0; 1 drivers
v0x56486b9c2c50_0 .var "next_pc", 31 0;
v0x56486b9c2d30_0 .var "pc", 31 0;
v0x56486b9c2e20_0 .net "rst", 0 0, v0x56486b9c3220_0; 1 drivers
E_0x56486b9afa90 .event posedge, v0x56486b99e730_0;
.scope S_0x56486b9b16c0;
T_0 ;
%wait E_0x56486b9afa90;
%load/vec4 v0x56486b9c2e20_0;
%flag_set/vec4 8;
%jmp/0xz T_0.0, 8;
%pushi/vec4 0, 0, 32;
%assign/vec4 v0x56486b9c2d30_0, 0;
%jmp T_0.1;
T_0.0 ;
%load/vec4 v0x56486b9c2d30_0;
%assign/vec4 v0x56486b9c2c50_0, 0;
%load/vec4 v0x56486b9c2d30_0;
%addi 1, 0, 32;
%assign/vec4 v0x56486b9c2d30_0, 0;
T_0.1 ;
%jmp T_0;
.thread T_0;
.scope S_0x56486b9b1530;
T_1 ;
%load/vec4 v0x56486b9c2f90_0;
%inv;
%store/vec4 v0x56486b9c2f90_0, 0, 1;
%delay 2, 0;
%jmp T_1;
.thread T_1;
.scope S_0x56486b9b1530;
T_2 ;
%vpi_call 2 20 "$dumpfile", "pc.vcd" {0 0 0};
%vpi_call 2 21 "$dumpvars" {0 0 0};
%pushi/vec4 0, 0, 1;
%store/vec4 v0x56486b9c2f90_0, 0, 1;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x56486b9c3220_0, 0, 1;
%delay 4, 0;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x56486b9c3220_0, 0, 1;
%delay 80, 0;
%vpi_call 2 25 "$finish" {0 0 0};
%end;
.thread T_2;
# The file index is used to find the file name in the following table.
:file_names 4;
"N/A";
"<interactive>";
"pcTB.v";
"pc.v";

19
chapter4/pc.v Normal file
View File

@@ -0,0 +1,19 @@
module pc (
input rst,
input clk,
output reg [31:0] pc,
output reg [31:0] next_pc
);
always @(posedge clk) begin
if(rst) begin
pc <= 0;
end
else begin
next_pc <= pc;
pc <= pc + 1;
end
end
endmodule

201
chapter4/pc.vcd Normal file
View File

@@ -0,0 +1,201 @@
$date
Mon Aug 18 02:30:00 2025
$end
$version
Icarus Verilog
$end
$timescale
1s
$end
$scope module pcTB $end
$var wire 32 ! pc [31:0] $end
$var wire 32 " next_pc [31:0] $end
$var reg 1 # clk $end
$var reg 1 $ rst $end
$scope module uut $end
$var wire 1 # clk $end
$var wire 1 $ rst $end
$var reg 32 % next_pc [31:0] $end
$var reg 32 & pc [31:0] $end
$upscope $end
$upscope $end
$enddefinitions $end
$comment Show the parameter values. $end
$dumpall
$end
#0
$dumpvars
bx &
bx %
1$
0#
bx "
bx !
$end
#2
b0 !
b0 &
1#
#4
0#
0$
#6
b1 !
b1 &
b0 "
b0 %
1#
#8
0#
#10
b10 !
b10 &
b1 "
b1 %
1#
#12
0#
#14
b11 !
b11 &
b10 "
b10 %
1#
#16
0#
#18
b100 !
b100 &
b11 "
b11 %
1#
#20
0#
#22
b101 !
b101 &
b100 "
b100 %
1#
#24
0#
#26
b110 !
b110 &
b101 "
b101 %
1#
#28
0#
#30
b111 !
b111 &
b110 "
b110 %
1#
#32
0#
#34
b1000 !
b1000 &
b111 "
b111 %
1#
#36
0#
#38
b1001 !
b1001 &
b1000 "
b1000 %
1#
#40
0#
#42
b1010 !
b1010 &
b1001 "
b1001 %
1#
#44
0#
#46
b1011 !
b1011 &
b1010 "
b1010 %
1#
#48
0#
#50
b1100 !
b1100 &
b1011 "
b1011 %
1#
#52
0#
#54
b1101 !
b1101 &
b1100 "
b1100 %
1#
#56
0#
#58
b1110 !
b1110 &
b1101 "
b1101 %
1#
#60
0#
#62
b1111 !
b1111 &
b1110 "
b1110 %
1#
#64
0#
#66
b10000 !
b10000 &
b1111 "
b1111 %
1#
#68
0#
#70
b10001 !
b10001 &
b10000 "
b10000 %
1#
#72
0#
#74
b10010 !
b10010 &
b10001 "
b10001 %
1#
#76
0#
#78
b10011 !
b10011 &
b10010 "
b10010 %
1#
#80
0#
#82
b10100 !
b10100 &
b10011 "
b10011 %
1#
#84
0#

87
chapter4/pcIMem Executable file
View File

@@ -0,0 +1,87 @@
#! /usr/bin/vvp
:ivl_version "12.0 (stable)";
:ivl_delay_selection "TYPICAL";
:vpi_time_precision + 0;
:vpi_module "/usr/lib64/ivl/system.vpi";
:vpi_module "/usr/lib64/ivl/vhdl_sys.vpi";
:vpi_module "/usr/lib64/ivl/vhdl_textio.vpi";
:vpi_module "/usr/lib64/ivl/v2005_math.vpi";
:vpi_module "/usr/lib64/ivl/va_math.vpi";
S_0x562710cf28c0 .scope module, "pcIMemTB" "pcIMemTB" 2 1;
.timescale 0 0;
v0x562710d063a0_0 .var "clk", 0 0;
v0x562710d06460_0 .net "instr", 31 0, L_0x562710d06a00; 1 drivers
v0x562710d06500_0 .net "next_pc", 31 0, v0x562710d06080_0; 1 drivers
v0x562710d06600_0 .net "pc", 31 0, v0x562710d06160_0; 1 drivers
v0x562710d066d0_0 .var "rst", 0 0;
S_0x562710cf2a50 .scope module, "dut" "pcIMem" 2 9, 3 1 0, S_0x562710cf28c0;
.timescale 0 0;
.port_info 0 /INPUT 1 "rst";
.port_info 1 /INPUT 1 "clk";
.port_info 2 /OUTPUT 32 "pc";
.port_info 3 /OUTPUT 32 "next_pc";
.port_info 4 /OUTPUT 32 "instr";
L_0x562710d06a00 .functor BUFZ 32, L_0x562710d067c0, C4<00000000000000000000000000000000>, C4<00000000000000000000000000000000>, C4<00000000000000000000000000000000>;
v0x562710cdff80_0 .net *"_ivl_0", 31 0, L_0x562710d067c0; 1 drivers
v0x562710d05d10_0 .net *"_ivl_3", 29 0, L_0x562710d068c0; 1 drivers
v0x562710d05df0_0 .net "clk", 0 0, v0x562710d063a0_0; 1 drivers
v0x562710d05e90 .array "imem", 255 0, 31 0;
v0x562710d05f50_0 .net "instr", 31 0, L_0x562710d06a00; alias, 1 drivers
v0x562710d06080_0 .var "next_pc", 31 0;
v0x562710d06160_0 .var "pc", 31 0;
v0x562710d06240_0 .net "rst", 0 0, v0x562710d066d0_0; 1 drivers
E_0x562710cf0790 .event posedge, v0x562710d05df0_0;
L_0x562710d067c0 .array/port v0x562710d05e90, L_0x562710d068c0;
L_0x562710d068c0 .part v0x562710d06160_0, 2, 30;
.scope S_0x562710cf2a50;
T_0 ;
%wait E_0x562710cf0790;
%load/vec4 v0x562710d06240_0;
%flag_set/vec4 8;
%jmp/0xz T_0.0, 8;
%pushi/vec4 0, 0, 32;
%assign/vec4 v0x562710d06160_0, 0;
%jmp T_0.1;
T_0.0 ;
%load/vec4 v0x562710d06160_0;
%assign/vec4 v0x562710d06080_0, 0;
%load/vec4 v0x562710d06160_0;
%addi 4, 0, 32;
%assign/vec4 v0x562710d06160_0, 0;
T_0.1 ;
%jmp T_0;
.thread T_0;
.scope S_0x562710cf2a50;
T_1 ;
%vpi_call 3 25 "$readmemh", "program.hex", v0x562710d05e90 {0 0 0};
%end;
.thread T_1;
.scope S_0x562710cf28c0;
T_2 ;
%load/vec4 v0x562710d063a0_0;
%inv;
%store/vec4 v0x562710d063a0_0, 0, 1;
%delay 2, 0;
%jmp T_2;
.thread T_2;
.scope S_0x562710cf28c0;
T_3 ;
%vpi_call 2 22 "$dumpfile", "pcIMem.vcd" {0 0 0};
%vpi_call 2 23 "$dumpvars" {0 0 0};
%pushi/vec4 0, 0, 1;
%store/vec4 v0x562710d063a0_0, 0, 1;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x562710d066d0_0, 0, 1;
%delay 4, 0;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x562710d066d0_0, 0, 1;
%delay 38, 0;
%vpi_call 2 27 "$finish" {0 0 0};
%end;
.thread T_3;
# The file index is used to find the file name in the following table.
:file_names 4;
"N/A";
"<interactive>";
"pcIMemTB.v";
"pcIMem.v";

34
chapter4/pcIMem.v Normal file
View File

@@ -0,0 +1,34 @@
module pcIMem (
input rst,
input clk,
output reg [31:0] pc,
output reg [31:0] next_pc,
output wire [31:0] instr
);
//PC
always @(posedge clk) begin
if(rst) begin
pc <= 32'h0;
end
else begin
next_pc <= pc;
pc <= pc + 32'h4;
end
end
//IMem
reg [31:0] imem [0:255];
initial begin
$readmemh("program.hex", imem);
end
assign instr = imem[pc[31:2]];
//Decoder
r
endmodule

145
chapter4/pcIMem.vcd Normal file
View File

@@ -0,0 +1,145 @@
$date
Mon Aug 18 06:14:05 2025
$end
$version
Icarus Verilog
$end
$timescale
1s
$end
$scope module pcIMemTB $end
$var wire 32 ! pc [31:0] $end
$var wire 32 " next_pc [31:0] $end
$var wire 32 # instr [31:0] $end
$var reg 1 $ clk $end
$var reg 1 % rst $end
$scope module dut $end
$var wire 1 $ clk $end
$var wire 32 & instr [31:0] $end
$var wire 1 % rst $end
$var reg 32 ' next_pc [31:0] $end
$var reg 32 ( pc [31:0] $end
$upscope $end
$upscope $end
$enddefinitions $end
$comment Show the parameter values. $end
$dumpall
$end
#0
$dumpvars
bx (
bx '
bx &
1%
0$
bx #
bx "
bx !
$end
#2
b10011 #
b10011 &
b0 !
b0 (
1$
#4
0$
0%
#6
b100000000000010010011 #
b100000000000010010011 &
b100 !
b100 (
b0 "
b0 '
1$
#8
0$
#10
b1000000000000100010011 #
b1000000000000100010011 &
b1000 !
b1000 (
b100 "
b100 '
1$
#12
0$
#14
b1100001000000110010011 #
b1100001000000110010011 &
b1100 !
b1100 (
b1000 "
b1000 '
1$
#16
0$
#18
b10000001000001000010011 #
b10000001000001000010011 &
b10000 !
b10000 (
b1100 "
b1100 '
1$
#20
0$
#22
b10100010000001010010011 #
b10100010000001010010011 &
b10100 !
b10100 (
b10000 "
b10000 '
1$
#24
0$
#26
b11000010000001100010011 #
b11000010000001100010011 &
b11000 !
b11000 (
b10100 "
b10100 '
1$
#28
0$
#30
b110000011000001110010011 #
b110000011000001110010011 &
b11100 !
b11100 (
b11000 "
b11000 '
1$
#32
0$
#34
b110100101000010000010011 #
b110100101000010000010011 &
b100000 !
b100000 (
b11100 "
b11100 '
1$
#36
0$
#38
b11111111111111111111011100110111 #
b11111111111111111111011100110111 &
b100100 !
b100100 (
b100000 "
b100000 '
1$
#40
0$
#42
bx #
bx &
b101000 !
b101000 (
b100100 "
b100100 '
1$

229
chapter4/pcIMemDec Executable file
View File

@@ -0,0 +1,229 @@
#! /usr/bin/vvp
:ivl_version "12.0 (stable)";
:ivl_delay_selection "TYPICAL";
:vpi_time_precision - 12;
:vpi_module "/usr/lib64/ivl/system.vpi";
:vpi_module "/usr/lib64/ivl/vhdl_sys.vpi";
:vpi_module "/usr/lib64/ivl/vhdl_textio.vpi";
:vpi_module "/usr/lib64/ivl/v2005_math.vpi";
:vpi_module "/usr/lib64/ivl/va_math.vpi";
S_0x5615a9568800 .scope module, "pcIMemDecTB" "pcIMemDecTB" 2 3;
.timescale -9 -12;
v0x5615a9591ae0_0 .var "clk", 0 0;
v0x5615a9591ba0_0 .net "instr", 31 0, L_0x5615a95920d0; 1 drivers
v0x5615a9591c40_0 .net "next_pc", 31 0, v0x5615a95917c0_0; 1 drivers
v0x5615a9591ce0_0 .net "pc", 31 0, v0x5615a95918a0_0; 1 drivers
v0x5615a9591d80_0 .var "rst", 0 0;
v0x5615a9591e20 .array "test_mem", 5 0, 31 0;
S_0x5615a9568990 .scope module, "dut" "pcIMemDec" 2 28, 3 1 0, S_0x5615a9568800;
.timescale 0 0;
.port_info 0 /INPUT 1 "rst";
.port_info 1 /INPUT 1 "clk";
.port_info 2 /OUTPUT 32 "pc";
.port_info 3 /OUTPUT 32 "next_pc";
.port_info 4 /OUTPUT 32 "instr";
L_0x5615a95920d0 .functor BUFZ 32, L_0x5615a9591ec0, C4<00000000000000000000000000000000>, C4<00000000000000000000000000000000>, C4<00000000000000000000000000000000>;
L_0x5615a95925c0 .functor OR 1, L_0x5615a9592280, L_0x5615a9592490, C4<0>, C4<0>;
L_0x5615a9592b70 .functor OR 1, L_0x5615a9592770, L_0x5615a95929a0, C4<0>, C4<0>;
L_0x5615a9592ed0 .functor OR 1, L_0x5615a9592b70, L_0x5615a9592d20, C4<0>, C4<0>;
L_0x5615a9592e60 .functor OR 1, L_0x5615a9592ed0, L_0x5615a95930b0, C4<0>, C4<0>;
L_0x5615a9593580 .functor OR 1, L_0x5615a9592e60, L_0x5615a95933b0, C4<0>, C4<0>;
L_0x5615a9593b90 .functor OR 1, L_0x5615a9593770, L_0x5615a95939f0, C4<0>, C4<0>;
L_0x5615a9593ea0 .functor OR 1, L_0x5615a9593b90, L_0x5615a9593ca0, C4<0>, C4<0>;
L_0x5615a95942b0 .functor OR 1, L_0x5615a9593ea0, L_0x5615a95940a0, C4<0>, C4<0>;
L_0x5615a9594950 .functor OR 1, L_0x5615a9594460, L_0x5615a9594720, C4<0>, C4<0>;
v0x5615a9563ea0_0 .net *"_ivl_0", 31 0, L_0x5615a9591ec0; 1 drivers
v0x5615a958e600_0 .net *"_ivl_10", 0 0, L_0x5615a9592280; 1 drivers
v0x5615a958e6c0_0 .net *"_ivl_103", 6 0, L_0x5615a9594ac0; 1 drivers
L_0x7f12ec2a43c0 .functor BUFT 1, C4<1100011>, C4<0>, C4<0>, C4<0>;
v0x5615a958e780_0 .net/2u *"_ivl_104", 6 0, L_0x7f12ec2a43c0; 1 drivers
v0x5615a958e860_0 .net *"_ivl_109", 6 0, L_0x5615a9594f60; 1 drivers
L_0x7f12ec2a4408 .functor BUFT 1, C4<1101111>, C4<0>, C4<0>, C4<0>;
v0x5615a958e990_0 .net/2u *"_ivl_110", 6 0, L_0x7f12ec2a4408; 1 drivers
v0x5615a958ea70_0 .net *"_ivl_13", 6 0, L_0x5615a95923f0; 1 drivers
L_0x7f12ec2a4060 .functor BUFT 1, C4<0010111>, C4<0>, C4<0>, C4<0>;
v0x5615a958eb50_0 .net/2u *"_ivl_14", 6 0, L_0x7f12ec2a4060; 1 drivers
v0x5615a958ec30_0 .net *"_ivl_16", 0 0, L_0x5615a9592490; 1 drivers
v0x5615a958ecf0_0 .net *"_ivl_21", 6 0, L_0x5615a95926d0; 1 drivers
L_0x7f12ec2a40a8 .functor BUFT 1, C4<0000011>, C4<0>, C4<0>, C4<0>;
v0x5615a958edd0_0 .net/2u *"_ivl_22", 6 0, L_0x7f12ec2a40a8; 1 drivers
v0x5615a958eeb0_0 .net *"_ivl_24", 0 0, L_0x5615a9592770; 1 drivers
v0x5615a958ef70_0 .net *"_ivl_27", 6 0, L_0x5615a9592900; 1 drivers
L_0x7f12ec2a40f0 .functor BUFT 1, C4<0000111>, C4<0>, C4<0>, C4<0>;
v0x5615a958f050_0 .net/2u *"_ivl_28", 6 0, L_0x7f12ec2a40f0; 1 drivers
v0x5615a958f130_0 .net *"_ivl_3", 29 0, L_0x5615a9591f90; 1 drivers
v0x5615a958f210_0 .net *"_ivl_30", 0 0, L_0x5615a95929a0; 1 drivers
v0x5615a958f2d0_0 .net *"_ivl_33", 0 0, L_0x5615a9592b70; 1 drivers
v0x5615a958f390_0 .net *"_ivl_35", 6 0, L_0x5615a9592c30; 1 drivers
L_0x7f12ec2a4138 .functor BUFT 1, C4<0010011>, C4<0>, C4<0>, C4<0>;
v0x5615a958f470_0 .net/2u *"_ivl_36", 6 0, L_0x7f12ec2a4138; 1 drivers
v0x5615a958f550_0 .net *"_ivl_38", 0 0, L_0x5615a9592d20; 1 drivers
v0x5615a958f610_0 .net *"_ivl_41", 0 0, L_0x5615a9592ed0; 1 drivers
v0x5615a958f6d0_0 .net *"_ivl_43", 6 0, L_0x5615a9593010; 1 drivers
L_0x7f12ec2a4180 .functor BUFT 1, C4<0011011>, C4<0>, C4<0>, C4<0>;
v0x5615a958f7b0_0 .net/2u *"_ivl_44", 6 0, L_0x7f12ec2a4180; 1 drivers
v0x5615a958f890_0 .net *"_ivl_46", 0 0, L_0x5615a95930b0; 1 drivers
v0x5615a958f950_0 .net *"_ivl_49", 0 0, L_0x5615a9592e60; 1 drivers
v0x5615a958fa10_0 .net *"_ivl_51", 6 0, L_0x5615a9593310; 1 drivers
L_0x7f12ec2a41c8 .functor BUFT 1, C4<1100111>, C4<0>, C4<0>, C4<0>;
v0x5615a958faf0_0 .net/2u *"_ivl_52", 6 0, L_0x7f12ec2a41c8; 1 drivers
v0x5615a958fbd0_0 .net *"_ivl_54", 0 0, L_0x5615a95933b0; 1 drivers
v0x5615a958fc90_0 .net *"_ivl_59", 6 0, L_0x5615a95936d0; 1 drivers
L_0x7f12ec2a4210 .functor BUFT 1, C4<0101111>, C4<0>, C4<0>, C4<0>;
v0x5615a958fd70_0 .net/2u *"_ivl_60", 6 0, L_0x7f12ec2a4210; 1 drivers
v0x5615a958fe50_0 .net *"_ivl_62", 0 0, L_0x5615a9593770; 1 drivers
v0x5615a958ff10_0 .net *"_ivl_65", 6 0, L_0x5615a9593950; 1 drivers
L_0x7f12ec2a4258 .functor BUFT 1, C4<0110011>, C4<0>, C4<0>, C4<0>;
v0x5615a958fff0_0 .net/2u *"_ivl_66", 6 0, L_0x7f12ec2a4258; 1 drivers
v0x5615a95902e0_0 .net *"_ivl_68", 0 0, L_0x5615a95939f0; 1 drivers
v0x5615a95903a0_0 .net *"_ivl_7", 6 0, L_0x5615a95921e0; 1 drivers
v0x5615a9590480_0 .net *"_ivl_71", 0 0, L_0x5615a9593b90; 1 drivers
v0x5615a9590540_0 .net *"_ivl_73", 6 0, L_0x5615a95938b0; 1 drivers
L_0x7f12ec2a42a0 .functor BUFT 1, C4<0111011>, C4<0>, C4<0>, C4<0>;
v0x5615a9590620_0 .net/2u *"_ivl_74", 6 0, L_0x7f12ec2a42a0; 1 drivers
v0x5615a9590700_0 .net *"_ivl_76", 0 0, L_0x5615a9593ca0; 1 drivers
v0x5615a95907c0_0 .net *"_ivl_79", 0 0, L_0x5615a9593ea0; 1 drivers
L_0x7f12ec2a4018 .functor BUFT 1, C4<0110111>, C4<0>, C4<0>, C4<0>;
v0x5615a9590880_0 .net/2u *"_ivl_8", 6 0, L_0x7f12ec2a4018; 1 drivers
v0x5615a9590960_0 .net *"_ivl_81", 6 0, L_0x5615a9594000; 1 drivers
L_0x7f12ec2a42e8 .functor BUFT 1, C4<0110011>, C4<0>, C4<0>, C4<0>;
v0x5615a9590a40_0 .net/2u *"_ivl_82", 6 0, L_0x7f12ec2a42e8; 1 drivers
v0x5615a9590b20_0 .net *"_ivl_84", 0 0, L_0x5615a95940a0; 1 drivers
v0x5615a9590be0_0 .net *"_ivl_89", 6 0, L_0x5615a95943c0; 1 drivers
L_0x7f12ec2a4330 .functor BUFT 1, C4<0100011>, C4<0>, C4<0>, C4<0>;
v0x5615a9590cc0_0 .net/2u *"_ivl_90", 6 0, L_0x7f12ec2a4330; 1 drivers
v0x5615a9590da0_0 .net *"_ivl_92", 0 0, L_0x5615a9594460; 1 drivers
v0x5615a9590e60_0 .net *"_ivl_95", 6 0, L_0x5615a9594680; 1 drivers
L_0x7f12ec2a4378 .functor BUFT 1, C4<0100111>, C4<0>, C4<0>, C4<0>;
v0x5615a9590f40_0 .net/2u *"_ivl_96", 6 0, L_0x7f12ec2a4378; 1 drivers
v0x5615a9591020_0 .net *"_ivl_98", 0 0, L_0x5615a9594720; 1 drivers
v0x5615a95910e0_0 .net "clk", 0 0, v0x5615a9591ae0_0; 1 drivers
v0x5615a95911a0 .array "imem", 255 0, 31 0;
v0x5615a9591260_0 .net "instr", 31 0, L_0x5615a95920d0; alias, 1 drivers
v0x5615a9591340_0 .net "isBType", 0 0, L_0x5615a9594d70; 1 drivers
v0x5615a9591400_0 .net "isIType", 0 0, L_0x5615a9593580; 1 drivers
v0x5615a95914c0_0 .net "isJType", 0 0, L_0x5615a9595000; 1 drivers
v0x5615a9591580_0 .net "isRType", 0 0, L_0x5615a95942b0; 1 drivers
v0x5615a9591640_0 .net "isSType", 0 0, L_0x5615a9594950; 1 drivers
v0x5615a9591700_0 .net "isUType", 0 0, L_0x5615a95925c0; 1 drivers
v0x5615a95917c0_0 .var "next_pc", 31 0;
v0x5615a95918a0_0 .var "pc", 31 0;
v0x5615a9591980_0 .net "rst", 0 0, v0x5615a9591d80_0; 1 drivers
E_0x5615a9561800 .event posedge, v0x5615a95910e0_0;
L_0x5615a9591ec0 .array/port v0x5615a95911a0, L_0x5615a9591f90;
L_0x5615a9591f90 .part v0x5615a95918a0_0, 2, 30;
L_0x5615a95921e0 .part L_0x5615a95920d0, 0, 7;
L_0x5615a9592280 .cmp/eq 7, L_0x5615a95921e0, L_0x7f12ec2a4018;
L_0x5615a95923f0 .part L_0x5615a95920d0, 0, 7;
L_0x5615a9592490 .cmp/eq 7, L_0x5615a95923f0, L_0x7f12ec2a4060;
L_0x5615a95926d0 .part L_0x5615a95920d0, 0, 7;
L_0x5615a9592770 .cmp/eq 7, L_0x5615a95926d0, L_0x7f12ec2a40a8;
L_0x5615a9592900 .part L_0x5615a95920d0, 0, 7;
L_0x5615a95929a0 .cmp/eq 7, L_0x5615a9592900, L_0x7f12ec2a40f0;
L_0x5615a9592c30 .part L_0x5615a95920d0, 0, 7;
L_0x5615a9592d20 .cmp/eq 7, L_0x5615a9592c30, L_0x7f12ec2a4138;
L_0x5615a9593010 .part L_0x5615a95920d0, 0, 7;
L_0x5615a95930b0 .cmp/eq 7, L_0x5615a9593010, L_0x7f12ec2a4180;
L_0x5615a9593310 .part L_0x5615a95920d0, 0, 7;
L_0x5615a95933b0 .cmp/eq 7, L_0x5615a9593310, L_0x7f12ec2a41c8;
L_0x5615a95936d0 .part L_0x5615a95920d0, 0, 7;
L_0x5615a9593770 .cmp/eq 7, L_0x5615a95936d0, L_0x7f12ec2a4210;
L_0x5615a9593950 .part L_0x5615a95920d0, 0, 7;
L_0x5615a95939f0 .cmp/eq 7, L_0x5615a9593950, L_0x7f12ec2a4258;
L_0x5615a95938b0 .part L_0x5615a95920d0, 0, 7;
L_0x5615a9593ca0 .cmp/eq 7, L_0x5615a95938b0, L_0x7f12ec2a42a0;
L_0x5615a9594000 .part L_0x5615a95920d0, 0, 7;
L_0x5615a95940a0 .cmp/eq 7, L_0x5615a9594000, L_0x7f12ec2a42e8;
L_0x5615a95943c0 .part L_0x5615a95920d0, 0, 7;
L_0x5615a9594460 .cmp/eq 7, L_0x5615a95943c0, L_0x7f12ec2a4330;
L_0x5615a9594680 .part L_0x5615a95920d0, 0, 7;
L_0x5615a9594720 .cmp/eq 7, L_0x5615a9594680, L_0x7f12ec2a4378;
L_0x5615a9594ac0 .part L_0x5615a95920d0, 0, 7;
L_0x5615a9594d70 .cmp/eq 7, L_0x5615a9594ac0, L_0x7f12ec2a43c0;
L_0x5615a9594f60 .part L_0x5615a95920d0, 0, 7;
L_0x5615a9595000 .cmp/eq 7, L_0x5615a9594f60, L_0x7f12ec2a4408;
.scope S_0x5615a9568990;
T_0 ;
%wait E_0x5615a9561800;
%load/vec4 v0x5615a9591980_0;
%flag_set/vec4 8;
%jmp/0xz T_0.0, 8;
%pushi/vec4 0, 0, 32;
%assign/vec4 v0x5615a95918a0_0, 0;
%jmp T_0.1;
T_0.0 ;
%load/vec4 v0x5615a95918a0_0;
%assign/vec4 v0x5615a95917c0_0, 0;
%load/vec4 v0x5615a95918a0_0;
%addi 4, 0, 32;
%assign/vec4 v0x5615a95918a0_0, 0;
T_0.1 ;
%jmp T_0;
.thread T_0;
.scope S_0x5615a9568990;
T_1 ;
%vpi_call 3 25 "$readmemh", "program.hex", v0x5615a95911a0 {0 0 0};
%end;
.thread T_1;
.scope S_0x5615a9568800;
T_2 ;
%pushi/vec4 4151, 0, 32;
%ix/load 4, 0, 0;
%flag_set/imm 4, 0;
%store/vec4a v0x5615a9591e20, 4, 0;
%pushi/vec4 1048723, 0, 32;
%ix/load 4, 1, 0;
%flag_set/imm 4, 0;
%store/vec4a v0x5615a9591e20, 4, 0;
%pushi/vec4 1081779, 0, 32;
%ix/load 4, 2, 0;
%flag_set/imm 4, 0;
%store/vec4a v0x5615a9591e20, 4, 0;
%pushi/vec4 1089571, 0, 32;
%ix/load 4, 3, 0;
%flag_set/imm 4, 0;
%store/vec4a v0x5615a9591e20, 4, 0;
%pushi/vec4 1082979, 0, 32;
%ix/load 4, 4, 0;
%flag_set/imm 4, 0;
%store/vec4a v0x5615a9591e20, 4, 0;
%pushi/vec4 12583023, 0, 32;
%ix/load 4, 5, 0;
%flag_set/imm 4, 0;
%store/vec4a v0x5615a9591e20, 4, 0;
%vpi_call 2 23 "$writememh", "program.hex", v0x5615a9591e20 {0 0 0};
%delay 1000, 0;
%end;
.thread T_2;
.scope S_0x5615a9568800;
T_3 ;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x5615a9591ae0_0, 0, 1;
T_3.0 ;
%delay 5000, 0;
%load/vec4 v0x5615a9591ae0_0;
%inv;
%store/vec4 v0x5615a9591ae0_0, 0, 1;
%jmp T_3.0;
%end;
.thread T_3;
.scope S_0x5615a9568800;
T_4 ;
%vpi_call 2 44 "$dumpfile", "pcIMemDec.vcd" {0 0 0};
%vpi_call 2 45 "$dumpvars", 32'sb00000000000000000000000000000000, S_0x5615a9568800 {0 0 0};
%pushi/vec4 1, 0, 1;
%store/vec4 v0x5615a9591d80_0, 0, 1;
%delay 20000, 0;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x5615a9591d80_0, 0, 1;
%vpi_call 2 50 "$monitor", "Time=%0t PC=%h Instr=%h Types: U=%b I=%b R=%b S=%b B=%b J=%b", $time, v0x5615a9591ce0_0, v0x5615a9591ba0_0, v0x5615a9591700_0, v0x5615a9591400_0, v0x5615a9591580_0, v0x5615a9591640_0, v0x5615a9591340_0, v0x5615a95914c0_0 {0 0 0};
%delay 200000, 0;
%vpi_call 2 54 "$finish" {0 0 0};
%end;
.thread T_4;
# The file index is used to find the file name in the following table.
:file_names 4;
"N/A";
"<interactive>";
"pcIMemDecTB.v";
"pcIMemDec.v";

72
chapter4/pcIMemDec.v Normal file
View File

@@ -0,0 +1,72 @@
module pcIMemDec (
input rst,
input clk,
output reg [31:0] pc,
output reg [31:0] next_pc,
output wire [31:0] instr
);
//PC
always @(posedge clk) begin
if(rst) begin
pc <= 32'h0;
end
else begin
next_pc <= pc;
pc <= pc + 32'h4;
end
end
//IMem
reg [31:0] imem [0:255];
initial begin
$readmemh("program.hex", imem);
end
assign instr = imem[pc[31:2]];
//Decoder
wire isUType = ((instr[6:0] == 7'b0110111) || (instr[6:0] == 7'b0010111));
wire isIType = ((instr[6:0] == 7'b0000011) || (instr[6:0] == 7'b0000111) || (instr[6:0] == 7'b0010011) || (instr[6:0] == 7'b0011011) || (instr [6:0] == 7'b1100111));
wire isRType = ((instr[6:0] == 7'b0101111) || (instr[6:0] == 7'b0110011) || (instr[6:0] == 7'b0111011) || (instr[6:0] == 7'b0110011));
wire isSType = ((instr[6:0] == 7'b0100011) || (instr[6:0] == 7'b0100111));
wire isBType = (instr[6:0] == 7'b1100011);
wire isJType = (instr[6:0] == 7'b1101111);
wire [4:0] rs1 = instr[19:15];
wire [4:0] rs2 = instr[24:20];
wire [4:0] rd = instr[11:7];
wire rs2Valid = (isRType || isSType || isBType);
wire rs1Valid = (~isUType && ~isJType);
wire rdValid = (~isSType && ~isBType);
wire [3:0] funct3 = instr[14:12];
wire [6:0] funct7 = instr[31:25];
wire funct3Valid = rs1Valid;
wire funct7Valid = isRType;
wire [31:0] Iimm = {{21{instr[31]}}, {instr[30:25]}, {instr[24:20]}};
wire [31:0] Simm = {{21{instr[31]}}, {instr[30:25]}, {instr[11:7]}};
wire [31:0] Bimm = {{20{instr[31]}}, {instr[7]}, {instr[30:25]}, {instr[11:8]}, 1'b0};
wire [31:0] Uimm = {{instr[31]}, {instr[30:20]}, {instr[19:12]}, {12{1'b0}};
wire [31:0] Jimm = {{12{instr[31]}}, {instr[19:12]}, {instr[20]}, {instr[30:25]}, {instr[24:21]}, 1'b0};
//Instructions
isBEQ = (funct3 == 000 && isBType);
isBNE = (funct3 == 001 && isBType);
isBLT = (funct3 == 100 && isBType);
isBGE = (funct3 == 101 && isBType);
isBLTU = (funct3 == 110 && isBType);
isBGEU = (funct3 == 111 && isBType);
isADDI = (funct3 == 000 && isIType);
isADD = (funct7[5] == 0 && isRType);
endmodule

257
chapter4/pcIMemDec.vcd Normal file
View File

@@ -0,0 +1,257 @@
$date
Mon Aug 18 06:47:55 2025
$end
$version
Icarus Verilog
$end
$timescale
1ps
$end
$scope module pcIMemDecTB $end
$var wire 32 ! pc [31:0] $end
$var wire 32 " next_pc [31:0] $end
$var wire 32 # instr [31:0] $end
$var reg 1 $ clk $end
$var reg 1 % rst $end
$scope module dut $end
$var wire 1 $ clk $end
$var wire 32 & instr [31:0] $end
$var wire 1 ' isIType $end
$var wire 1 ( isRType $end
$var wire 1 ) isSType $end
$var wire 1 * isUType $end
$var wire 1 % rst $end
$var wire 1 + isJType $end
$var wire 1 , isBType $end
$var reg 32 - next_pc [31:0] $end
$var reg 32 . pc [31:0] $end
$upscope $end
$upscope $end
$enddefinitions $end
$comment Show the parameter values. $end
$dumpall
$end
#0
$dumpvars
bx .
bx -
x,
x+
x*
x)
x(
x'
bx &
1%
0$
bx #
bx "
bx !
$end
#5000
0'
0(
1*
0)
0,
0+
b1000000110111 #
b1000000110111 &
b0 !
b0 .
1$
#10000
0$
#15000
1$
#20000
0$
0%
#25000
1'
0*
b100000000000010010011 #
b100000000000010010011 &
b100 !
b100 .
b0 "
b0 -
1$
#30000
0$
#35000
0'
1(
b100001000000110110011 #
b100001000000110110011 &
b1000 !
b1000 .
b100 "
b100 -
1$
#40000
0$
#45000
0(
1)
b100001010000000100011 #
b100001010000000100011 &
b1100 !
b1100 .
b1000 "
b1000 -
1$
#50000
0$
#55000
0)
1,
b100001000011001100011 #
b100001000011001100011 &
b10000 !
b10000 .
b1100 "
b1100 -
1$
#60000
0$
#65000
0,
1+
b110000000000000001101111 #
b110000000000000001101111 &
b10100 !
b10100 .
b10000 "
b10000 -
1$
#70000
0$
#75000
x*
x'
x(
x)
x,
x+
bx #
bx &
b11000 !
b11000 .
b10100 "
b10100 -
1$
#80000
0$
#85000
b11100 !
b11100 .
b11000 "
b11000 -
1$
#90000
0$
#95000
b100000 !
b100000 .
b11100 "
b11100 -
1$
#100000
0$
#105000
b100100 !
b100100 .
b100000 "
b100000 -
1$
#110000
0$
#115000
b101000 !
b101000 .
b100100 "
b100100 -
1$
#120000
0$
#125000
b101100 !
b101100 .
b101000 "
b101000 -
1$
#130000
0$
#135000
b110000 !
b110000 .
b101100 "
b101100 -
1$
#140000
0$
#145000
b110100 !
b110100 .
b110000 "
b110000 -
1$
#150000
0$
#155000
b111000 !
b111000 .
b110100 "
b110100 -
1$
#160000
0$
#165000
b111100 !
b111100 .
b111000 "
b111000 -
1$
#170000
0$
#175000
b1000000 !
b1000000 .
b111100 "
b111100 -
1$
#180000
0$
#185000
b1000100 !
b1000100 .
b1000000 "
b1000000 -
1$
#190000
0$
#195000
b1001000 !
b1001000 .
b1000100 "
b1000100 -
1$
#200000
0$
#205000
b1001100 !
b1001100 .
b1001000 "
b1001000 -
1$
#210000
0$
#215000
b1010000 !
b1010000 .
b1001100 "
b1001100 -
1$
#220000
0$

56
chapter4/pcIMemDecTB.v Normal file
View File

@@ -0,0 +1,56 @@
`timescale 1ns/1ps
module pcIMemDecTB();
// Inputs
reg clk;
reg rst;
// Outputs
wire [31:0] pc;
wire [31:0] next_pc;
wire [31:0] instr;
// Create test memory and program.hex FIRST
reg [31:0] test_mem [0:5];
initial begin
test_mem[0] = 32'h00001037; // lui x0, 1
test_mem[1] = 32'h00100093; // addi x1, x0, 1
test_mem[2] = 32'h001081b3; // add x3, x1, x1
test_mem[3] = 32'h0010a023; // sw x1, 0(x1)
test_mem[4] = 32'h00108663; // beq x1, x1, 12
test_mem[5] = 32'h00c0006f; // jal x0, 12
$writememh("program.hex", test_mem);
#1; // Small delay to ensure file creation
end
// Instantiate DUT AFTER file creation
pcIMemDec dut (
.clk(clk),
.rst(rst),
.pc(pc),
.next_pc(next_pc),
.instr(instr)
);
// Clock generation (100MHz)
initial begin
clk = 0;
forever #5 clk = ~clk;
end
// Test sequence
initial begin
$dumpfile("pcIMemDec.vcd");
$dumpvars(0, pcIMemDecTB);
rst = 1;
#20 rst = 0;
$monitor("Time=%0t PC=%h Instr=%h Types: U=%b I=%b R=%b S=%b B=%b J=%b",
$time, pc, instr,
dut.isUType, dut.isIType, dut.isRType, dut.isSType, dut.isBType, dut.isJType);
#200 $finish;
end
endmodule

29
chapter4/pcIMemTB.v Normal file
View File

@@ -0,0 +1,29 @@
module pcIMemTB();
reg rst;
reg clk;
wire [31:0] pc;
wire [31:0] next_pc;
wire [31:0] instr;
pcIMem dut (
.clk(clk),
.rst(rst),
.pc(pc),
.instr(instr),
.next_pc(next_pc)
);
always begin
clk = ~clk; #2;
end
initial begin
$dumpfile("pcIMem.vcd");
$dumpvars;
clk = 1'b0;
rst = 1'b1; #4;
rst = 1'b0; #38;
$finish;
end
endmodule

28
chapter4/pcTB.v Normal file
View File

@@ -0,0 +1,28 @@
module pcTB();
reg clk;
reg rst;
wire [31:0] pc;
wire [31:0] next_pc;
pc uut (
.clk(clk),
.rst(rst),
.pc(pc),
.next_pc(next_pc)
);
always begin
clk = ~clk; #2;
end
initial begin
$dumpfile("pc.vcd");
$dumpvars;
clk = 0;
rst = 1; #4;
rst = 0; #80;
$finish;
end
endmodule

7
chapter4/program.hex Normal file
View File

@@ -0,0 +1,7 @@
// 0x00000000
00001037
00100093
001081b3
0010a023
00108663
00c0006f