From 17f5cbe781ae761d86d55fec7d46ba3172167894 Mon Sep 17 00:00:00 2001 From: Bobby Bingham Date: Sun, 8 Jan 2017 21:58:16 -0600 Subject: Add carry input to ALU --- alu.v | 5 +++-- alu_stage.v | 10 ++++++++-- alu_tb.v | 9 +++++++-- ctrl_decode.v | 4 +++- ctrl_encode.v | 4 +++- decoder.v | 3 +++ decoder_stage.v | 7 +++++-- tests/alu | 15 ++++++++++----- 8 files changed, 42 insertions(+), 15 deletions(-) diff --git a/alu.v b/alu.v index 63812a7..37a84d5 100644 --- a/alu.v +++ b/alu.v @@ -2,6 +2,7 @@ module alu ( input [3:0] op, input [15:0] x, input [15:0] y, + input carry_in, output [15:0] result, output zero, output carry @@ -36,7 +37,7 @@ module alu ( assign issum = ~|(op[3:1]); - assign sum = x + (op[0] ? ~y + 1 : y); + assign sum = x + ({16{op[0]}} ^ y) + (op[0] ^ carry_in); assign prod = x * y; assign quot = x / y; assign anded = x & y; @@ -62,6 +63,6 @@ module alu ( shifted; assign zero = ~(|result); - assign carry = issum ? sum[16] : 1'b0; + assign carry = issum ? op[0] ^ sum[16] : 1'b0; endmodule diff --git a/alu_stage.v b/alu_stage.v index b178cad..92c8246 100644 --- a/alu_stage.v +++ b/alu_stage.v @@ -2,7 +2,7 @@ module alu_stage ( input clk, input en, input [15:0] pc_in, - input [32:0] control_signals_in, + input [34:0] control_signals_in, input [15:0] imm_in, // register file @@ -24,7 +24,7 @@ module alu_stage ( output setPC, output [15:0] setPCValue, - output reg [32:0] control_signals_out, + output reg [34:0] control_signals_out, output reg [15:0] imm_out, output reg [15:0] pc_out, @@ -39,6 +39,8 @@ module alu_stage ( wire [1:0] aluOpSource1_in; wire [1:0] aluOpSource2_in; wire aluDest_in; + wire [1:0] aluCarrySource; + wire aluCarry_in; wire [2:0] regDest_in; wire regSetH_in; wire regSetL_in; @@ -58,6 +60,7 @@ module alu_stage ( .aluOpSource1(aluOpSource1_in), // ALU first operand: 0 = reg, 1 = memory read, 2 = imm8, 3 = PC .aluOpSource2(aluOpSource2_in), // ALU second operand: 0 = reg, 1 = ~reg, 2 = PC, 3 = ??? .aluDest(aluDest_in), // 0 = reg, 1 = PC + .aluCarrySource(aluCarrySource), // ALU carry input source: 0 = zero, 1 = one, 2 = carry flag, 3 = inverted carry flag .regDest(regDest_in), .regSetH(regSetH_in), @@ -83,12 +86,15 @@ module alu_stage ( aluOpSource1_in == 2'h0 ? rf_dataB : aluOpSource1_in == 2'h1 ? ~rf_dataIn : pc_in; + assign aluCarry_in = aluCarrySource[0] ^ (aluCarrySource[1] & statusReg[0]); + wire [15:0] aluResult; wire aluZero, aluCarry; alu alu_inst ( .op(aluOp_in), .x(aluSrc1), .y(aluSrc2), + .carry_in(aluCarry_in), .result(aluResult), .zero(aluZero), .carry(aluCarry) diff --git a/alu_tb.v b/alu_tb.v index 31141ce..bfe3e8a 100644 --- a/alu_tb.v +++ b/alu_tb.v @@ -11,6 +11,7 @@ module alu_tb (); reg expected_zero; wire carry; reg expected_carry; + reg carry_in; reg [3*8:0] opstr; integer file, r; @@ -24,9 +25,12 @@ module alu_tb (); while (!$feof(file)) begin r = $fscanf(file, " 0x%x %3s 0x%x = 0x%x Z=%x C=%x\n", x, opstr, y, expected_result, expected_zero, expected_carry); + carry_in = opstr == "++" || opstr == "--"; case (opstr) - "+" : op = 0; - "-" : op = 1; + "+" : op = 0; + "++" : op = 0; + "-" : op = 1; + "--" : op = 1; "*" : op = 2; "/" : op = 3; "&" : op = 4; @@ -59,6 +63,7 @@ module alu_tb (); .op(op), .x(x), .y(y), + .carry_in(carry_in), .result(result), .zero(zero), .carry(carry) diff --git a/ctrl_decode.v b/ctrl_decode.v index ede591f..86ecc97 100644 --- a/ctrl_decode.v +++ b/ctrl_decode.v @@ -1,5 +1,5 @@ module ctrl_decode ( - input [32:0] control_signals, + input [34:0] control_signals, output [3:0] aluOp, output [2:0] aluReg1, @@ -7,6 +7,7 @@ module ctrl_decode ( output [1:0] aluOpSource1, // ALU first operand: 0 = reg, 1 = memory read, 2 = imm8, 3 = PC output [1:0] aluOpSource2, // ALU second operand: 0 = reg, 1 = ~reg, 2 = PC, 3 = ??? output aluDest, // 0 = reg, 1 = PC + output [1:0] aluCarrySource, // ALU carry flag input source output [2:0] regDest, output regSetH, @@ -28,6 +29,7 @@ module ctrl_decode ( aluOpSource1, aluOpSource2, aluDest, + aluCarrySource, regDest, regSetH, regSetL, diff --git a/ctrl_encode.v b/ctrl_encode.v index d76f34f..92ad3c6 100644 --- a/ctrl_encode.v +++ b/ctrl_encode.v @@ -5,6 +5,7 @@ module ctrl_encode ( input [1:0] aluOpSource1, // ALU first operand: 0 = reg, 1 = memory read, 2 = imm8, 3 = PC input [1:0] aluOpSource2, // ALU second operand: 0 = reg, 1 = ~reg, 2 = PC, 3 = ??? input aluDest, // 0 = reg, 1 = PC + input [1:0] aluCarrySource, // ALU carry flag input source input [2:0] regDest, input regSetH, @@ -18,7 +19,7 @@ module ctrl_encode ( input [5:0] setRegCond, // {should set when condition is true, Z doesn't matter, S doesn't matter, Z must be this, S must be this} - output [32:0] control_signals + output [34:0] control_signals ); assign control_signals = { @@ -28,6 +29,7 @@ module ctrl_encode ( aluOpSource1, aluOpSource2, aluDest, + aluCarrySource, regDest, regSetH, regSetL, diff --git a/decoder.v b/decoder.v index d6a1e02..3e08df3 100644 --- a/decoder.v +++ b/decoder.v @@ -7,6 +7,7 @@ module decoder ( output [1:0] aluOpSource1, // ALU first operand: 0 = reg, 1 = memory read, 2 = imm8, 3 = PC output [1:0] aluOpSource2, // ALU second operand: 0 = reg, 1 = ~reg, 2 = PC, 3 = ??? output aluDest, // 0 = reg, 1 = PC + output [1:0] aluCarrySource, // ALU carry input source: 0 = zero, 1 = one, 2 = carry, 3 = ~carry output [2:0] regDest, output regSetH, @@ -216,6 +217,8 @@ module decoder ( assign regDest = reg0; + assign aluCarrySource = 2'h0; + assign regSetH = instr_mov ? (mov_word | mov_dest_byte_high) : instr_movimm ? movimm_high : diff --git a/decoder_stage.v b/decoder_stage.v index fcc7d60..fa2721e 100644 --- a/decoder_stage.v +++ b/decoder_stage.v @@ -5,7 +5,7 @@ module decoder_stage ( input [15:0] instr_in, input [15:0] pc_in, - output reg [32:0] control_signals_out, + output reg [34:0] control_signals_out, output reg [15:0] imm_out, output reg [15:0] pc_out ); @@ -16,6 +16,7 @@ module decoder_stage ( wire [1:0] aluOpSource1_next; wire [1:0] aluOpSource2_next; wire aluDest_next; + wire [1:0] aluCarrySource_next; wire [2:0] regDest_next; wire regSetH_next; wire regSetL_next; @@ -35,6 +36,7 @@ module decoder_stage ( .aluOpSource1(aluOpSource1_next), .aluOpSource2(aluOpSource2_next), .aluDest(aluDest_next), + .aluCarrySource(aluCarrySource_next), .regDest(regDest_next), .regSetH(regSetH_next), .regSetL(regSetL_next), @@ -47,7 +49,7 @@ module decoder_stage ( .imm(imm_next) ); - wire [32:0] control_signals_next; + wire [34:0] control_signals_next; ctrl_encode encode_inst ( .aluOp(aluOp_next), @@ -56,6 +58,7 @@ module decoder_stage ( .aluOpSource1(aluOpSource1_next), .aluOpSource2(aluOpSource2_next), .aluDest(aluDest_next), + .aluCarrySource(aluCarrySource_next), .regDest(regDest_next), .regSetH(regSetH_next), .regSetL(regSetL_next), diff --git a/tests/alu b/tests/alu index 474acbb..d271a0c 100644 --- a/tests/alu +++ b/tests/alu @@ -1,8 +1,10 @@ # X op Y = RESULT ZERO CARRY # # Operations: -# + : add -# - : subtract +# + : add (x+y) +# ++ : add with carry (x+y+1) +# - : subtract (x-y) +# -- : subtract with borrow (x-y-1) # * : multiply # / : divide # & : and @@ -17,9 +19,12 @@ # ->> : right shift extended with most significant bit # >>> : right rotate -0x0123 + 0x1234 = 0x1357 Z=0 C=0 -0x0123 - 0x1234 = 0xeeef Z=0 C=1 -0x0123 - 0x0123 = 0x0000 Z=1 C=0 +0x0123 + 0x1234 = 0x1357 Z=0 C=0 +0x0123 ++ 0x1234 = 0x1358 Z=0 C=0 +0x0123 - 0x1234 = 0xeeef Z=0 C=1 +0x0123 -- 0x1234 = 0xeeee Z=0 C=1 +0x0123 - 0x0123 = 0x0000 Z=1 C=0 +0x0123 -- 0x0123 = 0xffff Z=0 C=1 0x0123 * 0x1234 = 0xb11c Z=0 C=0 0x3e58 / 0x0078 = 0x0085 Z=0 C=0 0xaf74 & 0x7cc7 = 0x2c44 Z=0 C=0 -- cgit v1.2.3