ECE 4DM4 - Computer Architecture Lab # 4 - A Pipelined ALU Unit
ECE 4DM4 - Computer Architecture Lab # 4 - A Pipelined ALU Unit
ECE 4DM4 - Computer Architecture Lab # 4 - A Pipelined ALU Unit
Instruction supplied to ALU_unit from ID_Unit Instruction supplied from ALU_unit to Load/Store Unit 32 bit A_operand for the ALU (from ID_Unit) 32 bit B_operand for the ALU (from ID_Unit) 5 bit identify of the destination register for the C_ operand 32 bit C_operand to be written back to the ID_unit 1 bit control signal: 1-> write the C_op to the register file in the ID_unit.
ALU-Unit - Behavioral Description Overview: The ALU_Unit accepts two operands (the A_op and B_op) from the ID_Unit per clock cycle, and performs the required ALU operations on those operands to produce the C_operand. In a 5-stage pipeline, The C_Operand would then go to the MEM and WB stages, where it is written back to the ID unit. The ALU operation to be performed is specified in the Opcode on the instruction supplied on the Instr_In port.
2 The ALU_unit will process instructions which are valid ALU instructions. If the ALU_Unit receives an instruction which is not an ALU instruction, ie a NO-OP, it simply passes it through the pipeline without doing anything. ALU UNIT Behavioural Rules: A rising clock edge denotes a new clock cycle, call it "clock cycle t". (1) At the beginning of clock cycle t, if Valid_Instr=1, then the instruction on the Instr_In port is valid, and the ALU_unit will process this instruction, its A operand and B operand. (2) Before the next rising clock edge, the C_operand computed in the current clock cycle is asserted onto the C_operand port for the duration of the current clock cycle, and the C_write signal is asserted. This allows the ID state to capture these values at the next rising edge, and allows the C operand to be written back to the registers in the ID stage, one clock cycle after they are computed. In our lab, the ALU unit is performing the Write-Back. Comments: - There are special situations called "data hazards" which can exist. You can assume that data hazards are handled by the compiler.
3 (5) Using the waveform editor, validate the ALU unit's behaviour through the following tests. DEMOS: You need to demonstrate the correct operation to your lab to a TA, and have them record the demonstration and its grade. You do not need to capture images to include in a lab report.
Tests to Demonstrate to your TA: (T1) The ALU unit receives the appropriate data from the ID_Unit : Set the instruction for the current clock cycle to be ADD R3,R2,R1. Set the A_op and B_op inputs to be +9 and -9 respectively. Verify that the C_op is 0, the C_addr is 3, and the C_write is asserted before the next rising edge. (T2) Modify and Repeat Test T1, for the other ALU instructions that you have implemented. In your report, it should be clear which instructions you have implemented, and which instructions you have validated through a test. The TA should record which instructions have been demonstrated successfully. (6) For the ALU lab report, answer parts (1)-(4), state which instructions were successfully demonstrated to the TA and state the TA's name, and include your documented VHDL code for the ALU Unit. If some aspect of your unit does not work, write a brief description to explain what needs to be done. If you cannot get the complete ID unit working, try for a subset. Good Luck with your design.
------------------------------------------------------------------------ main Entity declaration for IF_Unit -- not all I/O ports are here, so you wil have to add some ----------------------------------------------------------------------ENTITY ALU_unit IS PORT( clock, pause c_write, valid_instr instr_in, A_op, B_op instr_out, C_op C_write ); PROCESS(clock) variable A_op_temp : signed(30 downto 0); variable B_op_temp : signed(30 downto 0); -- more variables -- more code : IN : OUT : IN : OUT : OUT STD_LOGIC; STD_LOGIC; STD_LOGIC_VECTOR(31 DOWNTO 0); STD_LOGIC_VECTOR(31 DOWNTO 0); STD_LOGIC_VECTOR(4 DOWNTO 0)
CASE op_code(7 downto 0) IS WHEN ADD => c_op_temp<=CONV_STD_LOGIC_VECTOR ((SIGNED(A_op)+SIGNED(B_op)),32); -- handle other OP-code cases END CASE; END ALU_unit; ------------------------------------------------------------------------ main Architecture declaration: -- describe the ALU Unit behaviourally ------------------------------------------------------------------------ARCHITECTURE ALU_behavioral OF ALU_unit IS BEGIN Process_1: PROCESS(clock) BEGIN -- do something END PROCESS Process_1; END ALU_behavioral;
Lab. 5 (Optional) : Putting Stages 1 - 3 Together Sample VHDL Code for the 4DM4 CPU
----------------------------------------------------------------------------------------------------- Entity: CPU_ENTITY for 4DM4 COMPUTER ARCHITECTURE -- Designers: the 4DM4 class -- Note: this code may need revision. -- In Lab. 5 which is optional, we will likely ask that all the stages that you created be -- connected together and demonstrated to the professor and the TA(s); -- this code gives you a starting point -- you may add an external memory module to this too ---------------------------------------------------------------------------------------------------LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.std_logic_arith.ALL; USE ieee.std_logic_unsigned.ALL; LIBRARY STD; USE STD.TEXTIO.ALL; ENTITY cpu IS PORT ( clock, pause : done : instr_in : addr : read : ); END ENTITY cpu; -- for debugging statements
IN STD_LOGIC; IN STD_LOGIC; IN STD_LOGIC_VECTOR(31 DOWNTO 0); OUT STD_LOGIC_VECTOR (31 DOWNTO 0); OUT STD_LOGIC
ARCHITECTURE cpu_structural OF cpu IS COMPONENT if_unit PORT ( clock, pause : load_bta, done : addr, instr_out : read, valid_instr : instr_in : offset : ); END COMPONENT;
IN STD_LOGIC; IN STD_LOGIC; OUT STD_LOGIC_VECTOR(31 DOWNTO 0); OUT STD_LOGIC; IN STD_LOGIC_VECTOR (31 DOWNTO 0); IN STD_LOGIC_VECTOR(15 DOWNTO 0)
7 COMPONENT id_unit PORT ( clock, pause : IN STD_LOGIC; c_write : IN STD_LOGIC; instr_in, c_op : IN STD_LOGIC_VECTOR(31 downto 0); c_addr : IN STD_LOGIC_VECTOR(4 downto 0); instr_out, op_a, op_b : OUT STD_LOGIC_VECTOR(31 downto 0); offset : OUT STD_LOGIC_VECTOR(15 downto 0); load_bta, valid_instr : OUT STD_LOGIC ); END COMPONENT; COMPONENT alu_unit PORT( clock, pause : instr_in : op_a, op_b : instr_out : c_op : c_addr : c_write ); END COMPONENT;
IN STD_LOGIC; IN STD_LOGIC_VECTOR(31 DOWNTO 0); IN STD_LOGIC_VECTOR(31 DOWNTO 0); OUT STD_LOGIC_VECTOR(31 DOWNTO 0); OUT STD_LOGIC_VECTOR(31 DOWNTO 0); OUT STD_LOGIC_VECTOR(4 DOWNTO 0); : OUT STD_LOGIC;
-- define the wires (internal signals) to connect the 3 pipeline stages SIGNAL if_id_instr, id_alu_instr, alu_ls_instr : SIGNAL op_a, op_b, c_op : SIGNAL c_addr : SIGNAL c_write, load_bta : SIGNAL cond_code : SIGNAL offset : BEGIN -- instantiate the 3 components, and interconnect them using PORT MAPs -- here we use an "explicit association" rather than "implicit association" PORT MAP -- the mapping between a global signal and a components I/O ports is explicit, -- so that the order does not matter -- CHECK ALL THESE CONNECTIONS THEY ARE ILLUSTRATIVE ONLY if_inst: if_unit PORT MAP ( STD_LOGIC_VECTOR(31 DOWNTO 0); STD_LOGIC_VECTOR(31 DOWNTO 0); STD_LOGIC_VECTOR (4 DOWNTO 0); STD_LOGIC; STD_LOGIC_VECTOR (2 DOWNTO 0); STD_LOGIC_VECTOR (15 DOWNTO 0);
8 clock=>clock, pause=>pause, read=>read, addr=>addr, instr=>instr_in, done=>done, instr_out=>if_id_instr, offset=>offset, load_bta=>load_bta); id_inst: id_unit PORT MAP ( clock=>clock, pause=>pause, instr_in=>if_id_instr, c_write=>c_write, c_op=>c_op, op_a=>op_a, op_b=>op_b, c_addr=>c_addr, instr_out=>id_alu_instr, offset=>offset, load_bta=>load_bta); alu_inst: alu_unit PORT MAP ( clock=>clock, pause=>pause, instr_in=>id_alu_instr, op_a=>op_a, op_b =>op_b, instr_out=>alu_ls_instr, c_op=>c_op, c_addr=>c_addr, c_write=>c_write); END ARCHITECTURE cpu_structural;