diff --git a/ALU_8/ALU_8.v b/ALU_8/ALU_8.v new file mode 100644 index 0000000..4838906 --- /dev/null +++ b/ALU_8/ALU_8.v @@ -0,0 +1,110 @@ +module ALU_8(opcode, a, b, res, carry, zero); + + input [7:0] a, b; + input [3:0] opcode; + output reg [8:0] res; //Final result + output reg carry, zero; //Flags + + parameter [3:0] //Assigning 4 bit values to operations + ADD = 4'b0000, + SUB = 4'b0001, + MULT = 4'b0010, + DIV = 4'b0011, + AND = 4'b0100, + OR = 4'b0101, + NAND = 4'b0110, + NOR = 4'b0111, + XOR = 4'b1000, + SHIFTR = 4'b1001, + SHIFTL = 4'b1010, + COMP = 4'b1011; + + always @(opcode or a or b) begin + case (opcode) //Cases for each opcode with their respective operations + ADD : begin + res = a + b; + carry = res[8]; + zero = (res == 9'b0); + end + SUB : begin + res = a - b; + carry = res[8]; + zero = (res == 9'b0); + end + MULT : begin + res = a * b; + zero = (res == 9'b0); + carry = 0; + end + DIV : begin + res = a / b; + zero = (res == 9'b0); + carry = 0; + end + AND : begin + res = a & b; + zero = (res == 9'b0); + carry = 0; + end + OR : begin + res = a | b; + zero = (res == 9'b0); + carry = 0; + end + NAND : begin + res = ~(a & b); + zero = (res == 9'b0); + carry = 0; + end + NOR : begin + res = ~(a | b); + zero = (res == 9'b0); + carry = 0; + end + XOR : begin + res = a ^ b; + zero = (res == 9'b0); + end + SHIFTR : begin + res = a >> 1; + zero = (res == 9'b0); + carry = 0; + end + SHIFTL : begin + res = a << 1; + zero = (res == 9'b0); + carry = 0; + end + COMP : begin + res = (a > b) ? 9'b111111111 : 9'b0; + zero = (res == 9'b0); + carry = 0; + end + default : begin + res = (a > b) ? 9'b111111111 : 9'b0; + zero = (res == 9'b0); + carry = 0; + end + + endcase + end +endmodule + + + + + + + + + + + + + + + + + + + diff --git a/ALU_8/ALU_8_tb.v b/ALU_8/ALU_8_tb.v new file mode 100644 index 0000000..677d48e --- /dev/null +++ b/ALU_8/ALU_8_tb.v @@ -0,0 +1,26 @@ +module ALU_8_tb(); + + reg [7:0] a, b; + reg [3:0] opcode; + wire [8:0] res; + wire carry, zero; + + ALU_8 uut(.opcode(opcode), .a(a), .b(b), .res(res), .carry(carry), .zero(zero)); + + initial begin + $dumpfile("ALU_8.vcd"); + $dumpvars(0, ALU_8_tb); + a = 8'b00010100; //Number of bits'Binary system Value + b = 8'b01001111; + opcode = 4'b0; + + #60 $finish; //global reset, # is time delay (in nanoseconds) + end + + always #5 opcode = opcode + 1; //Clock input + + initial begin + $monitor("time = %0t, a = %b, b = %b, res = %b, carry = %b, zero = %b", $time, a, b, res[7:0], carry, zero); + end + +endmodule \ No newline at end of file diff --git a/ALU_8/README.md b/ALU_8/README.md new file mode 100644 index 0000000..157bbd2 --- /dev/null +++ b/ALU_8/README.md @@ -0,0 +1,91 @@ +# 8 Bit ALU in Verilog HDL + +## Inputs + +Operands, Opcode. + +## Outputs + +Result, Carry flag, Zero flag. + +## Functions + +The ALU has 11 functions that are binary or unary, and that can be used on 8 bit binary numbers. These 11 functions are + +- Add $\to$ 0000 + +- Subtract $\to$ 0001 + +- Multiply $\to$ 0010 + +- Divide $\to$ 0011 + +- And $\to$ 0100 + +- Or $\to$ 0101 + +- Nand $\to$ 0110 + +- Nor $\to$ 0111 + +- XOR $\to$ 1000 + +- Shift right $\to$ 1001 + +- Shift left $\to$ 1010 + +- Compare $\to$ 1011 + +Each of these functions have their own four bit opcodes, which have been specified beside them. These opcodes are what the ALU uses to determine which operation needs to be computed. + +Two flags have been initialised in the ALU, one for the carry and one for indicating if the output is a zero. The carry flag is 1 when there is an output carry and is zero in all other cases, while the zero flag is 1 when the output is zero. + +### Add function + +Takes two 8 bit inputs. Returns the sum as a result, along with the appropriate flags. + +### Subtract function + +Takes two 8 bit inputs. Returns the difference as a result, along with the appropriate flags. + +### Multiply function + +Takes two 8 bit inputs. Returns the product as a result, along with the appropriate flags. + +### Divide function + +Takes two 8 bit inputs. Returns the quotient as a result, along with the appropriate flags. + +### And function + +Takes two 8 bit inputs. Returns the logical AND value of the two as a result, along with the appropriate flags. + +### Or function + +Takes two 8 bit inputs. Returns the logical OR value of the two as a result, along with the appropriate flags. + +### Nand function + +Takes two 8 bit inputs. Returns the logical NAND value of the two as a result, along with the appropriate flags. + +### Nor function + +Takes two 8 bit inputs. Returns the logical NOR value of the two as a result, along with the appropriate flags. + +### XOR function + +Takes two 8 bit inputs. Returns the logical XOR value of the two as a result, along with the appropriate flags. + +### Shift right function + +Takes one 8 bit input. Shifts all the bits by one position to the right. + +### Shift left function + +Takes one 8 bit input. Shifts all the bits by one position to the left. + +### Compare function + +Takes two 8 bit inputs. Returns an 8 bit number with all 1s if the first is greater than the second. All 0s in the 8 bit numer otherwise. + +--- \ No newline at end of file diff --git a/jk_ff/jk_ff.v b/jk_ff/jk_ff.v new file mode 100644 index 0000000..84df2f4 --- /dev/null +++ b/jk_ff/jk_ff.v @@ -0,0 +1,31 @@ +module jk_ff(j, k, clk, q, qc); +//Positive edge triggered flipflop + input j, k, clk; + output reg q, qc; + always @(posedge clk) + begin + if(k == 0) + begin + if(j == 1) + begin + q <= 1; + qc <= 0; + end + else + begin + q <= q; + qc <= qc; + end + end + else if(j == 1) + begin + q <= ~q; + qc <= ~qc; + end + else + begin + q <= 0; + qc <= 1; + end + end +endmodule \ No newline at end of file diff --git a/jk_ff/jk_ff_tb.v b/jk_ff/jk_ff_tb.v new file mode 100644 index 0000000..211a00c --- /dev/null +++ b/jk_ff/jk_ff_tb.v @@ -0,0 +1,24 @@ +module jk_ff_tb(); + + reg j, k, clk; + wire q, qc; + + jk_ff uut(.j(j), .k(k), .clk(clk), .q(q), .qc(qc)); + initial begin + $dumpfile("jk_ff.vcd"); + $dumpvars(0, jk_ff_tb); + //Initialise inputs + j = 1'b0; //Number of bits'Binary system or whatever system with whatever value(0 here) + k = 1'b0; + clk = 1'b0; + #180 $finish; + end + + always #5 clk=~clk; //Different test cases, 00, 10, 01, 11 + always #20 j=~j; + always #40 k=~k; + + always @(posedge clk) + $monitor("time = %0t, j = %b, k = %b, q = %b, q' = %b", $time, j, k, q, qc); + +endmodule \ No newline at end of file