Verilog Code for 16bit RISC Processor

16BIT RISC PROCESSOR

Hola Amigos
I have designed a 16bit RISC processor designed with Xilinx iSim ans iSim simulator. RISC stands for Reduced Instruction Set Computer which is small microprocessor designed to favour small tasks and compute instructions with less time for the execution process. 
Common RISC processors that you would see around are ARM, MIPS, IBM Pc. 

Why was RISC introduced ?
As compared with CISC (Complex Instruction Set Computer) which takes a complex time to execute the instructions was reducing the performance of computing where the speed was drowning when CPU contacts the data memory. Hence another alternative was set in motion and that was RISC architecture.

Coming down to my 16bit processor.
ALU  Code-
**************************************************************************************

module ALU(ain,bin,func,result,z);
input [7:0]ain;
input [7:0]bin;
output reg[7:0]result;
reg carry,temp=0;
input [3:0]func;
output reg z;
//wire [7:0]result;
//assign n = result[7];
always @(ain or bin)begin
if(func==4’b0000)begin
{temp,result} = ain + bin;
carry = temp;
if(result==0)
z=1;
end
else if(func==4’b0001)begin
{temp,result} = ain – bin;
carry = temp;
if(result==0)
z=1;
end
else if(func==4’b0010)begin
{temp,result} = ain + 1;
carry = temp;
if(result==0)
z=1;
end
else if(func==4’b0011)begin
{temp,result} = ain – 1;
carry = temp;
if(result==0)
z=1;
end
else if(func==4’b0100)begin
result = ain | bin;
carry = 0;
if(result==0)
z=1;end //OR
else if(func==4’b0101)begin 
result = ain & bin;
carry = 0;
if(result==0)
z=1;end //AND
else if(func==4’b0110)begin 
result = ain^bin;
carry = 0;
if(result==0)
z=1;end //XOR
else if(func==4’b0111)begin 
result[0] = ~(ain[0]&bin[0]);
result[1] = ~(ain[1]&bin[1]);
result[2] = ~(ain[2]&bin[2]);
result[3] = ~(ain[3]&bin[3]);
result[4] = ~(ain[4]&bin[4]);
result[5] = ~(ain[5]&bin[5]);
result[6] = ~(ain[6]&bin[6]);
result[7] = ~(ain[7]&bin[7]);
carry = 0;
if(result==0)
z=1;end //NAND
else if(func==4’b1000)begin 
result[0] = ~ain[0];
result[1] = ~ain[1];
result[2] = ~ain[2];
result[3] = ~ain[3];
result[4] = ~ain[4];
result[5] = ~ain[5];
result[6] = ~ain[6];
result[7] = ~ain[7];
carry = 0;
if(result==0)
z=1;end //NOT
else begin 
result = 4’bxxxx;
carry = 0;
end //Default
if(result==0)
z = 1’b1;
else
z = 0;
end

endmodule

Instruction Memory
**************************************************************************************
module instruction(address,clk,opcode,jump,jiz,addA,addB,write_add,iformat,im_select);
input [15:0]address;
input clk,im_select;
output reg[3:0]opcode;
output reg[11:0] jump;
output reg[7:0] jiz;
output reg[3:0] addA;
output reg[3:0] addB;
output reg[3:0] write_add;
output reg[3:0] iformat;
reg [3:0]dest;
reg [15:0]instruction;
reg [15:0] imem[0:15];
initial begin
imem[2]<=16'b0000_0000_0000_0101; 
imem[1]<=16'b0001_0010_0011_0011; 
imem[3]<=16'b0010_0100_0010_0011;
imem[0]<=16'b0010_0000_0000_0101;
imem[4]<=16'b0010_0111_0010_0011;
imem[5]<=16'b0011_0010_0011_0010;
imem[6]<=16'b0110_0001_0001_0011;
imem[7]<=16'b0001_0110_0001_0011;
imem[8]<=16'b0110_0001_0011_0001; 
end
always @(im_select)begin
if(im_select==1)begin
dest=write_add;
instruction = imem[address];
opcode = instruction[15:12];
jump = instruction[11:0];
jiz = instruction[7:0];
addA = instruction[11:8];
addB = instruction[7:4];
write_add = instruction[3:0];
iformat = instruction[3:0];
end
end

endmodule

Register File
**************************************************************************************
module Register(reg_wrt,readA,clk,readB,dest,data,readA_out,readB_out);
input reg_wrt;
input [3:0]readA,readB,dest;
input [7:0]data;
input clk;
reg [7:0] Register [0:15];
initial begin
Register[0]=0;//R0 alwayscontains zero
Register[1]=2;  //Random values stored
Register[2]=4;
Register[3]=6;
Register[4]=8;
Register[5]=10; // You can change any value within this initial block
Register[6]=12;
Register[7]=14;
end
output reg [7:0]readA_out,readB_out;
always @(posedge clk)begin
readA_out <= Register[readA];
readB_out <= Register[readB];
if(reg_wrt==1)
Register[dest]=data;
end

endmodule

RAM (Datamemory) 
**************************************************************************************
module RAM(address,clk,data_in,data_out,re,wr);
input [7:0]address;
input [7:0]data_in;
input clk,re,wr;
output [7:0]data_out;
reg[7:0] mem [0:30];
reg[7:0] data;
assign data_out = data;
initial
mem[16]=25;
always @(posedge clk)begin
if(wr)begin
mem[address] = data_in;
end
end
always @(address or re)begin
if(re)begin
data = mem[address];
end
end

endmodule

Program Counter
**************************************************************************************
module PC(in,clk,out,pc_sel,reset);
input [15:0]in;
input clk,reset,pc_sel;
output reg[15:0]out;
initial 
out = 0;
always @(posedge clk)begin
if(reset==1)
out <= 16'bx;
else if(pc_sel==1 && in<50)
out <= in+1;
else if(pc_sel==0)
out <= in;
end

endmodule


Multiplexers
**************************************************************************************

module Mux1(a,b,sel,c);

input [3:0] a,b;

input sel;

output reg [3:0]c;

always @(*)begin

if(sel==0)

c = a;

else

c = b;

end

endmodule


module Mux2(a,b,sel,c);
input [7:0] a,b;
input [1:0]sel;
output reg [7:0]c;
always @(*)begin
if(sel==2’b0)
c = a;
else if(sel==2’b01)
c = b;
else if(sel==2’b10)
c = 8’b0;
end
endmodule
module Mux3(a,b,sel,c);
input [15:0] a,b;
input sel;
output reg [15:0]c;
always @(*)begin
if(sel==0)
c = a;
else
c = b;
end
endmodule
Sign Extend
**************************************************************************************
module sign(a,b);
input [3:0]a;
output reg[7:0]b;
always @(a or b)begin
if(a[3]==1)
b = {4’b1111,a};
else
b = {4’b0000,a};
end
endmodule
Latch
**************************************************************************************
module lat(in,out,clk);
input [7:0] in;
input clk;
output reg[7:0] out;
reg [7:0]memdataout;
always @ (posedge clk)
out=in;
endmodule

Datapath
**************************************************************************************
module datapath(alu_op,opcode,clk,carry,sel1,sel2,sel3,sel5,sel6,re,wr,reg_wrt,reset,pc_sel,im_select,branch);
input clk;
output carry;
input [1:0]sel2;
input sel1,sel3,sel5,sel6,re,wr;
input reg_wrt;
input reset;
output [3:0]opcode;
input [3:0]alu_op;
input im_select;
input branch,pc_sel;
wire [7:0] shift;
wire [15:0] next_pc;
wire [15:0] next_alu_out,jump_add;
wire [11:0] jump;
and (sel4,branch,zero);
wire [15:0]op3,out;
wire [15:0]pc_out;
wire [3:0]iformat,addA,addB,write_add,out1;
wire [7:0]data_out;
wire [7:0]result;
wire [7:0]regData,aluMux;
wire [7:0] dataA,dataB,xtended,out2,latchout;
Mux2 alu(dataA,8’bx,sel5,aluMux);
PC programcounter(op3,clk,pc_out,pc_sel,reset);
instruction im(pc_out,clk,opcode,jump,addA,addB,write_add,iformat,pc_sel);
Mux1 multi1(addB,write_add,sel1,out1);
Register regfile(reg_wrt,addA,clk,addB,out1,regData,dataA,dataB);
sign xtend(iformat,xtended);
lat latch(xtended,latchout,clk);
Mux2 multi2(dataB,latchout,sel2,out2);
ALU alux(aluMux,out2,alu_op,result,zero);
RAM datamemory(result,clk,dataB,data_out,re,wr);
Mux2 multi3(result,data_out,sel3,regData);
//assign next_pc = pc_out+1’b1;
assign next_alu_out = latchout + pc_out;
assign jump_add = {pc_out[15:12],jump}; 
Mux3 multi4(pc_out,next_alu_out,sel4,out);
Mux3 multi5(jump_add,out,sel6,op3);
endmodule

Control Unit
**************************************************************************************
module control(alu_op,opcode,clk,carry,reset,reg_wrt,re,wr,Mux1,Mux2,Mux3,MuxAlu,Mux5,branch,pc_sel,im_select);
input clk,carry,reset;
input [3:0] opcode;
output reg[3:0]alu_op;
output reg reg_wrt,re,wr,Mux1,Mux3,MuxAlu,Mux5,branch,pc_sel,im_select;
output reg[1:0]Mux2;
reg [3:0]pstate,nstate;
parameter s0 = 4’b0000,s1 = 4’b0001, s2=4’b0010, s3=4’b0011, s4=4’b0100, s5=4’b0101, s6=4’b0110, s7=4’b0111, s11=4’b1000;
initial
pstate = s0;
always @(posedge clk)begin
case(pstate)
//*********************************************************************************************************************
s0:begin  //DO NOT MODIFY INSTRUCTION FETCH  //
reg_wrt<=1'b0;
re<=1'b0;
wr<=1'b0;
Mux1<=1'b0;
Mux2<=1'b1;
Mux3<=1'b0;
Mux3<=1'b1;
Mux5<=1'b1;
alu_op<=4'bxxxx;
MuxAlu<=1'b1;
branch<=1'b0;
pc_sel<=1'b1;
im_select<=1'b1;
pstate<=s1;
end
//*********************************************************************************************************************
s1:begin  // DO NOT MODIFY DECODE STAGE  //
case(opcode)
4’b0000:begin
alu_op<=4'b0;
reg_wrt<=1'b1;
re<=1'b0;
wr<=1'b0;
Mux1<=1'b1;
Mux2<=1'b0;
Mux3<=1'b0;
Mux5<=1'b1;
MuxAlu<=1'b0;
branch<=1'b0;
pc_sel<=1'b0;
im_select<=1'b1;
pstate<=s0;
end
//*********************************************************************************************************************
4’b0001:begin  /* DO NOT MODIFY R-FORMAT STARTS HERE */
alu_op<=4'b0001;
reg_wrt<=1'b1;
re<=1'b0;
wr<=1'b0;
Mux1<=1'b1;
Mux2<=2'b0;
Mux3<=1'b0;
Mux5<=1'b1;
MuxAlu<=1'b0;
branch<=1'b0;
pc_sel<=1'b0;
im_select<=1'b1;
pstate<=s0;
end
//*********************************************************************************************************************
4’b0010:begin
alu_op<=4'b0010;
reg_wrt<=1'b1;
re<=1'b0;
wr<=1'b0;
Mux1<=1'b1;
Mux2<=2'b0;
Mux3<=1'b0;
Mux5<=1'b1;
MuxAlu<=1'b0;
branch<=1'b0;
pc_sel<=1'b0;
im_select<=1'b1;
pstate<=s0;
end
//*********************************************************************************************************************
4’b0011:begin
alu_op<=4'b0011;
reg_wrt<=1'b1;
re<=1'b0;
wr<=1'b0;
Mux1<=1'b1;
Mux2<=2'b0;
Mux3<=1'b0;
Mux5<=1'b1;
MuxAlu<=1'b0;
branch<=1'b0;
pc_sel<=1'b0;
im_select<=1'b1;
pstate<=s0;
end
//*********************************************************************************************************************
4’b0100:begin
alu_op<=4'b0100;
reg_wrt<=1'b1;
re<=1'b0;
wr<=1'b0;
Mux1<=1'b1;
Mux2<=2'b0;
Mux3<=1'b0;
Mux5<=1'b1;
MuxAlu<=1'b0;
branch<=1'b0;
pc_sel<=1'b0;
im_select<=1'b1;
pstate<=s0;
end
//*********************************************************************************************************************
4’b0101:begin
alu_op<=4'b0101;
reg_wrt<=1'b1;
re<=1'b0;
wr<=1'b0;
Mux1<=1'b1;
Mux2<=2'b0;
Mux3<=1'b0;
Mux5<=1'b1;
MuxAlu<=1'b0;
branch<=1'b0;
pc_sel<=1'b0;
im_select<=1'b1;
pstate<=s0;
end
//*********************************************************************************************************************
4’b0110:begin
alu_op<=4'b0110;
reg_wrt<=1'b1;
re<=1'b0;
wr<=1'b0;
Mux1<=1'b1;
Mux2<=2'b0;
Mux3<=1'b0;
Mux5<=1'b1;
MuxAlu<=1'b0;
branch<=1'b0;
pc_sel<=1'b0;
im_select<=1'b1;
pstate<=s0;
end
//*********************************************************************************************************************
4’b0111:begin
alu_op<=4'b0111;
reg_wrt<=1'b1;
re<=1'b0;
wr<=1'b0;
Mux1<=1'b1;
Mux2<=2'b0;
Mux3<=1'b0;
Mux5<=1'b1;
MuxAlu<=1'b0;
branch<=1'b0;
pc_sel<=1'b0;
im_select<=1'b1;
pstate<=s0;
end
//*********************************************************************************************************************
4’b1000:begin
alu_op<=4'b1000;
reg_wrt<=1'b1;
re<=1'b0;
wr<=1'b0;
Mux1<=1'b1;
Mux2<=2'b0;
Mux3<=1'b0;
Mux5<=1'b1;
MuxAlu<=1'b0;
branch<=1'b0;
pc_sel<=1'b0;
im_select<=1'b0;
pstate<=s0;
end
//*********************************************************************************************************************
4’b1001:begin
alu_op<=4'b1001;
reg_wrt<=1'b1;
re<=1'b0;
wr<=1'b0;
Mux1<=1'b1;
Mux2<=2'b0;
Mux3<=1'b0;
Mux5<=1'b1;
MuxAlu<=1'b0;
branch<=1'b0;
pc_sel<=1'b0;
im_select<=1'b0;
pstate<=s0;
end
//*********************************************************************************************************************
4’b1010:begin
alu_op<=4'b1010;
reg_wrt<=1'b1;
re<=1'b0;
wr<=1'b0;
Mux1<=1'b1;
Mux2<=2'b0;
Mux3<=1'b0;
Mux5<=1'b1;
MuxAlu<=1'b0;
branch<=1'b0;
pc_sel<=1'b0;
im_select<=1'b0;
pstate<=s0;
end   /* DO NOT MODIFY R-FORMAT ENDS HERE */
//*********************************************************************************************************************
4’b1011:begin /*DO NOT MODIFY–I FORMAT STARTS HERE–LOAD*/
alu_op<=4'b0;
reg_wrt<=1'b1;
re<=1'b1;
wr<=1'b0;
Mux1<=1'b0;
Mux2<=2'b01;
Mux3<=1'b1;
Mux5<=1'b1;
MuxAlu<=1'b0;
branch<=1'b0;
pc_sel<=1'b0;
im_select<=1'b1;
pstate<=s0;
end
//********************************************************************************************************************
4’b1100:begin /*DO NOT MODIFY–I FORMAT–STORE*/
alu_op<=4'b0;
reg_wrt<=1'b0;
re<=1'b0;
wr<=1'b1;
Mux1<=1'b1;
Mux2<=2'b01;
Mux3<=1'b1;
Mux5<=1'b1;
MuxAlu<=1'b0;
branch<=1'b0;
pc_sel<=1'b0;
im_select<=1'b1;
pstate<=s0;
end   /* DO NOT MODIFY–I FORMAT ENDS HERE  */
//********************************************************************************************************************
4’b1101:begin /* DO NOT MODIFY — BEQ  */
alu_op<=4'b0001;
reg_wrt<=1'b0;
re<=1'b0;
wr<=1'b0;
Mux1<=1'b1;
Mux2<=2'b0;
Mux3<=1'b0;
Mux5<=1'b1;
MuxAlu<=1'b0;
branch<=1'b1;
pc_sel<=1'b0;
im_select<=1'b1;
pstate<=s0;
end   /* DO NOT MODIFY — BEQ */
//*******************************************************************************************************************
4’b1110:begin /* DO NOT MODIFY — JMP  */
alu_op<=4'b1110;
reg_wrt<=1'b0;
re<=1'b0;
wr<=1'b0;
Mux1<=1'b1;
Mux2<=2'b10;
Mux3<=1'b0;
Mux5<=1'b0;
MuxAlu<=1'b0;
branch<=1'b0;
pc_sel<=1'b0;
im_select<=1'b1;
pstate<=s0;
end   
endcase
end
s2:begin
reg_wrt<=1'b0;
re<=1'b0;
wr<=1'b0;
Mux1<=1'b0;
Mux2<=1'b0;
Mux3<=1'b0;
alu_op<=4'bxxxx;
MuxAlu<=1'b0;
branch<=1'b1;
pc_sel<=1'b0;
im_select<=1'b0;
pstate<=s0;
end
s3:begin
reg_wrt<=1'b1;
re<=1'bx;
wr<=1'b0;
Mux1<=1'b1;
Mux2<=1'b1;
Mux3<=1'b1;
alu_op<=4'bxxxx;
MuxAlu<=1'b0;
branch<=1'b0;
pc_sel<=1'b0;
im_select<=1'b0;
pstate<=s0;
end
endcase
end
endmodule

Risc Top Module
**************************************************************************************
module risc(clk,reset);
input clk,reset;
wire [3:0]opcode;
wire [3:0]alu_op;
wire [2:0] alu_sel;
wire [1:0] opb_sel,data_sel;
wire [15:0] outA;
wire carry,reset,reg_wrt,re,wr,Mux1,Mux2,Mux3,branch,im_wrt,sel1,sel2,sel3;
control control_path(alu_op,opcode,clk,carry,reset,reg_wrt,re,wr,sel1,sel2,sel3,sel5,sel6,branch,pc_sel,im_select);
datapath data_path(alu_op,opcode,clk,carry,sel1,sel2,sel3,sel5,sel6,re,wr,reg_wrt,reset,pc_sel,im_select,branch);

endmodule

Testbench
**************************************************************************************

`timescale 1ns / 1ps


////////////////////////////////////////////////////////////////////////////////

// Company: 

// Engineer:

//

// Create Date:   02:38:30 04/03/2017

// Design Name:   risc

// Module Name:   F:/Season 1/RiscPipeline/JIZ.v

// Project Name:  RiscPipeline

// Target Device:  

// Tool versions:  
// Description: 
//
// Verilog Test Fixture created by ISE for module: risc
//
// Dependencies:
// 
// Revision:
// Revision 0.01 – File Created
// Additional Comments:
// 
////////////////////////////////////////////////////////////////////////////////
module JIZ;
// Inputs
reg clk;
reg reset;
// Instantiate the Unit Under Test (UUT)
risc uut (
.clk(clk), 
.reset(reset)
);
initial begin
// Initialize Inputs
clk = 0;
reset = 0;
// Wait 100 ns for global reset to finish
#40$finish;
        
// Add stimulus here
end
always #1 clk = !clk;
      
endmodule
**************************************************************************************
For more details amigos you can also visit my page
Here is the Data Path of processor
However if you cannot find image in fine condition you can mail me at 
shashisuman17@aol.com. I will send highest quality Datapath
The schematic block diagram
Here is the processor in action
ISA as per my design- Can be modified too

15 GPRs in Register File
R0 always contains zero. Modify it as you want but not recommended.
Instructions are represented by 2 bytes.
LOAD and STORE moves data to and forth from register to RAM and vice versa

Cheers Guys- If you get in some trouble comment and if you have found some mistakes be kind to inform me. 🙂

Patch 1.0.0 released – Download
1. JIZ instruction has been added.
    Opcode 1111 if Register has content as zero then it will jump to the given address

If you face any problem with code reply immediately

So Long 🙂

Published by Shashi Suman

I am Shashi Suman. I am passionate about robots, 3D Printing, Verilog and automation. My current dream is make my own 3D printed intelligent robot.

43 thoughts on “Verilog Code for 16bit RISC Processor

  1. Yes I amBut I have excluded shift left 2 because it is required when we jump by 4 to next pc_address to remove last 2 zeros. But here we don't need it. I have modified and verified it.

    Like

  2. I used it and got A grade from my teacher however I am a bit confused. Why have you avoided alucontrol instead used opcode directly from control unit ?Are you goin to add more instructions ?:)

    Like

  3. hi,shashi sumanI use your all code to simulation,but it can't run wave , a lot of signaldisplay \”Z\” (Hign resistance) , Have your code wrong ? or imcomplete ?

    Like

  4. hi,shashi suman,I use your all code to simulation , but it can't run wave,a lot of signal display \”Z\”(high resistance) , have your code wrong? or incomplete ?

    Like

  5. Hello Tony, the code is complete, You must simulate the top level module, This will only show the wave of clk and reset, however other waves can be added using the navigation to all modules from the navigator at left side in Xilinx Simulator.

    Like

  6. If you are using Xilinx then in the simulation windows check the left paneIt will show all modules.All you have to do is add any port of the module to the wave window by dragging or right click and add.

    Like

  7. Regarding What kind of output should be there?Well you have to provide the right instruction and the program will do operation according to the opcode and it will be stored in the destination register whih you will have to drag in the window to see the stored value

    Like

  8. Hi Everyone, I have edited and cleaned the code. I will repost with single cycle code as well as pipelined code with complete explanation.Thanks for your patience with my blog.

    Like

Leave a comment

Design a site like this with WordPress.com
Get started