Professional Documents
Culture Documents
Mips Implementation
Mips Implementation
Master of Engineering
VLSI Design Project Report
Processor
Implementation
in VHDL
According to Computer Organisation & Design
by David A. Patterson and John L. Hennessy
Author(s):
M. Linder
M. Schmid
Supervisor(s): J. Frber
A. Eder
Submitted: 06/07/07
Date
Author
Description
0.1
15/05/2007
M. Schmid
0.2
15/05/2007
M. Linder
0.3
29/05/2007
M. Linder
0.4
10/06/2007
M. Linder
0.5
30/06/2007
M. Linder
0.6
02/07/2007
M. Linder
0.6.1
02/07/2007
M. Schmid
0.6.2
03/07/2007
M. Schmid
Design Tasks
0.7
04/07/2007
M. Linder
- Synthesis Results
- References
0.8
05/07/2007
M. Linder, M. Schmid
- Synthesis Results
- Source Code
- Conclusion
1.0
05/07/2007
M. Linder, M. Schmid
Final release
Designer(s)
M. Linder
michael-linder@web.de
M. Schmid
martin-werner.schmid@gmx.de
Contact
Michael Linder
Angerstrae 8a
86356 Neus, Germany
Phone: +49 (0) 176 22 93 58 30
Mail: michael-linder@web.de
Martin Schmid
Fichtenstrae 2
86500 Kutzenhausen, Germany
Phone: +49 (0) 160 92 94 91 54
Mail: martin-werner.schmid@gmx.de
M. Linder, M. Schmid
II
Contents
Department of Electrical Engineering
Contents
1
Introduction................................................................................ 1
1.1
1.2
1.3
Target Specification................................................................... 3
2.1
Building a Datapath............................................................................... 3
2.1.1
Major Components.................................................................................... 3
2.1.2
2.1.3
2.1.4
2.1.5
Jump Instruction........................................................................................ 6
2.2
2.2.1
2.2.2
ALU Control............................................................................................... 8
2.2.3
Main Control.............................................................................................. 9
2.2.4
2.3
Multicycle Implementation...................................................................11
2.3.1
2.3.2
2.3.3
Design Tasks............................................................................ 21
Module Specification............................................................... 22
4.1
ALU......................................................................................................22
4.1.1
Functional Description............................................................................. 22
4.1.2
Block Diagram......................................................................................... 23
4.1.3
Simulation Results................................................................................... 26
4.1.4
Design Files............................................................................................. 26
4.2
Memory................................................................................................27
4.2.1
Functional Description............................................................................. 27
4.2.2
Block Diagram......................................................................................... 28
4.2.3
Simulation Results................................................................................... 28
4.2.4
Design Files............................................................................................. 29
M. Linder, M. Schmid
III
Contents
Department of Electrical Engineering
4.3
Control..................................................................................................30
4.3.1
Functional Description............................................................................. 30
4.3.2
State Diagram......................................................................................... 31
4.3.3
Block Diagram......................................................................................... 32
4.3.4
Simulation Results................................................................................... 33
4.3.5
Design Files............................................................................................. 33
4.4
Data Path.............................................................................................34
4.4.1
Instruction Fetch...................................................................................... 34
4.4.1.1
Functional Description.................................................................................... 34
4.4.1.2
Block Diagram................................................................................................ 34
4.4.1.3
Design Files.................................................................................................... 35
4.4.2
Instruction Decode.................................................................................. 35
4.4.2.1
Functional Description.................................................................................... 35
4.4.2.2
Block Diagram................................................................................................ 35
4.4.2.3
Design Files.................................................................................................... 36
4.4.3
Execution................................................................................................. 36
4.4.3.1
Functional Description.................................................................................... 36
4.4.3.2
Block Diagram................................................................................................ 37
4.4.3.3
Design Files.................................................................................................... 38
4.4.4
Memory Writeback.................................................................................. 39
4.4.4.1
Functional Description.................................................................................... 39
4.4.4.2
Block Diagram................................................................................................ 40
4.4.4.3
Design Files.................................................................................................... 41
4.4.5
Data Path................................................................................................ 42
4.4.5.1
Block Diagram................................................................................................ 42
4.4.5.2
Design Files.................................................................................................... 42
4.5
4.5.1
Functional Description............................................................................. 43
4.5.2
Block Diagram......................................................................................... 43
4.5.3
Design Files............................................................................................. 44
Synthesis Results.................................................................... 45
6.1
Description...........................................................................................47
6.2
Simulation Result.................................................................................49
Conclusion................................................................................ 50
7.1
M. Linder, M. Schmid
IV
Contents
Department of Electrical Engineering
7.2
7.3
Appendix................................................................................... 52
8.1
Design files..........................................................................................52
8.1.1
Project Entities........................................................................................ 52
8.1.2
Project Architectures............................................................................... 58
8.1.3
Package.................................................................................................. 79
8.1.4
Testbenches............................................................................................ 80
8.2
References...........................................................................................91
M. Linder, M. Schmid
Contents
Department of Electrical Engineering
List of Figures
Figure 1.1: Simple block diagram with datapaths [PaHe98] p. 352....................... 1
Figure 1.2: Multicycle Datapath [PaHe98] p. 414...................................................2
Figure 1.3: Pipelined Version of the Datapath [PaHe98], p. 452........................... 2
Figure 2.1: Instruction Memory, Program Counter and Adder [PaHe98], p 344....3
Figure 2.2: Datapath for fetching instructions and incrementing the PC
[PaHe98] p. 345......................................................................................................3
Figure 2.3: Register and ALU [PaHe98] p. 346......................................................4
Figure 2.4: Datapath for R-type Instructions [PaHe98] p. 347...............................4
Figure 2.5: Data Memory and Sign extension unit [PaHe98] p. 348......................5
Figure 2.6: Load or Store Word instruction field.....................................................5
Figure 2.7: Datapath for Load Word and Store Word [PaHe98] p. 348.................5
Figure 2.8: Datapath for a branch instruction [PaHe98] p. 350..............................6
Figure 2.9: Completed Simple Datapath [PaHe98] p. 353.....................................7
Figure 2.10: MIPS field...........................................................................................8
Figure 2.11: Table for ALU Control.........................................................................8
Figure 2.12: Datapath with ALU Control Unit [PaHe98] p. 358..............................9
Figure 2.13: Meaning of the main control signals [PaHe98] p. 359....................... 9
Figure 2.14: The simple datapath with the control unit [PaHe98] p. 360.............10
Figure 2.15: Truth table of the main control unit [PaHe98] p. 361.......................10
Figure 2.16: Abstract view of a multicycle desing [PaHe98] p. 378..................... 11
Figure 2.17: Complete Datapath for multicycle design [PaHe98] p. 383............. 13
Figure 2.18: Actions of 1-bit control signals [PaHe98] p. 384..............................14
Figure 2.19: Actions of 2-bit control signals [PaHe98] p. 384..............................14
Figure 2.20: Summary of the multicycle steps [PaHe98] p. 389..........................18
Figure 2.21: Complete finite state machine control [PaHe98] p. 396.................. 19
Figure 2.22: Setting of Control Signals.................................................................20
Figure 4.1: ALU 1/3...............................................................................................23
Figure 4.2: ALU 2/3...............................................................................................24
Figure 4.3: ALU 3/3...............................................................................................25
Figure 4.4: Simulation Results of ALU..................................................................26
Figure 4.5: Memory...............................................................................................28
M. Linder, M. Schmid
VI
Contents
Department of Electrical Engineering
M. Linder, M. Schmid
VII
Contents
Department of Electrical Engineering
List of VHDL-Source
VHDLSource 8.1: e_control_ControlFSM.vhd......................................................52
VHDLSource 8.2: e_control_ALUControl.vhd...................................................... 52
VHDLSource 8.3: e_control.vhd...........................................................................52
VHDLSource 8.4: e_tempreg.vhd.........................................................................53
VHDLSource 8.5: e_pc.vhd..................................................................................53
VHDLSource 8.6: e_instreg.vhd...........................................................................53
VHDLSource 8.7: e_regfile.vhd............................................................................54
VHDLSource 8.8: e_alu_vhd................................................................................54
VHDLSource 8.9: e_data_fetch.vhd.....................................................................54
VHDLSource 8.10: e_data_decode.vhd...............................................................55
VHDLSource 8.11: e_data_execution.vhd...........................................................55
VHDLSource 8.12: e_data_memwriteback.vhd................................................... 56
VHDLSource 8.13: e_data.vhd.............................................................................56
VHDLSource 8.14: e_ram.vhd..............................................................................56
VHDLSource 8.15: e_memory.vhd.......................................................................57
VHDLSource 8.16: e_mips.vhd............................................................................57
VHDLSource 8.17: e_procmem.vhd.....................................................................57
VHDLSource 8.18: a_control_ControlFSM.vhd....................................................60
VHDLSource 8.19: a_control_ALUControl.vhd.................................................... 61
VHDLSource 8.20: a_control.vhd.........................................................................62
VHDLSource 8.21: a_tempreg_behave.vhd.........................................................63
VHDLSource 8.22: a_pc_behave.vhd..................................................................63
VHDLSource 8.23: a_instreg_behave.vhd...........................................................64
VHDLSource 8.24: a_regfile_behave.vhd............................................................64
VHDLSource 8.25: a_alu_behave.vhd.................................................................65
VHDLSource 8.26: a_data_fetch.vhd...................................................................67
VHDLSource 8.27: a_data_decode.vhd...............................................................69
VHDLSource 8.28: a_data_execution.vhd...........................................................69
VHDLSource 8.29: a_data_memwriteback.vhd................................................... 70
VHDLSource 8.30: a_data.vhd.............................................................................73
VHDLSource 8.31: a_ram_rtl.vhd.........................................................................73
M. Linder, M. Schmid
VIII
Contents
Department of Electrical Engineering
M. Linder, M. Schmid
IX
1 Introduction
Department of Electrical Engineering
1 Introduction
The performance of software systems is dramatically affected by how well software designers understand the basic hardware technologies at work in a system. According to the book Computer Organization & Design written by David
A. Patterson and John L. Hennessy the hardware and behaviour of a microprocessor is implemented in VHDL.
2 Target Specification
Department of Electrical Engineering
2 Target Specification
2.1 Building a Datapath
2.1.1 Major Components
At first we look at the elements required to execute the MIPS instructions and
their connection.
The first element needed is a place to store the program instructions. This Instruction Memory is used to hold and supply instructions given an address.
The address must be kept in the Program Counter (PC), and in order to increment the PC to the address of the next instruction, we also need an Adder.
All these elements are shown in figure 2.1.
Figure 2.1: Instruction Memory, Program Counter and Adder [PaHe98], p 344
After fetching one instruction from the instruction memory, the program counter
has to be incremented so that it points to the address of the next instruction 4
bytes later.
This is realised by the datapath shown in figure 2.2.
Figure 2.5: Data Memory and Sign extension unit [PaHe98] p. 348
The sw- and lw-instructions compute a memory address by adding a register value to the 16-bit signed offset field contained in the instruction.
Because the ALU has 32-bit values, the instruction offset field must be sign extended from 16 to 32 bits simply by concatenating the sign-bit 16 times to the
original value.
The instruction field for a lw- or sw-instruction is shown in figure 2.6:
op
6 bits
rs
5 bits
rt
5 bits
address
16 bits
Figure 2.7: Datapath for Load Word and Store Word [PaHe98] p. 348
rs
5 bits
rt
5 bits
rd
5 bits
shamt
5 bits
funct
6 bits
Desired
ALU action
ALU control
input
op:
basic operation
rs:
rt:
rd:
register destination
shamt:
shift amount
funct:
function
Instruction
opcode
ALUOp
Instruction
operation
Funct field
LW
00
load word
XXXXXX
add
010
SW
00
store word
XXXXXX
add
010
Branch equal
01
branch equal
XXXXXX
subtract
110
R-type
10
add
100000
add
010
R-type
10
subtract
100010
subtract
110
R-type
10
AND
100100
and
000
R-type
10
OR
100101
or
001
R-type
10
101010
111
RegDst
The register destination number for the Write register comes from the rt field (bits 20-16).
The register destination number for the Write register comes from the rd field (bits 15-11).
RegWrite
None
ALUSrc
The second ALU operand comes from the second register file output (Read data 2).
PCSrc
MemRead
None
Data memory contents designated by the address input are put on the Read data output.
MemWrite
None
Data memory contents designated by the address input are replaced by the value on the Write data input.
MemtoReg
The value fed to the register Write data input comes from the ALU.
The value fed to the register Write data input comes from the data memory.
The connection of the main control unit is shown in figure 2.14. This and the
meaning of the signals described in figure 2.13 leads directly to the truth table for
the main control unit shown in figure 2.15.
Figure 2.14: The simple datapath with the control unit [PaHe98] p. 360
RegDst
ALUSrc
MemtoReg
Reg
Write
Mem
Read
Mem
Write
Branch
ALUOp1
ALUOp2
lw
sw
beq
Instruction
R-format
Figure 2.15: Truth table of the main control unit [PaHe98] p. 361
11
Because the IR holds the value during the whole time of the execution of a
instruction, it requires a write control signal.
The reduction from former three ALUs to one causes also the following changes
in the datapath:
An additional multiplexer is added for the first ALU input to choose between the
A register and the PC.
The multiplexer at the second ALU input is changed from a two-way to a fourway multiplexer. The two new inputs are a constant 4 to increment the PC and
the sign-extended and shifted offset field for the branch instruction.
In order to handle branches and jumps more additions in the datapath are
required.
The three cases of R-type instructions, branch instruction and jump instruction
cause three different values to be written into the PC:
The output of the ALU which is PC + 4 should be stored directly to the PC.
The lower 26 bits of the IR shifted left by two and concatenated with the
upper 4 bits of the incremented PC, when the instruction is jump.
If the instruction is branch, the write signal for the PC is conditional. Only if the
the two compared registers are equal, the computed branch address has to be
written to the PC.
Therefore the PC needs two write signals, which are PCWrite if the write is
unconditional (value is PC + 4 or jump instruction) and PCWriteCond if the write
is conditional.
12
13
Signal name
RegDst
RegWrite
None
The general-purpose register selected by the Write register number is written with the value of the
Write data input.
ALUSrcA
MemRead
None
MemWrite
None
MemtoReg
IorD
IRWrite
None
PCWrite
None
PCWriteCond
None
ALUSrcB
PCSource
Value
Effect
00
01
10
00
01
10
The second input to the ALU is the sign-extended, lower 16 bits of the IR.
11
The second input to the ALU is the sign-extended, lower 16 bits of the IR shifted left
2 bits.
00
01
The contents of ALUOut (the branch target address) are sent to the PC for writing.
10
The jump target address (IR[25-0] shifted left 2 bits and concatenated with
PC +4[31-28]) is sent to the PC for writing.
14
15
2. Arithmetic-logical instruction:
ALUOut = A op B
3. Branch:
if (A == B) PC = ALUOut
4. Jump:
PC = PC[31-28] & (IR[25-0] << 2)
16
or
Memory [ALUOut] = B
or MemWrite = 1
IorD = 1
2. Arithmetic-logical instruction:
Reg[IR[15-11]] = ALUOut
17
Step name
Instruction fetch
Action for
branches
Action for
jumps
IR = Memory[PC]
PC = PC + 4
Instruction decode
register fetch
A = Reg[IR[25-21]]
B = Reg[IR[20-16]]
ALUOut = PC + (sign-extend(IR[15-0] << 2)
Execution, address
computation,
branch/jump completion
ALUOut = A op B
ALUOut = A + sign-extend
(IR[15-0])
Reg[IR[15-11]] =
ALUOut
if (A == B) then
PC = ALUOut
PC = PC[31-28] ||
(IR[25-0] << 2)
18
19
Signal name
State
0
RegDst
RegWrite
ALUSrcA
MemRead
MemWrite
MemtoReg
IorD
IRWrite
PCWrite
PCWriteCond
ALUOp
00
00
00
00
00
00
10
10
01
00
ALUSrcB
01
11
10
10
10
10
00
00
00
11
PCSource
00
00
00
00
00
00
00
00
01
10
20
3 Design Tasks
Department of Electrical Engineering
3 Design Tasks
Prototype Testing
Milestone Presentations
Description
toplevel
toplevel/src
toplevel/work
toplevel/simulation
simulation results
toplevel/stimuli
toplevel/pnr
toplevel/scripts
toplevel/log
toplevel/doc
21
4 Module Specification
Department of Electrical Engineering
4 Module Specification
4.1 ALU
4.1.1 Functional Description
The arithmetic-logic unit (ALU) performs basic arithmetic and logic operations
which are controlled by the opcode. The result of the instruction is written to the
output. An additional zero-bit signalizes an high output if the result equals zero.
At the present time, the basic arithmetic operations add and sub and the logic
operations and, or and slt can be applied to inputs. The inputs are 32 bit wide
with type unsigned. A detection of overflow or borrow is not supported at the moment.
22
23
24
25
File Type
Description
e_alu.vhd
a_alu_behave.vhd
Arithmetic-logic unit
t_alu.vhd
t_alu_fileio.vhd
26
4.2 Memory
Department of Electrical Engineering
4.2 Memory
4.2.1 Functional Description
Data is synchronously written to or read from the memory with a data bus width
of 32 bit. The memory consists of four ram blocks with 8 bit data width each.
A control signal enables the memory to be written, otherwise data is only read. In
order to store data to the memory the data word is subdivided into four bytes
which are separately written to the ram blocks. Vice versa, the single bytes are
concatenated to get the data word back again.
At the moment, it is only possible to read and write data words. An addressing of
half-words or single bytes is not allowed. In order to write or read data words, all
ram blocks have to be selected. Hence, the lowest two bit are not examined for
chip-select logic.
Data is addressed by the MIPS-processor with an address width of 32 bit, while
the address width of a ram block is 8 bit each. All ram blocks are connected to
the same address, namely from mem_address(9 downto 2). Since we do not use
the full address width for addressing and chip selects, data words are addressed
by multiple addresses.
27
28
Figure 4.7 shows the simulation results with unregistered output. Note that the
simulation contains unknown values, because the memory initialisation files are
not supported.
File Type
Description
e_ram.vhd
a_ram_rtl.vhd
a_ram_syn.vhd
a_ram_lpm.vhd
e_memory.vhd
a_memory_behave.vhd
t_memory.vhd
./simulation/ram0_256x8.hex
./simulation/ram1_256x8.hex
./simulation/ram2_256x8.hex
./simulation/ram3_256x8.hex
29
4.3 Control
Department of Electrical Engineering
4.3 Control
4.3.1 Functional Description
The control of the processor is realised by a Finite State Machine described in
section 2.3.3.
The input to the State Machine are the upper 6 bits of the function field containing the instruction.
The outputs of the state machine are the control signals of the single functional
units of the processor implementation especially the multiplexers of the datapath.
The Operation Code of the ALU is stored in a truth table and the corresponding
Opcode is produced depending on the ALUOp signal of the state machine and
the lower 6 bits of the function field containing the information which of the arithmetic or logic instruction is to use.
30
ErrorState
An additional Error State is inserted which is a deadlock. If any unknown instruction occurs the Error State is entered.
31
32
File Type
Description
e_control_ControlFSM.vhd
a_control_ControlFSM.vhd
e_control_ALUControl.vhd
a_control_ALUControl.vhd
e_control.vhd
a_control.vhd
Controlpath
33
34
File Type
Description
e_pc.vhd
a_pc_behave.vhd
Program Counter
e_tempreg.vhd
a_tempreg_behave.vhd
e_instreg.vhd
a_instreg_behave.vhd
Instruction Register
e_data_fetch.vhd
a_data_fetch_behave_vhd
35
File Type
Description
e_regfile.vhd
a_regfile_behave.vhd
Register File
e_tempreg.vhd
a_tempreg_behave.vhd
e_data_decode.vhd
a_data_decode_behave.vhd
4.4.3 Execution
4.4.3.1 Functional Description
The Execution contains the ALU as main element and computes the desired result of the instruction.
It also computes the jump target address and provides it for the Memory Writeback Block.
The operands loaded to the ALU are chosen by two multiplexers which are sensible to the signals ALUSrcA and ALUSrcB.
36
4.4 Execution
Department of Electrical Engineering
37
4.4 Execution
Department of Electrical Engineering
File Type
Description
e_alu.vhd
a_alu_behave.vhd
ALU
e_data_execution.vhd
a_data_execution.vhd
Execution Block
38
39
40
File Type
Description
e_tempreg.vhd
a_tempreg_behave.vhd
e_data_memwriteback.vhd
a_data_memwriteback.vhd
41
File Type
Description
e_data.vhd
a_data_vhd
Datapath
e_data_fetch.vhd
a_data_fetch.vhd
e_data_decode.vhd
a_data_decode.vhd
e_data_execution.vhd
a_data_execution.vhd
e_data_memwriteback.vhd
a_data_memwriteback.vhd
e_tempreg.vhd
a_tempreg_behave.vhd
e_alu.vhd
a_alu_behave.vhd
ALU
e_regfile.vhd
a_regfile_behave.vhd
Register File
e_pc.vhd
a_pc_behave.vhd
Program Counter
e_instreg.vhd
a_instreg_behave.vhd
Instruction Register
42
43
File Type
Description
e_control_ControlFSM.vhd
a_control_ControlFSM.vhd
e_control_ALUControl.vhd
a_control_ALUControl.vhd
e_control.vhd
a_control.vhd
Controlpath
e_data.vhd
a_data.vhd
Datapath
e_data_fetch.vhd
a_data_fetch.vhd
e_data_decode.vhd
a_data_decode.vhd
e_data_execution.vhd
a_data_execution.vhd
e_data_memwriteback.vhd
a_data_memwriteback.vhd
e_tempreg.vhd
a_tempreg_behave.vhd
e_alu.vhd
a_alu_behave.vhd
ALU
e_regfile.vhd
a_regfile_behave.vhd
Register File
e_pc.vhd
a_pc_behave.vhd
Program Counter
e_instreg.vhd
a_instreg_behave.vhd
Instruction Register
e_ram.vhd
a_ram_rtl.vhd
a_ram_syn.vhd
a_ram_lpm.vhd
t_procmem.vhd
t_procmem_init.vhd
44
5 Synthesis Results
Department of Electrical Engineering
5 Synthesis Results
+------------------------------------------------------------------------------+
; Analysis & Synthesis Summary
;
+------------------------------------+-----------------------------------------+
; Analysis & Synthesis Status
; Successful - Thu Jul 05 11:15:33 2007
;
; Quartus II Version
; 7.0 Build 33 02/05/2007 SJ Full Version ;
; Revision Name
; procmem
;
; Top-level Entity Name
; procmem
;
; Family
; Cyclone II
;
; Total logic elements
; 0
;
;
Total combinational functions ; 0
;
;
Dedicated logic registers
; 0
;
; Total registers
; 0
;
; Total pins
; 2
;
; Total virtual pins
; 0
;
; Total memory bits
; 0
;
; Embedded Multiplier 9-bit elements ; 0
;
; Total PLLs
; 0
;
+------------------------------------+-----------------------------------------+
+--------------------------------------------------------------------------------------------------------------+
; Analysis & Synthesis Settings
;
+--------------------------------------------------------------------+--------------------+--------------------+
; Option
; Setting
; Default Value
;
+--------------------------------------------------------------------+--------------------+--------------------+
; Device
; EP2C20F484C7
;
;
; Top-level entity name
; procmem
; procmem
;
; Family name
; Cyclone II
; Stratix
;
; Restructure Multiplexers
; Auto
; Auto
;
; Create Debugging Nodes for IP Cores
; Off
; Off
;
; Preserve fewer node names
; On
; On
;
; Disable OpenCore Plus hardware evaluation
; Off
; Off
;
; Verilog Version
; Verilog_2001
; Verilog_2001
;
; VHDL Version
; VHDL93
; VHDL93
;
; State Machine Processing
; Auto
; Auto
;
; Safe State Machine
; Off
; Off
;
; Extract Verilog State Machines
; On
; On
;
; Extract VHDL State Machines
; On
; On
;
; Ignore Verilog initial constructs
; Off
; Off
;
; Add Pass-Through Logic to Inferred RAMs
; On
; On
;
; DSP Block Balancing
; Auto
; Auto
;
; NOT Gate Push-Back
; On
; On
;
; Power-Up Don't Care
; On
; On
;
; Remove Redundant Logic Cells
; Off
; Off
;
; Remove Duplicate Registers
; On
; On
;
; Ignore CARRY Buffers
; Off
; Off
;
; Ignore CASCADE Buffers
; Off
; Off
;
; Ignore GLOBAL Buffers
; Off
; Off
;
; Ignore ROW GLOBAL Buffers
; Off
; Off
;
; Ignore LCELL Buffers
; Off
; Off
;
; Ignore SOFT Buffers
; On
; On
;
; Limit AHDL Integers to 32 Bits
; Off
; Off
;
; Optimization Technique -- Cyclone II
; Balanced
; Balanced
;
; Carry Chain Length -- Stratix/Stratix GX/Cyclone/MAX II/Cyclone II ; 70
; 70
;
; Auto Carry Chains
; On
; On
;
; Auto Open-Drain Pins
; On
; On
;
; Perform WYSIWYG Primitive Resynthesis
; Off
; Off
;
; Perform gate-level register retiming
; Off
; Off
;
; Allow register retiming to trade off Tsu/Tco with Fmax
; On
; On
;
; Auto ROM Replacement
; On
; On
;
; Auto RAM Replacement
; On
; On
;
; Auto Shift Register Replacement
; On
; On
;
; Auto Clock Enable Replacement
; On
; On
;
; Allow Synchronous Control Signals
; On
; On
;
; Force Use of Synchronous Clear Signals
; Off
; Off
;
; Auto RAM to Logic Cell Conversion
; Off
; Off
;
; Auto Resource Sharing
; Off
; Off
;
; Allow Any RAM Size For Recognition
; Off
; Off
;
; Allow Any ROM Size For Recognition
; Off
; Off
;
; Allow Any Shift Register Size For Recognition
; Off
; Off
;
; Ignore translate_off and synthesis_off directives
; Off
; Off
;
; Show Parameter Settings Tables in Synthesis Report
; On
; On
;
; Ignore Maximum Fan-Out Assignments
; Off
; Off
;
45
5 Synthesis Results
Department of Electrical Engineering
+-----------------------------------------------------+
; Compilation Hierarchy
;
+-----------------------------------------------------+
; |procmem
;
;
|mips
;
;
|control:inst_control|
;
;
|ALUControl:inst_ALUControl|
;
;
|ControlFSM:inst_ControlFSM|
;
;
|data:inst_data|
;
;
|data_decode:inst_data_decode|
;
;
|regfile:inst_regfile|
;
;
|tempreg:A|
;
;
|tempreg:B|
;
;
|data_execution:inst_data_execution|
;
;
|alu:alu_inst|
;
;
|data_fetch:inst_data_fetch|
;
;
|instreg:instr_reg|
;
;
|pc:proc_cnt|
;
;
|tempreg:mem_data_reg|
;
;
|data_memwriteback:inst_data_memwriteback| ;
;
|tempreg:tempreg_inst|
;
;
|memory
;
;
|ram:mem_block0|
;
;
|altsyncram:ram_block_rtl_0|
;
;
|altsyncram_ia61:auto_generated|
;
;
|ram:mem_block1|
;
;
|altsyncram:ram_block_rtl_1|
;
;
|altsyncram_ia61:auto_generated|
;
;
|ram:mem_block2|
;
;
|altsyncram:ram_block_rtl_2|
;
;
|altsyncram_ia61:auto_generated|
;
;
|ram:mem_block3|
;
;
|altsyncram:ram_block_rtl_3|
;
;
|altsyncram_ia61:auto_generated|
;
+-----------------------------------------------------+
46
Instruction Field
Address
Instruction
op
rs
rt
000
lw $s0, 128($zero)
100011
00000
10000
004
lw $s1, 132($zero)
100011
00000
10001
008
000000
10000
10001
012
sw $s2, 136($zero)
101011
00000
10010
016
000000
10001
10000
020
sw $s3, 140($zero)
101011
00000
10011
024
000000
10001
10000
028
sw $s4, 144($zero)
101011
00000
10100
032
000000
10001
10000
036
sw $s5, 148($zero)
101011
00000
10101
040
000000
10000
10001
044
sw $s6, 152($zero)
101011
00000
10110
048
000100
10000
10100
052
UNDEFINED
UUUUUU
UUUUU
UUUUU
056
j8
000010
rd
shamt
funct
0000000010000000
0000000010000100
10010
00000
100000
0000000010001000
10011
00000
100010
0000000010001100
10100
00000
100100
0000000010010000
10101
00000
100101
0000000010010100
10110
00000
101010
0000000010011000
0000000000000001
UUUUU
UUUUU
UUUUUU
00000000000000000000000010
Data (dec)
Data (bin)
128
379
00000000
00000000
00000001
01111011
132
383
00000000
00000000
00000001
01111111
47
6.1 Description
Department of Electrical Engineering
Data (dec)
Data (bin)
136
762
00000000
00000000
00000010
11111010
140
00000000
00000000
00000000
00000100
144
379
00000000
00000000
00000001
01111011
148
383
00000000
00000000
00000001
01111111
152
00000000
00000000
00000000
00000001
The simulation starts at memory address 000 with a load word instruction. The
value of memory address 128 is written into register $s0. The PC is incremented
and the next instruction of memory address 004 is executed. It is also an load
word instruction which loads the value of memory address 132 to register $s1.
Then an add instruction follows which adds the two operands written into the registers $s0 and $s1 and writes the result to register $s2.
Then a store word instruction writes the content of register $s2 to the memory at
address 136.
The following instructions are for subtract, add, or, slt, beq and jump. The result
of a computation is always stored to the memory by a store word instruction.
Note:
For description of the register numbers and names used for the test see Figure
3.13 of [PaHe98] p. 140.
The used assembler instructions are not completely declared in this report.
For information on the machine language see [PaHe98] Chapter 3, especially figure 3.14 on page 141.
48
49
7 Conclusion
Department of Electrical Engineering
7 Conclusion
7.1 Our own experiences
While working on our miniproject, we applied a lot of knowledge learned in the
lecture VHDL. Furthermore, we gained a lot of experience in using the simulation
and synthesis tools. It was very interesting and exciting to describe real hardware
and to see the expected results in simulation and the block diagrams after synthesis.
Our miniproject implementing a processor in VHDL has been a real challenge.
The complexity was not located in the single components, but rather in the implementation of the synchronous operation of the whole control and datapath. Due
to an intensive preparation of the desired hardware according to the literature
Computer Organization & Design [PaHe98], we prevented unintended design
errors. Since our project transcends a pure implementation of VHDL code, we
were able to gain experience in hierarchical design with component instantiation
and package design.
Additionally, while implementing a microprocessor, we could refresh our knowledge in processor operations, memory addressing and MIPS instruction coding.
50
51
8 Appendix
Department of Electrical Engineering
8 Appendix
8.1 Design files
8.1.1 Project Entities
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ENTITY ControlFSM IS
PORT (clk, rst_n : IN std_ulogic;
instr_31_26 : IN std_ulogic_vector(5 downto 0);
RegDst, RegWrite, ALUSrcA, MemRead, MemWrite, MemtoReg, IorD, IRWrite, PCWrite,
PCWriteCond : OUT std_ulogic;
ALUOp, ALUSrcB, PCSource : OUT std_ulogic_vector(1 downto 0)
);
END ControlFSM;
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ENTITY ALUControl IS
PORT (instr_15_0 : IN std_ulogic_vector(15 downto 0);
ALUOp : IN std_ulogic_vector(1 downto 0);
ALUopcode : OUT std_ulogic_vector(2 downto 0)
);
END ALUControl;
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ENTITY control IS
PORT (clk, rst_n : IN std_ulogic;
instr_31_26 : IN std_ulogic_vector(5 downto 0);
instr_15_0 : IN std_ulogic_vector(15 downto 0);
zero
: IN std_ulogic;
ALUopcode
: OUT std_ulogic_vector(2 downto 0);
RegDst, RegWrite, ALUSrcA, MemRead, MemWrite, MemtoReg, IorD, IRWrite : OUT
std_ulogic;
ALUSrcB, PCSource : OUT std_ulogic_vector(1 downto 0);
PC_en
: OUT std_ulogic
);
END control
52
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ENTITY tempreg IS
PORT (
clk
: IN STD_ULOGIC;
rst_n
: IN STD_ULOGIC;
reg_in
reg_out
END tempreg
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ENTITY pc IS
PORT (
clk
rst_n
pc_in
PC_en
pc_out
END pc;
:
:
:
:
:
IN
IN
IN
IN
OUT
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
STD_ULOGIC;
STD_ULOGIC_VECTOR(width-1 DOWNTO 0) );
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ENTITY instreg IS
PORT (
clk
: IN STD_ULOGIC;
rst_n
: IN STD_ULOGIC;
memdata
: IN STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
IRWrite
: IN STD_ULOGIC;
instr_31_26
instr_25_21
instr_20_16
instr_15_0
:
:
:
:
OUT
OUT
OUT
OUT
END instreg;
53
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
-- use package
USE work.procmem_definitions.ALL;
ENTITY regfile IS
PORT (clk,rst_n
wen
writeport
adrwport
adrport0
adrport1
readport0
readport1
);
END regfile;
:
:
:
:
:
:
:
:
IN
IN
IN
IN
IN
IN
OUT
OUT
std_ulogic;
std_ulogic;
-- write control
std_ulogic_vector(width-1 DOWNTO 0); -- register input
std_ulogic_vector(regfile_adrsize-1 DOWNTO 0);-- address write
std_ulogic_vector(regfile_adrsize-1 DOWNTO 0);-- address port 0
std_ulogic_vector(regfile_adrsize-1 DOWNTO 0);-- address port 1
std_ulogic_vector(width-1 DOWNTO 0); -- output port 0
std_ulogic_vector(width-1 DOWNTO 0)
-- output port 1
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ENTITY alu IS
PORT (
a, b
: IN
opcode : IN
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ENTITY data_fetch IS
PORT (
-- inputs
clk
: IN STD_ULOGIC;
rst_n
: IN STD_ULOGIC;
pc_in
: IN STD_ULOGIC_VECTOR(width-1 DOWNTO
alu_out
: IN STD_ULOGIC_VECTOR(width-1 DOWNTO
mem_data
: IN std_ulogic_vector(width-1 DOWNTO
-- control signals
PC_en
: IN STD_ULOGIC;
IorD
: IN STD_ULOGIC;
IRWrite
: IN STD_ULOGIC;
-- outputs
reg_memdata : OUT STD_ULOGIC_VECTOR(width-1 DOWNTO
instr_31_26 : OUT STD_ULOGIC_VECTOR(5 DOWNTO 0);
instr_25_21 : OUT STD_ULOGIC_VECTOR(4 DOWNTO 0);
instr_20_16 : OUT STD_ULOGIC_VECTOR(4 DOWNTO 0);
instr_15_0 : OUT STD_ULOGIC_VECTOR(15 DOWNTO 0);
mem_address : OUT std_ulogic_vector(width-1 DOWNTO
pc_out
: OUT std_ulogic_vector(width-1 DOWNTO
);
0);
0);
0);
0);
0);
0)
END data_fetch;
54
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ENTITY data_decode IS
PORT (
-- inputs
clk
: IN STD_ULOGIC;
rst_n
: IN STD_ULOGIC;
instr_25_21 : IN STD_ULOGIC_VECTOR(4 DOWNTO 0);
instr_20_16 : IN STD_ULOGIC_VECTOR(4 DOWNTO 0);
instr_15_0 : IN STD_ULOGIC_VECTOR(15 DOWNTO 0);
reg_memdata : IN STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
alu_out
: IN STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
-- control signals
RegDst
: IN STD_ULOGIC;
RegWrite
: IN STD_ULOGIC;
MemtoReg
: IN STD_ULOGIC;
-- outputs
reg_A
: OUT STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
reg_B
: OUT STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
instr_15_0_se : OUT STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
instr_15_0_se_sl : OUT STD_ULOGIC_VECTOR(width-1 DOWNTO 0)
);
END data_decode;
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ENTITY data_execution IS
PORT (instr_25_21 : IN
instr_20_16 : IN
instr_15_0 : IN
ALUSrcA
: IN
ALUSrcB
: IN
ALUopcode
: IN
reg_A, reg_B
pc_out
instr_15_0_se
instr_15_0_se_sl
downto
downto
downto
downto
0);
0);
0);
0);
jump_addr
: OUT std_ulogic_vector(width-1 downto 0);
alu_result : OUT std_ulogic_vector(width-1 downto 0);
zero
: OUT std_ulogic
);
END data_execution;
55
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ENTITY data_memwriteback IS
PORT (clk, rst_n : IN std_ulogic;
jump_addr
: IN std_ulogic_vector(width-1 downto 0);
alu_result : IN std_ulogic_vector(width-1 downto 0);
PCSource
: IN std_ulogic_vector(1 downto 0);
pc_in
alu_out
);
END data_memwriteback;
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ENTITY data IS
PORT (clk, rst_n : IN std_ulogic;
PC_en, IorD, MemtoReg, IRWrite, ALUSrcA, RegWrite, RegDst : IN std_ulogic;
PCSource, ALUSrcB : IN std_ulogic_vector(1 downto 0);
ALUopcode : IN std_ulogic_vector(2 downto 0);
mem_data : IN std_ulogic_vector(width-1 downto 0);
reg_B, mem_address : OUT std_ulogic_vector(width-1 downto 0);
instr_31_26 : OUT std_ulogic_vector(5 downto 0);
instr_15_0 : OUT std_ulogic_vector(15 downto 0);
zero : OUT std_ulogic
);
END data;
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
-- use altera_mf library for RAM block
LIBRARY altera_mf;
USE altera_mf.ALL;
-- use package
USE work.procmem_definitions.ALL;
ENTITY ram IS
GENERIC (adrwidth : positive := ram_adrwidth;
datwidth : positive := ram_datwidth;
ramfile : string
:= ramfile_std
-- initial RAM content
-- in IntelHEX Format
);
PORT (address : IN std_logic_vector(ram_adrwidth-1 DOWNTO 0);
data
: IN std_logic_vector(ram_datwidth-1 DOWNTO 0);
inclock : IN std_logic;
-- used to write data in RAM cells
wren_p : IN std_logic;
q
: OUT std_logic_vector(ram_datwidth-1 DOWNTO 0));
END ram;
56
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ENTITY memory IS
PORT (
clk
:
rst_n
:
MemRead
:
MemWrite
:
mem_address :
data_in
:
data_out
:
END memory;
IN
IN
IN
IN
IN
IN
OUT
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
STD_ULOGIC_VECTOR(width-1 DOWNTO 0) );
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ENTITY mips IS
PORT (clk, rst_n : IN std_ulogic;
mem_data
: IN std_ulogic_vector(width-1 downto 0);
reg_B, mem_address : OUT std_ulogic_vector(width-1 downto 0);
MemRead, MemWrite : OUT std_ulogic
);
END mips;
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ENTITY procmem IS
PORT (clk, rst_n : IN std_ulogic
);
END procmem;
57
58
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ARCHITECTURE behave OF ControlFSM IS
-------------------------------------------------------------------------------- Definition of the state names
TYPE state_type IS (InstDec, MemAddComp, MemAccL, MemReadCompl, MemAccS, Exec, RCompl, BranchCompl, JumpCompl, ErrState, InstFetch);
SIGNAL state, next_state : state_type;
BEGIN
-------------------------------------------------------------------------------- State process
state_reg : PROCESS(clk, rst_n)
BEGIN
IF rst_n = '0' THEN
state <= InstFetch;
ELSIF RISING_EDGE(clk) THEN
state <= next_state;
END IF;
END PROCESS;
-------------------------------------------------------------------------------- Logic Process
logic_process : PROCESS(state, instr_31_26)
-- RegDst RegWrite ALUSrcA MemRead MemWrite MemtoReg IorD IRWrite PCWrite PCWriteCond
10x1bit
-ALUOp
ALUSrcB
PCSource
3x2bit
VARIABLE control_signals : std_ulogic_vector(15 downto 0);
-- Defintion of Constants for the value of the Inst_Funct_Field
Constant LOADWORD : std_ulogic_vector(5 Downto 0) := "100011";
Constant STOREWORD : std_ulogic_vector(5 Downto 0) := "101011";
Constant RTYPE : std_ulogic_vector(5 Downto 0) := "000000";
Constant BEQ : std_ulogic_vector(5 Downto 0) := "000100";
Constant JMP : std_ulogic_vector(5 Downto 0) := "000010";
BEGIN
CASE state IS
-- Instruction Fetch
WHEN InstFetch =>
control_signals := "0001000110000100";
next_state <= InstDec;
-- Instruction Decode and Register Fetch
WHEN InstDec =>
control_signals := "0000000000001100";
IF instr_31_26 = LOADWORD OR instr_31_26 = STOREWORD THEN
next_state <= MemAddComp;
ELSIF instr_31_26 = RTYPE THEN
next_state <= Exec;
ELSIF instr_31_26 = BEQ
THEN
next_state <= BranchCompl;
ELSIF instr_31_26 = JMP THEN
next_state <= JumpCompl;
ELSE
next_state <= ErrState;
END IF;
-- Memory Address Computation
WHEN MemAddComp =>
control_signals := "0010000000001000";
if instr_31_26 = LOADWORD THEN
next_state <= MemAccL;
ELSIF instr_31_26 = STOREWORD THEN
next_state <= MemAccS;
ELSE
next_state <= ErrState;
END IF;
59
60
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ARCHITECTURE behave OF ALUControl IS
BEGIN
Alu_Control : PROCESS(instr_15_0, ALUOp)
CONSTANT
CONSTANT
CONSTANT
CONSTANT
CONSTANT
cADD
cSUB
cAND
cOR
cSLT
:
:
:
:
:
std_ulogic_vector(5
std_ulogic_vector(5
std_ulogic_vector(5
std_ulogic_vector(5
std_ulogic_vector(5
downto
downto
downto
downto
downto
0)
0)
0)
0)
0)
:=
:=
:=
:=
:=
"100000";
"100010";
"100100";
"100101";
"101010";
BEGIN
case ALUOp is
when "00" => ALUopcode <= "010";
-- add
when "01" => ALUopcode <= "110";
-- subtract
when "10" =>
-- operation depends on function field
case instr_15_0(5 downto 0) is
when cADD => ALUopcode <= "010";
-- add
when cSUB => ALUopcode <= "110";
-- subtract
when cAND => ALUopcode <= "000";
-- AND
when cOR => ALUopcode <= "001";
-- OR
when cSLT => ALUopcode <= "111";
-- slt
when others => ALUopcode <= "000";
end case;
when others => ALUopcode <= "000";
end case;
END PROCESS;
END behave;
61
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ARCHITECTURE behave OF control IS
COMPONENT ControlFSM
PORT (
clk, rst_n
: IN std_ulogic;
instr_31_26
: IN std_ulogic_vector(5 downto 0);
RegDst, RegWrite, ALUSrcA, MemRead, MemWrite, MemtoReg, IorD, IRWrite, PCWrite,
PCWriteCond : OUT std_ulogic;
ALUOp, ALUSrcB, PCSource
: OUT std_ulogic_vector(1 downto 0)
);
END COMPONENT;
COMPONENT ALUControl
PORT (
instr_15_0
: IN std_ulogic_vector(15 downto 0);
ALUOp
: IN std_ulogic_vector(1 downto 0);
ALUopcode
: OUT std_ulogic_vector(2 downto 0)
);
END COMPONENT;
SIGNAL ALUOp_intern : std_ulogic_vector(1 downto 0);
SIGNAL PCWrite_intern : std_ulogic;
SIGNAL PCWriteCond_intern : std_ulogic;
BEGIN
inst_ControlFSM : ControlFSM
PORT MAP (
clk
=> clk,
rst_n
=> rst_n,
instr_31_26
=> instr_31_26,
RegDst
=> RegDst,
RegWrite
=> RegWrite,
ALUSrcA
=> ALUSrcA,
MemRead
=> MemRead,
MemWrite
=> MemWrite,
MemtoReg
=> MemtoReg,
IorD
=> IorD,
IRWrite
=> IRWrite,
PCWrite
=> PCWrite_intern,
PCWriteCond
=> PCWriteCond_intern,
ALUOp
=> ALUOp_intern,
ALUSrcB
=> ALUSrcB,
PCSource
=> PCSource
);
inst_ALUControl : ALUControl
PORT MAP (
instr_15_0
=> instr_15_0,
ALUOp
=> ALUOp_intern,
ALUopcode
=> ALUopcode
);
PC_en <= PCWrite_intern OR (PCWriteCond_intern AND zero);
END behave;
62
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ARCHITECTURE behave OF tempreg IS
BEGIN
temp_reg: PROCESS(clk, rst_n)
BEGIN
IF rst_n = '0' THEN
reg_out <= (OTHERS => '0');
ELSIF RISING_EDGE(clk) THEN
-- write register input to output at rising edge
reg_out <= reg_in;
END IF;
END PROCESS;
END behave;
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ARCHITECTURE behave OF pc IS
BEGIN
proc_pc : PROCESS(clk, rst_n)
VARIABLE pc_temp : STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
BEGIN
IF rst_n = '0' THEN
pc_temp := (OTHERS => '0');
ELSIF RISING_EDGE(clk) THEN
IF PC_en = '1' THEN
pc_temp := pc_in;
END IF;
END IF;
pc_out <= pc_temp;
END PROCESS;
END behave;
63
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ARCHITECTURE behave OF instreg IS
BEGIN
proc_instreg : PROCESS(clk, rst_n)
BEGIN
IF rst_n = '0' THEN
instr_31_26 <= (OTHERS => '0');
instr_25_21 <= (OTHERS => '0');
instr_20_16 <= (OTHERS => '0');
instr_15_0 <= (OTHERS => '0');
ELSIF RISING_EDGE(clk) THEN
-- write the output of the memory into the instruction register
IF(IRWrite = '1') THEN
instr_31_26 <= memdata(31 DOWNTO 26);
instr_25_21 <= memdata(25 DOWNTO 21);
instr_20_16 <= memdata(20 DOWNTO 16);
instr_15_0 <= memdata(15 DOWNTO 0);
END IF;
END IF;
END PROCESS;
END behave;
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ARCHITECTURE behave OF regfile IS
SUBTYPE WordT IS std_ulogic_vector(width-1 DOWNTO 0); -- reg word TYPE
TYPE
StorageT IS ARRAY(0 TO regfile_depth-1) OF WordT;
-- reg array TYPE
SIGNAL registerfile : StorageT;
-- reg file contents
BEGIN
-- perform write operation
PROCESS(rst_n, clk)
BEGIN
IF rst_n = '0' THEN
FOR i IN 0 TO regfile_depth-1 LOOP
registerfile(i) <= (OTHERS => '0');
END LOOP;
ELSIF rising_edge(clk) THEN
IF wen = '1' THEN
registerfile(to_integer(unsigned(adrwport))) <= writeport;
END IF;
END IF;
END PROCESS;
-- perform reading ports
readport0 <= registerfile(to_integer(unsigned(adrport0)));
readport1 <= registerfile(to_integer(unsigned(adrport1)));
END behave;
64
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
ARCHITECTURE behave OF alu IS
BEGIN
PROCESS(a, b, opcode)
-- declaration
VARIABLE a_uns
VARIABLE b_uns
VARIABLE r_uns
VARIABLE z_uns
of variables
: UNSIGNED(width-1 DOWNTO 0);
: UNSIGNED(width-1 DOWNTO 0);
: UNSIGNED(width-1 DOWNTO 0);
: UNSIGNED(0 DOWNTO 0);
BEGIN
-- initialize values
a_uns := UNSIGNED(a);
b_uns := UNSIGNED(b);
r_uns := (OTHERS => '0');
z_uns(0) := '0';
-- select desired operation
CASE opcode IS
-- add
WHEN "010" =>
r_uns := a_uns + b_uns;
-- sub
WHEN "110" =>
r_uns := a_uns - b_uns;
-- and
WHEN "000" =>
r_uns := a_uns AND b_uns;
-- or
WHEN "001" =>
r_uns := a_uns OR b_uns;
-- slt
WHEN "111" =>
r_uns := a_uns - b_uns;
IF SIGNED(r_uns) < 0 THEN
r_uns := TO_UNSIGNED(1, r_uns'LENGTH);
ELSE
r_uns := (OTHERS => '0');
END IF;
-- others
WHEN OTHERS => r_uns := (OTHERS => 'X');
END CASE;
-- set zero bit if result equals zero
IF TO_INTEGER(r_uns) = 0 THEN
z_uns(0) := '1';
ELSE
z_uns(0) := '0';
END IF;
-- assign variables to output signals
result <= STD_ULOGIC_VECTOR(r_uns);
zero <= z_uns(0);
END PROCESS;
END behave;
65
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ARCHITECTURE behave OF data_fetch IS
COMPONENT instreg
PORT (
clk
:
rst_n
:
memdata
:
IRWrite
:
instr_31_26 :
instr_25_21 :
instr_20_16 :
instr_15_0 :
END COMPONENT;
IS
COMPONENT tempreg
PORT (
clk
:
rst_n
:
reg_in
:
reg_out
:
END COMPONENT;
IS
COMPONENT pc IS
PORT (
clk
rst_n
pc_in
PC_en
pc_out
END COMPONENT;
IN STD_ULOGIC;
IN STD_ULOGIC;
IN STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
IN STD_ULOGIC;
OUT STD_ULOGIC_VECTOR(5 DOWNTO 0);
OUT STD_ULOGIC_VECTOR(4 DOWNTO 0);
OUT STD_ULOGIC_VECTOR(4 DOWNTO 0);
OUT STD_ULOGIC_VECTOR(15 DOWNTO 0) );
:
:
:
:
:
IN STD_ULOGIC;
IN STD_ULOGIC;
IN STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
OUT STD_ULOGIC_VECTOR(width-1 DOWNTO 0) );
IN
IN
IN
IN
OUT
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
STD_ULOGIC;
STD_ULOGIC_VECTOR(width-1 DOWNTO 0) );
tempreg
clk,
rst_n,
mem_data,
reg_memdata );
-- multiplexer
addr_mux : PROCESS(IorD, pc_out_intern, alu_out)
VARIABLE mem_address_temp : STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
BEGIN
IF IorD = '0' THEN
mem_address_temp := pc_out_intern;
ELSIF IorD = '1' THEN
mem_address_temp := alu_out;
ELSE
66
67
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ARCHITECTURE behave OF data_decode IS
COMPONENT regfile
PORT (clk,rst_n
wen
writeport
adrwport
adrport0
adrport1
readport0
readport1
);
END COMPONENT;
IS
: IN
: IN
: IN
: IN
: IN
: IN
: OUT
: OUT
COMPONENT tempreg
PORT (
clk
:
rst_n
:
reg_in
:
reg_out
:
END COMPONENT;
IS
std_ulogic;
std_ulogic;
-- write control
std_ulogic_vector(width-1 DOWNTO 0); -- register input
std_ulogic_vector(regfile_adrsize-1 DOWNTO 0);-- address write
std_ulogic_vector(regfile_adrsize-1 DOWNTO 0);-- address port 0
std_ulogic_vector(regfile_adrsize-1 DOWNTO 0);-- address port 1
std_ulogic_vector(width-1 DOWNTO 0); -- output port 0
std_ulogic_vector(width-1 DOWNTO 0)
-- output port 1
IN STD_ULOGIC;
IN STD_ULOGIC;
IN STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
OUT STD_ULOGIC_VECTOR(width-1 DOWNTO 0) );
-- internal signals
SIGNAL write_reg
SIGNAL write_data
SIGNAL data_1
SIGNAL data_2
:
:
:
:
BEGIN
A : tempreg
PORT MAP (
clk
=>
rst_n
=>
reg_in =>
reg_out =>
clk,
rst_n,
data_1,
reg_A );
B : tempreg
PORT MAP (
clk
=>
rst_n
=>
reg_in =>
reg_out =>
clk,
rst_n,
data_2,
reg_B );
inst_regfile :
PORT MAP (
clk
rst_n
wen
writeport
adrwport
adrport0
adrport1
readport0
readport1
regfile
=>
=>
=>
=>
=>
=>
=>
=>
=>
clk,
rst_n,
RegWrite,
write_data,
write_reg,
instr_25_21,
instr_20_16,
data_1,
data_2 );
68
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ARCHITECTURE behave OF data_execution IS
COMPONENT alu
PORT (
a, b
: IN
opcode : IN
result : OUT
zero
: OUT
);
END COMPONENT;
SIGNAL mux_A_out
SIGNAL mux_B_out
BEGIN
alu_inst: alu
PORT MAP (
a
b
opcode
result
zero
);
=>
=>
=>
=>
=>
mux_A_out,
mux_B_out,
ALUopcode,
alu_result,
zero
--
69
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ARCHITECTURE behave OF data_memwriteback IS
COMPONENT tempreg
PORT (
clk
:
rst_n
:
reg_in
:
reg_out
:
);
END COMPONENT;
IN STD_ULOGIC;
IN STD_ULOGIC;
IN STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
OUT STD_ULOGIC_VECTOR(width-1 DOWNTO 0)
=>
=>
=>
=>
clk,
rst_n,
alu_result,
alu_out_internal
70
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ARCHITECTURE behave OF data IS
COMPONENT data_fetch
PORT (
clk
: IN
rst_n
: IN
pc_in
: IN
alu_out
: IN
mem_data
: IN
PC_en
: IN
IorD
: IN
IRWrite
: IN
reg_memdata : OUT
instr_31_26 : OUT
instr_25_21 : OUT
instr_20_16 : OUT
instr_15_0 : OUT
mem_address : OUT
pc_out
: OUT
END COMPONENT;
COMPONENT data_decode
PORT (
clk
:
rst_n
:
instr_25_21
:
instr_20_16
:
instr_15_0
:
reg_memdata
:
alu_out
:
RegDst
:
RegWrite
:
MemtoReg
:
reg_A
:
reg_B
:
instr_15_0_se
:
instr_15_0_se_sl :
END COMPONENT;
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC_VECTOR(width-1 DOWNTO
STD_ULOGIC_VECTOR(width-1 DOWNTO
std_ulogic_vector(width-1 DOWNTO
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC_VECTOR(width-1 DOWNTO
STD_ULOGIC_VECTOR(5 DOWNTO 0);
STD_ULOGIC_VECTOR(4 DOWNTO 0);
STD_ULOGIC_VECTOR(4 DOWNTO 0);
STD_ULOGIC_VECTOR(15 DOWNTO 0);
std_ulogic_vector(width-1 DOWNTO
std_ulogic_vector(width-1 DOWNTO
IN
IN
IN
IN
IN
IN
IN
IN
IN
IN
OUT
OUT
OUT
OUT
COMPONENT data_execution
PORT (
instr_25_21
: IN
instr_20_16
: IN
instr_15_0
: IN
ALUSrcA
: IN
ALUSrcB
: IN
ALUopcode
: IN
reg_A, reg_B
: IN
pc_out
: IN
instr_15_0_se
: IN
instr_15_0_se_sl : IN
jump_addr
: OUT
alu_result
: OUT
zero
: OUT
END COMPONENT;
0);
0);
0));
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC_VECTOR(4 DOWNTO 0);
STD_ULOGIC_VECTOR(4 DOWNTO 0);
STD_ULOGIC_VECTOR(15 DOWNTO 0);
STD_ULOGIC_VECTOR(width-1 DOWNTO
STD_ULOGIC_VECTOR(width-1 DOWNTO
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC_VECTOR(width-1 DOWNTO
STD_ULOGIC_VECTOR(width-1 DOWNTO
STD_ULOGIC_VECTOR(width-1 DOWNTO
STD_ULOGIC_VECTOR(width-1 DOWNTO
COMPONENT data_memwriteback
PORT (
clk, rst_n : IN std_ulogic;
jump_addr : IN std_ulogic_vector(width-1 downto
alu_result : IN std_ulogic_vector(width-1 downto
PCSource
: IN std_ulogic_vector(1 downto 0);
pc_in
: OUT std_ulogic_vector(width-1 downto
alu_out
: OUT std_ulogic_vector(width-1 downto
END COMPONENT;
SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
0);
0);
0);
0);
0);
0);
0);
0);
0));
0);
0);
0);
0);
0);
0);
0);
0);
0);
0));
71
SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
BEGIN
inst_data_fetch: data_fetch
PORT MAP (
clk
=> clk,
rst_n
=> rst_n,
pc_in
=> pc_in_intern,
alu_out
=> alu_out_intern,
mem_data
=> mem_data,
PC_en
=> PC_en,
IorD
=> IorD,
IRWrite
=> IRWrite,
reg_memdata => reg_memdata_intern,
instr_31_26 => instr_31_26,
instr_25_21 => instr_25_21_intern,
instr_20_16 => instr_20_16_intern,
instr_15_0 => instr_15_0_intern,
mem_address => mem_address,
pc_out
=> pc_out_intern);
inst_data_decode : data_decode
PORT MAP (
clk
=> clk,
rst_n
=> rst_n,
instr_25_21
=> instr_25_21_intern,
instr_20_16
=> instr_20_16_intern,
instr_15_0
=> instr_15_0_intern,
reg_memdata
=> reg_memdata_intern,
alu_out
=> alu_out_intern,
RegDst
=> RegDst,
RegWrite
=> RegWrite,
MemtoReg
=> MemtoReg,
reg_A
=> reg_A_intern,
reg_B
=> reg_B_intern,
instr_15_0_se
=> instr_15_0_se_intern,
instr_15_0_se_sl => instr_15_0_se_sl_intern
);
inst_data_execution:
PORT MAP (
instr_25_21
instr_20_16
instr_15_0
ALUSrcA
ALUSrcB
ALUopcode
reg_A
reg_B
pc_out
instr_15_0_se
instr_15_0_se_sl
jump_addr
alu_result
zero
);
data_execution
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
instr_25_21_intern,
instr_20_16_intern,
instr_15_0_intern,
ALUSrcA,
ALUSrcB,
ALUopcode,
reg_A_intern,
reg_B_intern,
pc_out_intern,
instr_15_0_se_intern,
instr_15_0_se_sl_intern,
jump_addr_intern,
alu_result_intern,
zero
inst_data_memwriteback : data_memwriteback
PORT MAP (
clk
=> clk,
rst_n
=> rst_n,
jump_addr => jump_addr_intern,
alu_result => alu_result_intern,
PCSource
=> PCSource,
pc_in
=> pc_in_intern,
alu_out
=> alu_out_intern
);
reg_B <= reg_B_intern;
72
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ARCHITECTURE rtl OF ram IS
TYPE
MEM IS ARRAY(0 TO (2**ram_adrwidth)-1) OF std_logic_vector(ram_datwidth-1 DOWNTO 0);
SIGNAL ram_block
: MEM;
SIGNAL read_address_reg : std_logic_vector(ram_adrwidth-1 DOWNTO 0);
BEGIN
PROCESS (inclock)
BEGIN
IF rising_edge(inclock) THEN
IF (wren_p = '1') THEN
ram_block(to_integer(unsigned(address))) <= data;
END IF;
-- address is registered at rising edge
-- not used, because asynchronous data output is needed for MIPS design
--read_address_reg <= address;
END IF;
END PROCESS;
-- registered address is used for synchronous data output
--q <= ram_block(to_integer(unsigned(read_address_reg)));
-- asynchronous memory output (needed for MIPS design according to [PaHe98])
-- address is unregistered
q <= ram_block(to_integer(unsigned(address)));
END rtl;
73
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ARCHITECTURE behave OF memory IS
COMPONENT ram IS
GENERIC (adrwidth :
datwidth :
-- initial
ramfile :
);
PORT (address : IN
data
: IN
inclock : IN
wren_p : IN
q
: OUT
END COMPONENT;
-- internal signals
SIGNAL wren_p
SIGNAL data_in_0
SIGNAL data_in_1
SIGNAL data_in_2
SIGNAL data_in_3
SIGNAL data_out_0
SIGNAL data_out_1
SIGNAL data_out_2
SIGNAL data_out_3
SIGNAL address_0
SIGNAL address_1
SIGNAL address_2
SIGNAL address_3
:
:
:
:
:
:
:
:
:
:
:
:
:
positive :=
positive :=
RAM content
string
:=
8;
8;
in IntelHEX Format
"../simulation/ram256x8.hex"
std_logic_vector(adrwidth-1 DOWNTO
std_logic_vector(datwidth-1 DOWNTO
std_logic;
-- used to write
std_logic;
std_logic_vector(datwidth-1 DOWNTO
STD_LOGIC;
STD_LOGIC_VECTOR(ram_datwidth-1
STD_LOGIC_VECTOR(ram_datwidth-1
STD_LOGIC_VECTOR(ram_datwidth-1
STD_LOGIC_VECTOR(ram_datwidth-1
STD_LOGIC_VECTOR(ram_datwidth-1
STD_LOGIC_VECTOR(ram_datwidth-1
STD_LOGIC_VECTOR(ram_datwidth-1
STD_LOGIC_VECTOR(ram_datwidth-1
STD_LOGIC_VECTOR(ram_adrwidth-1
STD_LOGIC_VECTOR(ram_adrwidth-1
STD_LOGIC_VECTOR(ram_adrwidth-1
STD_LOGIC_VECTOR(ram_adrwidth-1
0);
0);
data in RAM cells
0));
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
DOWNTO
0);
0);
0);
0);
0);
0);
0);
0);
0);
0);
0);
0);
BEGIN
-- instances of 4 ram blocks
mem_block0 : ram
-- generic map used for definition of different ramfiles
GENERIC MAP (
adrwidth => ram_adrwidth,
datwidth => ram_datwidth,
ramfile
=> ramfile_block0)
PORT MAP (
address
=> address_0,
data
=> data_in_0,
inclock
=> clk,
wren_p
=> wren_p,
q
=> data_out_0 );
mem_block1 : ram
-- generic map used for definition of different ramfiles
GENERIC MAP (
adrwidth => ram_adrwidth,
datwidth => ram_datwidth,
ramfile
=> ramfile_block1)
PORT MAP (
address
=> address_1,
data
=> data_in_1,
inclock
=> clk,
wren_p
=> wren_p,
q
=> data_out_1 );
mem_block2 : ram
-- generic map used for definition of different ramfiles
GENERIC MAP (
adrwidth => ram_adrwidth,
datwidth => ram_datwidth,
ramfile
=> ramfile_block2)
PORT MAP (
address
=> address_2,
data
=> data_in_2,
inclock
=> clk,
wren_p
=> wren_p,
q
=> data_out_2 );
74
mem_block3 : ram
-- generic map used for definition of different ramfiles
GENERIC MAP (
adrwidth => ram_adrwidth,
datwidth => ram_datwidth,
ramfile
=> ramfile_block3)
PORT MAP (
address
=> address_3,
data
=> data_in_3,
inclock
=> clk,
wren_p
=> wren_p,
q
=> data_out_3 );
-- create a write_enable for instances
wren_p <= '1' WHEN MemWrite = '1' AND MemRead = '0' ELSE
'0' WHEN MemWrite = '0' AND MemRead = '1' ELSE
'0' WHEN MemWrite = '0' AND MemRead = '0' ELSE
'X';
-- assert address to ram blocks (pure logic)
addr_assert: PROCESS(mem_address)
VARIABLE temp_ram_address : STD_ULOGIC_VECTOR(ram_adrwidth-1 DOWNTO 0);
BEGIN
-- read/write only words: A1 A0 --> not used for address
-- note: ram blocks can be addressed with mulitple addresses
temp_ram_address := mem_address(ram_adrwidth-1+2 DOWNTO 2);
address_0
address_1
address_2
address_3
END PROCESS;
<=
<=
<=
<=
TO_STDLOGICVECTOR(temp_ram_address);
TO_STDLOGICVECTOR(temp_ram_address);
TO_STDLOGICVECTOR(temp_ram_address);
TO_STDLOGICVECTOR(temp_ram_address);
75
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ARCHITECTURE behave OF mips IS
COMPONENT control
PORT (
clk, rst_n
: IN
std_ulogic;
instr_31_26
: IN
std_ulogic_vector(5 downto 0);
instr_15_0
: IN
std_ulogic_vector(15 downto 0);
zero
: IN
std_ulogic;
ALUopcode
: OUT
std_ulogic_vector(2 downto 0);
RegDst, RegWrite, ALUSrcA, MemRead, MemWrite, MemtoReg, IorD, IRWrite : OUT
std_ulogic;
ALUSrcB, PCSource
: OUT
std_ulogic_vector(1 downto 0);
PC_en
: OUT
std_ulogic);
END COMPONENT;
COMPONENT data
PORT (
clk, rst_n
: IN std_ulogic;
PC_en, IorD, MemtoReg, IRWrite, ALUSrcA, RegWrite, RegDst : IN std_ulogic;
PCSource, ALUSrcB
: IN
std_ulogic_vector(1 downto 0);
ALUopcode
: IN
std_ulogic_vector(2 downto 0);
mem_data
: IN
std_ulogic_vector(width-1 downto 0);
reg_B, mem_address
: OUT
std_ulogic_vector(width-1 downto 0);
instr_31_26
: OUT
std_ulogic_vector(5 downto 0);
instr_15_0
: OUT
std_ulogic_vector(15 downto 0);
zero
: OUT std_ulogic);
END COMPONENT;
-- internal signals for connection of components
SIGNAL instr_31_26_intern : std_ulogic_vector(5 downto 0);
SIGNAL instr_15_0_intern : std_ulogic_vector(15 downto 0);
SIGNAL zero_intern : std_ulogic;
SIGNAL ALUopcode_intern : std_ulogic_vector(2 downto 0);
SIGNAL RegDst_intern : std_ulogic;
SIGNAL RegWrite_intern : std_ulogic;
SIGNAL ALUSrcA_intern : std_ulogic;
SIGNAL MemtoReg_intern : std_ulogic;
SIGNAL IorD_intern : std_ulogic;
SIGNAL IRWrite_intern : std_ulogic;
SIGNAL ALUSrcB_intern : std_ulogic_vector(1 downto 0);
SIGNAL PCSource_intern : std_ulogic_vector(1 downto 0);
SIGNAL PC_en_intern : std_ulogic;
BEGIN
inst_control : control
PORT MAP (
clk
=> clk,
rst_n
=> rst_n,
instr_31_26 => instr_31_26_intern,
instr_15_0 => instr_15_0_intern,
zero
=> zero_intern,
ALUopcode
=> ALUopcode_intern,
RegDst
=> RegDst_intern,
RegWrite
=> RegWrite_intern,
ALUSrcA
=> ALUSrcA_intern,
MemRead
=> MemRead,
MemWrite
=> MemWrite,
MemtoReg
=> MemtoReg_intern,
76
IorD
IRWrite
ALUSrcB
PCSource
PC_en
);
inst_data: data
PORT MAP (
clk
rst_n
PC_en
IorD
MemtoReg
IRWrite
ALUSrcA
RegWrite
RegDst
PCSource
ALUSrcB
ALUopcode
mem_data
reg_B
mem_address
instr_31_26
instr_15_0
zero
);
=>
=>
=>
=>
=>
IorD_intern,
IRWrite_intern,
ALUSrcB_intern,
PCSource_intern,
PC_en_intern
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
clk,
rst_n,
PC_en_intern,
IorD_intern,
MemtoReg_intern,
IRWrite_intern,
ALUSrcA_intern,
RegWrite_intern,
RegDst_intern,
PCSource_intern,
ALUSrcB_intern,
ALUopcode_intern,
mem_data,
reg_B,
mem_address,
instr_31_26_intern,
instr_15_0_intern,
zero_intern
END behave;
77
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
ARCHITECTURE behave OF procmem IS
COMPONENT mips
PORT (
clk, rst_n
mem_data
reg_B, mem_address
MemRead, MemWrite
END COMPONENT;
COMPONENT memory
PORT (
clk
:
rst_n
:
MemRead
:
MemWrite
:
mem_address :
data_in
:
data_out
:
END COMPONENT;
SIGNAL
signal
signal
signal
signal
IN
IN
IN
IN
IN
IN
OUT
:
:
:
:
IN
IN
OUT
OUT
std_ulogic;
std_ulogic_vector(width-1 downto 0);
std_ulogic_vector(width-1 downto 0);
std_ulogic);
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
STD_ULOGIC_VECTOR(width-1 DOWNTO 0));
BEGIN
inst_mips : mips
PORT MAP (
clk
=>
rst_n
=>
mem_data
=>
reg_B
=>
mem_address =>
MemRead
=>
MemWrite
=>
);
clk,
rst_n,
mem_data,
reg_B,
mem_address,
MemRead,
MemWrite
inst_memory : memory
PORT MAP (
clk
=> clk,
rst_n
=> rst_n,
MemRead
=> MemRead,
MemWrite
=> MemWrite,
mem_address => mem_address,
data_in
=> reg_B,
data_out
=> mem_data
);
END behave;
78
8.1 Package
Department of Electrical Engineering
8.1.3 Package
PACKAGE ProcMem_definitions IS
-- globals
CONSTANT width
: NATURAL := 32;
-- definitions for regfile
CONSTANT regfile_depth
: positive := 32; -- register file depth = 2**adrsize
CONSTANT regfile_adrsize : positive := 5;
-- address vector size = log2(depth)
-- definitions for memory
CONSTANT ram_adrwidth
: positive := 8;
-- m x n - RAM Block
CONSTANT ram_datwidth
: positive := 8;
-- initial RAM content in IntelHEX Format
CONSTANT ramfile_std
: string
:= "./simulation/ram_256x8.hex";
CONSTANT ramfile_block0 : string
:= "./simulation/ram0_256x8.hex";
CONSTANT ramfile_block1 : string
:= "./simulation/ram1_256x8.hex";
CONSTANT ramfile_block2 : string
:= "./simulation/ram2_256x8.hex";
CONSTANT ramfile_block3 : string
:= "./simulation/ram3_256x8.hex";
END ProcMem_definitions;
79
8.1 Testbenches
Department of Electrical Engineering
8.1.4 Testbenches
80
8.1 Testbenches
Department of Electrical Engineering
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
USE std.textio.ALL;
USE ieee.std_logic_textio.ALL;
-- use package
USE work.procmem_definitions.ALL;
------------------------------------------------------------------------------ENTITY t_alu IS
END t_alu;
------------------------------------------------------------------------------ARCHITECTURE tbenchfileio OF t_alu IS
-- component generics
CONSTANT width : NATURAL := 32;
COMPONENT alu
PORT (
a, b
: IN
opcode : IN
result : OUT
zero
: OUT
END COMPONENT;
-- component ports
SIGNAL a, b
: STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
SIGNAL opcode : STD_ULOGIC_VECTOR(2 DOWNTO 0);
SIGNAL result : STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
SIGNAL zero
: STD_ULOGIC;
-- definition of a clock period
CONSTANT period : time
:= 10 ns;
FUNCTION TO_string(arg : std_ulogic) RETURN string IS
VARIABLE result_string : string(1 DOWNTO 1);
BEGIN
CASE arg IS
WHEN 'U' => result_string(1) := 'U';
WHEN 'X' => result_string(1) := 'X';
WHEN '0' => result_string(1) := '0';
WHEN '1' => result_string(1) := '1';
WHEN 'Z' => result_string(1) := 'Z';
WHEN 'W' => result_string(1) := 'W';
WHEN 'L' => result_string(1) := 'L';
WHEN 'H' => result_string(1) := 'H';
WHEN '-' => result_string(1) := '-';
END CASE;
RETURN result_string;
END TO_string;
FUNCTION TO_string(arg : unsigned) RETURN string IS
ALIAS u
: unsigned(arg'length DOWNTO 1) IS arg;
VARIABLE result_string : string(arg'length DOWNTO 1);
BEGIN
FOR i IN u'range LOOP
CASE u(i) IS
WHEN 'U' => result_string(i) := 'U';
WHEN 'X' => result_string(i) := 'X';
WHEN '0' => result_string(i) := '0';
WHEN '1' => result_string(i) := '1';
WHEN 'Z' => result_string(i) := 'Z';
WHEN 'W' => result_string(i) := 'W';
WHEN 'L' => result_string(i) := 'L';
WHEN 'H' => result_string(i) := 'H';
WHEN '-' => result_string(i) := '-';
END CASE;
END LOOP;
RETURN result_string;
END TO_string;
BEGIN
-- tbenchfileio
81
8.1 Testbenches
Department of Electrical Engineering
-- component instantiation
DUT: alu
PORT MAP (
a
=> a,
b
=> b,
opcode => opcode,
result => result,
zero
=> zero);
stimuli_observer : PROCESS
VARIABLE errflag
VARIABLE Li
VARIABLE Lo
FILE vectorfile
:
:
:
:
boolean
:= false;
line;
-- pointer to file input buffer
line;
-- pointer to file output buffer
text OPEN read_mode IS "./stimuli/testpattern-ALU.in";
82
8.1 Testbenches
Department of Electrical Engineering
83
8.1 Testbenches
Department of Electrical Engineering
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
------------------------------------------------------------------------------ENTITY t_memory IS
END t_memory;
------------------------------------------------------------------------------ARCHITECTURE tbench OF t_memory IS
COMPONENT memory IS
PORT (
clk
: IN
rst_n
: IN
MemRead
: IN
MemWrite
: IN
mem_address : IN
data_in
: IN
data_out
: OUT
END COMPONENT;
-- component ports
SIGNAL clk
SIGNAL rst_n
SIGNAL MemRead
SIGNAL MemWrite
SIGNAL mem_address
SIGNAL data_in
SIGNAL data_out
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
STD_ULOGIC_VECTOR(width-1 DOWNTO 0) );
:
:
:
:
:
:
:
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
84
8.1 Testbenches
Department of Electrical Engineering
END CASE;
END LOOP;
RETURN result;
END TO_string;
BEGIN
-- tbench
-- component instantiation
DUT: memory
PORT MAP (
clk
=> clk,
rst_n
=> rst_n,
MemRead
=> MemRead,
MemWrite
=> MemWrite,
mem_address => mem_address,
data_in
=> data_in,
data_out
=> data_out );
-- clock generation
clock_proc : PROCESS
BEGIN
WHILE clken_p LOOP
clk <= '0'; WAIT FOR period/2;
clk <= '1'; WAIT FOR period/2;
END LOOP;
WAIT;
END PROCESS;
-- reset generation
reset : rst_n <= '0', '1' AFTER period;
-- waveform generation
WaveGen_Proc : PROCESS
VARIABLE mem_temp : STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
TYPE array_vector IS ARRAY (0 TO 5) OF
STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
VARIABLE addr_pattern : array_vector;
VARIABLE data_pattern : array_vector;
BEGIN
-- initialization
MemRead <= '1';
MemWrite <= '0';
mem_address <= (OTHERS => '0');
-- addr_pattern
addr_pattern := (
x"00000000",
x"00000004",
x"00000008",
x"0000000C",
x"00000010",
x"00000014");
data_pattern := (
x"01020304",
x"05060708",
x"090A0B0C",
x"0D0E0F10",
x"11121314",
x"15161718");
-- block: 3, 2, 1, 0
-- use correct word address
-- reset
WAIT FOR period;
-- write pattern to mem
MemRead <= '0';
MemWrite <= '1';
FOR i in data_pattern'RANGE LOOP
data_in <= data_pattern(i);
mem_address <= addr_pattern(i);
WAIT FOR period;
END LOOP;
-- read memory and compare with pattern
85
8.1 Testbenches
Department of Electrical Engineering
86
8.1 Testbenches
Department of Electrical Engineering
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE work.procmem_definitions.ALL;
------------------------------------------------------------------------------ENTITY t_procmem IS
END t_procmem;
------------------------------------------------------------------------------ARCHITECTURE tbench OF t_procmem IS
COMPONENT procmem IS
PORT (
-- tbench
-- component instantiation
DUT: procmem
PORT MAP (
clk
=> clk,
rst_n
=> rst_n
);
-- clock generation
clock_proc : PROCESS
BEGIN
WHILE clken_p LOOP
clk <= '0'; WAIT FOR period/2;
clk <= '1'; WAIT FOR period/2;
END LOOP;
WAIT;
END PROCESS;
-- reset generation
reset : rst_n <= '0', '1' AFTER period;
-- waveform generation
WaveGen_Proc : PROCESS
BEGIN
-- reset
WAIT FOR period;
-- wait for results
WAIT FOR 25*period;
clken_p <= false;
WAIT;
END PROCESS WaveGen_Proc;
END tbench;
87
8.1 Testbenches
Department of Electrical Engineering
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- use package
USE work.procmem_definitions.ALL;
------------------------------------------------------------------------------ENTITY t_procmem_init IS
END t_procmem_init;
------------------------------------------------------------------------------ARCHITECTURE tbench OF t_procmem_init IS
COMPONENT mips
PORT (
clk, rst_n
mem_data
reg_B, mem_address
MemRead, MemWrite
END COMPONENT;
COMPONENT memory
PORT (
clk
:
rst_n
:
MemRead
:
MemWrite
:
mem_address :
data_in
:
data_out
:
END COMPONENT;
IN
IN
IN
IN
IN
IN
OUT
:
:
:
:
IN
IN
OUT
OUT
std_ulogic;
std_ulogic_vector(width-1 downto 0);
std_ulogic_vector(width-1 downto 0);
std_ulogic);
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC;
STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
STD_ULOGIC_VECTOR(width-1 DOWNTO 0));
-- component ports
SIGNAL clk
: STD_ULOGIC;
SIGNAL rst_n
: STD_ULOGIC;
SIGNAL
signal
signal
signal
signal
SIGNAL
signal
signal
signal
signal
SIGNAL
signal
signal
signal
signal
-- tbench
inst_mips : mips
PORT MAP (
clk
=>
rst_n
=>
mem_data
=>
reg_B
=>
mem_address =>
MemRead
=>
MemWrite
=>
);
clk,
rst_n,
mem_data_mux,
reg_B,
mem_address,
MemRead,
MemWrite
inst_memory : memory
88
8.1 Testbenches
Department of Electrical Engineering
PORT MAP (
clk
rst_n
MemRead
MemWrite
mem_address
data_in
data_out
);
=>
=>
=>
=>
=>
=>
=>
clk,
rst_n,
MemRead_mux,
MemWrite_mux,
mem_address_mux,
reg_B_mux,
mem_data
-- clock generation
clock_proc : PROCESS
BEGIN
WHILE clken_p LOOP
clk <= '0'; WAIT FOR period/2;
clk <= '1'; WAIT FOR period/2;
END LOOP;
WAIT;
END PROCESS;
-- reset generation
-- not used because of initialisation during explicit reset
--reset : rst_n <= '0', '1' AFTER period;
-- multiplexer for memory initialization signals,
-- because there is only one driver allowed at each signal
mux
:
PROCESS(rst_n,
MemWrite_ini,
MemRead_ini,
mem_address_ini,
MemWrite, MemRead, mem_data, reg_B, mem_address)
BEGIN
IF rst_n = '0' THEN
MemWrite_mux <= MemWrite_ini;
MemRead_mux <= MemRead_ini;
mem_data_mux <= mem_data_ini;
reg_B_mux <= reg_B_ini;
mem_address_mux <= mem_address_ini;
ELSE
MemWrite_mux <= MemWrite;
MemRead_mux <= MemRead;
mem_data_mux <= mem_data;
reg_B_mux <= reg_B;
mem_address_mux <= mem_address;
END IF;
END PROCESS;
mem_data_ini,
reg_B_ini,
-- waveform generation
WaveGen_Proc : PROCESS
VARIABLE mem_temp : STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
TYPE array_vector IS ARRAY (0 TO 15) OF
STD_ULOGIC_VECTOR(width-1 DOWNTO 0);
VARIABLE addr_pattern : array_vector;
VARIABLE data_pattern : array_vector;
BEGIN
-- pattern needed for memory initialisation at the beginning
addr_pattern := (
x"00000000",
x"00000004",
x"00000008",
x"0000000C",
x"00000010",
x"00000014",
x"00000018",
x"0000001C",
x"00000020",
x"00000024",
x"00000028",
x"0000002C",
x"00000030",
x"00000038",
x"00000080",
x"00000084"
);
data_pattern := (
89
8.1 Testbenches
Department of Electrical Engineering
"10001100000100000000000010000000",
"10001100000100010000000010000100",
"00000010000100011001000000100000",
"10101100000100100000000010001000",
"00000010001100001001100000100010",
"10101100000100110000000010001100",
"00000010001100001010000000100100",
"10101100000101000000000010010000",
"00000010001100001010100000100101",
"10101100000101010000000010010100",
"00000010000100011011000000101010",
"10101100000101100000000010011000",
"00010010000101000000000000000001",
"00001000000000000000000000000010",
"00000000000000000000000101111011",
"00000000000000000000000101111111");
-- explicit reset
rst_n <= '0';
-- initialize memory output
mem_data_ini <= (OTHERS => '0');
-- write pattern to mem
MemWrite_ini <= '1';
MemRead_ini <= '0';
FOR i in data_pattern'RANGE LOOP
reg_B_ini <= data_pattern(i);
mem_address_ini <= addr_pattern(i);
WAIT FOR period;
END LOOP;
-- set signals to zero before quitting initialisation
WAIT FOR period;
MemWrite_ini <= '0';
MemRead_ini <= '0';
reg_B_ini <= (OTHERS => '0');
mem_address_ini <= (OTHERS => '0');
mem_data_ini <= (OTHERS => '0');
WAIT FOR 2*period;
-- start
rst_n <= '1';
-- wait for results
WAIT FOR 100*period;
clken_p <= false;
WAIT;
END PROCESS WaveGen_Proc;
END tbench;
90
8.2 References
Department of Electrical Engineering
8.2 References
[PaHe98]:
es_cycii.pdf
Altera Corporation
Cyclone II FPGA Family Erata Sheet ES-030405-1.3
www.altera.com
91