RISC-X System
RISC-X System
To design the datapath and control unit for the RISC-X system, we need to follow these steps:
3. Define the control signals that are required for the correct operation of the system.
4. Design the control unit that generates the control signals based on the instruction opcode
and funct1 field.
Here is the datapath and control unit for the RISC-X system:
┌─────────┐
│ │
│ ROM │
│ │
└───┬─────┘
│ Output1 (16-bit instruction)
│
▼
+--------------+
| Control Unit |
+--------------+
│ Opcode and funct1
│
▼
+-------+
| |
+------+ ALU +------+
| | | |
| +-------+ |
| |
▼ ▼
+---------------+ +---------------+
| | | |
| Register | | Data Memory |
| File | | |
| | | |
+---------------+ +---------------+
│ Read1, Read2 │ ReadE, WriteE
│ Data1, Data2 │ Input1, Input2
│ Writereg │ Output1
│ Writedata │
│ Regwrite │
▼ ▼
+------+ +------+
| | | |
| X0 | | RAM |
| | | |
+------+ +------+
RISC-X system 1
The control unit generates the following control signals:
1. ALUOp: 4-bit signal that selects the operation to be performed by the ALU based on the
opcode and funct1 field of the instruction.
2. RegDst: 1-bit signal that selects the destination register for the result of the ALU
operation.
3. MemtoReg: 1-bit signal that selects the source of the data to be written to the destination
register.
4. MemRead: 1-bit signal that enables reading from the data memory.
6. Branch: 1-bit signal that indicates whether a branch should be taken based on the result
of the ALU operation.
7. ALUSrc: 1-bit signal that selects the second operand for the ALU operation.
Now, let's test the functionality of the design with the provided code:
1. Instruction fetch: The instruction "addi x7, x0, 3" is fetched from the ROM.
3. The control unit generates control signals based on the opcode of the instruction and the
state of the datapath. These control signals are used to enable or disable specific
components of the datapath.
4. The datapath reads the instruction from the instruction memory using the program
counter (PC) as the address, and then increments the PC to point to the next instruction.
The instruction is then decoded, and the appropriate registers and/or memory locations
are read or written based on the instruction operands.
5. If the instruction is a branch instruction, the control unit checks whether the branch
condition is met, and if so, sets the program counter to the target address specified by the
instruction.
6. The ALU performs the arithmetic or logic operation specified by the instruction, and the
result is written back to a register or memory location as specified by the instruction.
RISC-X system 2
7. The code can be translated into machine code as follows:
+-----------+ +-----------+
| | | |
+----------> Instruction Memory <----------+
| | | | |
| +-----------+ +-----------+
| | Clock |
| | |
| | |
| | |
| | |
| | |
| v |
| +------------+ |
| | | |
| | Control | |
| | Unit | |
| | | |
| +------------+ |
| | Clock |
| | |
| | |
| | |
| | |
| | |
| v |
| +------------+ |
| | | |
+----------> ALU <-----------+
| |
+------------+
|
| ALU Control
|
|
|
|
v
+------------+
| |
| Data Memory|
| |
+------------+
RISC-X system 3
The control unit generates control signals that drive the datapath. The instruction memory
and data memory are implemented as separate components, each with its own interface.
9. The functionality of the design can be tested using the provided code as follows:
10. Set the initial values of all registers to zero, except for X0, which should always be zero.
12. Execute each instruction in turn, following the control signals generated by the control
unit.
13. Verify that the final values of the registers are as expected.
For the given code, the expected final values of the registers are:
X0: 0
X1: 3
X2: 0
X3: -1
X4: 3
X5: 2
X6: -1
X7: 3
Note that the branch instruction is not taken, so it has no effect on the final register values.
2. The first instruction is read from instruction memory at address 0: "addi x7, x0, 3".
3. The control unit generates control signals to enable the register file to read from X0 and
write to X7, and to enable the ALU to perform an add immediate operation.
4. The register file reads the value 0 from X0 and stores it in Data1, and the ALU adds 3 to
this value to produce the result 3, which is stored in Writedata.
RISC-X system 4
5. The control unit sets Regwrite to 1, enabling the register file to write the value 3 to X7.
7. The second instruction is read from instruction memory at address 1: "sb x7, 0(x0)".
8. The control unit generates control signals to enable the register file to read from X7 and
X0, and to enable the data memory to write to address 0.
9. The register file reads the value 3 from X7 and stores it in Data2, and reads the value 0
from X0 and stores it in Read2.
10. The control unit sets WriteE to 1, enabling the data memory to write the value 3 to
address 0.
12. The third instruction is read from instruction memory at address 2: "addi x6, x0, -1".
13. The control unit generates control signals to enable the register file to read from X0 and
write to X6, and to enable the ALU to perform an add immediate operation.
14. The register file reads the value 0 from X0 and stores it in Data1, and the ALU subtracts 1
from this value to produce the result -1, which is stored in Writedata.
15. The control unit sets Regwrite to 1, enabling the register file to write the value -1 to X6.
17. The fourth instruction is read from instruction memory at address 3: "sb x6, 2(x0)".
18. The control unit generates control signals to enable the register file to read from X6 and
X0, and to enable the data memory to write to address 2.
19. The register file reads the value -1 from X6 and stores it in Data2, and reads the value 0
from X0 and stores it in Read2.
20. The control unit sets WriteE to 1, enabling the data memory to write the value -1 to
address 2.
21. The control unit generates a signal to set the regwrite control signal to 1 to enable writing
to the register file.
22. The ALU result is written to register x4 by setting the writereg to x4 and writedata to the
result.
23. The control unit generates a signal to set the regwrite control signal to 1 to enable writing
to the register file.
24. The ALU result is written to register x5 by setting the writereg to x5 and writedata to the
result.
25. The control unit generates a signal to set the regwrite control signal to 1 to enable writing
to the register file.
RISC-X system 5
26. The PC is updated to point to the next instruction by adding 2 to the current value of the
PC.
27. The control unit generates a signal to enable reading from the instruction memory.
28. The instruction memory outputs the instruction at the updated PC.
29. The instruction is decoded to determine the operation and the registers to use.
30. The control unit generates signals to set the read1 and read2 signals to the appropriate
register addresses.
31. The control unit generates a signal to set the PC to the new branch address, which is
obtained by adding the immediate value to the current PC.
32. The control unit generates a signal to enable writing to the data memory.
33. The ALU result, which is the value of x6, is written to data memory address 2 by setting
the writeE to 1 and the write address to 2.
34. The control unit generates a signal to set the PC to point to the next instruction.
35. The control unit generates a signal to enable reading from the instruction memory.
36. The instruction memory outputs the instruction at the updated PC.
37. The instruction is decoded to determine the operation and the registers to use.
38. The control unit generates signals to set the read1 and read2 signals to the appropriate
register addresses.
39. The ALU performs the AND operation on the contents of registers x6 and x7.
40. The control unit generates a signal to set the regwrite control signal to 1 to enable writing
to the register file.
41. The ALU result is written to register x4 by setting the writereg to x4 and writedata to the
result.
42. The control unit generates a signal to set the PC to point to the next instruction.
43. The control unit generates a signal to enable reading from the instruction memory.
44. The instruction memory outputs the instruction at the updated PC.
45. The instruction is decoded to determine the operation and the registers to use.
46. The control unit generates signals to set the read1 and read2 signals to the appropriate
register addresses.
47. The ALU performs the ADD operation on the contents of registers x6 and x7.
48. The control unit generates a signal to set the regwrite control signal to 1 to enable writing
to the register file.
RISC-X system 6
49. The ALU result is written to register x5 by setting the writereg to x5 and writedata to the
result.
50. The control unit generates a signal to set the PC to point to the next instruction.
51. The control unit generates a signal to enable reading from the instruction memory.
52. The instruction memory outputs the instruction at the updated PC.
53. The instruction is decoded to determine the operation and the registers to use.
54. The control unit generates signals to set the read1 and read2 signals to the appropriate
register addresses.
55. The immediate value 3 is added to register x0 using the ADDI instruction.
56. The control unit generates a signal to set the regwrite control signal to 1 to enable writing
to the register file.
58. Write the result of the ALU operation (0x02) to the register file, using the writereg signal
to determine which register to write to, and the writedata signal to determine the data to
write.
59. The next instruction to execute is "and x4, x6, x7". The control unit generates the
appropriate control signals to read the contents of x6 and x7 from the register file, and
pass them as inputs to the ALU.
60. The ALU performs the "and" operation on the inputs (0xFF & 0x03), and sets the zero-bit
flag to 0 since the result is not 0.
61. Write the result of the ALU operation (0x03) to the register file, using the writereg signal
to determine which register to write to, and the writedata signal to determine the data to
write.
62. The program has now completed execution. The final contents of the register file are:
X0: 0x00
X1: 0x00
X2: 0x00
X3: 0x00
X4: 0x03
X5: 0x00
X6: 0xFF
X7: 0x03
RISC-X system 7
Address 0x02: 0xFF
Address 0x03: 0x00
So here’s the logic implementation of the RISC-X system in Lua. Here's the Lua code for the
RISC-X datapath and control:
-- RISC-X datapath
function datapath(instruction, rs1, rs2, rd, imm, pc, reg)
local alu_res = 0
local mem_res = 0
local reg_write_data = 0
RISC-X system 8
pc = reg[rs1] + imm
end
-- RISC-X control
function control(opcode)
local reg_write = 0
local mem_write = 0
local mem_read = 0
local branch = 0
local jump = 0
local alu_op = 0
-- Registers
local PC = 0
local IR = 0
local A = 0
local B = 0
local ALU = 0
local MAR = 0
local MDR = 0
local Reg = {}
-- Memory
local Mem = {}
-- Control Signals
local RegDst = 0
local ALUSrc = 0
local MemtoReg = 0
local RegWrite = 0
local MemRead = 0
local MemWrite = 0
local Branch = 0
local Jump = 0
local ALUOp = 0
-- Opcode Constants
local R_TYPE = 0
local I_TYPE = 1
local J_TYPE = 2
-- Instruction Memory
local Inst_Mem = {0x00001021, 0x00001022, 0x00411020, 0x7FF11020}
RISC-X system 9
for i = 0, 31 do
Reg[i] = 0
end
for i = 0, 1023 do
Mem[i] = 0
end
end
-- Fetch Cycle
function Fetch()
MAR = PC
MDR = Inst_Mem[MAR+1]
IR = MDR
PC = PC + 1
end
-- Decode Cycle
function Decode()
local opcode = bit.rshift(IR, 26)
local rs = bit.rshift(bit.band(IR, 0x03E00000), 21)
local rt = bit.rshift(bit.band(IR, 0x001F0000), 16)
local rd = bit.rshift(bit.band(IR, 0x0000F800), 11)
local shamt = bit.rshift(bit.band(IR, 0x000007C0), 6)
local funct = bit.band(IR, 0x0000003F)
local imm = bit.band(IR, 0x0000FFFF)
local target = bit.band(IR, 0x03FFFFFF)
RISC-X system 10
RegWrite = 1
elseif opcode == 0
-- Registers
local registers = {}
for i = 0, 31 do
registers[i] = 0
end
-- Memory
local memory = {}
for i = 0, 65535 do
memory[i] = 0
end
-- Program counter
local pc = 0
-- Instruction register
local ir = 0
-- ALU flags
local zero_flag = false
local carry_flag = false
local overflow_flag = false
-- Control signals
local alu_control = 0
local alu_src_b = false
local mem_write = false
local mem_read = false
local reg_write = false
local mem_to_reg = false
local branch = false
-- Decode
local opcode = bit32.rshift(ir, 26)
local rs = bit32.band(bit32.rshift(ir, 21), 0x1F)
local rt = bit32.band(bit32.rshift(ir, 16), 0x1F)
local rd = bit32.band(bit32.rshift(ir, 11), 0x1F)
local shamt = bit32.band(bit32.rshift(ir, 6), 0x1F)
local funct = bit32.band(ir, 0x3F)
local imm = bit32.band(ir, 0xFFFF)
if bit32.band(imm, 0x8000) > 0 then
imm = imm - 0xFFFF0000
end
-- Control signals
alu_control = 0
alu_src_b = false
mem_write = false
mem_read = false
reg_write = false
mem_to_reg = false
branch = false
if opcode == 0 then
if funct == 0x20 then
RISC-X system 11
-- ADD
alu_control = 0
alu_src_b = true
reg_write = true
mem_to_reg = false
elseif funct == 0x22 then
-- SUB
alu_control = 1
alu_src_b = true
reg_write = true
mem_to_reg = false
elseif funct == 0x24 then
-- AND
alu_control = 2
alu_src_b = true
reg_write = true
mem_to_reg = false
elseif funct == 0x25 then
-- OR
alu_control = 3
alu_src_b = true
reg_write = true
mem_to_reg = false
elseif funct == 0x2A then
-- SLT
alu_control = 4
alu_src_b = true
reg_write = true
mem_to_reg = false
elseif funct == 0 then
-- SLL
alu_control = 5
shamt = bit32.band(ir, 0x7F)
alu_src_b = false
reg_write = true
mem_to_reg = false
elseif funct == 2 then
-- SRL
alu_control = 6
shamt = bit32.band(ir, 0x7F)
alu_src_b = false
reg_write = true
mem_to_reg = false
elseif funct == 8 then
-- JR
pc = registers[rs]
-- Program counter
pc = Register()
-- Instruction memory
instrMem = Memory({
data = {
0x31050001, -- addi $a0, $t0, 1
0x01295020, -- add $t2, $t1, $a1
0x11400003, -- beq $t2, $zero, 3
0x012a5820, -- add $t3, $t1, $a2
0x014b6020, -- add $t4, $t2, $t3
0x00c22022, -- sub $a0, $a2, $v0
0x08000000 -- j 0
}
})
-- Data memory
RISC-X system 12
dataMem = Memory({
data = {
0x00000000, -- 0($zero)
0x00000001, -- 4($zero)
0x00000002, -- 8($zero)
0x00000003 -- 12($zero)
}
})
-- Registers
regFile = RegisterFile({
reg = {
[8] = 0x00000003, -- $t0 = 3
[9] = 0x00000001, -- $t1 = 1
[10] = 0x00000002, -- $t2 = 2
[11] = 0x00000004, -- $t3 = 4
[12] = 0x00000005, -- $t4 = 5
[2] = 0x00000006, -- $v0 = 6
}
})
-- ALU control
aluControl = ALUControl()
-- ALU
alu = ALU()
-- MUXes
muxA = MUX()
muxB = MUX()
muxC = MUX()
-- Sign extend
signExtend = SignExtend()
-- Shift left 2
shiftLeft2 = ShiftLeft2()
-- Branch control
branchControl = BranchControl()
-- PC adder
pcAdder = Adder()
-- Connect components
pc.out:connect(instrMem.addr)
instrMem.out:connect(muxC.sel)
muxC.out:connect(signExtend.inp)
signExtend.out:connect(muxB.sel)
muxB.out:connect(regFile.readData1)
muxA.out:connect(pcAdder.out)
pc.out:connect(pcAdder.inp1)
shiftLeft2.out:connect(pcAdder.inp2)
regFile.writeData:connect(alu.out)
muxB.out:connect(alu.in1)
muxA.out:connect(alu.in2)
regFile.writeData:connect(shiftLeft2.inp)
branchControl.out:connect(muxC.sel)
aluControl.out:connect(alu.control)
muxA.out:connect(pcAdder.inp1)
pc.out:connect(muxA.sel)
dataMem.out:connect(regFile.writeData)
regFile.readData2:connect(muxC.sel)
muxC.out:connect(branchControl.inp)
RISC-X system 13
This Lua code defines the different components of the RISC-X system and connects them as
shown in the block diagram.
+-----------------------------------+
| Program |
+-----------------------------------+
| Instruction Fetch
|
+-------------------+
| Control |
+-------------------+
| Control Signals
|
+-------------------+
| ALU |
+-------------------+
| ALU result
|
+-------------------+
| Register Access |
+-------------------+
| Register value
|
+-------------------+
| Memory |
+-------------------+
| Memory data
|
+-------------------+
| PC |
+-------------------+
| PC value
|
+-------------------+
| Instruction |
| Memory (IM) |
+-------------------+
The program is fed into the system, which performs instruction fetches. The control unit then
decodes the instruction and generates control signals that are sent to the ALU, register
access, and memory modules. The ALU performs operations on data and returns the result to
the register access module, which stores the value in a register. The memory module is used
for loading and storing data, and the program counter (PC) keeps track of the current
instruction being executed. The instruction memory module stores the instructions that are
fetched and decoded by the system.
Here is the continued block diagram for the RISC-X system implementation:
RISC-X system 14
+---------+ +---------+
| | | |
| Fetch +----->+ Decode |
| | | |
+---------+ +---------+
| |
| |
v |
+---------+ |
| | |
| Execute +-----------+
| |
+---------+
|
|
v
+---------+
| |
| Write |
| Back |
| |
+---------+
The block diagram shows the four main stages of the RISC-X system: Fetch, Decode,
Execute, and Write Back. The arrows represent the flow of data and control signals between
the stages.
In the Fetch stage, instructions are fetched from memory and stored in the instruction
register. In the Decode stage, the instruction is decoded and the necessary data is read from
the register file and/or memory. In the Execute stage, the ALU performs the necessary
operations on the data. Finally, in the Write Back stage, the results are written back to the
register file or memory.
Overall, this block diagram provides a high-level view of how the RISC-X system operates
and the different stages involved in processing instructions.
RISC-X system 15