0% found this document useful (0 votes)
7 views

RISC_1

Uploaded by

210276
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

RISC_1

Uploaded by

210276
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 40

DIGITAL SYSTEM

DESIGN PROJECT
REPORT

SUBMITTED TO:

Engr. Usman Hameed


SUBMITTED BY:
210276 Muhammad Muneeb khan
210294 Noor ul Huda
210312 AbdurRehman

Date: 26/05/24
Contents
Introduction................................................................................................................................................3
Principles of RISC Architecture...................................................................................................................3
Advantages of RISC Architecture................................................................................................................3
Disadvantages of RISC Architecture...........................................................................................................4
RISC SPM.....................................................................................................................................................5
RISC SPM Instruction set.............................................................................................................................7
RISC SPM Controller....................................................................................................................................8
Code........................................................................................................................................................8
Clock unit.................................................................................................................................................8
D_flop....................................................................................................................................................10
RISC_SPM..............................................................................................................................................11
Processing unit......................................................................................................................................14
Register Unit..........................................................................................................................................17
Address Register....................................................................................................................................18
Instruction Register...............................................................................................................................19
Program Counter...................................................................................................................................20
5 channel multiplexer............................................................................................................................23
3 channel Multiplexer............................................................................................................................24
ALU_RISC...............................................................................................................................................25
Control Unit...........................................................................................................................................28
Memory Unit.........................................................................................................................................35
Test bench:................................................................................................................................................37
Output:......................................................................................................................................................39
Conclusion:................................................................................................................................................39
Figure 1: RISC SPM.......................................................................................................................................5
Figure 2: Control Signals..............................................................................................................................6
Figure 3: RISC SPM Instruction set...............................................................................................................7
Figure 4: RTL Clock Unit...............................................................................................................................8
Figure 5: RTL D_Flop..................................................................................................................................10
Figure 6: RTL RISC SPM..............................................................................................................................12
Figure 7: Processing Unit...........................................................................................................................15
Figure 8: RTL Processing Unit....................................................................................................................15
Figure 9: RTL Register Unit........................................................................................................................17
Figure 10: RTL Address Register................................................................................................................18
Figure 11: RTL Instruction Register............................................................................................................19
Figure 12: Program counter.......................................................................................................................20
Figure 13: RTL Program Counter................................................................................................................21
Figure 14: RTL 5 channel multiplexer.........................................................................................................22
Figure 15: RTL 3 Channel Multiplexer........................................................................................................24
Figure 16: ALU RISC...................................................................................................................................26
Figure 17: RTL ALU RISC.............................................................................................................................26
Figure 18: Control Unit..............................................................................................................................33
Figure 19: RTL Control Unit........................................................................................................................34
Figure 20: RTL Memory Unit......................................................................................................................36
Figure 21: Test Bench Output....................................................................................................................39
Introduction
Reduced Instruction Set Computer (RISC) architecture represents a fundamental shift in computer
design philosophy. RISC architectures prioritize simplicity and efficiency in instruction execution by
limiting the number of instructions and emphasizing simpler instructions that execute in a single clock
cycle. This report provides an overview of RISC architecture, its principles, advantages, disadvantages,
and its impact on modern computing.

Principles of RISC Architecture


RISC architecture is characterized by several key principles:

1. Simplicity: RISC architectures focus on a reduced set of simple instructions. Each instruction
performs a single operation, leading to streamlined instruction execution.

2. Fixed Instruction Length: Instructions in RISC architectures typically have a fixed length,
simplifying instruction decoding and improving performance.

3. Register-Register Architecture: RISC architectures predominantly use a load-store architecture,


where arithmetic and logical operations are performed only between registers, with memory
accesses limited to load and store instructions.

4. Pipeline-Friendly Design: RISC architectures are inherently suitable for pipelining due to their
simple and regular instruction set. Pipelining enables overlapping of instruction execution
stages, improving throughput and performance.

5. Hardwired Control Unit: RISC processors often utilize hardwired control units, which are faster
and more efficient compared to microprogrammed control units found in Complex Instruction
Set Computing (CISC) architectures.

Advantages of RISC Architecture


1. Performance: RISC architectures typically offer improved performance due to their simplified
instruction set and pipelining capabilities. Instructions execute in fewer clock cycles, resulting in
faster overall execution.

2. Compiler Optimization: The simplicity of RISC instructions makes it easier for compilers to
optimize code, resulting in more efficient execution.

3. Predictable Performance: With fixed-length instructions and regular instruction execution


times, RISC architectures offer predictable performance characteristics, facilitating easier
performance tuning and analysis.
4. Reduced Hardware Complexity: RISC architectures generally require less complex hardware
compared to CISC architectures, leading to lower manufacturing costs and power consumption.

5. Scalability: The modular and simplified nature of RISC architectures makes them well-suited for
scalability, enabling the development of processors ranging from embedded systems to high-
performance computing.

Disadvantages of RISC Architecture


1. Code Size: Due to the reduced instruction set, RISC instructions may require more instructions
to perform certain tasks compared to CISC architectures, resulting in larger code size.

2. Memory Bandwidth: RISC architectures often rely heavily on memory access due to the load-
store architecture, potentially leading to increased memory bandwidth requirements.

3. Limited Instruction Set: The reduced instruction set may lack certain complex instructions found
in CISC architectures, requiring more instructions or additional processing steps to accomplish
certain tasks.

4. Transition Challenges: Transitioning from CISC to RISC architectures may require software and
toolchain changes, which can be complex and time-consuming.

5. Less Suitable for Specific Applications: Some specialized applications may benefit from the rich
instruction sets of CISC architectures, making RISC architectures less suitable for these specific
use cases.
RISC SPM

Figure 1: RISC SPM

 RISC_SPM is a data path controller. It consists of controller (Control unit)


 , processor (Data path unit) and memory.
 The resgisters R0, R1,R2 and R3 are register files of the processor.
 Multiplexer ‘Mux_1’ does the selection of program counter and the R0, R1,R2 and R3 registers.
The selection pin comes from the controller.
 Multiplexer ‘Mux_2’ selects out the result of AlU, data from the bus 1 and ‘mem_word’ from the
memory module.
 “Add R”, address register stores the address of the memory
 Instructions are fetches synchronously from memory, decoded and executed to:
 Operate on data with ALU
 Change the contents of the register files
 Change the contents of PC, IR and ADD_R
 Change the contents of memory
 Retrieve data and instruction from memory
 Control the movement of data in buses
 Instruction register stores the instruction which the processor is currently
executing.
 Program counter register stores the address of the next instruction that is to be
executed.
 Address register stores the address of the memory location that will be addressed
next by a read or write operation. explain this to me. It serves as a pointer to the
specific memory location that the CPU will access next during a read or write
operation.

Figure 2: Control Signals


RISC SPM Instruction set

Figure 3: RISC SPM Instruction set

RISC SPM Controller


Code
Clock unit
module Clock_Unit(output reg clock);
parameter delay = 0;
parameter half_cycle = 10;

initial begin
#delay clock = 0;
end

always begin
#half_cycle clock = ~clock;
end
endmodule
1. module Clock_Unit( output reg clock);: This line defines a Verilog module named Clock_Unit. It
has one output port named clock, declared as a register (reg). The output keyword specifies that
clock is an output port.

2. parameter delay = 0;: This line defines a parameter named delay with a default value of 0.
Parameters in Verilog are used to specify constants that can be easily modified without changing
the main code.

3. parameter half_cycle = 10;: This line defines another parameter named half_cycle with a

Figure 4: RTL Clock Unit

default value of 10. This parameter represents the duration of half a clock cycle in time units.
4. initial begin #delay clock = 0;: This line is an initial block that runs once at the beginning of
simulation. It delays the execution by delay time units (#delay) and then sets the value of clock
to 0. This initializes the clock signal.

5. always begin #half_cycle clock = ~clock; end: This line is a continuous loop that toggles the
value of clock every half_cycle time units. It uses blocking assignment (=) to toggle clock
between its current value (~clock represents the logical negation of clock) and the opposite
value. This generates a square wave clock signal with a period of 2 * half_cycle time units.

This module generates a clock signal with a specified half-cycle duration. The clock starts with an initial
value of 0 and toggles between 0 and 1 in a continuous loop, creating a square wave clock signal. The
parameters delay and half_cycle allow flexibility in adjusting the timing characteristics of the generated
clock signal.

D_flop

module D_flop(output reg data_out,input data_in,load,clk,rst);


always@(posedge clk, negedge rst)
if(rst==1'b0) data_out<=0;
else if (load==1'b1) data_out<=data_in;

endmodule

1. module D_flop(output reg data_out, input data_in, load, clk, rst);: This line defines a Verilog
module named D_flop. It has five ports: data_out (output), data_in (input), load (input), clk
(input), and rst (input). The output reg declaration specifies that data_out is an output port and
is declared as a register (reg).

2. always@(posedge clk, negedge rst): This line starts an always block, which is sensitive to the
positive edge of the clk signal and the negative edge of the rst signal. This means that the block
will execute whenever there is a rising edge of the clock (clk) signal or a falling edge of the reset
(rst) signal.

3. if (rst == 1'b0) data_out <= 0;: This line checks if the rst signal is low (0). If it is, it indicates that
the flip-flop is being reset. In this case, the value of data_out is assigned to 0, effectively
resetting the output to 0.

4. else if (load == 1'b1) data_out <= data_in;: This line checks if the load signal is high (1). If it is, it
indicates that the flip-flop should load new data from the data_in input. In this case, the value
of data_out is assigned the value of data_in, effectively storing the input data into the flip-flop.

This module implements a D flip-flop. It has an input for data (data_in), a control signal (load) to
determine when to load new data, a clock input (clk) for synchronization, and a reset input (rst) for
resetting the flip-flop. The output (data_out) stores the current state of the flip-flop and updates based
on the input data when the load signal is asserted.

RISC_SPM
module RISC_SPM #(parameter word_size = 8, Sel1_size = 3, Sel2_size = 2)(
input clk, rst
);

// Data Nets

wire [Sel1_size-1:0] Sel_Bus_1_Mux;


wire [Sel2_size-1:0] Sel_Bus_2_Mux;

wire zero;

wire [word_size-1:0] instruction, address, Bus_1, mem_word;


// Control Nets

wire Load_R0, Load_R1, Load_R2, Load_R3, Load_PC, Inc_PC, Load_IR,


Load_Add_R, Load_Reg_Y, Load_Reg_Z, write;

Processing_Unit M0_Processor (instruction, address, Bus_1, zero, mem_word,


Load_R0, Load_R1, Load_R2, Load_R3, Load_PC, Inc_PC, Sel_Bus_1_Mux,
Sel_Bus_2_Mux, Load_IR, Load_Add_R, Load_Reg_Y, Load_Reg_Z, clk, rst);

Control_Unit M1_Controller (Sel_Bus_2_Mux, Sel_Bus_1_Mux, Load_R0,


Load_R1, Load_R2, Load_R3, Load_PC, Inc_PC, Load_IR, Load_Add_R,
Load_Reg_Y, Load_Reg_Z, write, instruction, zero, clk, rst);

Memory_Unit M2_MEM (

.data_out(mem_word),

.data_in(Bus_1),

.address(address),

.clk(clk),

.write(write)
);

Endmodule

1. module RISC_SPM #(parameter word_size = 8, Sel1_size = 3, Sel2_size = 2)( input clk, rst );:
This line defines a Verilog module named RISC_SPM with parameters word_size, Sel1_size, and
Sel2_size. It has two input ports: clk for the clock signal and rst for the reset signal.

2. wire [Sel1_size-1:0] Sel_Bus_1_Mux; and wire [Sel2_size-1:0] Sel_Bus_2_Mux;: These lines


declare wires (Sel_Bus_1_Mux and Sel_Bus_2_Mux) used for selecting different data paths
within the processor.

3. wire zero;: This line declares a wire zero which may be used as a constant value.

4. wire [word_size-1:0] instruction, address, Bus_1, mem_word;: These lines declare wires for
various signals including instruction, address, Bus_1, and mem_word, each of which has a
specified bit width based on the provided parameters.
5. wire Load_R0, Load_R1, Load_R2, Load_R3, Load_PC, Inc_PC, Load_IR, Load_Add_R,
Load_Reg_Y, Load_Reg_Z, write;: These lines declare wires representing various control signals
used to control the operation of the processor.

6. Processing_Unit M0_Processor (...);: This line instantiates a module named Processing_Unit,


representing the processing unit of the RISC architecture. It passes various control signals and
data paths to this module for processing.

7. Control_Unit M1_Controller (...);: This line instantiates a module named Control_Unit,


representing the control unit of the RISC architecture. It passes control signals, data paths, and
instructions to this module for controlling the operation of the processor.

8. Memory_Unit M2_MEM (...);: This line instantiates a module named Memory_Unit,


representing the memory unit of the RISC architecture. It passes data paths and control signals
to this module for memory operations.

This module represents a simple RISC architecture with a Scratchpad Memory (SPM). It consists of a
processing unit, a control unit, and a memory unit. The processing unit performs operations based on
instructions received, the control unit manages control signals, and the memory unit handles memory
operations.

Processing unit

module Processing_Unit #(parameter


word_size = 8, op_size = 4 , Sel1_size = 3, Sel2_size = 2)(
output [word_size -1:0] instruction, address, Bus_1,
output Zflag,
input [word_size -1:0] mem_word,
input Load_R0,Load_R1,Load_R2,Load_R3,Load_PC,Inc_PC,
input [Sel1_size -1:0] Sel_Bus_1_Mux,
input [Sel2_size -1:0] Sel_Bus_2_Mux,
input Load_IR,Load_Add_R,Load_Reg_Y,Load_Reg_Z,
input clk,rst
);
wire [word_size - 1:0] Bus_2;
wire [word_size - 1:0] R0_out,Rl_out,R2_out,R3_out;
wire [word_size -1:0] PC_count,Y_value,alu_out;
wire alu_zero_flag;
wire [op_size -1:0] opcode= instruction[word_size-1:word_size-op_size];

Register_Unit R0 (R0_out, Bus_2,Load_R0,clk,rst);


Register_Unit R1 (R1_out, Bus_2,Load_R1,clk,rst);
Register_Unit R2 (R2_out, Bus_2,Load_R2,clk,rst);
Register_Unit R3 (R3_out, Bus_2,Load_R3,clk,rst);
Register_Unit Reg_Y (Y_value,Bus_2,Load_Reg_Y,clk,rst);
Register_Unit Reg_Z (Zflag,alu_zero_flag,Load_Reg_z,clk,rst);
Address_Register Add_R (address,Bus_2,Load-add_R,clk,rst);
Instruction_Register IR(instruction,Bus_2,Load_IP,clk,rst);
Program_Counter PC (PC_count,Bus_2,Load_PC,Inc_PC,clk,rst);

Multiplexer_5ch Mux_1 (Bus_1,R0_out,R1_out,R2_out,R3_out,PC_count,Sel_Bus_1_Mux);


Multiplexer_3ch Mux_2 (Bus_2,alu_out,Bus-1,mem_word,Sel_Bus_2_Mux);
Alu_RISC ALU(alu_out,alu_zero_flag,Y_value,Bus_1,opcode);

Endmodule
Figure 7: Processing Unit

Figure 8: RTL Processing Unit

1. module Processing_Unit #(parameter word_size = 8, op_size = 4, Sel1_size = 3, Sel2_size = 2)


(...): This line defines a Verilog module named Processing_Unit. It takes parameters word_size,
op_size, Sel1_size, and Sel2_size to specify the widths of various signals. It has several input and
output ports representing various control signals and data paths.

2. wire [word_size - 1:0] Bus_2;: This line declares a wire Bus_2 with a width of word_size.

3. wire [word_size - 1:0] R0_out, R1_out, R2_out, R3_out;: These lines declare wires representing
the output values of four registers (R0, R1, R2, R3) with a width of word_size.

4. wire [word_size - 1:0] PC_count, Y_value, alu_out;: These lines declare wires representing the
output values of the program counter (PC_count), register Y (Y_value), and the ALU output
(alu_out) with a width of word_size.

5. wire alu_zero_flag;: This line declares a wire alu_zero_flag which represents the zero flag status
of the ALU.

6. wire [op_size - 1:0] opcode = instruction[word_size-1:word_size-op_size];: This line extracts


the opcode from the instruction based on the specified op_size.
7. Instantiation of Register Units (R0, R1, R2, R3, Reg_Y, Reg_Z), Address Register (Add_R),
Instruction Register (IR), Program Counter (PC), Multiplexers (Mux_1, Mux_2), and ALU (ALU).
Each instantiation connects the respective input and output signals.

8. The Register_Unit modules represent register storage elements. Each register unit (R0, R1, R2,
R3, Reg_Y, Reg_Z) stores data and updates based on control signals (Load_Rx), clock (clk), and
reset (rst).

9. The Address_Register, Instruction_Register, and Program_Counter modules manage memory


addresses, instruction storage, and program counter operations, respectively.

10. The Multiplexer_5ch and Multiplexer_3ch modules perform multiplexing operations to select
data sources based on control signals.

11. The Alu_RISC module performs arithmetic and logic operations based on the opcode extracted
from the instruction.

This module represents the Processing Unit of a RISC architecture. It includes various components such
as registers, address registers, instruction registers, program counters, multiplexers, and an ALU, all
interconnected to process instructions and data according to the RISC architecture's design.

Register Unit

module Register_Unit#(parameter word_size=8)


(output reg [word_size-1:0] data_out,
input [word_size-1:0] data_in,
input load,clk,rst);

always @(posedge clk, negedge rst)


if(rst==1'b0) data_out<=0;
else if(load) data_out<=data_in;

endmodule
1. module Register_Unit#(parameter word_size=8)(output reg [word_size-1:0] data_out, input
[word_size-1:0] data_in, input load, clk, rst);: This line declares a Verilog module named
Register_Unit. It has parameters word_size, which specifies the size of the register in bits. It has
three output ports: data_out, an word_size-bit register output, and two input ports: data_in, an
word_size-bit data input, load, a control signal to load data into the register, and clk, a clock
input, and rst, a reset input.

2. always @(posedge clk, negedge rst): This line begins an always block, which executes whenever
there is a rising edge of the clock signal (clk) or a falling edge of the reset signal (rst).

3. if (rst == 1'b0) data_out <= 0;: This line checks if the reset signal (rst) is low (0). If it is, indicating
that the register is being reset, the data_out is assigned to 0, effectively resetting the register.

4. else if (load) data_out <= data_in;: This line checks if the load signal is asserted (1). If it is,
indicating that new data should be loaded into the register, the data_in value is assigned to
data_out. This updates the register with the input data.

This Verilog module defines a register unit that stores data (data_out) and updates it based on a control
signal (load) and input data (data_in). It operates on a clock signal (clk), and it can be reset using a reset
signal (rst). This module is commonly used as a basic storage element in digital circuits, such as
processors, where temporary storage of data is required.
Address Register
module Address_Register#(parameter word_size=8)
( output reg [word_size-1:0] data_out,
input [word_size-1:0] data_in,
input load,clk,rst);

always@(posedge clk, negedge rst)


if(rst==1'b0) data_out<=0;
else if(load==1'b1) data_out<=data_in;

endmodule

Figure 10: RTL Address Register


1. module Address_Register#(parameter word_size=8) (output reg [word_size-1:0] data_out,
input [word_size-1:0] data_in, input load, clk, rst);: This line declares a Verilog module named
Address_Register. It has a parameter word_size which determines the size of the register in
bits. It consists of an output port data_out which is a register storing the address, an input port
data_in for the input address data, and inputs load, clk, and rst representing control signals for
loading data into the register, clock signal, and reset signal respectively.

2. always@(posedge clk, negedge rst): This line initiates an always block that triggers on the
positive edge of the clock (clk) and the negative edge of the reset signal (rst).

3. if (rst == 1'b0) data_out <= 0;: This line checks if the reset signal (rst) is low (0). If it is, indicating
that the register is being reset, the data_out is assigned to 0, effectively resetting the register.

4. else if (load == 1'b1) data_out <= data_in;: This line checks if the load signal is high (1). If it is,
indicating that new address data should be loaded into the register, the data_in value is
assigned to data_out. This updates the register with the input address.
This module defines an address register that stores memory addresses. It updates its stored address
based on a control signal (load) and input address data (data_in). It operates on a clock signal (clk) and
can be reset using a reset signal (rst). This module is essential in digital systems for storing memory
addresses used for data retrieval and manipulation.

Instruction Register

module Instruction_Register#(parameter word_size=8)


(output reg [word_size-1:0] data_out,
input [word_size-1:0] data_in,
input load, clk, rst);
always@(posedge clk, negedge rst)
if (rst==1'b0) data_out<=0;
else if (load==1'b1) data_out<=data_in;

endmodule

Figure 11: RTL Instruction Register

1. module Instruction_Register#(parameter word_size=8) (output reg [word_size-1:0] data_out,


input [word_size-1:0] data_in, input load, clk, rst);: This line declares a Verilog module named
Instruction_Register. It has a parameter word_size which determines the size of the register in
bits. It consists of an output port data_out which is a register storing the instruction, an input
port data_in for the input instruction data, and inputs load, clk, and rst representing control
signals for loading data into the register, clock signal, and reset signal respectively.
2. always@(posedge clk, negedge rst): This line initiates an always block that triggers on the
positive edge of the clock (clk) and the negative edge of the reset signal (rst).

3. if (rst == 1'b0) data_out <= 0;: This line checks if the reset signal (rst) is low (0). If it is, indicating
that the register is being reset, the data_out is assigned to 0, effectively resetting the register.

4. else if (load == 1'b1) data_out <= data_in;: This line checks if the load signal is high (1). If it is,
indicating that a new instruction should be loaded into the register, the data_in value is
assigned to data_out. This updates the register with the input instruction.

This module defines an instruction register that stores instructions fetched from memory. It updates its
stored instruction based on a control signal (load) and input instruction data (data_in). It operates on a
clock signal (clk) and can be reset using a reset signal (rst). This module is a fundamental component in
digital systems for storing instructions to be executed by the processor.

Program Counter
module Program_Counter#(parameter word_size=8)
(output reg [word_size-1:0] count,
input [word_size-1:0] data_in,
input Load_PC, Inc_PC,
input clk,rst);

always@ (posedge clk, negedge rst)


if (rst==1'b0) count<=0;
else if (Load_PC==1'b1) count<=data_in;
else if (Inc_PC==1'b1) count<=count+1;
endmodule

Figure 12: Program counter


Figure 13: RTL Program Counter
1. module Program_Counter#(parameter word_size=8) (output reg [word_size-1:0] count, input
[word_size-1:0] data_in, input Load_PC, Inc_PC, input clk, rst);: This line declares a Verilog
module named Program_Counter. It has a parameter word_size which determines the size of
the program counter in bits. It consists of an output port count which represents the current
value of the program counter, and input ports data_in for the input data to load into the
program counter, Load_PC to signal when to load new data into the program counter, Inc_PC to
signal when to increment the program counter, clk for the clock signal, and rst for the reset
signal.

2. always @ (posedge clk, negedge rst): This line initiates an always block that triggers on the
positive edge of the clock (clk) and the negative edge of the reset signal (rst).

3. if (rst==1'b0) count<=0;: This line checks if the reset signal (rst) is low (0). If it is, indicating that
the module is being reset, the count is assigned to 0, effectively resetting the program counter.

4. else if (Load_PC==1'b1) count<=data_in;: This line checks if the Load_PC signal is high (1). If it is,
indicating that new data should be loaded into the program counter, the value from data_in is
assigned to count. This updates the program counter with the input data.

5. else if (Inc_PC==1'b1) count<=count+1;: This line checks if the Inc_PC signal is high (1). If it is,
indicating that the program counter should be incremented, the value of count is incremented
by 1. This advances the program counter to the next memory address.

This module defines a Program Counter that keeps track of the memory address of the next instruction
to be fetched. It updates its value based on control signals (Load_PC and Inc_PC) and input data
(data_in). It operates on a clock signal (clk) and can be reset using a reset signal (rst). This module is a
critical component in digital systems for controlling the program flow and executing instructions
sequentially.
5 Channel multiplexer

module Multiplexer_5ch#(parameter word_size=8)


(
output [word_size-1:0] mux_out,
input [word_size-1:0] data_a, data_b, data_c, data_d,data_e,
input [2:0] sel
);

assign mux_out=(sel==0) ?data_a:(sel==1)


?data_b:(sel==2)
?data_c:(sel==3)
?data_d:(sel==4)
?data_e:'bx;
Endmodule

Figure 14: RTL 5 channel multiplexer

1. module Multiplexer_5ch#(parameter word_size=8) (...): This line declares a Verilog module


named Multiplexer_5ch. It has a parameter word_size which determines the size of the data
bus in bits. It includes output port mux_out, representing the output of the multiplexer, and five
input ports: data_a, data_b, data_c, data_d, and data_e, representing the data inputs to the
multiplexer. It also has an input port sel of width 3 bits to select one of the inputs.

2. assign mux_out = (sel == 0) ? data_a : (sel == 1) ? data_b : (sel == 2) ? data_c : (sel == 3) ?


data_d : (sel == 4) ? data_e : 'bx;: This line defines the logic of the multiplexer. It uses a
conditional operator (?:) to select one of the input data based on the value of sel.

 If sel is 0, data_a is selected.

 If sel is 1, data_b is selected.

 If sel is 2, data_c is selected.

 If sel is 3, data_d is selected.

 If sel is 4, data_e is selected.

 If sel is any other value, represented by 'bx, the output is assigned to a don't-care value.

3. mux_out: This line assigns the output of the multiplexer to mux_out based on the selected
input data.

This module implements a 5-channel multiplexer. It selects one of the five input data based on the value
of the selection signal sel and provides it as output. This multiplexer is commonly used in digital systems
for selecting among multiple data sources.

3 Channel Multiplexer

module Multiplexer_3ch#(parameter word_size=8)


(
output [word_size-1:0] mux_out,
input [word_size-1:0] data_a,data_b, data_c,
input [1:0] sel
);
assign mux_out=(sel==0)?data_a:(sel==1)?data_b:(sel==2)?data_c:'bx;
endmodule
1. module Multiplexer_3ch#(parameter word_size=8) (...): This line declares a Verilog module
named Multiplexer_3ch. It has a parameter word_size which determines the size of the data
bus in bits. It includes output port mux_out, representing the output of the multiplexer, and
three input ports: data_a, data_b, and data_c, representing the data inputs to the multiplexer.
It also has an input port sel of width 2 bits to select one of the inputs.

2. assign mux_out = (sel == 0) ? data_a : (sel == 1) ? data_b : (sel == 2) ? data_c : 'bx;: This line
defines the logic of the multiplexer. It uses a conditional operator (?:) to select one of the input
data based on the value of sel.

 If sel is 0, data_a is selected.

Figure 15: RTL 3 Channel Multiplexer

 If sel is 1, data_b is selected.

 If sel is 2, data_c is selected.

 If sel is any other value, represented by 'bx, the output is assigned to a don't-care value.

3. mux_out: This line assigns the output of the multiplexer to mux_out based on the selected
input data.

This module implements a 3-channel multiplexer. It selects one of the three input data based on the
value of the selection signal sel and provides it as output. This multiplexer is commonly used in digital
systems for selecting among multiple data sources.
ALU_RISC

module Alu_RISC#(parameter word_size = 8, op_size = 4,


//opcodes
NOP = 4'b0000,
ADD = 4'b0001,
SUB = 4'b0010,
AND = 4'b0011,
NOT = 4'b0100,
RD = 4'b0101,
WR = 4'b0110,
BR = 4'b0111,
BRZ = 4'b1000
)(
output reg [word_size -1:0] alu_out,
output alu_zero_flag,
input [word_size -1:0] data_1,data_2,
input [op_size -1:0] sel
);

assign alu__zero_flag = ~|alu_out;


always@(sel,data_1,data_2)
case(sel)
NOP: alu_out = 0;
ADD: alu_out = data_1 + data_2;
SUB: alu_out = data_2 - data_1;
AND: alu_out = data_1 & data_2;
NOT: alu_out = ~data_2;
default: alu_out = 0;
endcase
endmodule
Figure 16: ALU RISC

Figure 17: RTL ALU RISC


1. module Alu_RISC#(parameter word_size = 8, op_size = 4, ... )(output reg [word_size -1:0]
alu_out, output alu_zero_flag, input [word_size -1:0] data_1, data_2, input [op_size -1:0] sel);:
This line defines a Verilog module named Alu_RISC. It has parameters word_size and op_size,
determining the size of data and opcode respectively. It includes output ports alu_out and
alu_zero_flag representing the ALU output and zero flag, and input ports data_1 and data_2 for
data inputs, and sel for opcode selection.

2. assign alu_zero_flag = ~|alu_out;: This line calculates the zero flag by performing a bitwise OR
operation (|) on the output of the ALU (alu_out) and then negating the result (~). The zero flag
is set if all bits of alu_out are zero.

3. always @(sel, data_1, data_2): This line starts an always block sensitive to changes in the sel,
data_1, and data_2 inputs.

4. case(sel): This line initiates a case statement based on the value of sel, which selects the
operation to be performed by the ALU.

5. NOP: alu_out = 0;: This line specifies the NOP (No Operation) operation. When sel is equal to
NOP, the output of the ALU (alu_out) is assigned to 0.

6. ADD: alu_out = data_1 + data_2;: This line specifies the addition operation. When sel is equal to
ADD, the output of the ALU is assigned to the sum of data_1 and data_2.

7. SUB: alu_out = data_2 - data_1;: This line specifies the subtraction operation. When sel is equal
to SUB, the output of the ALU is assigned to the difference of data_2 minus data_1.

8. AND: alu_out = data_1 & data_2;: This line specifies the bitwise AND operation. When sel is
equal to AND, the output of the ALU is assigned to the bitwise AND of data_1 and data_2.

9. NOT: alu_out = ~data_2;: This line specifies the bitwise NOT operation. When sel is equal to
NOT, the output of the ALU is assigned to the bitwise negation of data_2.

10. default: alu_out = 0;: This line specifies the default operation. If sel does not match any defined
opcode, the output of the ALU is assigned to 0.

This module implements an ALU for a RISC architecture, supporting operations such as addition,
subtraction, bitwise AND, and bitwise NOT. It produces both the ALU output (alu_out) and a zero flag
(alu_zero_flag) indicating whether the ALU output is zero or not.

Control Unit

module Control_Unit#(parameter
word_size = 8,op_size = 4, state_size= 4,src_size=2,dest_size=2,Sel1_size=3,Sel2_size=2)
(output [Sel2_size-1:0]Sel_Bus_2_Mux,
output [Sel1_size-1:0]Sel_Bus_1_Mux,
output reg
Load_R0,Load_R1,Load_R2,Load_R3,Load_PC,Inc_PC,Load_IR,Load_Add_R,Load_Reg_Y,Load_Reg_Z,
write,
input [word_size-1:0]instruction,
input zero,clk,rst

);

parameter S_idle=0,S_fet1=1,S_fet2=2,S_dec=3,
S_ex1=4,S_rd1=5,S_rd2=6,
S_wr1=7,S_wr2=8,S_br1=9,S_br2=10,S_halt=11;

parameter NOP=0,ADD=1,SUB=2,AND=3,NOT=4,RD=5,WR=6,BR=7,BRZ=8;

parameter R0=0,R1=1,R2=2,R3=3;

reg[state_size-1:0] state,next_state;
reg Sel_ALU,Sel_Bus_1,Sel_Mem;
reg Sel_R0,Sel_R1,Sel_R2,Sel_R3,Sel_PC;
reg err_flag;
wire [op_size-1:0]opcode=instruction[word_size-1:word_size-op_size];
wire [src_size-1:0]src=instruction[src_size+dest_size-1:dest_size];
wire [dest_size-1:0]dest=instruction[dest_size-1:0];

assign Sel_Bus_1_Mux[Sel1_size-1:0]=Sel_R0 ? 0:
Sel_R1 ? 1:
Sel_R2 ? 2:
Sel_R3 ? 3:
Sel_PC ? 4:3'bx;

assign Sel_Bus_2_Mux[Sel2_size-1:0] = Sel_ALU ? 0:


Sel_Bus_1 ? 0:
Sel_Mem ? 2:2'bx;

always@(posedge clk,negedge rst)


begin:State_transitions
if (rst==0)
state<=S_idle;
else state<=next_state;
end

always@(state,opcode,src,dest,zero)
begin:Output_and_next_state
Sel_R0=0; Sel_R1=0; Sel_R2=0; Sel_R3=0; Sel_PC=0;
Load_R0=0; Load_R1=0; Load_R2=0; Load_R3=0; Load_PC=0;
Load_IR=0; Load_Add_R=0; Load_Reg_Z=0;
Inc_PC=0;
Sel_Bus_1=0;
Sel_ALU = 0;
Sel_Mem = 0;
write =0;
err_flag=0;

next_state=state;
case (state)
S_idle:
next_state = S_fet1;
S_fet1:
begin
next_state = S_fet2;
Sel_PC=1;
Sel_Bus_1 = 1;
Load_Add_R = 1;
end
S_fet2:
begin
next_state = S_dec;
Sel_Mem=1;
Load_IR = 1;
Inc_PC = 1;
end
S_dec:
case (opcode)
NOP: next_state = S_fet1;
ADD,SUB,AND:
begin
next_state = S_ex1;
Sel_Bus_1 = 1;
Load_Reg_Y = 1;
case(src)
R0: Sel_R0 = 1;
R1: Sel_R1 = 1;
R2: Sel_R2 = 1;
R3: Sel_R3 = 1;
default err_flag=1;
endcase
end
NOT:
begin
next_state = S_fet1;
Load_Reg_Z = 1;
Sel_ALU = 1;
case(src)
R0: Sel_R0 = 1;
R1: Sel_R1 = 1;
R2: Sel_R2 = 1;
R3: Sel_R3 = 1;
default err_flag=1;
endcase
case(dest)
R0: Load_R0 = 1;
R1: Load_R1 = 1;
R2: Load_R2 = 1;
R3: Load_R3 = 1;
default err_flag=1;
endcase
end
RD:
begin
next_state = S_rd1;
Sel_PC = 1;
Sel_Bus_1 = 1;
Load_Add_R = 1;
end
WR:
begin
next_state = S_wr1;
Sel_PC = 1;
Sel_Bus_1 = 1;
Load_Add_R = 1;
end
BR:
begin
next_state = S_br1;
Sel_PC = 1;
Sel_Bus_1 = 1;
Load_Add_R = 1;
end
BRZ:
if (zero ==1)
begin
next_state = S_br1;
Sel_PC = 1;
Sel_Bus_1 = 1;
Load_Add_R = 1;
end
else
begin
next_state = S_fet1;
Inc_PC = 1;
end
default: next_state = S_halt;
endcase
S_ex1:
begin
next_state = S_fet1;
Load_Reg_Z = 1;
Sel_ALU = 1;
case(dest)
R0:begin Sel_R0 = 1;Load_R0 = 1; end
R1:begin Sel_R1 = 1;Load_R1 = 1; end
R2:begin Sel_R2 = 1;Load_R2 = 1; end
R3:begin Sel_R3 = 1;Load_R3 = 1; end
default: err_flag = 1;
endcase
end
S_rd1:
begin
next_state = S_rd2;
Sel_Mem = 1;
Load_Add_R = 1;
Inc_PC = 1;
end
S_wr1:
begin
next_state = S_wr2;
Sel_Mem = 1;
Load_Add_R = 1;
Inc_PC = 1;
end
S_rd2:
begin
next_state = S_fet1;
Sel_Mem = 1;
case(dest)
R0: Load_R0 = 1;
R1: Load_R1 = 1;
R2: Load_R2 = 1;
R3: Load_R3 = 1;
default err_flag = 1;
endcase
end
S_wr2:
begin
next_state = S_fet1;
write = 1;
case(src)
R0: Sel_R0 = 1;
R1: Sel_R1 = 1;
R2: Sel_R2 = 1;
R3: Sel_R3 = 1;
default err_flag = 1;
endcase
end
S_br1:
begin
next_state = S_br2;
Sel_Mem = 1;
Load_Add_R = 1;
end
S_br2:
begin
next_state = S_fet1;
Sel_Mem = 1;
Load_PC = 1;
end
S_halt:
next_state = S_halt;
default:
next_state = S_idle;
endcase
end
endmodule
1. module Control_Unit#(parameter word_size = 8, op_size = 4, state_size = 4, src_size = 2,
dest_size = 2, Sel1_size = 3, Sel2_size = 2) (...): This line declares a Verilog module named
Control_Unit. It has several parameters defining the sizes of various fields and signals used
within the module.
2. Output Ports: The module has several output ports including Sel_Bus_2_Mux, Sel_Bus_1_Mux,
and various control signals like Load_R0, Load_R1, Load_R2, Load_R3, Load_PC, Inc_PC,
Load_IR, Load_Add_R, Load_Reg_Y, Load_Reg_Z, and write. These control signals are used to
control various operations in the processor.

3. Input Ports: The module takes inputs including instruction, zero, clk, and rst. These inputs are
used to determine the control signals and the next state of the state machine.

4. Parameter Definitions: The module defines various parameters representing different states
(S_idle, S_fet1, etc.) and opcodes (NOP, ADD, SUB, etc.).

5. Registers: The module defines several registers (state, Sel_R0, Sel_R1, etc.) to store state
information and control signals.

6. Output and Next State Logic: The module contains an always block that determines the control
signals and the next state of the state machine based on the current state, opcode, and other
inputs.

7. State Transitions: The state transitions are defined using a case statement based on the current
state.
8. Output and Next State Assignments: Within each state, control signals and the next state are
assigned based on the opcode and other conditions.

9. Default Case: The module also includes a default case in the state machine to handle any
undefined states.

This module implements the control unit of a RISC architecture processor. It controls various operations
of the processor based on the current state, opcode, and other inputs, and it generates control signals
and determines the next state of the processor's state machine.

Memory Unit

module Memory_Unit #(parameter word_size = 8, memory_size = 256)(

output [word_size -1:0] data_out,

input [word_size-1:0] data_in,

input [word_size - 1:0 ] address,

input clk, write


);

reg [word_size-1:0] memory [memory_size-1: 0];

assign data_out = memory[address];

always @ (posedge clk)

if (write) memory[address] <= data_in;

endmodule
Figure 20: RTL Memory Unit

1. module Memory_Unit #(parameter word_size = 8, memory_size = 256)(...): This line declares a


Verilog module named Memory_Unit. It takes parameters word_size and memory_size, where
word_size determines the size of each memory location in bits, and memory_size determines
the number of memory locations in the memory unit.
2. Output and Input Ports: The module has output port data_out for retrieving data from memory,
input ports data_in for writing data into memory, address for specifying the memory address,
clk for the clock signal, and write to signal whether to write data into memory.
3. Memory Array: Inside the module, a memory array memory is declared using the specified
parameters. It's a 2-dimensional array with dimensions memory_size by word_size, where each
row represents a memory location and each column represents the bits of data stored in that
location.
4. assign data_out = memory[address];: This line assigns the output data_out to the content of
the memory location specified by the address. It retrieves the data stored at the specified
memory address.
5. always @ (posedge clk): This line starts an always block that triggers on the positive edge of the
clock signal clk. This means the following block of code will execute whenever there's a rising
edge of the clock signal.
6. if (write) memory[address] <= data_in;: Inside the always block, this line checks if the write
signal is high (indicating a write operation). If it is, the data specified by data_in is written into
the memory location specified by address.

This module represents a memory unit with read and write capabilities. It utilizes a 2-dimensional array
to store data, and data can be written into or read from memory based on control signals such as the
memory address and write enable signal. This module is a crucial component in digital systems for data
storage and retrieval.
Test bench:
module test_RISC_SPM#(parameter word_size = 8)();
reg rst;
wire clk;
reg[8:0] k;
Clock_Unit M1(clk);
RISC_SPM M2(clk,rst);

// define probes
wire[word_size -1:0]
word0,word1,word2,word3,word4,word5,word6,word7,word8,word9,word10,word11,word12,word1
3,word14,word128,word129,word130,word131,word132,word133,word134,word135,word136,word
137,word138,word139,word140,word255;

assign word0 = M2.M2_MEM.memory[0],


word1 = M2.M2_MEM.memory[1],
word2 = M2.M2_MEM.memory[2],
word3 = M2.M2_MEM.memory[3],
word4 = M2.M2_MEM.memory[4],
word5 = M2.M2_MEM.memory[5],
word6 = M2.M2_MEM.memory[6],
word7 = M2.M2_MEM.memory[7],
word8 = M2.M2_MEM.memory[8],
word9 = M2.M2_MEM.memory[9],
word10 = M2.M2_MEM.memory[10],
word11 = M2.M2_MEM.memory[11],
word12 = M2.M2_MEM.memory[12],
word13 = M2.M2_MEM.memory[13],
word14 = M2.M2_MEM.memory[14],
word128 = M2.M2_MEM.memory[128],
word129 = M2.M2_MEM.memory[129],
word130 = M2.M2_MEM.memory[130],
word131 = M2.M2_MEM.memory[131],
word132 = M2.M2_MEM.memory[132],
word133 = M2.M2_MEM.memory[133],
word134 = M2.M2_MEM.memory[134],
word135 = M2.M2_MEM.memory[135],
word136 = M2.M2_MEM.memory[136],
word137 = M2.M2_MEM.memory[137],
word138 = M2.M2_MEM.memory[138],
word139 = M2.M2_MEM.memory[139],
word140 = M2.M2_MEM.memory[140],
word255 = M2.M2_MEM.memory[255];
initial #2800 $finish;
//flush memory

initial begin:Flush_Memory
#2 rst = 0; for(k=0;k<255;k=k+1)M2.M2_MEM.memory[k] = 0; #10 rst = 1;
end

initial begin: Load_program


#5
M2.M2_MEM.memory[0] = 8'b0000_00_00;
M2.M2_MEM.memory[1] = 8'b0101_00_10;
M2.M2_MEM.memory[2] = 130;
M2.M2_MEM.memory[3] = 8'b0101_00_11;
M2.M2_MEM.memory[4] = 131;
M2.M2_MEM.memory[5] = 8'b0101_00_10;
M2.M2_MEM.memory[6] = 128;
M2.M2_MEM.memory[7] = 8'b0101_00_00;
M2.M2_MEM.memory[8] = 129;
M2.M2_MEM.memory[9] = 8'b0010_00_01;
M2.M2_MEM.memory[10] = 8'b1000_00_00;
M2.M2_MEM.memory[11] = 134;
M2.M2_MEM.memory[12] = 8'b1001_10_11;
M2.M2_MEM.memory[13] = 8'b0111_00_11;
M2.M2_MEM.memory[14] = 140;
//load data
M2.M2_MEM.memory[128] = 6;
M2.M2_MEM.memory[129] = 1;
M2.M2_MEM.memory[130] = 2;
M2.M2_MEM.memory[131] = 0;
M2.M2_MEM.memory[134] = 139;
M2.M2_MEM.memory[139] = 8'b1111_00_00;
M2.M2_MEM.memory[140] = 9;
M2.M2_MEM.memory[255] = 10;
end
endmodule
Output:

Figure 21: Test Bench Output


 The testbench initializes a clock signal and a reset signal, probes specific memory locations
within the RISC_SPM module, flushes the memory, and loads instructions and data into memory
for testing.
Conclusion:

You might also like