first commit

This commit is contained in:
Jose Luis Montañes Ojados
2026-02-28 21:59:55 +01:00
commit d094ff3148
21 changed files with 2286 additions and 0 deletions

32
adder_nbit/adder_nbit.v Normal file
View File

@@ -0,0 +1,32 @@
/*
Adder de N bits
*/
`include "./full_adder/full_adder.v"
module adder_nbit #(parameter N = 8)(
input [N-1:0] a,
input [N-1:0] b,
input carry_in,
output [N-1:0] sum,
output carry_out
);
wire [N:0] carry;
assign carry[0] = carry_in;
genvar i;
generate
for (i = 0; i < N; i = i + 1) begin: generar_full_adder
full_adder_structural full_adder(
.carry_in(carry[i]),
.a(a[i]),
.b(b[i]),
.sum(sum[i]),
.carry_out(carry[i+1])
);
end
endgenerate
assign carry_out = carry[N];
endmodule

330
adder_nbit/adder_nbit.vcd Normal file
View File

@@ -0,0 +1,330 @@
$date
Sat Feb 28 20:27:33 2026
$end
$version
Icarus Verilog
$end
$timescale
1s
$end
$scope module adder_nbit_tb $end
$var wire 1 ! carry_out $end
$var wire 8 " sum [7:0] $end
$var reg 8 # a [7:0] $end
$var reg 8 $ b [7:0] $end
$var reg 1 % carry_in $end
$scope module adder_8bit $end
$var wire 8 & a [7:0] $end
$var wire 8 ' b [7:0] $end
$var wire 9 ( carry [8:0] $end
$var wire 1 ) carry_in $end
$var wire 1 ! carry_out $end
$var wire 8 * sum [7:0] $end
$scope begin generar_full_adder[0] $end
$scope module full_adder $end
$var wire 1 + a $end
$var wire 1 , add1_carry $end
$var wire 1 - add1_sum $end
$var wire 1 . add2_carry $end
$var wire 1 / b $end
$var wire 1 0 carry_in $end
$var wire 1 1 carry_out $end
$var wire 1 2 sum $end
$scope module add1 $end
$var wire 1 + a $end
$var wire 1 / b $end
$var wire 1 , carry $end
$var wire 1 - sum $end
$upscope $end
$scope module add2 $end
$var wire 1 - a $end
$var wire 1 0 b $end
$var wire 1 . carry $end
$var wire 1 2 sum $end
$upscope $end
$upscope $end
$upscope $end
$scope begin generar_full_adder[1] $end
$scope module full_adder $end
$var wire 1 3 a $end
$var wire 1 4 add1_carry $end
$var wire 1 5 add1_sum $end
$var wire 1 6 add2_carry $end
$var wire 1 7 b $end
$var wire 1 8 carry_in $end
$var wire 1 9 carry_out $end
$var wire 1 : sum $end
$scope module add1 $end
$var wire 1 3 a $end
$var wire 1 7 b $end
$var wire 1 4 carry $end
$var wire 1 5 sum $end
$upscope $end
$scope module add2 $end
$var wire 1 5 a $end
$var wire 1 8 b $end
$var wire 1 6 carry $end
$var wire 1 : sum $end
$upscope $end
$upscope $end
$upscope $end
$scope begin generar_full_adder[2] $end
$scope module full_adder $end
$var wire 1 ; a $end
$var wire 1 < add1_carry $end
$var wire 1 = add1_sum $end
$var wire 1 > add2_carry $end
$var wire 1 ? b $end
$var wire 1 @ carry_in $end
$var wire 1 A carry_out $end
$var wire 1 B sum $end
$scope module add1 $end
$var wire 1 ; a $end
$var wire 1 ? b $end
$var wire 1 < carry $end
$var wire 1 = sum $end
$upscope $end
$scope module add2 $end
$var wire 1 = a $end
$var wire 1 @ b $end
$var wire 1 > carry $end
$var wire 1 B sum $end
$upscope $end
$upscope $end
$upscope $end
$scope begin generar_full_adder[3] $end
$scope module full_adder $end
$var wire 1 C a $end
$var wire 1 D add1_carry $end
$var wire 1 E add1_sum $end
$var wire 1 F add2_carry $end
$var wire 1 G b $end
$var wire 1 H carry_in $end
$var wire 1 I carry_out $end
$var wire 1 J sum $end
$scope module add1 $end
$var wire 1 C a $end
$var wire 1 G b $end
$var wire 1 D carry $end
$var wire 1 E sum $end
$upscope $end
$scope module add2 $end
$var wire 1 E a $end
$var wire 1 H b $end
$var wire 1 F carry $end
$var wire 1 J sum $end
$upscope $end
$upscope $end
$upscope $end
$scope begin generar_full_adder[4] $end
$scope module full_adder $end
$var wire 1 K a $end
$var wire 1 L add1_carry $end
$var wire 1 M add1_sum $end
$var wire 1 N add2_carry $end
$var wire 1 O b $end
$var wire 1 P carry_in $end
$var wire 1 Q carry_out $end
$var wire 1 R sum $end
$scope module add1 $end
$var wire 1 K a $end
$var wire 1 O b $end
$var wire 1 L carry $end
$var wire 1 M sum $end
$upscope $end
$scope module add2 $end
$var wire 1 M a $end
$var wire 1 P b $end
$var wire 1 N carry $end
$var wire 1 R sum $end
$upscope $end
$upscope $end
$upscope $end
$scope begin generar_full_adder[5] $end
$scope module full_adder $end
$var wire 1 S a $end
$var wire 1 T add1_carry $end
$var wire 1 U add1_sum $end
$var wire 1 V add2_carry $end
$var wire 1 W b $end
$var wire 1 X carry_in $end
$var wire 1 Y carry_out $end
$var wire 1 Z sum $end
$scope module add1 $end
$var wire 1 S a $end
$var wire 1 W b $end
$var wire 1 T carry $end
$var wire 1 U sum $end
$upscope $end
$scope module add2 $end
$var wire 1 U a $end
$var wire 1 X b $end
$var wire 1 V carry $end
$var wire 1 Z sum $end
$upscope $end
$upscope $end
$upscope $end
$scope begin generar_full_adder[6] $end
$scope module full_adder $end
$var wire 1 [ a $end
$var wire 1 \ add1_carry $end
$var wire 1 ] add1_sum $end
$var wire 1 ^ add2_carry $end
$var wire 1 _ b $end
$var wire 1 ` carry_in $end
$var wire 1 a carry_out $end
$var wire 1 b sum $end
$scope module add1 $end
$var wire 1 [ a $end
$var wire 1 _ b $end
$var wire 1 \ carry $end
$var wire 1 ] sum $end
$upscope $end
$scope module add2 $end
$var wire 1 ] a $end
$var wire 1 ` b $end
$var wire 1 ^ carry $end
$var wire 1 b sum $end
$upscope $end
$upscope $end
$upscope $end
$scope begin generar_full_adder[7] $end
$scope module full_adder $end
$var wire 1 c a $end
$var wire 1 d add1_carry $end
$var wire 1 e add1_sum $end
$var wire 1 f add2_carry $end
$var wire 1 g b $end
$var wire 1 h carry_in $end
$var wire 1 i carry_out $end
$var wire 1 j sum $end
$scope module add1 $end
$var wire 1 c a $end
$var wire 1 g b $end
$var wire 1 d carry $end
$var wire 1 e sum $end
$upscope $end
$scope module add2 $end
$var wire 1 e a $end
$var wire 1 h b $end
$var wire 1 f carry $end
$var wire 1 j sum $end
$upscope $end
$upscope $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
$dumpvars
0j
0i
0h
0g
0f
0e
0d
0c
0b
0a
0`
0_
0^
0]
0\
0[
0Z
0Y
0X
0W
0V
0U
0T
0S
0R
0Q
0P
0O
0N
0M
0L
0K
0J
0I
0H
0G
0F
0E
0D
0C
1B
0A
0@
1?
0>
1=
0<
0;
0:
09
08
07
06
05
04
03
12
01
00
1/
0.
1-
0,
0+
b101 *
0)
b0 (
b101 '
b0 &
0%
b101 $
b0 #
b101 "
0!
$end
#1
1:
1J
b1111 "
b1111 *
15
1E
13
1C
b1010 #
b1010 &
#2
1H
0:
0B
1A
b1000 (
1J
1Z
1b
b1101001 "
b1101001 *
05
0=
1<
0E
1U
1]
03
1;
0C
1S
1[
b1100100 #
b1100100 &
#3

421
adder_nbit/adder_nbit.vvp Normal file
View File

@@ -0,0 +1,421 @@
#! /c/iverilog/bin/vvp
:ivl_version "0.9.7 " "(v0_9_7)";
:vpi_time_precision + 0;
:vpi_module "system";
:vpi_module "v2005_math";
:vpi_module "va_math";
S_0118C068 .scope module, "adder_nbit_tb" "adder_nbit_tb" 2 3;
.timescale 0 0;
v011CE8B0_0 .var "a", 7 0;
v011CE3E0_0 .var "b", 7 0;
v011CE750_0 .var "carry_in", 0 0;
v011CE800_0 .net "carry_out", 0 0, L_011D03D8; 1 drivers
RS_0119B434/0/0 .resolv tri, L_011CEDD8, L_011CED80, L_011D0010, L_011CF880;
RS_0119B434/0/4 .resolv tri, L_011CF720, L_011CFFB8, L_011CFAE8, L_011D00C0;
RS_0119B434 .resolv tri, RS_0119B434/0/0, RS_0119B434/0/4, C4<zzzzzzzz>, C4<zzzzzzzz>;
v011CE7A8_0 .net8 "sum", 7 0, RS_0119B434; 8 drivers
S_0118BE48 .scope module, "adder_8bit" "adder_nbit" 2 10, 3 6, S_0118C068;
.timescale 0 0;
P_01190EEC .param/l "N" 3 6, +C4<01000>;
L_011D0B48 .functor BUFZ 1, v011CE750_0, C4<0>, C4<0>, C4<0>;
v011CE540_0 .net *"_s59", 0 0, L_011D0B48; 1 drivers
v011CE6F8_0 .net "a", 7 0, v011CE8B0_0; 1 drivers
v011CE438_0 .net "b", 7 0, v011CE3E0_0; 1 drivers
RS_0119B3EC/0/0 .resolv tri, L_011CEAC0, L_011CFCA0, L_011CF930, L_011CF8D8;
RS_0119B3EC/0/4 .resolv tri, L_011CF9E0, L_011CFB98, L_011CFB40, L_011CFEB0;
RS_0119B3EC/0/8 .resolv tri, L_011CF7D0, C4<zzzzzzzzz>, C4<zzzzzzzzz>, C4<zzzzzzzzz>;
RS_0119B3EC .resolv tri, RS_0119B3EC/0/0, RS_0119B3EC/0/4, RS_0119B3EC/0/8, C4<zzzzzzzzz>;
v011CE070_0 .net8 "carry", 8 0, RS_0119B3EC; 9 drivers
v011CE2D8_0 .net "carry_in", 0 0, v011CE750_0; 1 drivers
v011CE858_0 .alias "carry_out", 0 0, v011CE800_0;
v011CE120_0 .alias "sum", 7 0, v011CE7A8_0;
L_011CED28 .part RS_0119B3EC, 0, 1;
L_011CEBC8 .part v011CE8B0_0, 0, 1;
L_011CEB70 .part v011CE3E0_0, 0, 1;
L_011CEDD8 .part/pv L_011CDAF8, 0, 1, 8;
L_011CEAC0 .part/pv L_011CDA88, 1, 1, 9;
L_011CEC20 .part RS_0119B3EC, 1, 1;
L_011CE960 .part v011CE8B0_0, 1, 1;
L_011CEC78 .part v011CE3E0_0, 1, 1;
L_011CED80 .part/pv L_011CF060, 1, 1, 8;
L_011CFCA0 .part/pv L_011CEED8, 2, 1, 9;
L_011CF828 .part RS_0119B3EC, 2, 1;
L_011CFCF8 .part v011CE8B0_0, 2, 1;
L_011CFF08 .part v011CE3E0_0, 2, 1;
L_011D0010 .part/pv L_011CF140, 2, 1, 8;
L_011CF930 .part/pv L_011CEEA0, 3, 1, 9;
L_011CF988 .part RS_0119B3EC, 3, 1;
L_011CFDA8 .part v011CE8B0_0, 3, 1;
L_011D0068 .part v011CE3E0_0, 3, 1;
L_011CF880 .part/pv L_011CEE68, 3, 1, 8;
L_011CF8D8 .part/pv L_011CF0D0, 4, 1, 9;
L_011CFD50 .part RS_0119B3EC, 4, 1;
L_011CFC48 .part v011CE8B0_0, 4, 1;
L_011CF670 .part v011CE3E0_0, 4, 1;
L_011CF720 .part/pv L_011CEFF0, 4, 1, 8;
L_011CF9E0 .part/pv L_011CDC80, 5, 1, 9;
L_011CFA38 .part RS_0119B3EC, 5, 1;
L_011CF778 .part v011CE8B0_0, 5, 1;
L_011CFA90 .part v011CE3E0_0, 5, 1;
L_011CFFB8 .part/pv L_011CEF80, 5, 1, 8;
L_011CFB98 .part/pv L_011D0918, 6, 1, 9;
L_011CFF60 .part RS_0119B3EC, 6, 1;
L_011CFE00 .part v011CE8B0_0, 6, 1;
L_011CF6C8 .part v011CE3E0_0, 6, 1;
L_011CFAE8 .part/pv L_011D0AD8, 6, 1, 8;
L_011CFB40 .part/pv L_011D0B80, 7, 1, 9;
L_011CFBF0 .part RS_0119B3EC, 7, 1;
L_011D0118 .part v011CE8B0_0, 7, 1;
L_011CFE58 .part v011CE3E0_0, 7, 1;
L_011D00C0 .part/pv L_011D07C8, 7, 1, 8;
L_011CFEB0 .part/pv L_011D0870, 8, 1, 9;
L_011CF7D0 .part/pv L_011D0B48, 0, 1, 9;
L_011D03D8 .part RS_0119B3EC, 8, 1;
S_0118A908 .scope generate, "generar_full_adder[0]" "generar_full_adder[0]" 3 19, 3 19, S_0118BE48;
.timescale 0 0;
P_011910EC .param/l "i" 3 19, +C4<00>;
S_0118AF68 .scope module, "full_adder" "full_adder_structural" 3 20, 4 16, S_0118A908;
.timescale 0 0;
L_011CDA88 .functor OR 1, L_011CDC48, L_011CDBD8, C4<0>, C4<0>;
v011CD708_0 .net "a", 0 0, L_011CEBC8; 1 drivers
v011CD7B8_0 .net "add1_carry", 0 0, L_011CDC48; 1 drivers
v011CD760_0 .net "add1_sum", 0 0, L_011CDD98; 1 drivers
v011CD868_0 .net "add2_carry", 0 0, L_011CDBD8; 1 drivers
v011CD8C0_0 .net "b", 0 0, L_011CEB70; 1 drivers
v011CE0C8_0 .net "carry_in", 0 0, L_011CED28; 1 drivers
v011CE018_0 .net "carry_out", 0 0, L_011CDA88; 1 drivers
v011CDEB8_0 .net "sum", 0 0, L_011CDAF8; 1 drivers
S_0118AB28 .scope module, "add1" "half_adder" 4 23, 5 5, S_0118AF68;
.timescale 0 0;
L_011CDD98 .functor XOR 1, L_011CEBC8, L_011CEB70, C4<0>, C4<0>;
L_011CDC48 .functor AND 1, L_011CEBC8, L_011CEB70, C4<1>, C4<1>;
v011CD9C8_0 .alias "a", 0 0, v011CD708_0;
v011CD658_0 .alias "b", 0 0, v011CD8C0_0;
v011CD810_0 .alias "carry", 0 0, v011CD7B8_0;
v011CD6B0_0 .alias "sum", 0 0, v011CD760_0;
S_0118B650 .scope module, "add2" "half_adder" 4 24, 5 5, S_0118AF68;
.timescale 0 0;
L_011CDAF8 .functor XOR 1, L_011CDD98, L_011CED28, C4<0>, C4<0>;
L_011CDBD8 .functor AND 1, L_011CDD98, L_011CED28, C4<1>, C4<1>;
v011CD550_0 .alias "a", 0 0, v011CD760_0;
v011CD5A8_0 .alias "b", 0 0, v011CE0C8_0;
v011CD918_0 .alias "carry", 0 0, v011CD868_0;
v011CD600_0 .alias "sum", 0 0, v011CDEB8_0;
S_0118B4B8 .scope generate, "generar_full_adder[1]" "generar_full_adder[1]" 3 19, 3 19, S_0118BE48;
.timescale 0 0;
P_011910CC .param/l "i" 3 19, +C4<01>;
S_0118AEE0 .scope module, "full_adder" "full_adder_structural" 3 20, 4 16, S_0118B4B8;
.timescale 0 0;
L_011CEED8 .functor OR 1, L_011CF3A8, L_011CF3E0, C4<0>, C4<0>;
v011CD398_0 .net "a", 0 0, L_011CE960; 1 drivers
v011CD3F0_0 .net "add1_carry", 0 0, L_011CF3A8; 1 drivers
v011CD4F8_0 .net "add1_sum", 0 0, L_011CDB68; 1 drivers
v011CCAA8_0 .net "add2_carry", 0 0, L_011CF3E0; 1 drivers
v011CCB00_0 .net "b", 0 0, L_011CEC78; 1 drivers
v011CCB58_0 .net "carry_in", 0 0, L_011CEC20; 1 drivers
v011CCBB0_0 .net "carry_out", 0 0, L_011CEED8; 1 drivers
v011CD970_0 .net "sum", 0 0, L_011CF060; 1 drivers
S_0118B7E8 .scope module, "add1" "half_adder" 4 23, 5 5, S_0118AEE0;
.timescale 0 0;
L_011CDB68 .functor XOR 1, L_011CE960, L_011CEC78, C4<0>, C4<0>;
L_011CF3A8 .functor AND 1, L_011CE960, L_011CEC78, C4<1>, C4<1>;
v011CCA50_0 .alias "a", 0 0, v011CD398_0;
v011CD238_0 .alias "b", 0 0, v011CCB00_0;
v011CD290_0 .alias "carry", 0 0, v011CD3F0_0;
v011CCE70_0 .alias "sum", 0 0, v011CD4F8_0;
S_0118B320 .scope module, "add2" "half_adder" 4 24, 5 5, S_0118AEE0;
.timescale 0 0;
L_011CF060 .functor XOR 1, L_011CDB68, L_011CEC20, C4<0>, C4<0>;
L_011CF3E0 .functor AND 1, L_011CDB68, L_011CEC20, C4<1>, C4<1>;
v011CCDC0_0 .alias "a", 0 0, v011CD4F8_0;
v011CCE18_0 .alias "b", 0 0, v011CCB58_0;
v011CCFD0_0 .alias "carry", 0 0, v011CCAA8_0;
v011CD1E0_0 .alias "sum", 0 0, v011CD970_0;
S_0118B298 .scope generate, "generar_full_adder[2]" "generar_full_adder[2]" 3 19, 3 19, S_0118BE48;
.timescale 0 0;
P_0119130C .param/l "i" 3 19, +C4<010>;
S_0118AA18 .scope module, "full_adder" "full_adder_structural" 3 20, 4 16, S_0118B298;
.timescale 0 0;
L_011CEEA0 .functor OR 1, L_011CEF48, L_011CF290, C4<0>, C4<0>;
v011CD448_0 .net "a", 0 0, L_011CFCF8; 1 drivers
v011CCCB8_0 .net "add1_carry", 0 0, L_011CEF48; 1 drivers
v011CD4A0_0 .net "add1_sum", 0 0, L_011CF098; 1 drivers
v011CCD10_0 .net "add2_carry", 0 0, L_011CF290; 1 drivers
v011CCF78_0 .net "b", 0 0, L_011CFF08; 1 drivers
v011CD080_0 .net "carry_in", 0 0, L_011CF828; 1 drivers
v011CD188_0 .net "carry_out", 0 0, L_011CEEA0; 1 drivers
v011CCD68_0 .net "sum", 0 0, L_011CF140; 1 drivers
S_0118B980 .scope module, "add1" "half_adder" 4 23, 5 5, S_0118AA18;
.timescale 0 0;
L_011CF098 .functor XOR 1, L_011CFCF8, L_011CFF08, C4<0>, C4<0>;
L_011CEF48 .functor AND 1, L_011CFCF8, L_011CFF08, C4<1>, C4<1>;
v011CD2E8_0 .alias "a", 0 0, v011CD448_0;
v011CD028_0 .alias "b", 0 0, v011CCF78_0;
v011CCC60_0 .alias "carry", 0 0, v011CCCB8_0;
v011CCEC8_0 .alias "sum", 0 0, v011CD4A0_0;
S_0118B6D8 .scope module, "add2" "half_adder" 4 24, 5 5, S_0118AA18;
.timescale 0 0;
L_011CF140 .functor XOR 1, L_011CF098, L_011CF828, C4<0>, C4<0>;
L_011CF290 .functor AND 1, L_011CF098, L_011CF828, C4<1>, C4<1>;
v011CD340_0 .alias "a", 0 0, v011CD4A0_0;
v011CD130_0 .alias "b", 0 0, v011CD080_0;
v011CCC08_0 .alias "carry", 0 0, v011CCD10_0;
v011CD0D8_0 .alias "sum", 0 0, v011CCD68_0;
S_0118AE58 .scope generate, "generar_full_adder[3]" "generar_full_adder[3]" 3 19, 3 19, S_0118BE48;
.timescale 0 0;
P_011913AC .param/l "i" 3 19, +C4<011>;
S_0118B188 .scope module, "full_adder" "full_adder_structural" 3 20, 4 16, S_0118AE58;
.timescale 0 0;
L_011CF0D0 .functor OR 1, L_011CF450, L_011CEFB8, C4<0>, C4<0>;
v011CC6A8_0 .net "a", 0 0, L_011CFDA8; 1 drivers
v011CC7B0_0 .net "add1_carry", 0 0, L_011CF450; 1 drivers
v011CC700_0 .net "add1_sum", 0 0, L_011CF1E8; 1 drivers
v011CC808_0 .net "add2_carry", 0 0, L_011CEFB8; 1 drivers
v011CC860_0 .net "b", 0 0, L_011D0068; 1 drivers
v011CC8B8_0 .net "carry_in", 0 0, L_011CF988; 1 drivers
v011CC910_0 .net "carry_out", 0 0, L_011CF0D0; 1 drivers
v011CCF20_0 .net "sum", 0 0, L_011CEE68; 1 drivers
S_0118ABB0 .scope module, "add1" "half_adder" 4 23, 5 5, S_0118B188;
.timescale 0 0;
L_011CF1E8 .functor XOR 1, L_011CFDA8, L_011D0068, C4<0>, C4<0>;
L_011CF450 .functor AND 1, L_011CFDA8, L_011D0068, C4<1>, C4<1>;
v011CC5A0_0 .alias "a", 0 0, v011CC6A8_0;
v011CC5F8_0 .alias "b", 0 0, v011CC860_0;
v011CC650_0 .alias "carry", 0 0, v011CC7B0_0;
v011CC9C0_0 .alias "sum", 0 0, v011CC700_0;
S_0118B210 .scope module, "add2" "half_adder" 4 24, 5 5, S_0118B188;
.timescale 0 0;
L_011CEE68 .functor XOR 1, L_011CF1E8, L_011CF988, C4<0>, C4<0>;
L_011CEFB8 .functor AND 1, L_011CF1E8, L_011CF988, C4<1>, C4<1>;
v011CC1D8_0 .alias "a", 0 0, v011CC700_0;
v011CC758_0 .alias "b", 0 0, v011CC8B8_0;
v011CC968_0 .alias "carry", 0 0, v011CC808_0;
v011CC548_0 .alias "sum", 0 0, v011CCF20_0;
S_0118BED0 .scope generate, "generar_full_adder[4]" "generar_full_adder[4]" 3 19, 3 19, S_0118BE48;
.timescale 0 0;
P_011912EC .param/l "i" 3 19, +C4<0100>;
S_0118BF58 .scope module, "full_adder" "full_adder_structural" 3 20, 4 16, S_0118BED0;
.timescale 0 0;
L_011CDC80 .functor OR 1, L_011CF338, L_011CF5D8, C4<0>, C4<0>;
v011CC440_0 .net "a", 0 0, L_011CFC48; 1 drivers
v011CC128_0 .net "add1_carry", 0 0, L_011CF338; 1 drivers
v011CC4F0_0 .net "add1_sum", 0 0, L_011CF2C8; 1 drivers
v011CC180_0 .net "add2_carry", 0 0, L_011CF5D8; 1 drivers
v011CBE10_0 .net "b", 0 0, L_011CF670; 1 drivers
v011CBA48_0 .net "carry_in", 0 0, L_011CFD50; 1 drivers
v011CBEC0_0 .net "carry_out", 0 0, L_011CDC80; 1 drivers
v011CBF18_0 .net "sum", 0 0, L_011CEFF0; 1 drivers
S_0118B100 .scope module, "add1" "half_adder" 4 23, 5 5, S_0118BF58;
.timescale 0 0;
L_011CF2C8 .functor XOR 1, L_011CFC48, L_011CF670, C4<0>, C4<0>;
L_011CF338 .functor AND 1, L_011CFC48, L_011CF670, C4<1>, C4<1>;
v011CBCB0_0 .alias "a", 0 0, v011CC440_0;
v011CC338_0 .alias "b", 0 0, v011CBE10_0;
v011CC0D0_0 .alias "carry", 0 0, v011CC128_0;
v011CBDB8_0 .alias "sum", 0 0, v011CC4F0_0;
S_0118BFE0 .scope module, "add2" "half_adder" 4 24, 5 5, S_0118BF58;
.timescale 0 0;
L_011CEFF0 .functor XOR 1, L_011CF2C8, L_011CFD50, C4<0>, C4<0>;
L_011CF5D8 .functor AND 1, L_011CF2C8, L_011CFD50, C4<1>, C4<1>;
v011CC078_0 .alias "a", 0 0, v011CC4F0_0;
v011CBC58_0 .alias "b", 0 0, v011CBA48_0;
v011CC230_0 .alias "carry", 0 0, v011CC180_0;
v011CBBA8_0 .alias "sum", 0 0, v011CBF18_0;
S_0118C7D8 .scope generate, "generar_full_adder[5]" "generar_full_adder[5]" 3 19, 3 19, S_0118BE48;
.timescale 0 0;
P_01190CAC .param/l "i" 3 19, +C4<0101>;
S_0118C4A8 .scope module, "full_adder" "full_adder_structural" 3 20, 4 16, S_0118C7D8;
.timescale 0 0;
L_011D0918 .functor OR 1, L_011CDAC0, L_011D0C60, C4<0>, C4<0>;
v011CBB50_0 .net "a", 0 0, L_011CF778; 1 drivers
v011CC3E8_0 .net "add1_carry", 0 0, L_011CDAC0; 1 drivers
v011CBD08_0 .net "add1_sum", 0 0, L_011CDD28; 1 drivers
v011CBFC8_0 .net "add2_carry", 0 0, L_011D0C60; 1 drivers
v011CC390_0 .net "b", 0 0, L_011CFA90; 1 drivers
v011CBD60_0 .net "carry_in", 0 0, L_011CFA38; 1 drivers
v011CC020_0 .net "carry_out", 0 0, L_011D0918; 1 drivers
v011CC2E0_0 .net "sum", 0 0, L_011CEF80; 1 drivers
S_0118BD38 .scope module, "add1" "half_adder" 4 23, 5 5, S_0118C4A8;
.timescale 0 0;
L_011CDD28 .functor XOR 1, L_011CF778, L_011CFA90, C4<0>, C4<0>;
L_011CDAC0 .functor AND 1, L_011CF778, L_011CFA90, C4<1>, C4<1>;
v011CBC00_0 .alias "a", 0 0, v011CBB50_0;
v011CC288_0 .alias "b", 0 0, v011CC390_0;
v011CBE68_0 .alias "carry", 0 0, v011CC3E8_0;
v011CBAF8_0 .alias "sum", 0 0, v011CBD08_0;
S_0118BB18 .scope module, "add2" "half_adder" 4 24, 5 5, S_0118C4A8;
.timescale 0 0;
L_011CEF80 .functor XOR 1, L_011CDD28, L_011CFA38, C4<0>, C4<0>;
L_011D0C60 .functor AND 1, L_011CDD28, L_011CFA38, C4<1>, C4<1>;
v01196AC0_0 .alias "a", 0 0, v011CBD08_0;
v011CBF70_0 .alias "b", 0 0, v011CBD60_0;
v011CC498_0 .alias "carry", 0 0, v011CBFC8_0;
v011CBAA0_0 .alias "sum", 0 0, v011CC2E0_0;
S_0118BCB0 .scope generate, "generar_full_adder[6]" "generar_full_adder[6]" 3 19, 3 19, S_0118BE48;
.timescale 0 0;
P_01190C4C .param/l "i" 3 19, +C4<0110>;
S_0118C640 .scope module, "full_adder" "full_adder_structural" 3 20, 4 16, S_0118BCB0;
.timescale 0 0;
L_011D0B80 .functor OR 1, L_011D0988, L_011D0B10, C4<0>, C4<0>;
v01196490_0 .net "a", 0 0, L_011CFE00; 1 drivers
v011964E8_0 .net "add1_carry", 0 0, L_011D0988; 1 drivers
v011969B8_0 .net "add1_sum", 0 0, L_011D08A8; 1 drivers
v01196540_0 .net "add2_carry", 0 0, L_011D0B10; 1 drivers
v011966F8_0 .net "b", 0 0, L_011CF6C8; 1 drivers
v011968B0_0 .net "carry_in", 0 0, L_011CFF60; 1 drivers
v01196908_0 .net "carry_out", 0 0, L_011D0B80; 1 drivers
v01196A68_0 .net "sum", 0 0, L_011D0AD8; 1 drivers
S_0118BA08 .scope module, "add1" "half_adder" 4 23, 5 5, S_0118C640;
.timescale 0 0;
L_011D08A8 .functor XOR 1, L_011CFE00, L_011CF6C8, C4<0>, C4<0>;
L_011D0988 .functor AND 1, L_011CFE00, L_011CF6C8, C4<1>, C4<1>;
v01196120_0 .alias "a", 0 0, v01196490_0;
v011963E0_0 .alias "b", 0 0, v011966F8_0;
v01196858_0 .alias "carry", 0 0, v011964E8_0;
v01196438_0 .alias "sum", 0 0, v011969B8_0;
S_0118C6C8 .scope module, "add2" "half_adder" 4 24, 5 5, S_0118C640;
.timescale 0 0;
L_011D0AD8 .functor XOR 1, L_011D08A8, L_011CFF60, C4<0>, C4<0>;
L_011D0B10 .functor AND 1, L_011D08A8, L_011CFF60, C4<1>, C4<1>;
v01196750_0 .alias "a", 0 0, v011969B8_0;
v01196330_0 .alias "b", 0 0, v011968B0_0;
v01196A10_0 .alias "carry", 0 0, v01196540_0;
v01196070_0 .alias "sum", 0 0, v01196A68_0;
S_0118C0F0 .scope generate, "generar_full_adder[7]" "generar_full_adder[7]" 3 19, 3 19, S_0118BE48;
.timescale 0 0;
P_01190EAC .param/l "i" 3 19, +C4<0111>;
S_0118C398 .scope module, "full_adder" "full_adder_structural" 3 20, 4 16, S_0118C0F0;
.timescale 0 0;
L_011D0870 .functor OR 1, L_011D0790, L_011D0BF0, C4<0>, C4<0>;
v011960C8_0 .net "a", 0 0, L_011D0118; 1 drivers
v01196388_0 .net "add1_carry", 0 0, L_011D0790; 1 drivers
v011965F0_0 .net "add1_sum", 0 0, L_011D0BB8; 1 drivers
v011961D0_0 .net "add2_carry", 0 0, L_011D0BF0; 1 drivers
v01196018_0 .net "b", 0 0, L_011CFE58; 1 drivers
v01196598_0 .net "carry_in", 0 0, L_011CFBF0; 1 drivers
v01196800_0 .net "carry_out", 0 0, L_011D0870; 1 drivers
v011966A0_0 .net "sum", 0 0, L_011D07C8; 1 drivers
S_0118C178 .scope module, "add1" "half_adder" 4 23, 5 5, S_0118C398;
.timescale 0 0;
L_011D0BB8 .functor XOR 1, L_011D0118, L_011CFE58, C4<0>, C4<0>;
L_011D0790 .functor AND 1, L_011D0118, L_011CFE58, C4<1>, C4<1>;
v011962D8_0 .alias "a", 0 0, v011960C8_0;
v011967A8_0 .alias "b", 0 0, v01196018_0;
v01196228_0 .alias "carry", 0 0, v01196388_0;
v01196648_0 .alias "sum", 0 0, v011965F0_0;
S_0118C420 .scope module, "add2" "half_adder" 4 24, 5 5, S_0118C398;
.timescale 0 0;
L_011D07C8 .functor XOR 1, L_011D0BB8, L_011CFBF0, C4<0>, C4<0>;
L_011D0BF0 .functor AND 1, L_011D0BB8, L_011CFBF0, C4<1>, C4<1>;
v01196BC8_0 .alias "a", 0 0, v011965F0_0;
v01196960_0 .alias "b", 0 0, v01196598_0;
v01196280_0 .alias "carry", 0 0, v011961D0_0;
v01196178_0 .alias "sum", 0 0, v011966A0_0;
S_0118BDC0 .scope module, "full_adder_behavioral" "full_adder_behavioral" 4 37;
.timescale 0 0;
v011CE908_0 .net "a", 0 0, C4<z>; 0 drivers
v011CE178_0 .net "b", 0 0, C4<z>; 0 drivers
v011CE1D0_0 .net "carry_in", 0 0, C4<z>; 0 drivers
v011CE228_0 .var "carry_out", 0 0;
v011CE490_0 .var "sum", 0 0;
E_01190788 .event edge, v011CE908_0, v011CE178_0, v011CE1D0_0;
S_0118C530 .scope module, "full_adder_dataflow" "full_adder_dataflow" 4 29;
.timescale 0 0;
L_011D09F8 .functor XOR 1, C4<z>, C4<z>, C4<0>, C4<0>;
L_011D0A30 .functor XOR 1, L_011D09F8, C4<z>, C4<0>, C4<0>;
L_011D06B0 .functor AND 1, C4<z>, C4<z>, C4<1>, C4<1>;
L_011D0DB0 .functor XOR 1, C4<z>, C4<z>, C4<0>, C4<0>;
L_011D0D78 .functor AND 1, C4<z>, L_011D0DB0, C4<1>, C4<1>;
L_011CDA50 .functor OR 1, L_011D06B0, L_011D0D78, C4<0>, C4<0>;
v011CE4E8_0 .net *"_s0", 0 0, L_011D09F8; 1 drivers
v011CDE60_0 .net *"_s4", 0 0, L_011D06B0; 1 drivers
v011CE280_0 .net *"_s6", 0 0, L_011D0DB0; 1 drivers
v011CE388_0 .net *"_s8", 0 0, L_011D0D78; 1 drivers
v011CE598_0 .net "a", 0 0, C4<z>; 0 drivers
v011CE5F0_0 .net "b", 0 0, C4<z>; 0 drivers
v011CDF10_0 .net "carry_in", 0 0, C4<z>; 0 drivers
v011CDF68_0 .net "carry_out", 0 0, L_011CDA50; 1 drivers
v011CE330_0 .net "sum", 0 0, L_011D0A30; 1 drivers
S_0118C310 .scope module, "half_adder_behavioral" "half_adder_behavioral" 5 21;
.timescale 0 0;
v011CDFC0_0 .net "a", 0 0, C4<z>; 0 drivers
v011CE648_0 .net "b", 0 0, C4<z>; 0 drivers
v011CE6A0_0 .var "carry", 0 0;
v011CEA10_0 .var "sum", 0 0;
E_011907C8 .event edge, v011CE648_0, v011CDFC0_0;
S_0118C5B8 .scope module, "half_adder_dataflow" "half_adder_dataflow" 5 13;
.timescale 0 0;
L_011D0EB8 .functor XOR 1, C4<z>, C4<z>, C4<0>, C4<0>;
L_011D0EF0 .functor AND 1, C4<z>, C4<z>, C4<1>, C4<1>;
v011CECD0_0 .net "a", 0 0, C4<z>; 0 drivers
v011CEB18_0 .net "b", 0 0, C4<z>; 0 drivers
v011CE9B8_0 .net "carry", 0 0, L_011D0EF0; 1 drivers
v011CEA68_0 .net "sum", 0 0, L_011D0EB8; 1 drivers
.scope S_0118C068;
T_0 ;
%vpi_call 2 19 "$dumpfile", "./adder_nbit/adder_nbit.vcd";
%vpi_call 2 20 "$dumpvars", 1'sb0, S_0118C068;
%set/v v011CE8B0_0, 0, 8;
%movi 8, 5, 8;
%set/v v011CE3E0_0, 8, 8;
%set/v v011CE750_0, 0, 1;
%delay 1, 0;
%vpi_call 2 24 "$display", "a=%d, b=%d, sum=%d, carry=%b", v011CE8B0_0, v011CE3E0_0, v011CE7A8_0, v011CE800_0;
%movi 8, 10, 8;
%set/v v011CE8B0_0, 8, 8;
%movi 8, 5, 8;
%set/v v011CE3E0_0, 8, 8;
%set/v v011CE750_0, 0, 1;
%delay 1, 0;
%vpi_call 2 27 "$display", "a=%d, b=%d, sum=%d, carry=%b", v011CE8B0_0, v011CE3E0_0, v011CE7A8_0, v011CE800_0;
%movi 8, 100, 8;
%set/v v011CE8B0_0, 8, 8;
%movi 8, 5, 8;
%set/v v011CE3E0_0, 8, 8;
%set/v v011CE750_0, 0, 1;
%delay 1, 0;
%vpi_call 2 30 "$display", "a=%d, b=%d, sum=%d, carry=%b", v011CE8B0_0, v011CE3E0_0, v011CE7A8_0, v011CE800_0;
%end;
.thread T_0;
.scope S_0118BDC0;
T_1 ;
%wait E_01190788;
%load/v 8, v011CE908_0, 1;
%load/v 9, v011CE178_0, 1;
%xor 8, 9, 1;
%load/v 9, v011CE1D0_0, 1;
%xor 8, 9, 1;
%set/v v011CE490_0, 8, 1;
%load/v 8, v011CE908_0, 1;
%load/v 9, v011CE178_0, 1;
%and 8, 9, 1;
%load/v 9, v011CE1D0_0, 1;
%load/v 10, v011CE908_0, 1;
%load/v 11, v011CE178_0, 1;
%xor 10, 11, 1;
%and 9, 10, 1;
%or 8, 9, 1;
%set/v v011CE228_0, 8, 1;
%jmp T_1;
.thread T_1, $push;
.scope S_0118C310;
T_2 ;
%wait E_011907C8;
%load/v 8, v011CDFC0_0, 1;
%load/v 9, v011CE648_0, 1;
%xor 8, 9, 1;
%set/v v011CEA10_0, 8, 1;
%load/v 8, v011CDFC0_0, 1;
%load/v 9, v011CE648_0, 1;
%and 8, 9, 1;
%set/v v011CE6A0_0, 8, 1;
%jmp T_2;
.thread T_2, $push;
# The file index is used to find the file name in the following table.
:file_names 6;
"N/A";
"<interactive>";
".\adder_nbit\adder_nbit_tb.v";
"././adder_nbit/adder_nbit.v";
"././full_adder/full_adder.v";
"././half_adder/half_adder.v";

View File

@@ -0,0 +1,34 @@
`include "./adder_nbit/adder_nbit.v"
module adder_nbit_tb;
reg [7:0] a, b;
reg carry_in;
wire [7:0] sum;
wire carry_out;
adder_nbit adder_8bit(
.a(a),
.b(b),
.carry_in(carry_in),
.sum(sum),
.carry_out(carry_out)
);
initial begin
$dumpfile("./adder_nbit/adder_nbit.vcd");
$dumpvars(0, adder_nbit_tb);
a = 0; b = 5; carry_in = 0;
#1
$display("a=%d, b=%d, sum=%d, carry=%b", a, b, sum, carry_out);
a = 10; b = 5; carry_in = 0;
#1
$display("a=%d, b=%d, sum=%d, carry=%b", a, b, sum, carry_out);
a = 100; b = 5; carry_in = 0;
#1
$display("a=%d, b=%d, sum=%d, carry=%b", a, b, sum, carry_out);
end
endmodule

56
alu_basic/alu_basic.v Normal file
View File

@@ -0,0 +1,56 @@
/*
Basic ALU 16bit
inputs: opcode, a, b
outputs: result, zero, carry, negative
opcode[3:0] | Operación
-------------------------------
0x0 | ADD
0x1 | SUB
0x2 | MUL
0x3 | DIV
0x4 | AND
0x5 | OR
0x6 | NOT
0x7 | NAND
0x8 | NOR
0x9 | XOR
0xA | XNOR
0xB | NEG
*/
module basic_alu (
input [3:0] opcode,
input [15:0] a,
input [15:0] b,
output reg [15:0] result,
output zero,
output reg carry,
output negative
);
always @(*) begin
carry = 0;
case (opcode)
4'h0: {carry, result} = a + b; // ADD
4'h1: {carry, result} = a - b; // SUB
4'h2: result = a * b; // MUL
4'h3: result = a / b; // DIV
4'h4: result = a & b; // AND
4'h5: result = a | b; // OR
4'h6: result = ~a; // NOT
4'h7: result = ~(a & b); // NAND
4'h8: result = ~(a | b); // NOR
4'h9: result = a ^ b; // XOR
4'hA: result = ~(a ^ b); // XNOR
4'hB: result = ~a + 1; // NEG
default: result = 0;
endcase
end
assign zero = result == 0;
assign negative = result[15];
endmodule

133
alu_basic/alu_basic.vcd Normal file
View File

@@ -0,0 +1,133 @@
$date
Sat Feb 28 21:00:53 2026
$end
$version
Icarus Verilog
$end
$timescale
1s
$end
$scope module basic_alu_tb $end
$var wire 1 ! carry $end
$var wire 1 " negative $end
$var wire 16 # result [15:0] $end
$var wire 1 $ zero $end
$var reg 16 % a [15:0] $end
$var reg 16 & b [15:0] $end
$var reg 4 ' opcode [3:0] $end
$scope module alu $end
$var wire 16 ( a [15:0] $end
$var wire 16 ) b [15:0] $end
$var wire 1 " negative $end
$var wire 4 * opcode [3:0] $end
$var wire 1 $ zero $end
$var reg 1 + carry $end
$var reg 16 , result [15:0] $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
$dumpvars
b11001 ,
0+
b0 *
b101 )
b10100 (
b0 '
b101 &
b10100 %
0$
b11001 #
0"
0!
$end
#1
b1111 ,
b1111 #
b1 '
b1 *
#2
1+
1!
b0 ,
1$
b0 #
b1 &
b1 )
b1111111111111111 %
b1111111111111111 (
b0 '
b0 *
#3
1"
b1111111111110001 ,
0$
b1111111111110001 #
1+
1!
b10100 &
b10100 )
b101 %
b101 (
b1 '
b1 *
#4
0"
b111110100 ,
b111110100 #
0+
0!
b101 &
b101 )
b1100100 %
b1100100 (
b10 '
b10 *
#5
b10100 ,
b10100 #
b11 '
b11 *
#6
b111100000000 ,
b111100000000 #
b111111110000 &
b111111110000 )
b1111111100000000 %
b1111111100000000 (
b100 '
b100 *
#7
1"
b1111111111110000 ,
b1111111111110000 #
b101 '
b101 *
#8
b1111111111111111 ,
b1111111111111111 #
b0 &
b0 )
b0 %
b0 (
b110 '
b110 *
#9
b1111000011110000 ,
b1111000011110000 #
b111111110000 &
b111111110000 )
b1111111100000000 %
b1111111100000000 (
b1001 '
b1001 *
#10
b1111111111111111 ,
b1111111111111111 #
b0 &
b0 )
b1 %
b1 (
b1011 '
b1011 *
#11

240
alu_basic/alu_basic.vvp Normal file
View File

@@ -0,0 +1,240 @@
#! /c/iverilog/bin/vvp
:ivl_version "0.9.7 " "(v0_9_7)";
:vpi_time_precision + 0;
:vpi_module "system";
:vpi_module "v2005_math";
:vpi_module "va_math";
S_01049710 .scope module, "basic_alu_tb" "basic_alu_tb" 2 3;
.timescale 0 0;
v0104CEA0_0 .var "a", 15 0;
v0104CEF8_0 .var "b", 15 0;
v01080FC0_0 .net "carry", 0 0, v01041578_0; 1 drivers
v010811D0_0 .net "negative", 0 0, L_010810C8; 1 drivers
v01081070_0 .var "opcode", 3 0;
v01080D58_0 .net "result", 15 0, v0104CDF0_0; 1 drivers
v01081438_0 .net "zero", 0 0, L_01081018; 1 drivers
S_01049BD8 .scope module, "alu" "basic_alu" 2 10, 3 23, S_01049710;
.timescale 0 0;
v01045228_0 .net *"_s0", 16 0, L_010813E0; 1 drivers
v01045280_0 .net *"_s3", 0 0, C4<0>; 1 drivers
v010452D8_0 .net *"_s4", 16 0, C4<00000000000000000>; 1 drivers
v010414C8_0 .net "a", 15 0, v0104CEA0_0; 1 drivers
v01041520_0 .net "b", 15 0, v0104CEF8_0; 1 drivers
v01041578_0 .var "carry", 0 0;
v0104CD40_0 .alias "negative", 0 0, v010811D0_0;
v0104CD98_0 .net "opcode", 3 0, v01081070_0; 1 drivers
v0104CDF0_0 .var "result", 15 0;
v0104CE48_0 .alias "zero", 0 0, v01081438_0;
E_01072788 .event edge, v0104CD98_0, v010414C8_0, v01041520_0;
L_010813E0 .concat [ 16 1 0 0], v0104CDF0_0, C4<0>;
L_01081018 .cmp/eq 17, L_010813E0, C4<00000000000000000>;
L_010810C8 .part v0104CDF0_0, 15, 1;
.scope S_01049BD8;
T_0 ;
%wait E_01072788;
%set/v v01041578_0, 0, 1;
%load/v 8, v0104CD98_0, 4;
%cmpi/u 8, 0, 4;
%jmp/1 T_0.0, 6;
%cmpi/u 8, 1, 4;
%jmp/1 T_0.1, 6;
%cmpi/u 8, 2, 4;
%jmp/1 T_0.2, 6;
%cmpi/u 8, 3, 4;
%jmp/1 T_0.3, 6;
%cmpi/u 8, 4, 4;
%jmp/1 T_0.4, 6;
%cmpi/u 8, 5, 4;
%jmp/1 T_0.5, 6;
%cmpi/u 8, 6, 4;
%jmp/1 T_0.6, 6;
%cmpi/u 8, 7, 4;
%jmp/1 T_0.7, 6;
%cmpi/u 8, 8, 4;
%jmp/1 T_0.8, 6;
%cmpi/u 8, 9, 4;
%jmp/1 T_0.9, 6;
%cmpi/u 8, 10, 4;
%jmp/1 T_0.10, 6;
%cmpi/u 8, 11, 4;
%jmp/1 T_0.11, 6;
%set/v v0104CDF0_0, 0, 16;
%jmp T_0.13;
T_0.0 ;
%load/v 8, v010414C8_0, 16;
%mov 24, 0, 1;
%load/v 25, v01041520_0, 16;
%mov 41, 0, 1;
%add 8, 25, 17;
%set/v v0104CDF0_0, 8, 16;
%set/v v01041578_0, 24, 1;
%jmp T_0.13;
T_0.1 ;
%load/v 8, v010414C8_0, 16;
%mov 24, 0, 1;
%load/v 25, v01041520_0, 16;
%mov 41, 0, 1;
%sub 8, 25, 17;
%set/v v0104CDF0_0, 8, 16;
%set/v v01041578_0, 24, 1;
%jmp T_0.13;
T_0.2 ;
%load/v 8, v010414C8_0, 16;
%load/v 24, v01041520_0, 16;
%mul 8, 24, 16;
%set/v v0104CDF0_0, 8, 16;
%jmp T_0.13;
T_0.3 ;
%load/v 8, v010414C8_0, 16;
%load/v 24, v01041520_0, 16;
%div 8, 24, 16;
%set/v v0104CDF0_0, 8, 16;
%jmp T_0.13;
T_0.4 ;
%load/v 8, v010414C8_0, 16;
%load/v 24, v01041520_0, 16;
%and 8, 24, 16;
%set/v v0104CDF0_0, 8, 16;
%jmp T_0.13;
T_0.5 ;
%load/v 8, v010414C8_0, 16;
%load/v 24, v01041520_0, 16;
%or 8, 24, 16;
%set/v v0104CDF0_0, 8, 16;
%jmp T_0.13;
T_0.6 ;
%load/v 8, v010414C8_0, 16;
%inv 8, 16;
%set/v v0104CDF0_0, 8, 16;
%jmp T_0.13;
T_0.7 ;
%load/v 8, v010414C8_0, 16;
%load/v 24, v01041520_0, 16;
%and 8, 24, 16;
%inv 8, 16;
%set/v v0104CDF0_0, 8, 16;
%jmp T_0.13;
T_0.8 ;
%load/v 8, v010414C8_0, 16;
%load/v 24, v01041520_0, 16;
%or 8, 24, 16;
%inv 8, 16;
%set/v v0104CDF0_0, 8, 16;
%jmp T_0.13;
T_0.9 ;
%load/v 8, v010414C8_0, 16;
%load/v 24, v01041520_0, 16;
%xor 8, 24, 16;
%set/v v0104CDF0_0, 8, 16;
%jmp T_0.13;
T_0.10 ;
%load/v 8, v010414C8_0, 16;
%load/v 24, v01041520_0, 16;
%xor 8, 24, 16;
%inv 8, 16;
%set/v v0104CDF0_0, 8, 16;
%jmp T_0.13;
T_0.11 ;
%load/v 8, v010414C8_0, 16;
%mov 24, 0, 16;
%inv 8, 32;
%addi 8, 1, 32;
%set/v v0104CDF0_0, 8, 16;
%jmp T_0.13;
T_0.13 ;
%jmp T_0;
.thread T_0, $push;
.scope S_01049710;
T_1 ;
%vpi_call 2 21 "$dumpfile", "./alu_basic/alu_basic.vcd";
%vpi_call 2 22 "$dumpvars", 1'sb0, S_01049710;
%set/v v01081070_0, 0, 4;
%movi 8, 20, 16;
%set/v v0104CEA0_0, 8, 16;
%movi 8, 5, 16;
%set/v v0104CEF8_0, 8, 16;
%delay 1, 0;
%vpi_call 2 26 "$display", "opcode=%d, a=%d, b=%d, result=%d, zero=%b, carry=%b, negative=%b", v01081070_0, v0104CEA0_0, v0104CEF8_0, v01080D58_0, v01081438_0, v01080FC0_0, v010811D0_0;
%movi 8, 1, 4;
%set/v v01081070_0, 8, 4;
%movi 8, 20, 16;
%set/v v0104CEA0_0, 8, 16;
%movi 8, 5, 16;
%set/v v0104CEF8_0, 8, 16;
%delay 1, 0;
%vpi_call 2 29 "$display", "opcode=%d, a=%d, b=%d, result=%d, zero=%b, carry=%b, negative=%b", v01081070_0, v0104CEA0_0, v0104CEF8_0, v01080D58_0, v01081438_0, v01080FC0_0, v010811D0_0;
%set/v v01081070_0, 0, 4;
%set/v v0104CEA0_0, 1, 16;
%movi 8, 1, 16;
%set/v v0104CEF8_0, 8, 16;
%delay 1, 0;
%vpi_call 2 34 "$display", "opcode=%d, a=%d, b=%d, result=%d, zero=%b, carry=%b, negative=%b", v01081070_0, v0104CEA0_0, v0104CEF8_0, v01080D58_0, v01081438_0, v01080FC0_0, v010811D0_0;
%movi 8, 1, 4;
%set/v v01081070_0, 8, 4;
%movi 8, 5, 16;
%set/v v0104CEA0_0, 8, 16;
%movi 8, 20, 16;
%set/v v0104CEF8_0, 8, 16;
%delay 1, 0;
%vpi_call 2 39 "$display", "opcode=%d, a=%d, b=%d, result=%d, zero=%b, carry=%b, negative=%b", v01081070_0, v0104CEA0_0, v0104CEF8_0, v01080D58_0, v01081438_0, v01080FC0_0, v010811D0_0;
%movi 8, 2, 4;
%set/v v01081070_0, 8, 4;
%movi 8, 100, 16;
%set/v v0104CEA0_0, 8, 16;
%movi 8, 5, 16;
%set/v v0104CEF8_0, 8, 16;
%delay 1, 0;
%vpi_call 2 44 "$display", "opcode=%d, a=%d, b=%d, result=%d, zero=%b, carry=%b, negative=%b", v01081070_0, v0104CEA0_0, v0104CEF8_0, v01080D58_0, v01081438_0, v01080FC0_0, v010811D0_0;
%movi 8, 3, 4;
%set/v v01081070_0, 8, 4;
%movi 8, 100, 16;
%set/v v0104CEA0_0, 8, 16;
%movi 8, 5, 16;
%set/v v0104CEF8_0, 8, 16;
%delay 1, 0;
%vpi_call 2 49 "$display", "opcode=%d, a=%d, b=%d, result=%d, zero=%b, carry=%b, negative=%b", v01081070_0, v0104CEA0_0, v0104CEF8_0, v01080D58_0, v01081438_0, v01080FC0_0, v010811D0_0;
%movi 8, 4, 4;
%set/v v01081070_0, 8, 4;
%movi 8, 65280, 16;
%set/v v0104CEA0_0, 8, 16;
%movi 8, 4080, 16;
%set/v v0104CEF8_0, 8, 16;
%delay 1, 0;
%vpi_call 2 54 "$display", "opcode=%h, a=%h, b=%h, result=%h, zero=%b, carry=%b, negative=%b", v01081070_0, v0104CEA0_0, v0104CEF8_0, v01080D58_0, v01081438_0, v01080FC0_0, v010811D0_0;
%movi 8, 5, 4;
%set/v v01081070_0, 8, 4;
%movi 8, 65280, 16;
%set/v v0104CEA0_0, 8, 16;
%movi 8, 4080, 16;
%set/v v0104CEF8_0, 8, 16;
%delay 1, 0;
%vpi_call 2 59 "$display", "opcode=%h, a=%h, b=%h, result=%h, zero=%b, carry=%b, negative=%b", v01081070_0, v0104CEA0_0, v0104CEF8_0, v01080D58_0, v01081438_0, v01080FC0_0, v010811D0_0;
%movi 8, 6, 4;
%set/v v01081070_0, 8, 4;
%set/v v0104CEA0_0, 0, 16;
%set/v v0104CEF8_0, 0, 16;
%delay 1, 0;
%vpi_call 2 64 "$display", "opcode=%d, a=%d, b=%d, result=%d, zero=%b, carry=%b, negative=%b", v01081070_0, v0104CEA0_0, v0104CEF8_0, v01080D58_0, v01081438_0, v01080FC0_0, v010811D0_0;
%movi 8, 9, 4;
%set/v v01081070_0, 8, 4;
%movi 8, 65280, 16;
%set/v v0104CEA0_0, 8, 16;
%movi 8, 4080, 16;
%set/v v0104CEF8_0, 8, 16;
%delay 1, 0;
%vpi_call 2 69 "$display", "opcode=%h, a=%h, b=%h, result=%h, zero=%b, carry=%b, negative=%b", v01081070_0, v0104CEA0_0, v0104CEF8_0, v01080D58_0, v01081438_0, v01080FC0_0, v010811D0_0;
%movi 8, 11, 4;
%set/v v01081070_0, 8, 4;
%movi 8, 1, 16;
%set/v v0104CEA0_0, 8, 16;
%set/v v0104CEF8_0, 0, 16;
%delay 1, 0;
%vpi_call 2 74 "$display", "opcode=%d, a=%d, b=%d, result=%d, zero=%b, carry=%b, negative=%b", v01081070_0, v0104CEA0_0, v0104CEF8_0, v01080D58_0, v01081438_0, v01080FC0_0, v010811D0_0;
%end;
.thread T_1;
# The file index is used to find the file name in the following table.
:file_names 4;
"N/A";
"<interactive>";
".\alu_basic\alu_basic_tb.v";
"././alu_basic/alu_basic.v";

77
alu_basic/alu_basic_tb.v Normal file
View File

@@ -0,0 +1,77 @@
`include "./alu_basic/alu_basic.v"
module basic_alu_tb;
reg [15:0] a, b;
reg [3:0] opcode;
wire [15:0] result;
wire zero, carry, negative;
basic_alu alu(
.opcode(opcode),
.a(a),
.b(b),
.result(result),
.zero(zero),
.carry(carry),
.negative(negative)
);
initial begin
$dumpfile("./alu_basic/alu_basic.vcd");
$dumpvars(0, basic_alu_tb);
opcode = 4'h0; a = 20; b = 5;
#1
$display("opcode=%d, a=%d, b=%d, result=%d, zero=%b, carry=%b, negative=%b", opcode, a, b, result, zero, carry, negative);
opcode = 4'h1; a = 20; b = 5;
#1
$display("opcode=%d, a=%d, b=%d, result=%d, zero=%b, carry=%b, negative=%b", opcode, a, b, result, zero, carry, negative);
// ADD con overflow: 65535 + 1 = 0, carry=1, zero=1
opcode = 4'h0; a = 16'hFFFF; b = 1;
#1
$display("opcode=%d, a=%d, b=%d, result=%d, zero=%b, carry=%b, negative=%b", opcode, a, b, result, zero, carry, negative);
// SUB con negativo: 5 - 20, negative=1
opcode = 4'h1; a = 5; b = 20;
#1
$display("opcode=%d, a=%d, b=%d, result=%d, zero=%b, carry=%b, negative=%b", opcode, a, b, result, zero, carry, negative);
// MUL: 100 * 5 = 500
opcode = 4'h2; a = 100; b = 5;
#1
$display("opcode=%d, a=%d, b=%d, result=%d, zero=%b, carry=%b, negative=%b", opcode, a, b, result, zero, carry, negative);
// DIV: 100 / 5 = 20
opcode = 4'h3; a = 100; b = 5;
#1
$display("opcode=%d, a=%d, b=%d, result=%d, zero=%b, carry=%b, negative=%b", opcode, a, b, result, zero, carry, negative);
// AND: 0xFF00 & 0x0FF0 = 0x0F00
opcode = 4'h4; a = 16'hFF00; b = 16'h0FF0;
#1
$display("opcode=%h, a=%h, b=%h, result=%h, zero=%b, carry=%b, negative=%b", opcode, a, b, result, zero, carry, negative);
// OR: 0xFF00 | 0x0FF0 = 0xFFF0
opcode = 4'h5; a = 16'hFF00; b = 16'h0FF0;
#1
$display("opcode=%h, a=%h, b=%h, result=%h, zero=%b, carry=%b, negative=%b", opcode, a, b, result, zero, carry, negative);
// NOT: ~0 = 65535
opcode = 4'h6; a = 0; b = 0;
#1
$display("opcode=%d, a=%d, b=%d, result=%d, zero=%b, carry=%b, negative=%b", opcode, a, b, result, zero, carry, negative);
// XOR: 0xFF00 ^ 0x0FF0 = 0xF0F0
opcode = 4'h9; a = 16'hFF00; b = 16'h0FF0;
#1
$display("opcode=%h, a=%h, b=%h, result=%h, zero=%b, carry=%b, negative=%b", opcode, a, b, result, zero, carry, negative);
// NEG: -1 en complemento a 2 = 65535
opcode = 4'hB; a = 1; b = 0;
#1
$display("opcode=%d, a=%d, b=%d, result=%d, zero=%b, carry=%b, negative=%b", opcode, a, b, result, zero, carry, negative);
end
endmodule

45
full_adder/full_adder.v Normal file
View File

@@ -0,0 +1,45 @@
/*
Full Adder Declaration
A B Cin | Sum Cout
0 0 0 | 0 0
0 0 1 | 1 0
0 1 0 | 1 0
0 1 1 | 0 1
1 0 0 | 1 0
1 0 1 | 0 1
1 1 0 | 0 1
1 1 1 | 1 1
*/
`include "./half_adder/half_adder.v"
module full_adder_structural (carry_in, a, b, sum, carry_out);
input carry_in, a, b;
output sum, carry_out;
wire add1_sum, add1_carry;
wire add2_carry;
half_adder add1(a, b, add1_sum, add1_carry);
half_adder add2(add1_sum, carry_in, sum, add2_carry);
or final_or(carry_out, add1_carry, add2_carry);
endmodule
module full_adder_dataflow (carry_in, a, b, sum, carry_out);
input carry_in, a, b;
output sum, carry_out;
assign sum = a ^ b ^ carry_in;
assign carry_out = (a & b) | (carry_in & (a ^ b));
endmodule
module full_adder_behavioral (carry_in, a, b, sum, carry_out);
input carry_in, a, b;
output reg sum, carry_out;
always @(*) begin
sum = a ^ b ^ carry_in;
carry_out = (a & b) | (carry_in & (a ^ b));
end
endmodule

69
full_adder/full_adder.vcd Normal file
View File

@@ -0,0 +1,69 @@
$date
Sat Feb 28 20:25:22 2026
$end
$version
Icarus Verilog
$end
$timescale
1s
$end
$scope module full_adder_tb $end
$var wire 1 ! carry_out $end
$var wire 1 " sum $end
$var reg 1 # a $end
$var reg 1 $ b $end
$var reg 1 % carry_in $end
$scope module full_adder $end
$var wire 1 & a $end
$var wire 1 ' b $end
$var wire 1 ( carry_in $end
$var reg 1 ) carry_out $end
$var reg 1 * sum $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
$dumpvars
0*
0)
0(
0'
0&
0%
0$
0#
0"
0!
$end
#1
1*
1"
1%
1(
#2
0*
0"
0%
0(
#3
1*
1"
1#
1&
#4
1)
1!
0*
0"
1%
1(
#5
0%
0(
1$
1'
#6
1*
1"
1%
1(

154
full_adder/full_adder.vvp Normal file
View File

@@ -0,0 +1,154 @@
#! /c/iverilog/bin/vvp
:ivl_version "0.9.7 " "(v0_9_7)";
:vpi_time_precision + 0;
:vpi_module "system";
:vpi_module "v2005_math";
:vpi_module "va_math";
S_01022BC0 .scope module, "full_adder_dataflow" "full_adder_dataflow" 2 29;
.timescale 0 0;
L_000ED8B8 .functor XOR 1, C4<z>, C4<z>, C4<0>, C4<0>;
L_000ED8F0 .functor XOR 1, L_000ED8B8, C4<z>, C4<0>, C4<0>;
L_0105BC40 .functor AND 1, C4<z>, C4<z>, C4<1>, C4<1>;
L_0105BE00 .functor XOR 1, C4<z>, C4<z>, C4<0>, C4<0>;
L_0105BFC0 .functor AND 1, C4<z>, L_0105BE00, C4<1>, C4<1>;
L_0105BC78 .functor OR 1, L_0105BC40, L_0105BFC0, C4<0>, C4<0>;
v000ED828_0 .net *"_s0", 0 0, L_000ED8B8; 1 drivers
v01030E00_0 .net *"_s4", 0 0, L_0105BC40; 1 drivers
v01031278_0 .net *"_s6", 0 0, L_0105BE00; 1 drivers
v01030FB8_0 .net *"_s8", 0 0, L_0105BFC0; 1 drivers
v01030F60_0 .net "a", 0 0, C4<z>; 0 drivers
v01030CF8_0 .net "b", 0 0, C4<z>; 0 drivers
v01030E58_0 .net "carry_in", 0 0, C4<z>; 0 drivers
v010311C8_0 .net "carry_out", 0 0, L_0105BC78; 1 drivers
v01030D50_0 .net "sum", 0 0, L_000ED8F0; 1 drivers
S_01023220 .scope module, "full_adder_structural" "full_adder_structural" 2 16;
.timescale 0 0;
L_0105C2F0 .functor OR 1, L_0105BD90, L_0105C750, C4<0>, C4<0>;
v01031068_0 .net "a", 0 0, C4<z>; 0 drivers
v01031430_0 .net "add1_carry", 0 0, L_0105BD90; 1 drivers
v01031118_0 .net "add1_sum", 0 0, L_0105BCB0; 1 drivers
v01031170_0 .net "add2_carry", 0 0, L_0105C750; 1 drivers
v01030DA8_0 .net "b", 0 0, C4<z>; 0 drivers
v01030F08_0 .net "carry_in", 0 0, C4<z>; 0 drivers
v0105B3D0_0 .net "carry_out", 0 0, L_0105C2F0; 1 drivers
v0105B270_0 .net "sum", 0 0, L_0105BF88; 1 drivers
S_01022AB0 .scope module, "add1" "half_adder" 2 23, 3 5, S_01023220;
.timescale 0 0;
L_0105BCB0 .functor XOR 1, C4<z>, C4<z>, C4<0>, C4<0>;
L_0105BD90 .functor AND 1, C4<z>, C4<z>, C4<1>, C4<1>;
v010312D0_0 .alias "a", 0 0, v01031068_0;
v01030EB0_0 .alias "b", 0 0, v01030DA8_0;
v01031328_0 .alias "carry", 0 0, v01031430_0;
v01031380_0 .alias "sum", 0 0, v01031118_0;
S_01023660 .scope module, "add2" "half_adder" 2 24, 3 5, S_01023220;
.timescale 0 0;
L_0105BF88 .functor XOR 1, L_0105BCB0, C4<z>, C4<0>, C4<0>;
L_0105C750 .functor AND 1, L_0105BCB0, C4<z>, C4<1>, C4<1>;
v01031010_0 .alias "a", 0 0, v01031118_0;
v010313D8_0 .alias "b", 0 0, v01030F08_0;
v01031220_0 .alias "carry", 0 0, v01031170_0;
v010310C0_0 .alias "sum", 0 0, v0105B270_0;
S_010234C8 .scope module, "full_adder_tb" "full_adder_tb" 4 6;
.timescale 0 0;
v0105B588_0 .var "a", 0 0;
v0105B2C8_0 .var "b", 0 0;
v0105B320_0 .var "carry_in", 0 0;
v0105B1C0_0 .net "carry_out", 0 0, v0105B110_0; 1 drivers
v0105B638_0 .net "sum", 0 0, v0105ADA0_0; 1 drivers
S_010229A0 .scope module, "full_adder" "full_adder_behavioral" 4 10, 2 37, S_010234C8;
.timescale 0 0;
v0105B218_0 .net "a", 0 0, v0105B588_0; 1 drivers
v0105B5E0_0 .net "b", 0 0, v0105B2C8_0; 1 drivers
v0105B008_0 .net "carry_in", 0 0, v0105B320_0; 1 drivers
v0105B110_0 .var "carry_out", 0 0;
v0105ADA0_0 .var "sum", 0 0;
E_01023A48 .event edge, v0105B218_0, v0105B5E0_0, v0105B008_0;
S_01022EF0 .scope module, "half_adder_behavioral" "half_adder_behavioral" 3 21;
.timescale 0 0;
v0105AC98_0 .net "a", 0 0, C4<z>; 0 drivers
v0105B060_0 .net "b", 0 0, C4<z>; 0 drivers
v0105ACF0_0 .var "carry", 0 0;
v0105B428_0 .var "sum", 0 0;
E_01023B28 .event edge, v0105B060_0, v0105AC98_0;
S_010232A8 .scope module, "half_adder_dataflow" "half_adder_dataflow" 3 13;
.timescale 0 0;
L_0105C1A0 .functor XOR 1, C4<z>, C4<z>, C4<0>, C4<0>;
L_0105C1D8 .functor AND 1, C4<z>, C4<z>, C4<1>, C4<1>;
v0105B530_0 .net "a", 0 0, C4<z>; 0 drivers
v0105B378_0 .net "b", 0 0, C4<z>; 0 drivers
v0105AC40_0 .net "carry", 0 0, L_0105C1D8; 1 drivers
v0105ADF8_0 .net "sum", 0 0, L_0105C1A0; 1 drivers
.scope S_010229A0;
T_0 ;
%wait E_01023A48;
%load/v 8, v0105B218_0, 1;
%load/v 9, v0105B5E0_0, 1;
%xor 8, 9, 1;
%load/v 9, v0105B008_0, 1;
%xor 8, 9, 1;
%set/v v0105ADA0_0, 8, 1;
%load/v 8, v0105B218_0, 1;
%load/v 9, v0105B5E0_0, 1;
%and 8, 9, 1;
%load/v 9, v0105B008_0, 1;
%load/v 10, v0105B218_0, 1;
%load/v 11, v0105B5E0_0, 1;
%xor 10, 11, 1;
%and 9, 10, 1;
%or 8, 9, 1;
%set/v v0105B110_0, 8, 1;
%jmp T_0;
.thread T_0, $push;
.scope S_010234C8;
T_1 ;
%vpi_call 4 19 "$dumpfile", "./full_adder/full_adder.vcd";
%vpi_call 4 20 "$dumpvars", 1'sb0, S_010234C8;
%set/v v0105B588_0, 0, 1;
%set/v v0105B2C8_0, 0, 1;
%set/v v0105B320_0, 0, 1;
%delay 1, 0;
%set/v v0105B588_0, 0, 1;
%set/v v0105B2C8_0, 0, 1;
%set/v v0105B320_0, 1, 1;
%delay 1, 0;
%set/v v0105B588_0, 0, 1;
%set/v v0105B2C8_0, 0, 1;
%set/v v0105B320_0, 0, 1;
%delay 1, 0;
%set/v v0105B588_0, 1, 1;
%set/v v0105B2C8_0, 0, 1;
%set/v v0105B320_0, 0, 1;
%delay 1, 0;
%set/v v0105B588_0, 1, 1;
%set/v v0105B2C8_0, 0, 1;
%set/v v0105B320_0, 1, 1;
%delay 1, 0;
%set/v v0105B588_0, 1, 1;
%set/v v0105B2C8_0, 1, 1;
%set/v v0105B320_0, 0, 1;
%delay 1, 0;
%set/v v0105B588_0, 1, 1;
%set/v v0105B2C8_0, 1, 1;
%set/v v0105B320_0, 1, 1;
%end;
.thread T_1;
.scope S_01022EF0;
T_2 ;
%wait E_01023B28;
%load/v 8, v0105AC98_0, 1;
%load/v 9, v0105B060_0, 1;
%xor 8, 9, 1;
%set/v v0105B428_0, 8, 1;
%load/v 8, v0105AC98_0, 1;
%load/v 9, v0105B060_0, 1;
%and 8, 9, 1;
%set/v v0105ACF0_0, 8, 1;
%jmp T_2;
.thread T_2, $push;
# The file index is used to find the file name in the following table.
:file_names 5;
"N/A";
"<interactive>";
"././full_adder/full_adder.v";
"././half_adder/half_adder.v";
".\full_adder\full_adder_tb.v";

View File

@@ -0,0 +1,36 @@
/*
Full Adder testbench
*/
`include "./full_adder/full_adder.v"
module full_adder_tb;
reg a, b, carry_in;
wire sum, carry_out;
full_adder_behavioral full_adder(
.carry_in(carry_in),
.a(a),
.b(b),
.sum(sum),
.carry_out(carry_out)
);
initial begin
$dumpfile("./full_adder/full_adder.vcd");
$dumpvars(0, full_adder_tb);
a = 0; b = 0; carry_in = 0;
#1
a = 0; b = 0; carry_in = 1;
#1
a = 0; b = 0; carry_in = 0;
#1
a = 1; b = 0; carry_in = 0;
#1
a = 1; b = 0; carry_in = 1;
#1
a = 1; b = 1; carry_in = 0;
#1
a = 1; b = 1; carry_in = 1;
end
endmodule

30
half_adder/half_adder.v Normal file
View File

@@ -0,0 +1,30 @@
/*
Half Adder Declaration
*/
module half_adder (a,b,sum,carry);
input a,b;
output sum, carry;
xor x1(sum, a, b);
and a1(carry, a, b);
endmodule
module half_adder_dataflow (a, b, sum, carry);
input a, b;
output sum, carry;
assign sum = a ^ b;
assign carry = a & b;
endmodule
module half_adder_behavioral (a, b, sum, carry);
input a, b;
output reg sum, carry;
always @(a or b) begin
sum = a ^ b;
carry = a & b;
end
endmodule

51
half_adder/half_adder.vcd Normal file
View File

@@ -0,0 +1,51 @@
$date
Sat Feb 28 20:27:18 2026
$end
$version
Icarus Verilog
$end
$timescale
1s
$end
$scope module half_adder_tb $end
$var wire 1 ! carry $end
$var wire 1 " sum $end
$var reg 1 # a $end
$var reg 1 $ b $end
$scope module add1 $end
$var wire 1 % a $end
$var wire 1 & b $end
$var wire 1 ! carry $end
$var wire 1 " sum $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
$dumpvars
0&
0%
0$
0#
0"
0!
$end
#1
1"
1$
1&
#2
0$
0&
1#
1%
#3
0"
1!
1$
1&
#4
0!
0$
0&
0#
0%

74
half_adder/half_adder.vvp Normal file
View File

@@ -0,0 +1,74 @@
#! /c/iverilog/bin/vvp
:ivl_version "0.9.7 " "(v0_9_7)";
:vpi_time_precision + 0;
:vpi_module "system";
:vpi_module "v2005_math";
:vpi_module "va_math";
S_00119918 .scope module, "half_adder_behavioral" "half_adder_behavioral" 2 21;
.timescale 0 0;
v0011E700_0 .net "a", 0 0, C4<z>; 0 drivers
v0011CF80_0 .net "b", 0 0, C4<z>; 0 drivers
v0011E758_0 .var "carry", 0 0;
v0011E7B0_0 .var "sum", 0 0;
E_0011A260 .event edge, v0011CF80_0, v0011E700_0;
S_001191A8 .scope module, "half_adder_dataflow" "half_adder_dataflow" 2 13;
.timescale 0 0;
L_001115D0 .functor XOR 1, C4<z>, C4<z>, C4<0>, C4<0>;
L_0011D930 .functor AND 1, C4<z>, C4<z>, C4<1>, C4<1>;
v0011D828_0 .net "a", 0 0, C4<z>; 0 drivers
v0011D880_0 .net "b", 0 0, C4<z>; 0 drivers
v0011D8D8_0 .net "carry", 0 0, L_0011D930; 1 drivers
v001114C8_0 .net "sum", 0 0, L_001115D0; 1 drivers
S_001199A0 .scope module, "half_adder_tb" "half_adder_tb" 3 6;
.timescale 0 0;
v01030A60_0 .var "a", 0 0;
v01030A08_0 .var "b", 0 0;
v01030900_0 .net "carry", 0 0, L_01031290; 1 drivers
v01030E80_0 .net "sum", 0 0, L_0011D490; 1 drivers
S_001194D8 .scope module, "add1" "half_adder" 3 10, 2 5, S_001199A0;
.timescale 0 0;
L_0011D490 .functor XOR 1, v01030A60_0, v01030A08_0, C4<0>, C4<0>;
L_01031290 .functor AND 1, v01030A60_0, v01030A08_0, C4<1>, C4<1>;
v00111520_0 .net "a", 0 0, v01030A60_0; 1 drivers
v00111578_0 .net "b", 0 0, v01030A08_0; 1 drivers
v0011D400_0 .alias "carry", 0 0, v01030900_0;
v01031038_0 .alias "sum", 0 0, v01030E80_0;
.scope S_00119918;
T_0 ;
%wait E_0011A260;
%load/v 8, v0011E700_0, 1;
%load/v 9, v0011CF80_0, 1;
%xor 8, 9, 1;
%set/v v0011E7B0_0, 8, 1;
%load/v 8, v0011E700_0, 1;
%load/v 9, v0011CF80_0, 1;
%and 8, 9, 1;
%set/v v0011E758_0, 8, 1;
%jmp T_0;
.thread T_0, $push;
.scope S_001199A0;
T_1 ;
%vpi_call 3 13 "$dumpfile", "./half_adder/half_adder.vcd";
%vpi_call 3 14 "$dumpvars", 1'sb0, S_001199A0;
%set/v v01030A60_0, 0, 1;
%set/v v01030A08_0, 0, 1;
%delay 1, 0;
%set/v v01030A60_0, 0, 1;
%set/v v01030A08_0, 1, 1;
%delay 1, 0;
%set/v v01030A60_0, 1, 1;
%set/v v01030A08_0, 0, 1;
%delay 1, 0;
%set/v v01030A60_0, 1, 1;
%set/v v01030A08_0, 1, 1;
%delay 1, 0;
%set/v v01030A60_0, 0, 1;
%set/v v01030A08_0, 0, 1;
%end;
.thread T_1;
# The file index is used to find the file name in the following table.
:file_names 4;
"N/A";
"<interactive>";
"././half_adder/half_adder.v";
".\half_adder\half_adder_tb.v";

View File

@@ -0,0 +1,26 @@
/*
Testbench for half_adder
*/
`include "./half_adder/half_adder.v"
module half_adder_tb;
reg a, b;
wire sum, carry;
half_adder add1(a, b, sum, carry);
initial begin
$dumpfile("./half_adder/half_adder.vcd");
$dumpvars(0, half_adder_tb);
a = 0; b = 0;
#1
a = 0; b = 1;
#1
a = 1; b = 0;
#1
a = 1; b = 1;
#1
a = 0; b = 0;
end
endmodule

View File

@@ -0,0 +1,46 @@
#! /c/iverilog/bin/vvp
:ivl_version "0.9.7 " "(v0_9_7)";
:vpi_time_precision + 0;
:vpi_module "system";
:vpi_module "v2005_math";
:vpi_module "va_math";
S_0122D488 .scope module, "half_adder_tb" "half_adder_tb" 2 6;
.timescale 0 0;
v01225348_0 .var "a", 0 0;
v012253A0_0 .var "b", 0 0;
v012253F8_0 .net "carry", 0 0, L_0122C4C0; 1 drivers
v01225450_0 .net "sum", 0 0, L_0122D510; 1 drivers
S_01221390 .scope module, "add1" "half_adder" 2 10, 3 5, S_0122D488;
.timescale 0 0;
L_0122D510 .functor XOR 1, v01225348_0, v012253A0_0, C4<0>, C4<0>;
L_0122C4C0 .functor AND 1, v01225348_0, v012253A0_0, C4<1>, C4<1>;
v01221418_0 .net "a", 0 0, v01225348_0; 1 drivers
v01226F88_0 .net "b", 0 0, v012253A0_0; 1 drivers
v01221470_0 .alias "carry", 0 0, v012253F8_0;
v012252F0_0 .alias "sum", 0 0, v01225450_0;
.scope S_0122D488;
T_0 ;
%vpi_call 2 13 "$dumpfile", "half_adder.vcd";
%vpi_call 2 14 "$dumpvars", 1'sb0, S_0122D488;
%set/v v01225348_0, 0, 1;
%set/v v012253A0_0, 0, 1;
%delay 1, 0;
%set/v v01225348_0, 0, 1;
%set/v v012253A0_0, 1, 1;
%delay 1, 0;
%set/v v01225348_0, 1, 1;
%set/v v012253A0_0, 0, 1;
%delay 1, 0;
%set/v v01225348_0, 1, 1;
%set/v v012253A0_0, 1, 1;
%delay 1, 0;
%set/v v01225348_0, 0, 1;
%set/v v012253A0_0, 0, 1;
%end;
.thread T_0;
# The file index is used to find the file name in the following table.
:file_names 4;
"N/A";
"<interactive>";
".\half_adder_tb.v";
"./half_adder.v";

14
half_adder/readme.md Normal file
View File

@@ -0,0 +1,14 @@
1. Compilar el testbench
`
iverilog -o .\half_adder_tb.vvp .\half_adder_tb.v
`
2. Ejecutar simulacion del testbench
`
vvp .\half_adder_tb.vvp
`
3. Visualizar ondas
`
gtkwave .\half_adder.vcd
`

34
mux_demux/mux_demux.v Normal file
View File

@@ -0,0 +1,34 @@
/*
Mux / Demux
Mux
a b sel | out
-------------------
0 0 0 | 0
1 0 0 | 1
0 1 1 | 1
1 0 1 | 0
...
*/
module mux_2n1 #(parameter N = 8) (
input [N-1:0] a,
input [N-1:0] b,
input sel,
output [N-1:0] out
);
assign out = sel ? b : a;
endmodule
module demux_1n2 #(parameter N = 8) (
input [N-1:0] in,
input sel,
output [N-1:0] a,
output [N-1:0] b
);
assign a = sel ? 0 : in;
assign b = sel ? in : 0;
endmodule

370
roadmap.md Normal file
View File

@@ -0,0 +1,370 @@
# Verilog Roadmap: De Turing Complete a FPGA
> Objetivo: traducir tu CPU custom de 16 bits (Turing Complete) a Verilog sintetizable
> y montarla en la Tang Primer 20K (Gowin GW2A).
>
> Prerequisitos que ya tienes:
> - Logica digital (puertas, muxes, flip-flops, FSMs) — via Turing Complete
> - Arquitectura de CPU de 16 bits — tu CPU custom
> - Lenguaje j-lang + compilador para tu CPU
> - Toolchain: iverilog + vvp + gtkwave funcionando
> - Primer ejercicio (half_adder) completado en 3 estilos
>
> Tu CPU (mycpu_v2):
> - 16 registros de 16 bits (REG0-REG11 generales, REG12=RAM_VAL, REG13=RAM_ADDR,
> REG14=PC, REG15=IN/OUT)
> - Instrucciones de 64 bits: [OPCODE:16][PARAM1:16][PARAM2:16][TARGET:16]
> - Modo de direccionamiento en bits 7-6 del opcode (reg/reg, imm/reg, reg/imm, imm/imm)
> - 12 ops ALU (ADD,SUB,MUL,DIV,AND,OR,NOT,NAND,NOR,XOR,XNOR,NEG)
> - 6 condicionales (EQ,NEQ,LS,LSE,GR,GRE) — branch si condicion true
> - Stack: PUSH, POP, RSTR
> - Funciones: CALL, RET, HALT
> - ISA completo en: D:\Proyectos\c-labs\j-lang\mycpu_v2.md
>
> FPGA target: Tang Primer 20K (Gowin GW2A-LV18PG256C8/I7)
> - 20736 LUT4 | 15552 FF | 828K BSRAM | 48 multiplicadores 18x18
> - 128MB DDR3 | 32Mbit Flash | JTAG+UART debug | 117 IO
---
## Fase 1: Bloques combinacionales fundamentales
Cosas que ya conoces del juego, ahora las escribes en Verilog.
Cada ejercicio: modulo + testbench + simulacion con gtkwave.
### 1.1 Full Adder
- **Carpeta:** `full_adder/`
- **Objetivo:** Combinar dos half adders para hacer un full adder (con carry-in)
- **Practica:** Hacerlo structural (instanciando tu half_adder) y dataflow
- **Concepto Verilog:** instanciacion de modulos, jerarquia
### 1.2 Adder de N bits (ripple carry)
- **Carpeta:** `adder_nbit/`
- **Objetivo:** Sumador parametrizable de N bits usando `generate` y `parameter`
- **Practica:** Parametrizarlo a 4, 8 y 16 bits desde el testbench
- **Concepto Verilog:** `parameter`, `generate for`, buses `[N-1:0]`
### 1.3 ALU basica
- **Carpeta:** `alu_basic/`
- **Objetivo:** ALU de 16 bits con las 12 operaciones de tu CPU:
ADD, SUB, MUL, DIV, AND, OR, NOT, NAND, NOR, XOR, XNOR, NEG
- **Practica:** Selector de operacion de 4 bits (opcode[3:0]), flags (zero, carry, negative)
- **Concepto Verilog:** `case`, operadores aritmeticos, concatenacion `{}`
- **Conexion directa:** Este modulo es tu `alu.v` final casi tal cual
### 1.4 Multiplexor y Demultiplexor
- **Carpeta:** `mux_demux/`
- **Objetivo:** Mux 2:1, 4:1 y 8:1 parametrizables. Demux 1:4
- **Practica:** Mux con `assign` ternario vs `case` vs `generate`
- **Concepto Verilog:** operador ternario `? :`, seleccion por bits
### 1.5 Decoder / Encoder
- **Carpeta:** `decoder_encoder/`
- **Objetivo:** Decoder 3:8, encoder con prioridad
- **Practica:** Usar `casez` para don't cares
- **Concepto Verilog:** `casez`, `casex`, wildcards
---
## Fase 2: Bloques secuenciales
Aqui entran los flip-flops y el clock. Es el salto mas importante desde la logica
combinacional.
### 2.1 Flip-Flop D y registro
- **Carpeta:** `flip_flop/`
- **Objetivo:** FF-D con reset sincrono y asincrono, enable
- **Practica:** Registro de N bits parametrizable
- **Concepto Verilog:** `always @(posedge clk)`, `posedge`/`negedge`, blocking vs
non-blocking (`=` vs `<=`)
> **CRITICO:** En logica secuencial SIEMPRE usa `<=` (non-blocking).
> En combinacional usa `=` (blocking). Mezclarlos es el error #1 de Verilog.
### 2.2 Contador
- **Carpeta:** `counter/`
- **Objetivo:** Contador up/down de N bits con enable, load y reset
- **Practica:** Hacerlo parametrizable, probarlo a distintas frecuencias
- **Concepto Verilog:** Aritmetica en always secuencial, overflow
### 2.3 Shift Register
- **Carpeta:** `shift_register/`
- **Objetivo:** Registro de desplazamiento con carga paralela, shift left/right
- **Practica:** SISO, SIPO, PISO, PIPO
- **Concepto Verilog:** Operadores de shift en contexto secuencial
### 2.4 Register File
- **Carpeta:** `register_file/`
- **Objetivo:** Banco de 16 registros de 16 bits (como tu CPU: REG0-REG15),
2 puertos de lectura simultanea, 1 de escritura
- **Practica:** Lectura combinacional, escritura sincrona. Registros especiales
(REG12=RAM_VAL, REG13=RAM_ADDR, REG14=PC, REG15=IO) pueden tener logica extra
- **Concepto Verilog:** Arreglos `reg [15:0] regs [0:15]`, indexado por variable de 4 bits
---
## Fase 3: Memorias
### 3.1 RAM sincrona
- **Carpeta:** `ram/`
- **Objetivo:** RAM de 256x16 (256 posiciones de 16 bits), lectura/escritura sincrona
- **Practica:** Single port y dual port
- **Concepto Verilog:** Inferencia de block RAM, `$readmemh` para cargar datos iniciales
### 3.2 ROM
- **Carpeta:** `rom/`
- **Objetivo:** ROM de 256x16 con contenido inicializado desde archivo .hex
- **Practica:** Cargar un programa simple en hex y leerlo secuencialmente
- **Concepto Verilog:** `$readmemh`, `initial begin`
- **Conexion con tu proyecto:** Aqui eventualmente cargaras el binario que genera
tu compilador j-lang
### 3.3 Stack (LIFO)
- **Carpeta:** `stack/`
- **Objetivo:** Stack de 256 posiciones de 16 bits con PUSH, POP y RSTR (reset)
- **Practica:** Puntero de stack, deteccion de overflow/underflow
- **Conexion directa:** Tu CPU usa PUSH (0x19/0x59), POP (0x1A), RSTR (0x18)
y CALL/RET que tambien usan el stack para guardar/restaurar el PC
---
## Fase 4: Maquinas de estados finitos (FSM)
Ya las conoces de Turing Complete. Ahora las codificas formalmente.
### 4.1 FSM basica — Semaforo
- **Carpeta:** `fsm_traffic/`
- **Objetivo:** Semaforo con estados RED, GREEN, YELLOW y temporizador
- **Practica:** FSM con patron de 2 always (estado_actual + logica_siguiente)
- **Concepto Verilog:** `localparam` para estados, el patron clasico de FSM
### 4.2 FSM — Controlador UART TX (simplificado)
- **Carpeta:** `uart_tx/`
- **Objetivo:** Transmitir un byte por UART (start bit, 8 data, stop bit)
- **Practica:** Baud rate configurable con counter, FSM de transmision
- **Concepto:** FSM real que usaras para debug en FPGA
---
## Fase 5: Pipeline y CPU simples
Aqui empiezas a armar las piezas en subsistemas tipo CPU.
### 5.1 Fetch unit
- **Carpeta:** `fetch_unit/`
- **Objetivo:** Program Counter + ROM = fetch de instrucciones
- **Practica:** PC con increment, load (para jumps), reset
- **Conexion:** Este es el primer pedazo real de tu CPU
### 5.2 Decoder de instrucciones
- **Carpeta:** `instruction_decoder/`
- **Objetivo:** Tomar una instruccion de 64 bits y extraer:
- `opcode[7:0]` — operacion + tipo de grupo
- `opcode[7:6]` — modo de direccionamiento (00=R/R, 01=I/R, 10=R/I, 11=I/I)
- `opcode[5:4]` — grupo (00=ALU, 01=COND, 01=CTRL, 10=FUNC)
- `opcode[3:0]` — operacion dentro del grupo
- `param1[15:0]` — registro o inmediato segun modo
- `param2[15:0]` — registro o inmediato segun modo
- `target[15:0]` — registro destino o direccion de salto
- **Practica:** Generar senales de control: alu_op, reg_write, mem_read, mem_write,
branch, stack_op, is_immediate1, is_immediate2
- **Conexion:** Mapeo directo del ISA de mycpu_v2
### 5.3 CPU single-cycle minima
- **Carpeta:** `cpu_minimal/`
- **Objetivo:** CPU simplificada que ejecuta un subconjunto de tu ISA:
ADD (reg,imm), SUB, AND, OR — EQ, NEQ — PUSH, POP — CALL, RET, HALT
- **Practica:** Conectar fetch + decode + ALU + register file + RAM + stack
- **Concepto:** Datapath + Control Unit, todo single-cycle
- **Nota:** Tu instruccion es de 64 bits (4 words), asi que el fetch necesita
4 ciclos de lectura de ROM o una ROM con palabra de 64 bits
### 5.4 Programa de prueba
- **Objetivo:** Escribir a mano un programa en hex que sume numeros del 1 al 10
- **Practica:** Cargarlo en la ROM con `$readmemh`, simular, verificar resultado
- **Conexion:** Eventualmente esto lo hara tu compilador j-lang automaticamente
---
## Fase 6: TU CPU de Turing Complete en Verilog
Aqui es donde todo converge.
### 6.1 Documentar tu ISA (ya tienes mycpu_v2.md — completar)
- **Carpeta:** `tc_cpu/docs/`
- **Base:** Ya tienes mycpu_v2.md con registros, opcodes y modos
- **Que falta agregar para Verilog:**
- Diagrama de bloques del datapath (que se conecta con que)
- Ciclo de ejecucion: fetch (4 words) -> decode -> execute -> writeback
- Como funciona el acceso a RAM (escribir REG13=addr, leer/escribir REG12=data)
- Comportamiento exacto de CALL (push PC al stack, jump) y RET (pop PC del stack)
- Comportamiento de RSTR (reset del stack pointer?)
- Que pasa con flags/condiciones: se compara en el mismo ciclo?
- Senales de I/O via REG15: protocolo?
### 6.2 Implementar modulos individuales
- **Carpeta:** `tc_cpu/rtl/`
- **Objetivo:** Cada bloque testeado independientemente
- **Modulos concretos de tu CPU:**
| Modulo | Archivo | Descripcion |
| -------------------- | -------------------- | --------------------------------------------------- |
| ALU | `alu.v` | 12 ops (ADD-NEG), entradas 16bit, flags Z/C/N |
| Register File | `register_file.v` | 16 regs x 16bit, 2 read + 1 write, regs especiales |
| Program Counter | `pc.v` | Increment por 4 words, load para branch/CALL |
| Instruction Memory | `imem.v` | ROM de 64 bits de ancho (o 4 lecturas de 16 bits) |
| Data Memory (RAM) | `dmem.v` | RAM 16 bit, interfaz via REG12/REG13 |
| Stack | `stack.v` | PUSH/POP/RSTR, para datos y CALL/RET |
| Control Unit | `control_unit.v` | Decode opcode[7:0] -> senales de control |
| Mux de operandos | `operand_mux.v` | Selecciona reg o inmediato segun opcode[7:6] |
| Comparador | `comparator.v` | EQ/NEQ/LS/LSE/GR/GRE para branches |
| I/O Controller | `io_controller.v` | Interfaz REG15 con el mundo exterior |
### 6.3 Integrar el top-level
- **Archivo:** `tc_cpu/rtl/cpu_top.v`
- **Objetivo:** Conectar todos los modulos
- **Ciclo de ejecucion probable (multi-ciclo o FSM):**
1. **FETCH:** Leer 4 words consecutivos de IMEM -> registro de instruccion de 64 bits
2. **DECODE:** Extraer opcode, modo, param1, param2, target. Generar senales de control
3. **EXECUTE:** ALU o comparacion. Resolver operandos (reg/imm mux)
4. **MEMORY:** Si opcode accede a RAM (via REG12/REG13), hacer read/write
5. **WRITEBACK:** Escribir resultado en registro target
- **Nota:** Como tus instrucciones son de 64 bits, probablemente sea multi-ciclo
(4 ciclos de fetch + 1-2 de execute). Alternativa: ROM de 64 bits de ancho
### 6.4 Compilar j-lang -> hex -> simular en tu CPU Verilog
- **Objetivo:** Cerrar el loop completo
- **Flujo:** `codigo.j` -> compilador j-lang -> `.hex` -> `$readmemh` -> simulacion iverilog
- **Test sugerido:** Un programa j-lang simple (fibonacci, factorial, algo con loops)
- **Verificacion:** Comparar traza de ejecucion en gtkwave vs ejecucion en Turing Complete
- **Esto es el momento "wow":** el mismo programa que corria en Turing Complete
ahora corre en tu CPU Verilog
---
## Fase 7: FPGA — Tang Primer 20K
Tu placa: **Tang Primer 20K** con Gowin GW2A-LV18PG256C8/I7.
### Recursos de tu FPGA vs lo que necesita tu CPU
```
Recurso | Disponible | Tu CPU necesita (estimado)
-----------------|---------------|---------------------------
LUT4 | 20,736 | ~2,000-4,000 (sobra mucho)
Flip-Flops | 15,552 | ~500-1,000
BSRAM (828Kb) | 46 bloques | ~2-4 bloques (IMEM + DMEM)
Multiplicador | 48 (18x18) | 1 (para MUL de 16 bits)
PLL | 4 | 1 (para generar tu clock)
IO | 117 | ~20-30 (UART, LEDs, botones)
```
Te sobra FPGA para tu CPU. Podrias meter varias instancias si quisieras.
### 7.1 Instalar Gowin EDA y primer proyecto
- **Toolchain:** Gowin EDA (Education Edition es gratuita)
- Descarga: https://www.gowinsemi.com (necesitas registro)
- Incluye: Gowin Synthesizer, Place & Route, Programmer
- **Primer proyecto:** Blink LED
- Aprender: crear proyecto, seleccionar chip GW2A-LV18PG256C8/I7
- Constraints (.cst): asignar pines fisicos a senales
- Clock: la placa tiene un oscilador de 27 MHz, usar PLL para tu frecuencia
- Flujo: Synthesis -> Place & Route -> Generate Bitstream -> Program
- **Dock vs Lite:** Dependiendo de que placa de expansion uses, los pines cambian.
El Dock trae mas LEDs, botones y conectores
### 7.2 Adaptar tu CPU para sintesis
- **Cambios necesarios:**
- Quitar todo `$display`, `$dumpfile`, `$dumpvars`, `#delays` (solo simulacion)
- IMEM: Usar inicializacion de BSRAM de Gowin (soporta `$readmemh` en sintesis
para block RAM, pero verificar con Gowin Synthesizer)
- DMEM: Inferir BSRAM (el synthesizer lo detecta si sigues el patron correcto)
- MUL: Gowin puede mapear `*` a los multiplicadores DSP hardware automaticamente
- Clock: Usar la PLL Gowin (PLLVR primitive) para generar un clock limpio
- Reset: Usar el boton de la placa como reset global (con debouncing)
### 7.3 Agregar I/O real
- **Basico (debug):**
- LEDs de la placa -> mostrar estado/registro/flags
- Botones -> reset, step (ejecutar instruccion a instruccion), run
- 7-segmentos (si hay en el dock) -> mostrar PC o valor de registro
- **UART (esencial para debug):**
- Ya la habras hecho en Fase 4.2, conectarla al REG15 (IN/OUT)
- Permite enviar/recibir datos entre PC y tu CPU via terminal serial
- Debug: imprimir valor de registros, estado del PC, etc.
- **Avanzado (futuro):**
- LCD via el conector de 8 pines
- Tarjeta SD para cargar programas sin resintesis
- DDR3 para expandir RAM (requiere controlador DDR3, mas complejo)
### 7.4 Meta final
- Tu CPU ejecutando un programa compilado con j-lang en hardware real
- Poder cargar programas y ver resultados via UART desde tu PC
- El loop completo: `codigo.j` -> compilador -> `.hex` -> FPGA -> resultados reales
---
## Consejos generales
### Estructura de cada ejercicio
```
nombre_ejercicio/
nombre.v # modulo principal
nombre_tb.v # testbench
readme.md # notas, comandos, que aprendiste
```
### Comandos (ya los conoces)
```bash
iverilog -o modulo_tb.vvp modulo_tb.v
vvp modulo_tb.vvp
gtkwave modulo.vcd
```
### Errores comunes a evitar
1. **Blocking vs non-blocking:** `=` en combinacional, `<=` en secuencial. Siempre.
2. **Latch inferido:** Si usas `always @(*)` con `if` sin `else`, Verilog infiere un
latch. Siempre pon `else` o valores por defecto.
3. **Sensitivity list incompleta:** Usa `always @(*)` para combinacional, nunca listes
senales manualmente (es error-prone).
4. **Senales no inicializadas en testbench:** Todo `reg` empieza en `x` si no lo
inicializas.
5. **Confusion wire vs reg:** `wire` para assign y conexiones, `reg` para always blocks.
### Recursos recomendados
- **HDLBits** (hdlbits.01xz.net) — Ejercicios interactivos de Verilog online.
Excelente complemento para practicar sintaxis.
- **"Digital Design and Computer Architecture"** (Harris & Harris) — El libro de
referencia para ir de compuertas a CPU. Tiene ejemplos en Verilog.
- **Nand2Tetris** — Ya hiciste algo similar con Turing Complete, pero el libro tiene
buena formalizacion del ISA y el compilador.
---
## Progreso
- [x] Fase 1.0 — Half Adder (3 estilos + testbench)
- [x] Fase 1.1 — Full Adder
- [x] Fase 1.2 — Adder N bits
- [x] Fase 1.3 — ALU basica
- [ ] Fase 1.4 — Mux / Demux
- [ ] Fase 1.5 — Decoder / Encoder
- [ ] Fase 2.1 — Flip-Flop D y registro
- [ ] Fase 2.2 — Contador
- [ ] Fase 2.3 — Shift Register
- [ ] Fase 2.4 — Register File
- [ ] Fase 3.1 — RAM sincrona
- [ ] Fase 3.2 — ROM
- [ ] Fase 3.3 — Stack
- [ ] Fase 4.1 — FSM Semaforo
- [ ] Fase 4.2 — UART TX
- [ ] Fase 5.1 — Fetch Unit
- [ ] Fase 5.2 — Decoder de instrucciones
- [ ] Fase 5.3 — CPU single-cycle minima
- [ ] Fase 5.4 — Programa de prueba
- [ ] Fase 6.1 — Documentar ISA de tu CPU
- [ ] Fase 6.2 — Modulos individuales de tu CPU
- [ ] Fase 6.3 — Top-level integrado
- [ ] Fase 6.4 — j-lang -> hex -> simulacion
- [ ] Fase 7.1 — Gowin EDA + blink LED en Tang Primer 20K
- [ ] Fase 7.2 — CPU sintetizable (quitar sim-only, inferir BSRAM, PLL)
- [ ] Fase 7.3 — I/O real (LEDs, botones, UART)
- [ ] Fase 7.4 — j-lang corriendo en hardware real

14
run.ps1 Normal file
View File

@@ -0,0 +1,14 @@
param(
[Parameter(Mandatory=$true)]
[string]$module
)
$module = $module.TrimStart('.', '/', '\').TrimEnd('/', '\')
iverilog -o ".\$module\$module.vvp" ".\$module\${module}_tb.v"
if ($LASTEXITCODE -ne 0) { exit 1 }
vvp ".\$module\$module.vvp"
if ($LASTEXITCODE -ne 0) { exit 1 }
gtkwave ".\$module\$module.vcd"