16BIT RISC PROCESSOR
Hola AmigosI 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 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 sel1,sel2,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,Mux2,Mux3,MuxAlu,Mux5,branch,pc_sel,im_select;
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 FileR0 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 :)
Can you share the ISA for above architecture?
ReplyDeleteAre you following MIPS?
Yes I am
DeleteBut 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.
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 ?
ReplyDeleteAre you goin to add more instructions ?
:)
Congo !!
DeleteWell alucontrol was somehow taking a clock cycle and was making my processor a delay with 1 CC.
Yes there are 2 more patches coming soon. :)