Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Help in verilog for MIPS design

Status
Not open for further replies.

Adnan86

Full Member level 2
Joined
Apr 4, 2013
Messages
121
Helped
26
Reputation
52
Reaction score
26
Trophy points
1,308
Activity points
2,153
Hi, I write below code for single cycle MIPS, base on chapter 7 of Harris book(Digital design ...).
I used ISE 14.7 for simulation.
I just want use data in memory and show result in simulation.
but after simulate it , all out put show unknown " X " in output.
i will appreciate if some one give me some help.
thanks
Code:
// ---- Adder

module adder( input [31:0] datain1, datain2,
              output[31:0] dataout);
				  
assign dataout = datain1 + datain2;

endmodule
//--------------------------------------

// ---- ALU

module alu (input   [31:0] srca, srcb,
            input   [2:0] alucontrol,
            output reg [31:0] aluresult,
            output reg zero );
            
   always @(alucontrol, srcb, srca)
     begin
        case (alucontrol)
          
            3'b010 :     //add
               begin 
                 aluresult = srca + srcb ;
                 zero = 0 ;
               end
            3'b000   :   //and
               begin
                 aluresult = srca & srcb ;
                 zero = 0 ; 
               end
            3'b001   :   //or
               begin
                 aluresult = srca | srcb ;
                 zero = 0 ;
               end
            3'b110  :   //subtract
               begin
                   aluresult = srca - srcb ;
                   if (aluresult == 0) 
                         zero = 1 ;
                   else  zero = 0 ;

              
               end
            3'b111   :   //slt
               begin
                   aluresult = srca - srcb ;
                   if ({aluresult[31]} == 1)
                      begin
                         aluresult = 1 ;
                         zero = 0 ;
                      end
                   else if (aluresult[31] == 0)
                   zero = 1 ;
                   else   
                      begin
                      zero = 0  ;
                      aluresult = 0 ;
                      end
               end
            default   :   zero = 0 ;
       endcase
    end
endmodule
// --------------------------------------

// ---- Alu Decoder of Control Unit

module aludecoder (input  [5:0] funct,
                   input  [1:0] aluop,
                   output reg [2:0] alucontrol);
 
always @(aluop, funct)
begin
    if(aluop == 2'b00)
    begin
        alucontrol <= 3'b010 ; //add
    end
    else if(aluop == 2'b01)
    begin
        alucontrol <= 3'b110 ; //substract
    end
    else if(aluop == 2'b10 || aluop == 2'b11)
    begin
        case (funct)
            6'b100000 : alucontrol <= 3'b010; //add
            6'b100010 : alucontrol <= 3'b110; //subtract
            6'b100100 : alucontrol <= 3'b000; //and
            6'b100101 : alucontrol <= 3'b001; //or
            6'b101010 : alucontrol <= 3'b111; //slt
            default   : alucontrol <= 3'b001; //default
        endcase
    end
end
endmodule
// --------------------------------------

// ---- Main Decoder of Control Unit
 
module maindecoder (input [5:0] opcode,
                    output [1:0] aluop,
                    output memtoreg, memwrite, branch,
                    output alusrc, regdst, regwrite);
   
   reg [7:0] maindec;
   assign {regwrite, regdst, alusrc, branch, memwrite, memtoreg,  
     aluop} = maindec ;
    
    always @(opcode)
       case (opcode)
           6'b000000 : maindec <= 8'b11000010 ; //R-type
           6'b100011 : maindec <= 8'b10100100 ; // lw
           6'b101011 : maindec <= 8'b00101000 ; // sw
           6'b000100 : maindec <= 8'b00010001 ; // beq
           default   : maindec <= 8'b00000000; //default
       endcase
endmodule
// ----------------------------------------

// ---- Control Unit with combination of Main Decoder and Alu Decoder

module   controlunit (input [5:0] opcode, funct,
                      input zero,
                      output [2:0] alucontrol,
                      output memtoreg, memwrite, pcsrc,
                      output alusrc, regdst, regwrite);
                      
    wire branch ;
    wire [1:0] aluop ;
   
    maindecoder memdec1 (opcode,aluop,memtoreg, memwrite, branch,
                     alusrc, regdst, regwrite);
    aludecoder aludec1 ( funct, aluop, alucontrol);
    
    assign pcsrc = branch & zero ;
    
endmodule 
// ----------------------------------------

// ---- Data Memory 

module datamem (input  clk, we,
                input  [31:0] a, wd,
                output reg [31:0] rd);
   //(* ram_init_file = "dmem1.mif" *)reg [31:0] dmem[63:0];
	reg [31:0] dmem[63:0];
	
		always @(we)

		begin

			if(we==0)
				rd <= dmem[a];
		end

   always @ (posedge clk)
       begin
			if (we)   
		
			dmem[a] <= wd;
      	end
      //assign  rd = dmem[a[31:0]];
		initial $readmemh ("dmem.dat", dmem);
	
endmodule
//-------------------------------------

// ---- PC counter  

module pc_counter (input clk, 
             	   input [31:0] in,
             	   output reg [31:0] out);
             
    always @ (posedge clk )
		begin
  		 out <= in ;
        end
endmodule
//---------------------------------------

// ---- Instrution Memory 

module instrmemory(input[31:0] a,
				   output reg [31:0] rd);

	//(* ram_init_file = "imem1.mif" *) reg[31:0] imem[63:0];
	reg[31:0] imem[63:0];

		always @ (a)
			begin

				rd <= imem[a];
			end
		initial $readmemh ("imem.dat", imem);
endmodule
//----------------------------------

//---- MUX

/*module mux (input [31:0]i0, i1,
			input s,
            output e);
            
    assign e = (s!=0) ? i1 : i0 ;
    
endmodule*/
//---- 5 bits
module mux_5 (i0, i1, s, e);
	input [4:0]i0;
	input [4:0]i1;
	input s;
	output [4:0]e;
	            
	assign e = (s!=0) ? i1 : i0 ;    
endmodule
//---- 32 bits
module mux_32 (i0, i1,s,e);
input [31:0]i0;
input [31:0]i1;
input s;
output [31:0]e;
            
    assign e = (s!=0) ? i1 : i0 ;
    
endmodule
//------------------------------

// ---- Register File 

module registerfile (input clk,
							input we3,
							input [4:0] ra1, ra2, wa3,
							input [31:0] wd3,
							output [31:0] rd1, rd2);
   //(* ram_init_file = "regfile1.mif" *) reg [31:0] rg[31:0];
	reg [31:0] rg[31:0];
	 
   always @ (posedge clk)
		begin
      		if (we3)
			   rg[wa3] <= wd3;
   	    end
  
      
   	  assign rd2=rg[ra2];
		assign rd1=rg[ra1];
		initial $readmemh ("rg.dat", rg);
 endmodule
//----------------------------

// ---- Shift to Left by 2 bit 

module shiftleft2 (input [31:0] a,
                   output [31:0] b);
                   
    assign b = {a[29:0],2'b00} ;
endmodule
//----------------------------

// ---- Sign Extend 

module signextend (input [15:0] x,
                   output [31:0] y);
                   
    assign y = {{16{x[15]}}, x } ;
    
endmodule
//-----------------------------

// ---- MIPS 

module MIPS (input  clk,   
             output [31:0] instr, result, srca, srcb, aluresult ,
			 output	[2:0] alucontrol); 
			
    wire   memtoreg, memwrite, branch, alusrc, 
           zero, pcsrc, regdst, regwrite ;
    wire  [4:0] writereg ;
    wire  [31:0] pcplus4, signimm, signimmshift2, writedata, pc, nextpc;
    wire  [31:0]   readdata, pcbranch ;
    
   // pc counter
   pc_counter   pc_counter1 ( clk, nextpc, pc);
   adder        addplus4 (pc , 32'd4, pcplus4);
   shiftleft2   signshift ( signimm, signimmshift2);
   adder        pcbranch1 (signimmshift2 , pcplus4, pcbranch);
   mux_32       mux1 ( pcplus4, pcbranch, pcsrc, nextpc);
   
   // instruction memory
   instrmemory  insmem(pc, instr);
   
   //register file
   registerfile regfile1 ( clk, regwrite,instr[25:21], instr[20:16],
                           writereg, result, srca, writedata);
   
   mux_5        mux2  ( instr[20:16], instr[15:11], regdst, writereg); 
   mux_32       mux3  ( aluresult, readdata, memtoreg, result);
   signextend   signext1 (instr[15:0], signimm);
   alu          alu1  (srca, srcb, alucontrol, aluresult, zero );
   mux_32       mux4  ( writedata, signimm, alusrc, srcb); 
   
   //control unit
   controlunit  ctrl1 (instr[31:26], instr[5:0], zero, alucontrol,
              			 memtoreg, memwrite, pcsrc, alusrc, regdst, regwrite);
   	
          
   //data memory
   datamem      dm1   (clk , memwrite, aluresult, writedata, readdata );

endmodule

- - - Updated - - -

imem, rg , dmem
its just have some number in hex.

- - - Updated - - -

and save them in project
 

This memory certainly isn't going to synthesized correctly, as asynchronous write enabled memories don't exist in an FPGA.

Code:
		always @(we)

		begin

			if(we==0)
				rd <= dmem[a];
		end

You should really use the templates that the vendors usually show you in their synthesis guides.

I also don't get why you've broken the design up into such tiny modules, e.g.
Code:
// ---- PC counter  

module pc_counter (input clk, 
             	   input [31:0] in,
             	   output reg [31:0] out);
             
    always @ (posedge clk )
		begin
  		 out <= in ;
        end
endmodule

Doing this is just plain silly.


About your problem with a simulation full of X's is probably due to the lack of any reset for all of your flip-flops in the design.
 
Hi again
my code work correctly in quartus, but because i want to see data change in my data_memory when some data wrote in data memory, i cant bring memory of data_memory to show it in simulation. I want use ISE 14.7, because see of all internal signal and memory.
any time i simulate it my output show X' , so i try use reset in some sub model.
but i have error , that ERROR:Xst:871 - "mips.v" line 20: Invalid use of input signal <rst> as target.
so i have new problem .
I will appreciat to give me any advice to solve it.
Code:
// -- --
// -- VHDL Course (Verilog)
// -- MIPS
module mips(rst, clk,aluresult,instr,scra,writedata,result,readdata,alucontrol);

         input wire clk;
			input rst;
         
         output[31:0] aluresult,instr,scra,writedata,result,readdata;
		 output[2:0] alucontrol;
         wire[31:0] pc1,pc,pc_pluse4,out_pcbranch;
         wire[31:0] result,signimm,scra,scrb,writedata,aluresult,readdata;
         wire[4:0] writereg;
         //wire[2:0] alucontrol;
         wire pcscr,branch,zero,memtoreg,memwrite,aluscr,regdst,regwrite;

assign pcscr=branch & zero;


insteruction_memory ram0 (pc,instr, rst);

data_memory ram1 (aluresult,writedata,memwrite,readdata,clk,rst);

progrom_counter pc0 (pc1,pc,clk,rst);

register_file regfile0 (instr[25:21],instr[20:16],writereg[4:0],result,regwrite,scra,writedata,clk);

pcbranch pc12 (signimm,pc_pluse4,out_pcbranch);

sign_extend sign0 (instr[15:0],signimm);

adder adder0 (pc,pc_pluse4);

alu alu0 (scra,scrb,alucontrol,aluresult,zero);

control_unit control0 (instr[31:26],instr[5:0],memtoreg,memwrite,branch,
alucontrol,aluscr,regdst,regwrite);

mux_32 mux0 (pc_pluse4,out_pcbranch,pcscr,pc1);

mux_32 mux1 (writedata,signimm,aluscr,scrb);

mux_32 mux2 (aluresult,readdata,memtoreg,result);

mux_5 mux3 (instr[20:16],instr[15:11],regdst,writereg);


endmodule

//1/////////////////////////////   insteruction_memory   //////////////////////////////

module insteruction_memory( clk, a,rd,rst);

  input[31:0] a;
  input clk,rst;
 
 output reg[31:0] rd;

  //(* ram_init_file = "memory.mif" *) 
  reg[31:0] mem[63:0];
 

always@(posedge clk)

begin
if (rst)
rd<=0;
else
rd<=mem[a];
end
		initial $readmemh ("mem.dat", mem);
endmodule

//2///////////////////////////////////   data memory   ////////////////////////////////////

module data_memory(a,wd,we,rd,clk,rst);

input[31:0] wd;
     input we,clk,rst;
     input[31:0] a;

 output reg[31:0] rd;

//(* ram_init_file = "memory1.mif" *)
reg [31:0] mem1[63:0];

always@ (posedge clk)

begin
if (rst)
rd<=0;
else if(we==0)
rd<=mem1[a];

end

 always@(posedge clk)

begin
        if(we)
           mem1[a] <= wd;

 end
 initial $readmemh ("mem1.dat", mem1);
 endmodule

//3///////////////////////////////////   progrom counter   /////////////////////////////////

module progrom_counter(pc1,pc,clk,rst);

      input[31:0] pc1;
      input  clk,rst;

   output reg[31:0] pc;

always@(posedge clk)

begin
if (rst)
pc<=0;
else
pc<=pc1;

end

endmodule

//4////////////////////////////////////   register file   //////////////////////////////////

module register_file(a1,a2,a3,wd3,we3,rd1,rd2,clk);

       input[31:0] wd3;
       input[4:0] a1,a2,a3;
       input we3,clk;

      output[31:0] rd1,rd2;

reg[31:0] ram[31:0];

      

always@(posedge clk)

  begin

 if(we3)
 ram[a3]<=wd3;

 end
      assign rd1=ram[a1];
      assign rd2=ram[a2];

endmodule

//5///////////////////////////////////////   pcbranch   ////////////////////////////////////

module pcbranch(in_pcbranch0,in_pcbranch1,out_pcbranch);

    input[31:0] in_pcbranch0,in_pcbranch1;

  output[31:0] out_pcbranch;

            assign out_pcbranch=(in_pcbranch1+(in_pcbranch0<<2)); 

endmodule

//6/////////////////////////////////////////  sign extend  ////////////////////////////////

module sign_extend(in,out);

   input[15:0] in;

   output[31:0] out;

      assign out=in[15]?(in+32'hffff_0000):(in+32'h0000_0000);

endmodule

//7////////////////////////////////////   adder   ////////////////////////////////////////

module adder(in_adder,pcplus4);

      input[31:0] in_adder;

  output[31:0] pcplus4;

assign pcplus4=in_adder+32'h0000_0004;

endmodule

//8//////////////////////////////////////   alu    /////////////////////////////////////////

module alu(scra,scrb,alu_control,alu_result,zero);

  input[31:0] scra,scrb;
  input[2:0] alu_control;

        output reg[31:0] alu_result;
        output zero;

always@(scra or scrb or alu_control) 

 begin 
 
 case(alu_control)

       3'b010:alu_result=scra + scrb; 

       3'b110:alu_result=scra - scrb;

       3'b000:alu_result=scra & scrb;

       3'b001:alu_result=scra | scrb;

       3'b111:alu_result=scra > scrb;
default:alu_result=32'h0000_0000; // x to 0
endcase

end
   assign zero=~|alu_result;

endmodule

//9////////////////////////////////////   control unit   /////////////////////////////////// 

module control_unit(opcode,funct,mem_to_reg,mem_write,branch,alu_control,alu_scr,
reg_dst,reg_write);

   input[5:0] opcode;
   input[5:0] funct;

              output[2:0] alu_control;
              output mem_to_reg,mem_write,branch,alu_scr,reg_dst,reg_write;
               
   wire[1:0] aluop;

assign reg_write=(~|opcode[5:0]) | (opcode[5]& ~opcode[4]& ~opcode[3]& ~opcode[2]& opcode[1]& opcode[0]  );    
assign reg_dst=(~|opcode[5:0]);
assign alu_scr=(opcode[5]& ~opcode[4]& ~opcode[3]& ~opcode[2]& opcode[1]& opcode[0])|(opcode[5]& ~opcode[4]& opcode[3]& ~opcode[2]& opcode[1]& opcode[0]  );
assign branch=(~opcode[5]& ~opcode[4]& ~opcode[3]& opcode[2]& ~opcode[1]& ~opcode[0]);
assign mem_write=(opcode[5]& ~opcode[4]& opcode[3]& ~opcode[2]& opcode[1]& opcode[0]);
assign mem_to_reg=(opcode[5]& ~opcode[4]& ~opcode[3]& ~opcode[2]& opcode[1]& opcode[0]);
assign aluop[1]=reg_dst;
assign aluop[0]=branch;

assign alu_control[0]=(aluop[1] & funct[5]  & ~funct[4] & ~funct[3] & funct[2] & 
~funct[1] & funct[0])|
(aluop[1] & funct[5]  & ~funct[4] & funct[3] & ~funct[2] & funct[1] & ~funct[0]);

assign alu_control[1]=(~|aluop[1:0])|(aluop[0])|(aluop[1] & funct[5] & (~|funct[4:0]))
|(aluop[1] & funct[5]  & ~funct[4]& ~funct[3] & ~funct[2] & funct[1] & ~funct[0])|
(aluop[1] & funct[5]  & ~funct[4] & funct[3] & ~funct[2] & funct[1] & ~funct[0]);

assign alu_control[2]=aluop[0]|(aluop[1] & funct[5]  & ~funct[4]
& ~funct[3] & ~funct[2] & funct[1] & ~funct[0])|
(aluop[1] & funct[5]  & ~funct[4] & funct[3] & ~funct[2] & funct[1] & ~funct[0]);


endmodule

//10//////////////////////////////////////  mux 32  /////////////////////////////////////////

module mux_32(in0_mux,in1_mux,sel_mux,out_mux);

       input[31:0] in0_mux,in1_mux;
       input sel_mux;

   output[31:0] out_mux;

  assign out_mux=sel_mux ? in1_mux:in0_mux;

endmodule  

//11////////////////////////////////////  mux 5   /////////////////////////////////////////// 

module mux_5(in0_mux,in1_mux,sel_mux,out_mux);

       input[4:0] in0_mux,in1_mux;
       input sel_mux;

    output[4:0] out_mux;

  assign out_mux=sel_mux ? in1_mux:in0_mux;

endmodule
mips.png
I try to upload RTL.
 

You are connecting rst to output rd of module insteruction_memory - this won't happen with named port connection...
 
oopps , i solved it, but still output show X' , I think i should reset register file too ,so i added reset to it but because its like matrix, i have error again
Code:
module register_file(rst,a1,a2,a3,wd3,we3,rd1,rd2,clk);

       input[31:0] wd3;
       input[4:0] a1,a2,a3;
       input we3,clk,rst;

      output[31:0] rd1,rd2;

reg[31:0] ram[31:0];

      

always@(posedge clk)

  begin
 if (rst)
 ram <= 0;
 else if (we3)
 ram[a3]<=wd3;

 end
      assign rd1=ram[a1];
      assign rd2=ram[a2];

endmodule
ERROR:HDLCompilers:106 - "mips.v" line 146 Illegal left hand side of nonblocking assignment
this is outputs :
333333.png
 

you do understand the only way you can reset a "register file" is if that register file is implemented as FFs not as RAM. You can't initialize a RAM with a reset.
 
I don't think this will ever be put on an FPGA.

You can also use the "inital" block to give registers/rams/etc... initial values.
 
It happened with me too, reset all the signals and memories and give reset at the start of teshbench. if registers are not initialized with any value and assigned a value in the middle of the logic, they become x. assign all the regs to either 1 or 0 at initilzation or put them into reset logic.
 
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top