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

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