diff options
author | Nick McKinney <nick@kmonkey.net> | 2016-12-18 15:54:12 -0600 |
---|---|---|
committer | Nick McKinney <nick@kmonkey.net> | 2016-12-18 15:54:12 -0600 |
commit | 9a8d8892361dcd16ad3801ce29e25516c8cd1019 (patch) | |
tree | 01f8cd27475fa5c9535b507d54eef7880f95a830 /alu_stage.v | |
parent | 603bee2b743f1a72222fd8586fa809555f08ea77 (diff) |
Add ALU stage and hook it up. It sort of works.
Diffstat (limited to 'alu_stage.v')
-rw-r--r-- | alu_stage.v | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/alu_stage.v b/alu_stage.v new file mode 100644 index 0000000..0ab5265 --- /dev/null +++ b/alu_stage.v @@ -0,0 +1,107 @@ +module alu_stage ( + input clk, + input en, + input [15:0] pc_in, + input [31:0] control_signals_in, + input [15:0] imm_in, + + // register file + output [2:0] rf_regA, + output [2:0] rf_regB, + output [2:0] rf_regDest, + output [15:0] rf_dataIn, + output rf_we, + output rf_hb, + output rf_lb, + input [15:0] rf_dataA, + input [15:0] rf_dataB, + + // memory interface + input [15:0] memData_in, // read in from memory + output reg [15:0] memData_out, // to write out to memory + + output reg [31:0] control_signals_out, + output reg [15:0] imm_out, + output reg [15:0] pc_out +); + + // decode signals + wire [3:0] aluOp_in; + wire [2:0] aluReg1_in; + wire [2:0] aluReg2_in; + wire [1:0] aluOpSource1_in; + wire [1:0] aluOpSource2_in; + wire aluDest_in; + wire [2:0] regDest_in; + wire regSetH_in; + wire regSetL_in; + wire [2:0] regAddr_in; + wire memReadB_in; + wire memReadW_in; + wire memWriteB_in; + wire memWriteW_in; + wire [4:0] setRegCond_in; + + ctrl_decode ctrl_decode_inst ( + .control_signals(control_signals_in), + + .aluOp(aluOp_in), + .aluReg1(aluReg1_in), + .aluReg2(aluReg2_in), + .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 + + .regDest(regDest_in), + .regSetH(regSetH_in), + .regSetL(regSetL_in), + + .regAddr(regAddr_in), + .memReadB(memReadB_in), + .memReadW(memReadW_in), + .memWriteB(memWriteB_in), + .memWriteW(memWriteW_in), + + .setRegCond(setRegCond_in) // {should set when condition is true, Z doesn't matter, S doesn't matter, Z must be this, S must be this} + ); + + wire [15:0] aluSrc1; + assign aluSrc1 = + aluOpSource1_in == 2'h0 ? rf_dataA : + aluOpSource1_in == 2'h1 ? memData_in : + aluOpSource1_in == 2'h2 ? {imm_in} : pc_in; + + wire [15:0] aluSrc2; + assign aluSrc2 = + aluOpSource1_in == 2'h0 ? rf_dataB : + aluOpSource1_in == 2'h1 ? ~rf_dataIn : pc_in; + + wire [15:0] aluResult; + wire aluZero, aluCarry; + alu alu_inst ( + .op(aluOp_in), + .x(aluSrc1), + .y(aluSrc2), + .result(aluResult), + .zero(aluZero), + .carry(aluCarry) + ); + + assign rf_regA = aluReg1_in; + assign rf_regB = aluReg2_in; + assign rf_we = en & (regSetH_in | regSetL_in); + assign rf_hb = regSetH_in; + assign rf_lb = regSetL_in; + assign rf_dataIn = aluResult; + assign rf_regDest = regDest_in; + + always @(posedge clk) begin + if(en) begin + control_signals_out <= control_signals_in; + imm_out <= imm_in; + memData_out <= aluResult; + pc_out <= pc_in; + end + end + +endmodule |