URL
https://opencores.org/ocsvn/processor/processor/trunk
Subversion Repositories processor
[/] [processor/] [web_uploads/] [Atlast.v] - Rev 6
Compare with Previous | Blame | View Log
module tests; reg clk,rst; wire processor_out; single_cycle_microprocessor s1(processor_out , clk , rst ); // Emulate the master clock oscillator always #5 clk = ~clk; // Emulate the power-on reset, and initialize the clock initial begin clk = 0; rst = 1; #10 rst = 0; end 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 /* 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 /* 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 /* 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 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 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 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