0
\$\begingroup\$

I have a verilog as module I get the error

Error (10137): Verilog HDL Procedural Assignment error object "result" on

left-hand side of assignment must have a variable data type

If I add also reg [31:0] result;, I get another error

Error (10028): Can't resolve multiple constant 
drivers for net "tempreg[0][31]" at mips_core_testbench.v(55)
.
.
.
.
Error (10028): Can't resolve multiple constant 
drivers for net "tempreg[0][14]" at mips_core_testbench.v(55)
Error (12153): Can't elaborate top-level user hierarchy

Code:

module testbench (result, input_instruction, rs_content, rt_content);
    output [31:0] result;
    //reg [31:0] result;
    input [31:0] input_instruction;
    input [31:0] rs_content;
    input [31:0] rt_content;
    reg [31:0] tempreg [0:31];
    integer type;
    integer i;  

initial begin
    tempreg[0] = 1;
for (i = 1; i <= 31; i = i + 1)
        tempreg[i] <= 0;

end

    always@ (input_instruction) begin
        if(input_instruction[31:26] == 6'b000000)
            type = 1; // R-type
        else
            type = 0; // I-type
    end

    always@ (type) begin
        case(input_instruction[5:0])
            //add
            6'b100000:
            tempreg[input_instruction[15:11]] = tempreg[input_instruction[25:21]] + tempreg[input_instruction[20:16]];
            //sub
            6'b100010:
            tempreg[input_instruction[15:11]] = tempreg[input_instruction[25:21]] - tempreg[input_instruction[20:16]];
            //and
            6'b100100:
            tempreg[input_instruction[15:11]] = tempreg[input_instruction[25:21]] & tempreg[input_instruction[20:16]];
            //or
            6'b100101:
            tempreg[input_instruction[15:11]] = tempreg[input_instruction[25:21]] | tempreg[input_instruction[20:16]];
            //sra
            6'b000011:
            tempreg[input_instruction[15:11]] = tempreg[input_instruction[20:16]] >>> input_instruction[10:6];
            //srl
            6'b000010:
            tempreg[input_instruction[15:11]] = tempreg[input_instruction[20:16]] >> input_instruction[10:6];
            //sll
            6'b000010:
            tempreg[input_instruction[15:11]] = tempreg[input_instruction[20:16]] << input_instruction[10:6];
            //sltu------
            //6'b101011:


        endcase
    end

        always@ (!type) begin
        case(input_instruction[31:26])
            //addi
            6'b001000:
            tempreg[input_instruction[20:16]] = tempreg[input_instruction[25:21]] + tempreg[input_instruction[15:0]];
            //addiu----
            //6'b001001:
            //andi
            6'b001100:
            tempreg[input_instruction[20:16]] = tempreg[input_instruction[25:21]] & tempreg[input_instruction[15:0]];
            //ori
            6'b001101:
            tempreg[input_instruction[20:16]] = tempreg[input_instruction[25:21]] | tempreg[input_instruction[15:0]];
            //slti
            6'b001010:
                begin
                    if (tempreg[input_instruction[15:0]] - tempreg[input_instruction[25:21]] > 0 )          
                        tempreg[input_instruction[20:16]] = 1;
                    else
                        tempreg[input_instruction[20:16]] = 0;
                end
            //lui
            6'b001111:
            tempreg[input_instruction[20:16]] = tempreg[input_instruction[15:0]] << 16'b0;


        endcase
    end

    always @(type or tempreg[input_instruction[15:11]] or tempreg[input_instruction[20:16]])
begin

  if (type == 1)
    result <= tempreg[input_instruction[15:11]];
  else
    result <= tempreg[input_instruction[20:16]];

end

endmodule

Edited code:

module testbench (result, input_instruction, rs_content, rt_content);
    output reg[31:0] result;
    input [31:0] input_instruction;
    input [31:0] rs_content;
    input [31:0] rt_content;
    reg [31:0] tempreg [0:31];
    integer type;
    integer i;  

initial begin
    tempreg[0] = 1;
for (i = 1; i <= 31; i = i + 1)
        tempreg[i] = 0;

end

    always@ (input_instruction) begin
        if(input_instruction[31:26] == 6'b000000)
            type = 1; // R-type
        else
            type = 0; // I-type
    end

always @ * begin
    if (type) begin
        case (input_instruction[5:0])
         //add
            6'b100000:
            tempreg[input_instruction[15:11]] = tempreg[input_instruction[25:21]] + tempreg[input_instruction[20:16]];
            //sub
            6'b100010:
            tempreg[input_instruction[15:11]] = tempreg[input_instruction[25:21]] - tempreg[input_instruction[20:16]];
            //and
            6'b100100:
            tempreg[input_instruction[15:11]] = tempreg[input_instruction[25:21]] & tempreg[input_instruction[20:16]];
            //or
            6'b100101:
            tempreg[input_instruction[15:11]] = tempreg[input_instruction[25:21]] | tempreg[input_instruction[20:16]];
            //sra
            6'b000011:
            tempreg[input_instruction[15:11]] = tempreg[input_instruction[20:16]] >>> input_instruction[10:6];
            //srl
            6'b000010:
            tempreg[input_instruction[15:11]] = tempreg[input_instruction[20:16]] >> input_instruction[10:6];
            //sll
            6'b000010:
            tempreg[input_instruction[15:11]] = tempreg[input_instruction[20:16]] << input_instruction[10:6];
            //sltu------
            //6'b101011:
        endcase
    end else begin
        case (input_instruction[31:26])
             //addi
            6'b001000:
            tempreg[input_instruction[20:16]] = tempreg[input_instruction[25:21]] + tempreg[input_instruction[15:0]];
            //addiu----
            //6'b001001:
            //andi
            6'b001100:
            tempreg[input_instruction[20:16]] = tempreg[input_instruction[25:21]] & tempreg[input_instruction[15:0]];
            //ori
            6'b001101:
            tempreg[input_instruction[20:16]] = tempreg[input_instruction[25:21]] | tempreg[input_instruction[15:0]];
            //slti
            6'b001010:
                begin
                    if (tempreg[input_instruction[15:0]] - tempreg[input_instruction[25:21]] > 0 )          
                        tempreg[input_instruction[20:16]] = 1;
                    else
                        tempreg[input_instruction[20:16]] = 0;
                end
            //lui
            6'b001111:
            tempreg[input_instruction[20:16]] = tempreg[input_instruction[15:0]] << 16'b0;
        endcase
    end
end

always @(type or tempreg[input_instruction[15:11]] or tempreg[input_instruction[20:16]])
begin

  if (type == 1)
    result = tempreg[input_instruction[15:11]];
  else
    result = tempreg[input_instruction[20:16]];

end

endmodule
\$\endgroup\$
2
\$\begingroup\$

You have declared result in you module declaration to be of type wire. You can't assign values to wires in always blocks.

Instead you should declare result as the correct type as explained in this StackOverflow question (thanks @Greg).

output [31:0] result;
reg [31:0] result;

This makes it of reg type which can be assigned in an always block.


However, this is not your only problem. You are assigning values to temp_reg in two different always blocks. This is not allowed. You can only have one driver (one always block or assign statement) for any signal. Otherwise how can it implement it in logic.

You can fix this by doing:

always @ * begin
    if (type) begin
        case (...)
             ...
        endcase
    end else begin
        case (...)
             ...
        endcase
    end
end
\$\endgroup\$
  • \$\begingroup\$ output reg [31:0] result; is not valid syntax according to any IEEE1364 or IEEE1800. Some tools allow it but it is a bad practice. I explained it on another question here \$\endgroup\$ – Greg Dec 3 '15 at 18:11
  • \$\begingroup\$ I also get Error (10028): Can't resolve multiple constant drivers for net "tempreg[0][31]" at mips_core_testbench.v(54) \$\endgroup\$ – askque Dec 3 '15 at 18:12
  • 1
    \$\begingroup\$ @Greg indeed, I was only glancing over the code and assumed that everything was inside the module declaration (output reg ...) as that is how I usually do it (the ANSI style one). Although granted then it should have a comma, not a semicolon. Corrected that. \$\endgroup\$ – Tom Carpenter Dec 3 '15 at 18:14
  • \$\begingroup\$ @askque see my edit. \$\endgroup\$ – Tom Carpenter Dec 3 '15 at 18:16
  • \$\begingroup\$ thank you for your help sir. I have edited my code. Could you look? But, when I want to compile, it is compiling so slow compared to old one. How can it be improved? @TomCarpenter \$\endgroup\$ – askque Dec 3 '15 at 18:28
1
\$\begingroup\$

You need result to be a reg. If you want to continue using non-ANSI then use:

output [31:0] result;
reg [31:0] result;

For ANSI header use:

module testbench (
  output reg [31:0] result,
  input [31:0] input_instruction,
  input [31:0] rs_content,
  input [31:0] rt_content );

tempreg as being assigned in two always blocks, which is not sunthesizable. always @(type) and always @(!type) are not working the way you are thinking. Both will trigger on a change of value, but the value itself doesn't matter. Combine into one always @* (we are no longer in 1995, we don't have do list the full sensitivity list).

You should be using always @* (or the synonyms always @(*)) for all combinational logic blocks, and using blocking (=) assignments instead of non-blocking (<=). Non-blocking should be used for assigning flip-flops and latches, everything else should be blocking.

Make sure every bit of tempreg is assigned a value in one pass of the always block. Otherwise, you are inferring level sensitive latches.

Edit:
Looking at your code again, your going to need a clock. tempreg is storing values and will not be purely combinational logic. Use the template below, and use non-blocking assignments to tempreg. If you don't use the clock, then you will have complex latching logic. If you don't use non-blocking, then there is a potential race condition in the Verilog simulator.

always @(posedge clk) begin
    if (type) begin
        case (...)
             ... // use non-blocking assignments here
        endcase
    end else begin
        case (...)
             ... // use non-blocking assignments here
        endcase
    end
end

I advice you looking into ANSI style headers. Also, try not to use type as a variable name, it is not forward comparable with SystemVerilog.

\$\endgroup\$
  • \$\begingroup\$ I have added edited code sir. But, when I compile it, It is compiling so slow. I have ever seen speed in altera. Can be the code improved? or Why is it so slow? Thank you for your help. \$\endgroup\$ – askque Dec 3 '15 at 18:35
  • \$\begingroup\$ @askque , I updated my answer. You are going to need a clock. tempreg reg needs to be synchronous to work properly. \$\endgroup\$ – Greg Dec 3 '15 at 18:42
  • \$\begingroup\$ sir, when I change the always header I get the error, Error (10161): Verilog HDL error: object "clk" is not declared Should it be defined as input? If I define as input clk, is it enough? I have never used the posedge clk. Also, If I define input clk, I get the error Error (10206): Verilog HDL Module Declaration error at : top module port "clk" is not found in the port list \$\endgroup\$ – askque Dec 3 '15 at 18:46
  • \$\begingroup\$ @askque , your need to show your code. Update your question, change the "Edited code:" section. From your description you didn't add clk port list but you did declare it as an input. That is the annoyance with non-ANSI, you have define the port name, direction and type on different lines; with ANSI it is all together one the same line. \$\endgroup\$ – Greg Dec 3 '15 at 19:08
  • \$\begingroup\$ clocking is really efficient for this code. I will add the clk later. Thank you but, I get the slower part. My issue is here always @(type or registers[input_instruction[15:11]] or registers[input_instruction[20:16]]) begin if (type == 1) result = registers[input_instruction[15:11]]; else result = registers[input_instruction[20:16]]; end I try to show the specified result in result. I have edited as appropriate ANSI rule \$\endgroup\$ – askque Dec 3 '15 at 19:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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