### 1. 2-to-1 MUX

> page. B-10
```verilog
//Student ID: 314551134
`timescale 1ns/1ps
module MUX_2to1(
input src1,
input src2,
input select,
output reg result
);
/* Write down your code HERE */
wire g1, g2, _select, result_w;
not n(_select, select);
and a1(g1, src1, _select);
and a2(g2, src2, select);
or o(result_w, g1, g2);
always @(*) begin
result = result_w;
end
endmodule
```
Testbench:
```shell
SEL SRC1 SRC2 | RESULT
0 0 0 | 0
0 0 1 | 0
0 1 0 | 1
0 1 1 | 1
1 0 0 | 0
1 0 1 | 1
1 1 0 | 0
1 1 1 | 1
```
### 2. 4-to-1 MUX

```verilog
//Student ID: 314551134
`timescale 1ns/1ps
module MUX_4to1(
input src1,
input src2,
input src3,
input src4,
input [2-1:0] select,
output reg result
);
/* Write down your code HERE */
wire g1, g2, g3, g4, _sel0, _sel1;
not n1(_sel0, select[0]);
not n2(_sel1, select[1]);
and a1(g1, src1, _sel1, _sel0);
and a2(g2, src2, _sel1, select[0]);
and a3(g3, src3, select[1], _sel0);
and a4(g4, src4, select[1], select[0]);
or o1(result_w, g1, g2, g3, g4);
always @(*) begin
result = result_w;
end
endmodule
```
Testbench :
```shell
time sel data(src4..1) result expect
1000 00 0000 0 0
2000 01 0000 0 0
3000 10 0000 0 0
4000 11 0000 0 0
5000 00 0001 1 1
6000 01 0001 0 0
7000 10 0001 0 0
8000 11 0001 0 0
9000 00 0010 0 0
10000 01 0010 1 1
11000 10 0010 0 0
12000 11 0010 0 0
13000 00 0011 1 1
14000 01 0011 1 1
15000 10 0011 0 0
16000 11 0011 0 0
17000 00 0100 0 0
18000 01 0100 0 0
19000 10 0100 1 1
20000 11 0100 0 0
21000 00 0101 1 1
22000 01 0101 0 0
23000 10 0101 1 1
24000 11 0101 0 0
25000 00 0110 0 0
26000 01 0110 1 1
27000 10 0110 1 1
28000 11 0110 0 0
29000 00 0111 1 1
30000 01 0111 1 1
31000 10 0111 1 1
32000 11 0111 0 0
33000 00 1000 0 0
34000 01 1000 0 0
35000 10 1000 0 0
36000 11 1000 1 1
37000 00 1001 1 1
38000 01 1001 0 0
39000 10 1001 0 0
40000 11 1001 1 1
41000 00 1010 0 0
42000 01 1010 1 1
43000 10 1010 0 0
44000 11 1010 1 1
45000 00 1011 1 1
46000 01 1011 1 1
47000 10 1011 0 0
48000 11 1011 1 1
49000 00 1100 0 0
50000 01 1100 0 0
51000 10 1100 1 1
52000 11 1100 1 1
53000 00 1101 1 1
54000 01 1101 0 0
55000 10 1101 1 1
56000 11 1101 1 1
57000 00 1110 0 0
58000 01 1110 1 1
59000 10 1110 1 1
60000 11 1110 1 1
61000 00 1111 1 1
62000 01 1111 1 1
63000 10 1111 1 1
64000 11 1111 1 1
==== TEST PASSED ====
MUX_4to1_tb.v:56: $finish called at 64000 (1ps)
```
### 3. 1-bit ALU
- 此圖與課本不同,`OR gate` 與 `AND gate` 位置互換
- spec 要求不能有 `Full Adder.v`,故要直接寫在 1-bit ALU 中


Full Adder Circuit

```verilog
//Student ID: 314551134
`timescale 1ns/1ps
`include "MUX_2to1.v"
`include "MUX_4to1.v"
module ALU_1bit(
input src1, //1 bit source 1 (input)
input src2, //1 bit source 2 (input)
input less, //1 bit less (input)
input Ainvert, //1 bit A_invert (input)
input Binvert, //1 bit B_invert (input)
input cin, //1 bit carry in (input)
input [2-1:0] operation, //2 bit operation (input)
output reg result, //1 bit result (output)
output reg cout //1 bit carry out (output)
);
/* Write down your code HERE */
wire _src1, _src2, i1, i2, or_result, and_result, s;
not n1(_src1, src1);
not n2(_src2, src2);
MUX_2to1 mux1(
.src1(src1),
.src2(_src1),
.select(Ainvert),
.result(i1)
);
MUX_2to1 mux2(
.src1(src2),
.src2(_src2),
.select(Binvert),
.result(i2)
);
or o1(or_result, i1, i2);
and a1(and_result, i1, i2);
/* Full Adder */
wire g1, g2, g3, cout_w;
xor xor1(g1, i1, i2);
xor xor2(s, g1, cin);
and a2(g2, i1, i2);
and a3(g3, g1, cin);
or o2(cout_w, g2, g3);
wire result_w;
MUX_4to1 mux3(
.src1(or_result),
.src2(and_result),
.src3(s),
.src4(less),
.select(operation),
.result(result_w)
);
always @(*)begin
cout = cout_w;
result = result_w;
end
endmodule
```
Testbench:
```shell
VCD info: dumpfile ALU_1bit.vcd opened for output.
sum 1
carry 1
===============
sum 1
carry 1
===============
sum 0
carry 1
===============
```
### 4. 32-bits ALU
- ALU0 :
- ALU0 的 `Cin` 是 `Binvert`,且要將 ALU31 的 Full adder 結果拉到 `less`
- set 可直接用 xor 公式算出 `S = A ^ B ^ Cin`,需注意因為是做減法,所以要取 ~B
- ALU31 :
- 不需要另外實作一個,只需要額外設定 `zero`, `overflow` 即可
- `zero = ~|result` 的用法是 [Reduction operator](https://nandland.com/reduction-operators/) ,會先將所有 bit 做 or 運算,接著才取 not

```verilog
//Student ID: 314551134
`timescale 1ns/1ps
`include "ALU_1bit.v"
module ALU(
input rst_n, // negative reset (input)
input [32-1:0] src1, // 32 bits source 1 (input)
input [32-1:0] src2, // 32 bits source 2 (input)
input [ 4-1:0] ALU_control, // 4 bits ALU control input (input)
output reg [32-1:0] result, // 32 bits result (output)
output reg zero, // 1 bit when the output is 0, zero must be set (output)
output reg cout, // 1 bit carry out (output)
output reg overflow // 1 bit overflow (output)
);
/* Write down your code HERE */
/* Decode the control signal */
wire Ainvert = ALU_control[3];
wire Binvert = ALU_control[2];
wire [1:0] op = ALU_control[1:0];
wire [31:0] carry;
wire [31:0] result_w;
wire set = src1[31] ^ (~src2[31]) ^ carry[31]; // the less value of ALU0
genvar i;
generate
for (i = 0; i < 32; i = i + 1) begin : gen_alu
if(i == 0)
ALU_1bit alu0 (
.src1 (src1[i]),
.src2 (src2[i]),
.less (set),
.Ainvert (Ainvert),
.Binvert (Binvert),
.cin (Binvert),
.operation(op),
.result (result_w[i]),
.cout (carry[i])
);
else
ALU_1bit alui (
.src1 (src1[i]),
.src2 (src2[i]),
.less (1'b0),
.Ainvert (Ainvert),
.Binvert (Binvert),
.cin (carry[i-1]),
.operation(op),
.result (result_w[i]),
.cout (carry[i])
);
end
endgenerate
always @(*) begin
if (!rst_n) begin
result = 32'b0;
zero = 1'b0;
cout = 1'b0;
overflow = 1'b0;
end else begin
result = result_w;
zero = ~|result; // reduction or -> not
cout = (op == 2'b10) ? carry[31] : 1'b0;
overflow = (op == 2'b10) ? (carry[30] ^ carry[31]) : 1'b0;;
end
end
endmodule
```
Testbench:
```shell
VCD info: dumpfile alu.vcd opened for output.
***************************************************
* PATTERN RESULT TABLE *
***************************************************
* PATTERN * Result * ZCV *
***************************************************
* Congratulation! All data are correct! *
***************************************************
Correct Count: 30
testbench.v:91: $finish called at 415000 (1ps)
```