1
\$\begingroup\$

I am an undergraduate student and am new to Verilog.
I am writing Verilog code which simulates a processor along with registerFiles and memory (instruction + data memory).

Here is the instruction format:

enter image description here

All my modules only contact processor not anything else... They are instantiated here :

enter image description here

within the processor . I use the processor to fetch values into my local registers and send them to ALU...

Could you please look at the code below?

module Processor();// will decode incoming instruction from  instruction file

//instruction decoding variables
reg [5:0]pc;
wire [31:0]instruction;
reg [6:0]Op;
reg [5:0]rd;
reg [5:0]rs1;
reg [5:0]destReg;
reg [5:0]rs2;
reg [6:0]func7;
reg [2:0]func3;
reg [11:0]imm;


//mem variables
reg [31:0]LocationFetchORStore;
wire [31:0]FetchedMemData;
reg [31:0]storeData;

//reg file variables
reg Operation;
reg [5:0]inputreg;
reg [31:0]value;
wire [31:0]contents;

//alu variables
reg [31:0]dataRS1;
reg [31:0]dataRS2;
wire [31:0]dataDest;

InstructMem instMem(.pc(pc),.instruction(instruction)); //IF

registerFile rfa(.Operation(Operation),.inputreg(inputreg), .value(value),.contents(contents));//ID/RF

ALU alu(.Op(Op),.a1(dataRS1),.b1(dataRS2),.result(dataDest));//EX

DataMemory MM(.OpCode(Op),.LocationFetchORStore(LocationFetchORStore),.FetchedMemData(FetchedMemData),.storeData(storeData));//MEM+WB

initial begin
    pc = 0;
end

integer i=0;
always@(*)
begin
    for (i=0;i<7;i=i+1)
    begin
        pc = i;
        Op=instruction[6:0];
        if (Op<=10) begin
            rs1= {1'b0,instruction[19:15]};
            rs2= {1'b0,instruction[24:20]};
            rd = {1'b0,instruction[11:7]};
            func3 = instruction[14:12];
            func7 = instruction[31:25];
            destReg = rd;
            
            Operation = 0;
            inputreg = rs1;
            value=0;
            dataRS1 = contents;
            // $display("pc: %d | inputreg: %b | contents: %b", pc, inputreg,contents);

            //load value of data of register rs1... via regfile

            Operation = 0;
            inputreg = rs2;
            value=0;
            dataRS2 = contents;
            //load value of data of register rs2... via regfile

            Operation = 1;
            inputreg = rd;
            value = dataDest;
            //store value of data of register rd... via regfile
        end
        else if ( Op ==11) begin//lw -> I type

            //decode components of instruction
            rs1= instruction[19:15];
            rd = instruction[11:7];
            imm = instruction[31:20];
            func3 = instruction[14:12];
            destReg = rd;

            //extract data from reg file
            Operation = 0;
            inputreg = rs1;
            
            // fetch data from mem
            LocationFetchORStore = contents;
            LocationFetchORStore[31:0] = LocationFetchORStore[31:0] + imm[11:0];

            //store data in regfile
            Operation =1;
            inputreg = rd;
            value = FetchedMemData;
        end
        else if( Op == 12)begin//sw -> S type MM [rs1 + imm][0 : 31] = rs2[0 : 31]

            //decode components of instructions
            rs1 = {1'b0,instruction[19:15]};
            rs2 = {1'b0,instruction[24:20]};
            func3 = instruction[14:12];
            imm[11:5] = instruction[31:25];
            imm[4:0] = instruction[11:7];
            destReg = 0;

            //extract data from reg file
            //for getting location for storage ...
            Operation = 0;
            inputreg = rs1;
            storeData = contents;

            //for getting value to store ...
            Operation = 0;
            inputreg = rs2;

            // fetch data from mem
            LocationFetchORStore = contents;
            LocationFetchORStore[31:0] = LocationFetchORStore[31:0] + imm[11:0];
        end
       #10;
    end
end
endmodule

The individual codes for registerFile is

module registerFile(input Operation,input [5:0] inputreg, input [31:0] value, output reg [31:0] contents);

reg [31:0] registers [31:0];

integer i;
initial 
begin
    for(i=0;i<32;i=i+1)
    begin   
    registers[i]=i+1;
    end 
end

always@(Operation,inputreg,value)
begin
    if(Operation==0)
    begin//means read value
        contents = registers[inputreg];
    end
    else 
    begin//write
        registers[inputreg] = value;
    end
end
endmodule

for alu is

module ALU(input [6:0]Op, input [31:0]a1, [31:0]b1 ,output reg [31:0] result);

reg [31:0]w1;
reg [31:0]w2;
reg [31:0]w3;
reg [31:0]w4;
reg [31:0]w5;
reg [32:0]carry;
reg [31:0]a;
reg [31:0]b;

integer i;
always@ (Op,a,b)
begin
    carry = 32'b0;
    a = a1;
    b = b1;
    case(Op)

        7'd1: 
        begin
            for(i=0;i<32;i=i+1)//addn
            begin
                w1[i] = a[i]^b[i]^carry[i];
                carry[i+1] = (a[i]^b[i])&carry[i] | a[i]&b[i];
            end
            result = {carry[32], w1};
            $display("value it came with : a= %b, b= %b result = %b",a1,b1,result);
        end
        7'd2: 
        begin
            for(i=0;i<32;i=i+1)//subtrn
            begin
                w2[i] = a[i]^(~b[i])^carry[i];
                carry[i+1] = (a[i]^(~b[i]))&carry[i] | a[i]&(~b[i]);
            end
            w2[31:0]= w2[31:0]+1'b1;
            begin
                if(w2[31])
                    begin
                        carry[32]=1;
                    end
                else
                    begin
                        carry[32]=0;
                    end
            end
            result = {carry[32], w2};
        end
        7'd3: 
        begin
            for(i=0;i<32;i=i+1)//xor
            begin
                w3[i] = a[i]^(b[i]);
            end
            result = w3;
        end
        7'd4: 
        begin
            for(i=0;i<32;i=i+1)//or
            begin
                w4[i] = a[i]|b[i];
            end
            result = w4;
        end
        7'd5: 
        begin
            for(i=0;i<32;i=i+1)//and
            begin
                w5[i] = a[i]&b[i];
            end
            result = w5;
        end
        7'd6: //sll
        begin
            //rd = rs1 << rs2
            while (b!=0) begin
                a = {a[30:0],1'b0};
                b = b - 1;
            end
            result = a;
        end
        7'd7: //srl
        begin
            //rd = rs1 >> rs2
            while (b!=0) begin
                a = {1'b0,a[31:1]};
                b = b - 1;
            end
            result = a;
        end
        7'd8: //srla
        begin
            //rd = rs1 >> rs2(sign preserved)
            while (b!=0) begin
                a = {a[31],a[31:1]};
                b = b - 1;
            end
            result = a;
        end
        7'd9: //slt
        begin
            if(a>b)begin
                result= 32'b1;
            end
            else 
            begin
                result= 32'b0;
            end
        end
        7'd10: //srlU
        begin
            if((a<b && a>0 && b>0) || (b<a && a<0 && b<0) || (b>a && a<0 && b>0))
            begin// mod(b)>mod(a)
                result= 32'b1;
            end
            else 
            begin
                result= 32'b0;
            end
        end
        default:
        carry[0]=0;
    endcase

end

endmodule

for instruction mem ->

module InstructMem(input [5:0]pc,output reg [31:0] instruction);

reg [31:0] instructions [255:0];//makes 256-> 32bit registers...// ie each 4byte.(integer size)//1kb
integer i=0;//ok
initial
begin
    instructions[0] = 32'b00000000010100011000000000000001;
    // #10;
    instructions[1] = 32'b00000000011000010000001100000001;
    // #10;
    instructions[2] = 32'b00000000010100100000000100000001;
    // #10;
    instructions[3] = 32'b00000000010100011000000100000001;
    // #10;
    instructions[4] = 32'b00000000010100011000000100000001;
    // #10;
    instructions[5] = 32'b00000000010100011000000010000001;
    // #10;
    instructions[6] = 32'b00000000010100011000000010000001;
    // #10;
    for(i=7;i<256;i=i+1)
    begin
        instructions[i] = 32'b00000000010100011000000000000000;
    end
end
assign instruction = instructions[pc];

endmodule

Here is the output...

enter image description here

I have debugged all the files other than processor and found them to be working fine... simulating each....

But the problem occurs when I try to do this :

Operation = 0;
inputreg = rs1;
value=0;
dataRS1 = contents;
// $display("pc: %d | inputreg: %b | contents: %b", pc, inputreg,contents);

//load value of data of register rs1... via regfile

Operation = 0;
inputreg = rs2;
value=0;
dataRS2 = contents;
//load value of data of register rs2... via regfile

Operation = 1;
inputreg = rd;
value = dataDest;
//store value of data of register rd... via regfile

Data Memory

module DataMemory(input[6:0] OpCode,input [31:0]LocationFetchORStore,output reg [31:0]FetchedMemData,input [31:0] storeData);
reg [31:0] mem [255:0];//makes 256-> 32bit registers...// ie each 4byte.(integer size)//1kb

integer i;
initial
begin
    for(i=0;i<256;i=i+1)begin
        mem[i] = i+1;
    end
end
always@(OpCode,LocationFetchORStore,FetchedMemData)
begin
    if(OpCode ==11)begin//lw
        FetchedMemData = mem[LocationFetchORStore];
    end
    else begin //sw
        mem[LocationFetchORStore] = storeData;
    end
end

endmodule

I thought that if I would change Operation, inputreg etc it should automatically assign value to contents register and so I should be able to initialize dataRS1 and dataDest etc.. but it fails to do so... Can someone help me?

I have added all the folders of my project here.... https://drive.google.com/drive/folders/1r8jA5VxlMxirqClk8br87WOay8kypI8U?usp=drive_link anyone can open this and run processor.v directly in model sim

Edit:

Mistake 1:

Had traditional C++ mentality of writing code and seeing the output... Verilog is a hardware discription lang... so it accounts for delays which are there in circuits... which I didnt take into account while calling the same module multiple times....

Fix:

Add delays generously to give your poor circuit some time to work on....

as generously pointed out by Mr @toolic I have added delays in the code and here is the updated one...

module Processor();// will decode incoming instruction from  instruction file

//instruction decoding variables
reg [5:0]pc;
wire [31:0]instruction;
reg [6:0]Op;
reg [5:0]rd;
reg [5:0]rs1;
reg [5:0]destReg;
reg [5:0]rs2;
reg [6:0]func7;
reg [2:0]func3;
reg [11:0]imm;


//mem variables
reg [31:0]LocationFetchORStore;
wire [31:0]FetchedMemData;
reg [31:0]storeData;

//reg file variables
reg Operation;
reg [5:0]inputreg;
reg [31:0]value;
wire [31:0]contents;


//alu variables
reg [31:0]dataRS1;
reg [31:0]dataRS2;
wire [31:0]dataDest;


InstructMem instMem(.pc(pc),.instruction(instruction)); //IF

registerFile rfa(.Operation(Operation),.inputreg(inputreg), .value(value),.contents(contents));//ID/RF

ALU alu(.Op(Op),.a1(dataRS1),.b1(dataRS2),.result(dataDest));//EX

DataMemory MM(.OpCode(Op),.LocationFetchORStore(LocationFetchORStore),.FetchedMemData(FetchedMemData),.storeData(storeData));//MEM+WB

initial begin
    pc = 0;
end

integer i=0;
always@(*)
begin
    for (i=0;i<7;i=i+1)
    begin
        pc = i;
        Op=instruction[6:0];
        if (Op<=10) begin
            rs1= {1'b0,instruction[19:15]};
            rs2= {1'b0,instruction[24:20]};
            rd = {1'b0,instruction[11:7]};
            func3 = instruction[14:12];
            func7 = instruction[31:25];
            destReg = rd;
            
            #1;Operation = 0;
            inputreg = rs1;
            value=0;
            dataRS1 = contents;
            
            // $display("pc: %d | inputreg: %b | contents: %b", pc, inputreg,contents);

            //load value of data of register rs1... via regfile

            #1;Operation = 0;
            inputreg = rs2;
            value=0;
            dataRS2 = contents;
            //load value of data of register rs2... via regfile

            #1;Operation = 1;
            inputreg = rd;
            value = dataDest;
            //store value of data of register rd... via regfile
        end
        else if ( Op ==11) begin//lw -> I type

            //decode components of instruction
            rs1= instruction[19:15];
            rd = instruction[11:7];
            imm = instruction[31:20];
            func3 = instruction[14:12];
            destReg = rd;

            //extract data from reg file
            #1;Operation = 0;
            inputreg = rs1;
            
            // fetch data from mem
            #1;LocationFetchORStore = contents;
            LocationFetchORStore[31:0] = LocationFetchORStore[31:0] + imm[11:0];

            //store data in regfile
            #1;Operation =1;
            inputreg = rd;
            value = FetchedMemData;
        end
        else if( Op == 12)begin//sw -> S type MM [rs1 + imm][0 : 31] = rs2[0 : 31]

            //decode components of instructions
            rs1 = {1'b0,instruction[19:15]};
            rs2 = {1'b0,instruction[24:20]};
            func3 = instruction[14:12];
            imm[11:5] = instruction[31:25];
            imm[4:0] = instruction[11:7];
            destReg = 0;

            //extract data from reg file
            //for getting location for storage ...
            #1;Operation = 0;
            inputreg = rs1;
            storeData = contents;

            //for getting value to store ...
            #1;Operation = 0;
            inputreg = rs2;

            // fetch data from mem
            #1;LocationFetchORStore = contents;
            LocationFetchORStore[31:0] = LocationFetchORStore[31:0] + imm[11:0];
        end
        #10;
    end
end


endmodule

I have changed it and now it shows... we can see that the value of the contents does change on adding delays but still it does not load up dataRS1 and dataDest properly Please help me out

enter image description here

Here is the complete wave form...

enter image description here

\$\endgroup\$
4
  • \$\begingroup\$ I have instantiated all the modules within the processor InstructMem instMem(.pc(pc),.instruction(instruction)); //IF registerFile rfa(.Operation(Operation),.inputreg(inputreg), .value(value),.contents(contents));//ID/RF ALU alu(.Op(Op),.a1(dataRS1),.b1(dataRS2),.result(dataDest));//EX DataMemory MM(.OpCode(Op),.LocationFetchORStore(LocationFetchORStore),.FetchedMemData(FetchedMemData),.storeData(storeData));//MEM+WB \$\endgroup\$ Apr 19 at 13:17
  • \$\begingroup\$ @toolic Sir I have added the details.... If you want I have this link here for all folders of my project drive.google.com/drive/folders/… \$\endgroup\$ Apr 19 at 13:24
  • \$\begingroup\$ @toolic Thankyou so much sir for your help... indebted... I have added it \$\endgroup\$ Apr 19 at 13:33
  • \$\begingroup\$ @toolic the Opcode had 7 bits... please consider the same as mentioned above (Please note that I am not calling Data memory right now) since my instruction opcodes are mostly of addition and subtraction(first hand for testing purposes) \$\endgroup\$ Apr 19 at 13:37

1 Answer 1

1
\$\begingroup\$

The problem is how you drive the Operation signal. You set it to 0, but then at the same simulation time, you again set it to 1. This is why it is 1 at all times in your waveforms.

contents is always 0 because you set it to w in registerFile. You unconditionally set w=0 and only change it when Operation is 0.

You need to add delay between the times you set Operation, for example:

        #10 Operation = 0;
        inputreg = rs2;
        value=0;
        dataRS2 = contents;
        //load value of data of register rs2... via regfile

        #10 Operation = 1;
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.