100% found this document useful (1 vote)
300 views14 pages

Assignment3 2021HT80531

The document describes the design of a 5-stage pipelined RISC processor in Verilog. It involves: 1) Drawing the architecture diagram and creating behavioral models for each block. 2) Building the top-level structural model by instantiating the blocks. 3) Writing a testbench to initialize the instruction memory and registers and verify functionality.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
300 views14 pages

Assignment3 2021HT80531

The document describes the design of a 5-stage pipelined RISC processor in Verilog. It involves: 1) Drawing the architecture diagram and creating behavioral models for each block. 2) Building the top-level structural model by instantiating the blocks. 3) Writing a testbench to initialize the instruction memory and registers and verify functionality.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

VLSI ARCHITECTURE (MELZG642)

Assignment-3

PAVANSAI C
2021HT80531
Problem Statement:
STATEMENT: Given that the sequence of instructions to be executed by the processor is guaranteed to be free
from pipeline hazards, Design a 5 – stage (Instruction Fetch; Decode, Read operand; Execute; Write back)
pipelined RISC processor that can execute following register– to – register instructions with a throughput of
one instruction per clock cycle.

STEP 0: Draw the detailed architecture level diagram of the processor, naming and depicting the various
architectural blocks (e.g. register file, instruction memory, ALU, pipeline registers, PC and combinational
functional blocks etc).

STEP 1: Create Verilog/ VHDL behavioral models for each of the architectural blocks. (Register file, Instruction
memory, ALU, Pipeline registers, PC etc)

STEP 2: Build the top level structural model of the processor by instantiating and interconnecting the
architectural blocks created in step 1 and write test bench to verify the functionality.

STEP 3: Initialize the instruction memory with a program consisting of 4 instructions:

0000 MUL reg3, reg2, reg1


0004 SHIFT reg6, reg5, reg4
0008 XOR reg9, reg8, reg7
0012 NOR reg 13, reg11, reg10

Initialize the register file with the following data


reg2 = 60 reg1 = 40
reg5 = 40 reg4 = 60
reg7=FFFF856D reg8 = EEEE3721
reg10 = 1FFF756F reg11 = FFFF765E

Initialize PC with 0000 address.

Opcode
MUL 0 --------------- 001
SHIFT 0 --------------- 010
XOR 0 ------------------ 011
NOR 0 -------------- 100

The register file has 32 number of 32 bit registers. The data in registers is stored as unsigned integers. Assume
that register file has two 32-bit read ports: A and B for data reading and one 32 bit write port: C for data
writing. At the rising edge of the clock the read ports A and B output the data from the registers whose
addresses are present at port A address and port B address respectively if the enable read port A and enable
read port B signals are true. At the falling edge of a clock, data is written to the register whose address is
present at Port C address if write enable Port C is true. Design the pipeline registers such that they are latched
at the rising edge of the clock. Specify the size and format of all pipeline registers including the fields holding
the decoded control signals as well as data.
The instruction memory is of size 128 bytes. A read operation from the memory outputs 4 consecutive bytes of
information (starting from the byte address provided to the memory) at the positive edge of clock if the read
enable instruction memory signal is true. Byte addresses must be aligned and to be provided to memory must
be either 0 or multiples of 4.
Architecture Diagram

Verilog Design Code:

module program_counter (

input clk,

input reset,

output reg [6:0] out

);

parameter [7:0] COUNT_LIMIT = 12;

parameter [7:0] COUNT_STEP = 4;

always @ (posedge clk) begin

if (reset)

out <= 7'd0;

else if (out >= COUNT_LIMIT)


out <= 7'd0;

else

out <= out + COUNT_STEP;

end

endmodule

module instruction_mem (

input clk, reset,

input [6:0] addr,

input re,

output reg [31:0] instruction

);

localparam [7:0] INIT_MEMORY [0:127] = '{

8'h01, 8'h03, 8'h02, 8'h01, 8'h02, 8'h06, 8'h05, 8'h04,

8'h03, 8'h09, 8'h08, 8'h07, 8'h04, 8'hd, 8'hb, 8'ha,

8'h01, 8'h03, 8'h02, 8'h01, 8'h02, 8'h06, 8'h05, 8'h04,

8'h03, 8'h09, 8'h08, 8'h07, 8'h04, 8'hd, 8'hb, 8'ha,

8'h01, 8'h03, 8'h02, 8'h01, 8'h02, 8'h06, 8'h05, 8'h04,

8'h03, 8'h09, 8'h08, 8'h07, 8'h04, 8'hd, 8'hb, 8'ha,

8'h01, 8'h03, 8'h02, 8'h01, 8'h02, 8'h06, 8'h05, 8'h04,

8'h03, 8'h09, 8'h08, 8'h07, 8'h04, 8'hd, 8'hb, 8'ha,

8'h01, 8'h03, 8'h02, 8'h01, 8'h02, 8'h06, 8'h05, 8'h04,

8'h03, 8'h09, 8'h08, 8'h07, 8'h04, 8'hd, 8'hb, 8'ha,

8'h01, 8'h03, 8'h02, 8'h01, 8'h02, 8'h06, 8'h05, 8'h04,

8'h03, 8'h09, 8'h08, 8'h07, 8'h04, 8'hd, 8'hb, 8'ha,

8'h01, 8'h03, 8'h02, 8'h01, 8'h02, 8'h06, 8'h05, 8'h04,

8'h03, 8'h09, 8'h08, 8'h07, 8'h04, 8'hd, 8'hb, 8'ha,

8'h01, 8'h03, 8'h02, 8'h01, 8'h02, 8'h06, 8'h05, 8'h04,

8'h03, 8'h09, 8'h08, 8'h07, 8'h04, 8'hd, 8'hb, 8'ha

};

reg [7:0] memory [0:127];


always @ (posedge clk) begin

if (reset) begin

for (int i = 0; i < 128; i = i + 1) begin

memory[i] <= INIT_MEMORY[i];

end

instruction <= '0;

end else if (re)

instruction <= {9'b0,memory[addr], memory[addr +1][4:0],memory[addr


+2][4:0],memory[addr +3][4:0]};

end

endmodule

module decode (

input clk, reset,

input [31:0] instruction,

output reg [4:0] reg1, reg2, reg3,

output reg [3:0] opcode

);

always @ (posedge clk) begin

if (reset) begin

reg1 <= '0;

reg2 <= '0;

reg3 <= '0;

opcode <= '0;

end else begin

{opcode, reg3, reg1, reg2} <= instruction[18:0];

end

end

endmodule

module register_file (

input clk, reset, ra_en, rb_en,


input [4:0] ra,

input [4:0] rb,

input [4:0] wc,

input [31:0] wd,

input we,

output reg [31:0] rd_a,

output reg [31:0] rd_b

);

localparam [31:0] INIT_REGISTERS [0:31] = '{

32'h0, 40, 60, 32'h0, 60, 40, 32'h0, 32'hFFFF856D,

32'hEEEE3721, 32'h0, 32'h1FFF756F, 32'hFFFF765E,

32'h0, 40, 60, 32'h0, 60, 40, 32'h0, 32'hFFFF856D,

32'hEEEE3721, 32'h0, 32'h1FFF756F, 32'hFFFF765E,

32'h0, 40, 60, 32'h0, 60, 40, 32'h0, 32'hFFFF856D};

reg [31:0] registers[31:0];

always @ (posedge clk) begin

if (reset) begin

for (int i = 0; i < 32; i = i + 1) begin

registers[i] <= INIT_REGISTERS[i];

end

rd_a <= '0;

rd_b <= '0;

end else begin

if (ra_en)

rd_a <= registers[ra];

if (rb_en)

rd_b <= registers[rb];

end

end

always @ (negedge clk ) begin

if (we)
registers[wc] <= wd;

end

endmodule

module alu (

input [31:0] a,

input [31:0] b,

input [3:0] op,

output reg [31:0] y

);

function [31:0] alu_op;

input [31:0] a;

input [31:0] b;

input [3:0] op;

begin

case (op)

4'h1: alu_op = a * b;

4'h2: alu_op = b >> a;

4'h3: alu_op = a ^ b;

4'h4: alu_op = ~(a | b);

default: alu_op = 32'h00000000;

endcase

end

endfunction

always @ (*) begin

y = alu_op(a, b, op);

end

endmodule
module pipeline #(

parameter WIDTH = 32

input clk,

input reset,

input [WIDTH-1:0] in,

output reg [WIDTH-1:0] out

);

always @ (posedge clk) begin

if (reset)

out <= {WIDTH{1'b0}};

else

out <= in;

end

endmodule

module risc_proc (

input clk, reset, im_re, rf_ra_en, rf_rb_en, rf_we,

output [7:0] o_pc,

output [31:0] o_im, o_rf_r1, o_rf_r2, o_alu,

output [4:0] o_dec_reg1, o_dec_reg2, o_dec_reg3,

output [3:0] o_dec_op

);

logic [6:0] pc_out;

logic [31:0] im_out, reg1_val, reg2_val, alu_out, alu_out_p1;

logic [4:0] reg1, reg2, reg3, reg3_p2, reg3_p1;

logic [3:0] opcode, opcode_p1;


program_counter pc_0 (.clk(clk), .reset(reset), .out(pc_out));

instruction_mem imem_0 (.clk(clk), .reset(reset), .addr(pc_out),


.re(im_re), .instruction(im_out));

decode dec_0 (.clk(clk), .reset(reset), .instruction(im_out), .reg1(reg1),


.reg2(reg2), .reg3(reg3), .opcode(opcode));

register_file reg_f0 (.clk(clk), .reset(reset), .ra_en(rf_ra_en),


.rb_en(rf_rb_en), .ra(reg1), .rb(reg2), .we(rf_we), .wc(reg3_p2),
.wd(alu_out_p1), .rd_a(reg1_val), .rd_b(reg2_val));

alu alu_0 (.a(reg1_val), .b(reg2_val), .op(opcode_p1), .y(alu_out));

pipeline #(.WIDTH(4)) dec_p1 (.clk(clk), .reset(reset), .in(opcode),


.out(opcode_p1));

pipeline #(.WIDTH(5)) dec_p2 (.clk(clk), .reset(reset), .in(reg3),


.out(reg3_p1));

pipeline #(.WIDTH(5)) dec_p3 (.clk(clk), .reset(reset), .in(reg3_p1),


.out(reg3_p2));

pipeline #(.WIDTH(32)) alu1 (.clk(clk), .reset(reset), .in(alu_out),


.out(alu_out_p1));

assign o_pc = pc_out;

assign o_im = im_out;

assign o_dec_reg1 = reg1;

assign o_dec_reg2 = reg2;

assign o_dec_reg3 = reg3;

assign o_dec_op = opcode;

assign o_rf_r1 = reg1_val;

assign o_rf_r2 = reg2_val;

assign o_alu = alu_out_p1;

endmodule
Verilog Testbench Code:
module top_tb;

logic clk_ipt;

logic rst_ipt;

logic im_re_ipt, rf_rd_a_ipt, rf_rd_b_ipt, rf_we_ipt;

logic [7:0] opt_pc;

logic [31:0] opt_im, opt_rf_r1, opt_rf_r2, opt_alu,risc_opt;

logic [4:0] o_dec_reg1, o_dec_reg2, o_dec_reg3;

logic [3:0] o_dec_op,opcode;

bit Test_Pass =1;

// DUT

risc_proc dut_instance (

.clk(clk_ipt),

.reset(rst_ipt),

.im_re(im_re_ipt),

.rf_ra_en(rf_rd_a_ipt),

.rf_rb_en(rf_rd_b_ipt),

.rf_we(rf_we_ipt),

.o_pc(opt_pc),

.o_im(opt_im),

.o_dec_reg1(o_dec_reg1),

.o_dec_reg2(o_dec_reg2),

.o_dec_reg3(o_dec_reg3),

.o_dec_op(o_dec_op),

.o_rf_r1(opt_rf_r1),

.o_rf_r2(opt_rf_r2),

.o_alu(opt_alu));

// Clock

initial

begin
clk_ipt = 1'b0;

forever #10 clk_ipt = ~clk_ipt; // 20ns clock period

end

initial

begin

$dumpfile("dump.vcd");

$dumpvars();

end

// Reset generator

initial begin

rst_ipt = 1; // reset high

#20; // delay 20ns

rst_ipt = 0; // reset low

im_re_ipt =1;

rf_rd_a_ipt=1;

rf_rd_b_ipt=1;

rf_we_ipt=1;

#1000ns $finish;

end

assign opcode = dut_instance.alu_0.op;

// Monitor

always @(posedge clk_ipt) begin

case(opcode)

4'h1: risc_opt = opt_rf_r1 * opt_rf_r2;

4'h2: risc_opt = opt_rf_r2 >> opt_rf_r1;

4'h3: risc_opt = opt_rf_r1 ^ opt_rf_r2;

4'h4: risc_opt = ~(opt_rf_r1| opt_rf_r2);

endcase

end
always @(negedge clk_ipt) begin

if(risc_opt != opt_alu) begin

Test_Pass=0;

end

else begin

case(opcode)

4'h1: $display("MULTIPLICATION COMPARE PASSED");

4'h2: $display("SHIFT COMPARE PASSED");

4'h3: $display("XOR COMPARE PASSED");

4'h4: $display("NOR COMPARE PASSED");

endcase

end

end

final begin

if(Test_Pass == 1)

$display("TEST PASSED");//Test passed

else

$display("TEST FAILED");

end

endmodule
Simulation Output:

Log file Output:


[2023-04-30 09:53:36 EDT] xrun -Q -unbuffered '-timescale' '1ns/1ns' '-sysv' '-
access' '+rw' design.sv testbench.sv
TOOL: xrun 20.09-s003: Started on Apr 30, 2023 at 09:53:37 EDT
xrun: 20.09-s003: (c) Copyright 1995-2020 Cadence Design Systems, Inc.
Top level design units:
top_tb
xmelab: *W,DSEMEL: This SystemVerilog design will be simulated as per IEEE 1800-
2009 SystemVerilog simulation semantics. Use -disable_sem2009 option for turning
off SV 2009 simulation semantics.
Loading snapshot worklib.top_tb:sv .................... Done
xmsim: *W,DSEM2009: This SystemVerilog design is simulated as per IEEE 1800-2009
SystemVerilog simulation semantics. Use -disable_sem2009 option for turning off SV
2009 simulation semantics.
xcelium> source /xcelium20.09/tools/xcelium/files/xmsimrc
xcelium> run
MULTIPLICATION COMPARE PASSED
SHIFT COMPARE PASSED
XOR COMPARE PASSED
NOR COMPARE PASSED
MULTIPLICATION COMPARE PASSED
SHIFT COMPARE PASSED
XOR COMPARE PASSED
NOR COMPARE PASSED
MULTIPLICATION COMPARE PASSED
SHIFT COMPARE PASSED
XOR COMPARE PASSED
NOR COMPARE PASSED
MULTIPLICATION COMPARE PASSED
SHIFT COMPARE PASSED
XOR COMPARE PASSED
NOR COMPARE PASSED
MULTIPLICATION COMPARE PASSED
SHIFT COMPARE PASSED
XOR COMPARE PASSED
NOR COMPARE PASSED
MULTIPLICATION COMPARE PASSED
SHIFT COMPARE PASSED
XOR COMPARE PASSED
NOR COMPARE PASSED
MULTIPLICATION COMPARE PASSED
SHIFT COMPARE PASSED
XOR COMPARE PASSED
NOR COMPARE PASSED
MULTIPLICATION COMPARE PASSED
SHIFT COMPARE PASSED
XOR COMPARE PASSED
NOR COMPARE PASSED
MULTIPLICATION COMPARE PASSED
SHIFT COMPARE PASSED
XOR COMPARE PASSED
NOR COMPARE PASSED
MULTIPLICATION COMPARE PASSED
SHIFT COMPARE PASSED
XOR COMPARE PASSED
NOR COMPARE PASSED
MULTIPLICATION COMPARE PASSED
SHIFT COMPARE PASSED
XOR COMPARE PASSED
NOR COMPARE PASSED
MULTIPLICATION COMPARE PASSED
SHIFT COMPARE PASSED
XOR COMPARE PASSED
TEST PASSED
Simulation complete via $finish(1) at time 1020 NS + 0
./testbench.sv:57 #1000ns $finish;
xcelium> exit
TOOL: xrun 20.09-s003: Exiting on Apr 30, 2023 at 09:53:38 EDT (total:
00:00:01)
Finding VCD file...
./dump.vcd
[2023-04-30 09:53:38 EDT] Opening EPWave...
Done

Conclusion:
5 – stage (Instruction Fetch; Decode; Read operand; Execute; Write back)
pipelined RISC processor that can execute register– to – register instructions
with a throughput of one instruction per clock cycle is designed, simulated and
verified.

You might also like