Monday, December 1, 2008

mips single cycle processor

/*
This code is for 4 bit I/O. convert it to 32 I/O.
*/
module add (out,a,b);
output [31:0] out;
input [31:0] a,b;

assign out=a+b;
endmodule


/*
This code is for 4 bit I/O. convert it to 32 I/O.
*/

module add_4 (out , in);
output [31:0] out;
input [31:0] in;

assign out= in + 4;
endmodule

module ALU ( OUT , ALU_zero , A , B , ALU_Control );

output [31:0] OUT ;
output ALU_zero ;
input [31:0] A , B;
input [2:0] ALU_Control ;

reg [31:0] OUT;

assign ALU_zero = ~ ( | OUT ) ; // ALU_zero = 1 when OUT =0 ;

wire [31:0] DIFF = A - B ;

always @ ( A or B or ALU_Control or DIFF)

case(ALU_Control)

3'b000 : OUT = A & B ;
3'b001 : OUT = A | B ;
3'b010 : OUT = A + B ;
3'b110 : OUT = DIFF ;
3'b111 : OUT = { {31{1'b0}} , DIFF[31] } ; // OUT =00...001 when A < B
///3'b111 for slt instruction // DIFF[31] =1 when A < B
default : OUT = 32'hxxxxxxxx ;
endcase

endmodule


module ALU_Control(Operation, F, ALUop);
output [2:0] Operation;
input [5:0] F;
input [1:0] ALUop;

assign Operation[2] = (F[1] & ALUop[1]) | (ALUop[0]);

assign Operation[1] = (~ALUop[1]) | (~F[2]);

assign Operation[0] = (F[3] | F[0]) & (ALUop[1]);



// use always block or assign statements
// only 3 statements are required



endmodule


module Control ( RegDST ,
Branch ,
MemRead ,
MemtoReg ,
ALUOP ,
MemWrite ,
ALUSrc ,
RegWrite ,

op );

output RegDST,ALUSrc,MemtoReg,RegWrite,MemRead,MemWrite,Branch;
output[1:0] ALUOP;
input [5:0] op ;

wire r_format,lw,sw,beq,addi;

assign r_format =(~op[5] ) & (~op[4] ) & (~op[3] ) & (~op[2] ) & (~op[1]) &(~op[0] ) ;
assign lw =(op[5] ) & (~op[4] ) & (~op[3] ) & (~op[2] ) & (op[1] ) &(op[0] ) ;
assign sw =(op[5] ) & (~op[4] ) & (op[3] ) & (~op[2] ) & (op[1]) &(op[0] ) ;
assign beq =(~op[5] ) & (~op[4] ) & (~op[3] ) & (op[2] ) & (~op[1]) &(~op[0] ) ;
assign addi =(~op[5] ) & (~op[4] ) & (op[3] ) & (~op[2] ) & (~op[1]) &(~op[0] ) ;
assign RegDST=r_format,
ALUSrc= (lw)|(sw)|(addi),
MemtoReg=lw,
RegWrite=r_format|lw|addi,
MemRead= lw ,
MemWrite=sw ,
Branch=beq;

assign ALUOP[1]=r_format;
assign ALUOP[0]=beq ;



endmodule


/*
This code is for 4*4 data_memory. convert it to 16*32 data_memory.
*/
module data_memory ( data_out , address,data_in ,wr,clk ) ;
output [31:0] data_out;
input [31:0] data_in;
input [3:0] address;
input wr,clk;

reg [31:0] data_mem [15:0];

assign data_out=data_mem[address];

always @ (posedge clk )
if (wr==1)
data_mem[address]=data_in;

endmodule


/*
This code is for 4*4 instruction_memory. convert it to 16*32 instruction_memory.
*/

module instruction_memory ( data_out , address) ;
output [31:0] data_out ;
reg [31:0] data_out ;

input [3:0] address ;
wire [3:0] address ;

//}} End of automatically maintained section
always@( address )
case(address)
0: data_out=32'h20010004;
1: data_out=32'h20020008;
2: data_out=32'h00411820;
3: data_out=32'h00622022;
4: data_out=32'h0083282a;
5: data_out=32'hac020004;
6: data_out=32'h8c020004;
7: data_out=32'h00000000;
8: data_out=32'h00000000;
9: data_out=32'h00000000;
10: data_out=32'h00000000;
11: data_out=32'h00000000;
12: data_out=32'h00000000;
13: data_out=32'h00000000;
14: data_out=32'h00000000;
15: data_out=32'h00000000;
endcase
endmodule


module mux_5to1(out, a,b,sel);
output [4:0] out;
input [4:0] a,b;
input sel;
reg [4:0] out;
always @ (sel or a or b)
if(sel==0)
out = a;
else
out = b;
endmodule


/*
This code is for 4 bit instruction lines. convert them to 32 bit instruction lines.
*/
module mux_32to1(out, a,b,sel);
output [31:0] out;
input [31:0] a,b;
input sel;
reg [31:0] out;
always @ (sel or a or b)
if(sel==0)
out = a;
else
out = b;
endmodule


/*
This code is for 4 bit I/O. convert it to 32 I/O.
*/

module pc (out , in ,clk, rst);
output [31:0] out;
input [31:0] in;
input clk,rst;
reg [31:0]out;
always @ (posedge clk or posedge rst)
if(rst==1)
out = 0;
else
out = in;
endmodule


This code is for 4*4 register file. convert it to 32*32 register file.
*/
module register_file (data_out1,data_out2,data_in,wr,wr_enable,rd1,rd2,clk,rst);
output [31:0] data_out1,data_out2;
input [31:0] data_in;
input [4:0] wr,rd1,rd2;
input wr_enable,clk,rst;
reg [31:0] registers [31:0];

wire [31:0] R0 = registers[0],
R1 = registers[1],
R2 = registers[2],
R3 = registers[3],
R4 = registers[4],
R5 = registers[5],
R6 = registers[6];

assign data_out1=registers[rd1];
assign data_out2=registers[rd2];
integer i;
always@(posedge clk or posedge rst)
if(rst==1) begin for(i=0;i<=31;i=i+1) registers[i]<=0;end
else if (wr_enable==1)
registers[wr]<=data_in;

initial begin
registers[0] = 0;
registers[1] = 4;
registers[2] = 8;
registers[3] = 2;
end

endmodule


This code is for 16 bit I/O. convert it to 32 bit I/O.
*/

module shift_left2( out , in) ;
output [31:0] out;
input [31:0] in;

assign out=in << 2;
endmodule


module Sign_Ext (out , in );

output [31:0] out;
input [15:0] in;

assign out = { {16{in[15]}} , in[15:0] };

endmodule



module single_cycle_microprocessor (processor_out , clk , rst );

output [31:0] processor_out;
input clk , rst;

wire [31:0] pc_out,add4_out,instruction;
wire [3:0] frm_pc;
wire [5:0] opcode;
wire [4:0] Rs , Rt , Rd , mux1_out;
wire [15:0] Imm;
wire [5:0] FC;
wire [1:0] ALUOP;
wire [31:0] regA_out,regB_out,mux2_out;
wire [2:0] Operation;
wire [31:0] sign_out,sh_left_out,add_out,mux3_out ;
wire [31:0] ALU_OUT,data_out,mux4_out;
wire [3:0] ALU_Out_Adress;
wire PCSrc;
wire Branch , ALU_zero;


assign frm_pc = pc_out[5:2];
assign Rs = instruction[25:21];
assign Rt = instruction[20:16];
assign Rd = instruction[15:11];
assign opcode = instruction[31:26];
assign Imm = instruction[15:0];
assign FC = Imm[5:0];
assign ALU_Out_Adress = ALU_OUT[5:2];
assign PCSrc = Branch & ALU_zero;
assign processor_out=mux4_out;

pc PC(.out(pc_out) , .in(mux3_out) ,.clk(clk), .rst(rst));

add_4 ADD_4(.out(add4_out) , .in(pc_out));

instruction_memory INST_MEM ( .data_out(instruction) , .address(frm_pc)) ;

mux_5to1 MUX_1(.out(mux1_out),.a(Rt),.b(Rd),.sel(RegDST));

Control CONTROL(.RegDST(RegDST) , .Branch(Branch) , .MemRead(MemRead) , .MemtoReg(MemtoReg) ,.ALUOP(ALUOP) ,.MemWrite(MemWrite) ,.ALUSrc(ALUSrc) ,.RegWrite(RegWrite) ,.op(opcode) );

register_file REGISTER(.data_out1(regA_out),.data_out2(regB_out),.data_in(mux4_out),.wr(mux1_out),.wr_enable(RegWrite),.rd1(Rs),.rd2(Rt),.clk(clk),.rst(rst));

Sign_Ext SIGN_EXT(.out (sign_out) , .in(Imm) );

mux_32to1 MUX_2(.out(mux2_out),.a(regB_out),.b(sign_out),.sel(ALUSrc));

ALU_Control ALU_CONTROL(.Operation(Operation), .F(FC), .ALUop(ALUOP));

ALU ALU_32bit( .OUT(ALU_OUT) ,.ALU_zero( ALU_zero) , .A(regA_out),.B(mux2_out) , .ALU_Control(Operation) );

shift_left2 Shift_Left_2(.out(sh_left_out) , .in(sign_out)) ;

add ADD_32bit(.out(add_out),.a(add4_out),.b(sh_left_out));

mux_32to1 MUX_3(.out(mux3_out), .a(add4_out),.b(add_out),.sel(PCSrc));

data_memory DATA_MEM(.data_out( data_out) ,.address( ALU_Out_Adress) ,.data_in(regB_out) ,.wr(MemWrite),.clk(clk) ) ;

mux_32to1 MUX_4(.out(mux4_out),.a(ALU_OUT),.b(data_out),.sel(MemtoReg));


endmodule

No comments: