程序代写案例-ELEC-374

欢迎使用51辅导,51作业君孵化低价透明的学长辅导平台,服务保持优质,平均费用压低50%以上! 51fudao.top
1
Department of Electrical and Computer Engineering
Queen’s University

ELEC-374 Digital Systems Engineering
Laboratory Project
Winter 2020
Designing a Simple RISC Computer: Phase 3
----------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------
1. Objectives
The purpose of this project is to design, simulate, implement, and verify a simple RISC Computer (Mini SRC). So
far, you have designed and functionally simulated the Datapath portion of the Mini SRC (except for nop and halt
instructions that you will test in this phase). Phase 3 of this project consists of adding and testing the Control
Unit in Mini SRC. You are to design the Control Unit in VHDL or Verilog. Testing will be done by Functional
Simulation.

2. Preliminaries
2.1 Control Unit
A block diagram of the Control Unit for Mini SRC is shown in Figure 1. The Control Unit is at the heart of the
processor. It accepts as input those signals that are needed to operate the processor and provides as output all
the control signals necessary to execute the instructions. The outputs from the Control Unit are the control
signals that we have been using in the previous phases to generate control sequences for the instructions of the
Mini SRC.



Figure 1: Block diagram of the Control Unit

2
The Control Unit generates the control signals from four principal sources:

(a) The op-code fields of the IR
(b) Signals from the Datapath such as CON FF, and the condition code registers (if any)
(c) Control step information such as signals T0, T1, …
(d) External inputs such as Stop, Reset, Done (if memory is slow), and other signals such as interrupts (if any)

The external Reset input should get the Mini SRC to an initial state, where all registers including PC in the
Datapath are set to 0, the Run indicator is set to 1, and the processor starts at Step T0. As the clock continues
to run, instructions should be fetched and executed one after the other until a halt instruction is encountered,
at which point the control stepping process should be halted and the Run indicator is set to 0. Note that, the
external Stop input signal works the same way as the halt instruction.
During T0, T1, and T2, the control signals that are asserted to implement the “instruction fetch” sequence are
independent of the bits in the Instruction Register. For instance, in Step T0, the control signals PCout, MARin,
IncPC and Zin are set to 1. In Step T1, the control signals Zlowout, PCin, Read, and MDRin are set to 1. In Step
T2, the control signals MDRout and IRin are set to 1. However, from Step T3 onward, until the current instruction
is completed, the control signals that are asserted are a function of both Step Ti and the op-code bits in the IR
register.

In the following, you will see two different methods to design your Control Unit. There is a trade-off between
the two methods. Method 1 is clearly the easier method, but it may generate more hardware. Of course, you
are free to come up with your own design style, if you wish.

Method 1: It is possible to write the VHDL/Verilog code without worrying about the combinational logic
expressions for each control signal. Therefore, the code will come clean and the instructions will be executed
in the most efficient manner. However, it may generate more hardware. The following sample VHDL and
Verilog code are provided as a starting point for this method, which you may need to verify and revise for your
Control Unit:

-- this is the VHDL sample code for Method 1 for the Control Unit
LIBRARY ieee;
USE ieee.std_logic_1164.all;

ENTITY control_unit IS -- here, you will define the inputs and outputs to your Control Unit
PORT(Clock, Reset, Stop, …, CON_FF: IN STD_LOGIC;
IR: IN STD_LOGIC_VECTOR(31 DOWNTO 0);
Gra, Grb, Grc, Rin, …, Rout: OUT STD_LOGIC;
Yin, Zin, PCout, IncPC, …, MARin: OUT STD_LOGIC;
Read, Write, …, Clear: OUT STD_LOGIC;
ADD, AND, …, SHR: OUT STD_LOGIC);
END control_unit;

ARCHITECTURE Behavior of control_unit IS
TYPE State IS (Reset_state, fetch0, fetch1, fetch2, add3, add4, add5, …);
SIGNAL Present_state: State;
BEGIN
PROCESS (Clock, Reset) -- finite state machine
BEGIN
IF (Reset = ‘1’) THEN -- reset the processor
3
Present_state <= Reset_state;
ELSIF (rising_edge(Clock)) THEN -- if clock rising-edge
CASE Present_state IS
WHEN Reset_state =>
Present_state <= fetch0;
WHEN fetch0 =>
Present_state <= fetch1;
WHEN fetch1 =>
Present_state <= fetch2;
WHEN fetch2 => -- instruction decoding based on the opcode to set the next state
CASE IR(31 DOWNTO 27) IS
WHEN “00011” => -- this is the add instruction
Present_state <= add3;

WHEN OTHERS =>
END CASE;
WHEN add3 =>
Present_state <= add4;
WHEN add4 =>
Present_state <= add5;

WHEN OTHERS =>
END CASE;
END IF;
END PROCESS;

PROCESS (Present_state) -- do the job for each state
BEGIN
CASE Present_state IS -- assert the required signals in each state
WHEN Reset_state =>
Gra <= ‘0’; -- initialize the signals
Grb <= ‘0’;
Grc <= ‘0’;
Yin <= ‘0’;

WHEN fetch0 =>
PCout <= ‘1’; -- see if you need to de-assert these signals
MARin <= ‘1’;
IncPC <= ‘1’;
Zin <= ‘1’;
WHEN add3 =>
Grb <= ‘1’;
Rout <= ‘1’;
Yin <= ‘1’;

WHEN nop =>
WHEN OTHERS =>
END CASE;
END PROCESS;
END Behavior;
-----------------------------------------------------
// this is the Verilog sample code for Method 1 for the Control Unit
4
`timescale 1ns/10ps
module control_unit (
output reg Gra, Grb, Grc, Rin, …, Rout, // here, you will define the inputs and outputs to your Control Unit
Yin, Zin, PCout, IncPC, …, MARin,
Read, Write, …, Clear,
ADD, AND, …, SHR,
input [31:0] IR,
input Clock, Reset, Stop, …, Con_FF);
parameter Reset_state = 4’b0000, fetch0 = 4’b0001, fetch1 = 4’b0010, fetch2 = 4’b0011,
add3 = 4’b0100, add4 = 4’b0101, add5 = 4’b0110, …;
reg [3:0] Present_state = Reset_state; // adjust the bit pattern based on the number of states

always @(posedge Clock, posedge Reset) // finite state machine; if clock or reset rising-edge
begin
if (Reset == 1’b1) Present_state = Reset_state;
else case (Present_state)
Reset_state : Present_state = fetch0;
fetch0 : Present_state = fetch1;
fetch1 : Present_state = fetch2;
fetch2 : begin
case (IR[31:27]) // inst. decoding based on the opcode to set the next state
5’b00011 : Present_state = add3; // this is the add instruction

endcase
end
add3 : Present_state = add4;
add4 : Present_state = add5;

endcase
end

always @(Present_state) // do the job for each state
begin
case (Present_state) // assert the required signals in each state
Reset_state: begin
Gra <= 0; Grb <= 0; Grc <= 0; Yin <= 0; // initialize the signals

end
fetch0: begin
PCout <= 1; // see if you need to de-assert these signals
MARin <= 1;
IncPC <= 1;
Zin <= 0;
end
add3: begin
Grb <= 1; Rout <= 1;
Yin <= 0;
end

endcase
end
endmodule
5
Method 2: In this approach, you will need to derive all control signal setting conditions for all instructions. For
this, you must examine all of the control sequences of the machine. The logic for each control signal is generated
by going through the control sequences looking for every occurrence of that control signal and writing the
Boolean equation for the signal. For example, the Zlowout signal occurs at T1 in all instructions, at T5 in and,
or, add, sub, mul, div, shr, shl, ror, rol, ld, and ldi instructions, and in some T states for other instructions.
Therefore,

Zlowout = T1 + T5 . (AND + OR + ADD + SUB + MUL + DIV + SHR + SHL + ROR + ROL + …) + …

The problem with this approach is that the logic for each control signal may change with the addition of new
instructions, therefore this approach is provided here merely for the sake of completeness. You are advised to
use Method 1, especially if you intend to extend the scope of the project by adding new instructions, etc.

The following sample VHDL and Verilog code are provided as a starting point for Method 2, which you may need
to verify and revise for your Control Unit:

-- this is the VHDL sample code for Method 2 for the Control Unit
LIBRARY ieee;
USE ieee.std_logic_1164.all;

ENTITY control_unit IS -- Here, you will define the inputs and outputs to your Control Unit
PORT(Clock, Reset, Stop, …, CON_FF: IN STD_LOGIC;
IR: IN STD_LOGIC_VECTOR(31 DOWNTO 0);
Gra, Grb, Grc, Rin, …, Rout: OUT STD_LOGIC;
Yin, Zin, PCout, IncPC, Zlowout, …, MARin: OUT STD_LOGIC;
Read, Write, …, Clear: OUT STD_LOGIC;
ADD, AND, …, SHR: OUT STD_LOGIC);
END control_unit;

ARCHITECTURE Behavior of control_unit IS
SIGNAL T0, T1, T2, T3, T4, T5, …, : STD_LOGIC;
SIGNAL ADD_s, SUB_s, AND_s, OR_s, …, : STD_LOGIC;
TYPE State IS (Reset_state, S0, S1, …, );
SIGNAL Present_state: State;
BEGIN
PROCESS (Clock, Reset, …) -- finite state machine
BEGIN
IF (Reset = ‘1’) THEN -- reset the processor
Present_state <= Reset_state;
ELSIF (rising_edge(Clock)) THEN -- if clock rising-edge
T0 <= ‘0’; T1 <= ‘0’; T2 <= ‘0’; T3 <= ‘0’; T4 <= ‘0’; T5 <= ‘0’; …
CASE Present_state IS
WHEN Reset_state =>
Present_state <= S0;
T0 <= ‘1’;
WHEN S0 =>
Present_state <= S1;
T1 <= ‘1’;

WHEN OTHERS =>
6
END CASE;
END IF;
END PROCESS;

PROCESS (IR)
BEGIN
ADD_s <= ‘0’; AND_s <= ‘0’; …
CASE IR(31 DOWNTO 27) IS -- inst. decoding based on the opcode
WHEN “00011” =>
ADD_s <= ‘1’; -- this is the add instruction
WHEN “01001” =>
AND_s <= ‘1’; -- this is the and instruction

WHEN OTHERS =>
END CASE;
END PROCESS;

PROCESS (Clock, T0, T1, …)
BEGIN
ADD <= ADD_s AND T4; -- control signal assignment
Zlowout <= T1 OR (T5 AND (AND_s OR OR_s OR ADD_s OR SUB_s OR …)) OR …;

END PROCESS;
END Behavior;
-----------------------------------------------------

// this is the Verilog sample code for Method 2 for the Control Unit
`timescale 1ns/10ps
module control_unit (
output reg Gra, Grb, Grc, Rin, …, Rout, // here, you will define the inputs and outputs to your Control Unit
Yin, Zin, PCout, IncPC, Zlowout, …, MARin,
Read, Write, …, Clear,
ADD, AND, …, SHR,
input [31:0] IR,
input Clock, Reset, Stop, …, Con_FF);

parameter Reset_state = 4’b0000, S0 = 4’b0001, S1 = 4’b0010, …;
reg [3:0] Present_state = Reset_state; // adjust the bit pattern based on the number of states
reg T0, T1, T2, T3, T4, T5, ..., ;
reg ADD_s, SUB_s, AND_s, OR_s, ..., :

always @(posedge Clock, posedge Reset, …) // finite state machine; if clock or reset rising-edge
begin
if (Reset == 1’b1) Present_state = Reset_state; // reset the processor
else begin
T0 <= 0; T1 <= 0; T2 <= 0; T3 <= 0; T4 <= 0; T5 <= 0;
case (Present_state)
Reset_state: begin
Present_state = S0;
T0 <= 1;
end
7
S0: begin
Present_state = S1;
T1 <= 1;
end

endcase
end
end

always @(IR)
begin
ADD_s <= 0; AND_s <= 0; …
case (IR[31:27]) // inst. decoding based on the opcode
5’b00011: ADD_s <= 1; // this is the add instruction
5’b01001: AND_s <= 1; // this is the and instruction

endcase
end

always @(Clock, T0, T1, …)
begin
ADD <= ADD_s && T4; // control signal assignment
Zlowout <= T1 || (T5 && (AND_s || OR_s || ADD_s || SUB_s || …)) || …;

end
endmodule


3. Procedure
3.1) Use one of the above Methods (or come up with your own design style) and write your VHDL/Verilog code
to implement the Control Unit. Add the Control Unit to your Datapath.

3.2) Run a functional simulation of the following program on Mini SRC and put the results in your report. Note
that this program is provided just for the sake of testing the control unit and the instructions in Mini SRC,
except for brnz/brzr Branch and Input/Output instructions that will be included in the test code for Phase
4. This year, due to remote delivery, Phase 4 will in not be a part of the course as we do not have physical
access to the DE0 boards.

Encode your program in the memory with the starting address zero. Initialize the memory locations $75
and $58 with the 32-bit values $56 and $34, respectively.

Minimum outputs are IR, PC, MDR, MAR, R0 – R15, HI, and LO. Add any other signals you would like to
observe to convince yourself that your design works fine.


ORG 0
ldi R3, $87 ; R3 = $87
ldi R3, 1(R3) ; R3 = $88
ld R2, $75 ; R2 = ($75) = $56
8
ldi R2, -2(R2) ; R2 = $54
ld R1, 4(R2) ; R1 = ($58) = $34
ldi R0, 1 ; R0 = 1
ldi R3, $73 ; R3 = $73
brmi R3, 3 ; continue with the next instruction (will not branch)
ldi R3, 5(R3) ; R3 = $78
ld R7, -3(R3) ; R7 = ($78 - 3) = $56
nop
brpl R7, 2 ; continue with the instruction at “target” (will branch)
ldi R4, 6(R1) ; this instruction will not execute
ldi R3, 2(R4) ; this instruction will not execute
target: add R3, R2, R3 ; R3 = $CC
addi R7, R7, 3 ; R7 = $59
neg R7, R7 ; R7 = $FFFFFFA7
not R7, R7 ; R7 = $58
andi R7, R7, $0F ; R7 = 8
ori R7, R1, 3 ; R7 = $37
shr R2, R3, R0 ; R2 = $66
st $58, R2 ; ($58) = $66 new value in memory with address $58
ror R1, R1, R0 ; R1 = $1A
rol R2, R2, R0 ; R2 = $CC
or R2, R3, R0 ; R2 = $CD
and R1, R2, R1 ; R1 = $8
st $67(R1), R2 ; ($75) = $CD new value in memory with address $75
sub R3, R2, R3 ; R3 = 1
shl R1, R2, R0 ; R1 = $19A
ldi R4, 5 ; R4 = 5
ldi R5, $1D ; R5 = $1D
mul R5, R4 ; HI = 0; LO = $91
mfhi R7 ; R7 = 0
mflo R6 ; R6 = $91
div R5, R4 ; HI = 4, LO = 5
ldi R10, 0(R4) ; R10 = 5 setting up argument registers
ldi R11, 2(R5) ; R11 = $1F R8, R9, R10, and R11
ldi R12, 0(R6) ; R12 = $91
ldi R13, 0(R7) ; R13 = 0
jal R12 ; address of subroutine subA in R12 - return address in R14
halt ; upon return, the program halts

subA: ORG $91 ; procedure subA
add R9, R10, R12 ; R8 and R9 are return value registers
sub R8, R11, R13 ; R9 = $96, R8 = $1F
sub R9, R9, R8 ; R13 = $77
jr R14 ; return from procedure



9
4. Report

The phase 3 report (one per group) consists of:
- Printouts of your VHDL/Verilog code, and schematic (if any)
- Functional simulation run of the program
- Printouts of the contents of memory before and after the program run





欢迎咨询51作业君
51作业君

Email:51zuoyejun

@gmail.com

添加客服微信: abby12468