From 49d1871dfa54222a11aac7ea1348a51f3ac179ef Mon Sep 17 00:00:00 2001 From: ChUrl Date: Thu, 23 Mar 2023 21:51:50 +0100 Subject: [PATCH] Implement ALU/Register components --- ALU.sv | 44 ++++++++++++++++++++++++++++++++++++++++++++ ArithmeticUnit.sv | 20 ++++++++++++++++++++ ConditionalUnit.sv | 30 ++++++++++++++++++++++++++++++ Counter.sv | 23 +++++++++++++++++++++++ LogicalUnit.sv | 23 +++++++++++++++++++++++ RegisterFile.sv | 43 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 183 insertions(+) create mode 100644 ALU.sv create mode 100644 ArithmeticUnit.sv create mode 100644 ConditionalUnit.sv create mode 100644 Counter.sv create mode 100644 LogicalUnit.sv create mode 100644 RegisterFile.sv diff --git a/ALU.sv b/ALU.sv new file mode 100644 index 0000000..3684880 --- /dev/null +++ b/ALU.sv @@ -0,0 +1,44 @@ +`default_nettype none + +// Inst: MD OP +// 01 000 XXX +// OPs: 000 - AND +// 001 - OR +// 010 - NAND +// 011 - NOR +// 100 - ADD +// 101 - SUB +module ALU( + input var logic[2:0] opcode, + input var logic[7:0] operandA, + input var logic[7:0] operandB, + output var logic[7:0] result +); + + var logic[7:0] lu_result; + LogicalUnit lu( + .opcode(opcode), + .operandA(operandA), + .operandB(operandB), + .result(lu_result) + ); + + var logic[7:0] au_result; + ArithmeticUnit au( + .opcode(opcode), + .operandA(operandA), + .operandB(operandB), + .result(au_result) + ); + + // If the first most significant opcode bit is 0, it is a logical operation. + always_comb case (opcode) + 3'b000, + 3'b001, + 3'b010, + 3'b011: result = lu_result; + 3'b100, + 3'b101: result = au_result; + default: result = 0; + endcase +endmodule diff --git a/ArithmeticUnit.sv b/ArithmeticUnit.sv new file mode 100644 index 0000000..b12be9b --- /dev/null +++ b/ArithmeticUnit.sv @@ -0,0 +1,20 @@ +`default_nettype none + +// Inst: MD OP +// 01 000 XXX +// OPs: 100 - ADD +// 101 - SUB +module ArithmeticUnit( + input var logic[2:0] opcode, + input var logic[7:0] operandA, + input var logic[7:0] operandB, + output var logic[7:0] result +); + + // If the least significant opcode bit is 0, it is an addition + always_comb case (opcode) + 3'b100: result = operandA + operandB; + 3'b101: result = operandA - operandB; + default: result = 0; + endcase +endmodule diff --git a/ConditionalUnit.sv b/ConditionalUnit.sv new file mode 100644 index 0000000..30fb952 --- /dev/null +++ b/ConditionalUnit.sv @@ -0,0 +1,30 @@ +`default_nettype none + +// Inst: MD OP +// 11 000 XXX +// OPs: 000 - Never +// 001 - == 0 +// 010 - < 0 +// 011 - <= 0 +// 100 - Always +// 101 - != 0 +// 110 - > 0 +// 111 - >= 0 +module ConditionalUnit( + input var logic[2:0] opcode, + input var logic[7:0] operand, + output var logic result +); + + always_comb case (opcode) + 3'b000: result = 0; + 3'b001: result = (operand == 0); + 3'b010: result = (operand < 0); + 3'b011: result = (operand <= 0); + 3'b100: result = 1; + 3'b101: result = (operand != 0); + 3'b110: result = (operand > 0); + 3'b111: result = (operand >= 0); + default: result = 0; + endcase +endmodule diff --git a/Counter.sv b/Counter.sv new file mode 100644 index 0000000..d30523f --- /dev/null +++ b/Counter.sv @@ -0,0 +1,23 @@ +`default_nettype none + +module Counter( + input var logic clock, + input var logic reset, + input var logic decrement, + input var logic setvalue, + input var logic[7:0] valuein, + output var logic[7:0] valueout +); + + var logic[7:0] countervalue; + + always @(posedge clock or posedge reset) + if (reset) + countervalue <= 8'b0; + else if (setvalue) + countervalue <= valuein; + else + countervalue <= countervalue + (decrement ? -1 : 1); + + assign valueout = countervalue; +endmodule \ No newline at end of file diff --git a/LogicalUnit.sv b/LogicalUnit.sv new file mode 100644 index 0000000..b800d51 --- /dev/null +++ b/LogicalUnit.sv @@ -0,0 +1,23 @@ +`default_nettype none + +// Inst: MD OP +// 01 000 XXX +// OPs: 000 - AND +// 001 - OR +// 010 - NAND +// 011 - NOR +module LogicalUnit( + input var logic[2:0] opcode, + input var logic[7:0] operandA, + input var logic[7:0] operandB, + output var logic[7:0] result +); + + always_comb case (opcode) + 3'b000: result = operandA & operandB; + 3'b001: result = operandA | operandB; + 3'b010: result = ~(operandA & operandB); + 3'b011: result = ~(operandA | operandB); + default: result = 0; + endcase +endmodule diff --git a/RegisterFile.sv b/RegisterFile.sv new file mode 100644 index 0000000..2655d1b --- /dev/null +++ b/RegisterFile.sv @@ -0,0 +1,43 @@ +`default_nettype none + +// Regs: 000 - reg0 (Constant load) +// 001 - reg1 (ALU operandA) +// 010 - reg2 (ALU operandB) +// 011 - reg3 (ALU result/conditional operand) +// 100 - reg4 (General purpose A) +// 101 - reg5 (General purpose B) +module RegisterFile( + input var logic clock, + input var logic reset, + input var logic save, + + input var logic[2:0] saveselector, + input var logic[7:0] savebus, + input var logic[2:0] loadselector, + output var logic[7:0] loadbus, + + output var logic[7:0] aluoperandA, + output var logic[7:0] aluoperandB, + output var logic[7:0] aluresult +); + + // Our data is stored in here + var logic[7:0] registers[5:0]; + + // Reset everything to 0 or save value + always @(posedge clock or posedge reset) + if (reset) + for (int ii = 0; ii < 6; ii = ii + 1) + registers[ii] <= 8'b0; + else + if (save) + registers[saveselector] <= savebus; + + // Load selected register value to loadbus + assign loadbus = registers[loadselector]; + + // Always propagate contents of ALU registers + assign aluoperandA = registers[1]; + assign aluoperandB = registers[2]; + assign aluresult = registers[3]; +endmodule