0

I have the following code:

module X;
    wire [11:0] mga [0:15]; 
    // other code omitted here for clarity

    reg [11:0] globalStartAddresses [0:15];
    reg [11:0] globalEndAddresses [0:15];

    localMMU mmu[0:15](clock, globalStartAddresses, globalEndAddresses, mrw, mdi, mdo, mga);

    task dispatcher;
        // parameters
        output reg dataReady;
        input readWrite;
        input [7:0] dataIn;
        output reg [7:0] dataOut;
        input [11:0] globalAddress;

        // local variables
        integer x, selected;

        begin
            for(x=0; x<16; x=x+1) begin
                if(globalAddress >= globalStartAddresses[x] && globalAddress <= globalEndAddresses[x]) selected=x;
            end

            mrw[selected]=readWrite;
            mdi[selected]=dataIn;       
            assign mga[selected]=globalAddress;

            if(readWrite==1)
                wait(mdo[selected]!=0);
            else
                wait(mdo[selected]!=dataIn);

            dataOut=mdo[selected];
        end
    endtask
endmodule

I get 2 errors in the code:

  1. In the array instance declaration of "localMMU", it states that "globalStartAddress[ ] should be present", but I have declared it just above as is evident.
  2. In the assign statement inside the task, it states that only variables are allowed on LHS.

(I am using VeritakWin 3.84F) Please tell me how can I rectify these 2 problems. Thanks.

user1637645
  • 341
  • 3
  • 13

1 Answers1

1
  1. globalStartAddresses and globalEndAddresses are both of type array but array can not be passed directly between two modules. You must flatten the array into a vector and then pass it to a module. The problem is answered here :

    How to pass array structure between two verilog modules

  2. Left hand side of procedural continuous assignment can not be of type wire while in continuous assignment, left hand side must be just of type wire. As a solution, change mga type to reg. The same problem answered here:

    Continuous assignment verilog

Community
  • 1
  • 1
Mehran Torki
  • 977
  • 1
  • 9
  • 37
  • 1. If I flatten the array, I cannot use instance-array, I would have to declare 16 instances: mmu0, mmu1, ... like that, instead of mmu[0:15]. Is there a way around this? 2. The "mga" is used as a parameter to "inout" port of another module (not shown in the code), but if I change it to "reg", it gives an error that "reg" cannot be passed as output parameter. It is "inout" and not "output". Only when it is used as "in" mode, the "dispatcher" task is called (from another module [not shown]) and I need to assign a value to it using the problematic assign statement. How can I solve this? – user1637645 Feb 23 '16 at 01:20
  • 1. The only way i know in this situation is to use `generate` statement to instantiate modules. Read here (Danielpoe's answer):http://stackoverflow.com/questions/1378159/can-we-have-an-array-of-custom-modules 2. Unfortunately i have no idea in that situation, i'll let you know if i found a solution. – Mehran Torki Feb 23 '16 at 09:02
  • 2. For the second problem, as `mga` should be of type `wire`, there is no way to use **procedural continuous assignment** so you have to put `assign` statement out of `dispatcher`. My solution is to create a `generate` loop that assigns `mga[i]`, like this: `assign mga[i] = (write_bool) ? helper[i] : 'bz;`. Define a global array of vectors named `helper` : `reg [11:0] helper [0:15];`. Then do this in `dispatcher` task: `helper[selected] = globalAddress; write_bool = 1`. This way you can put value on `mga`. By encountering this kind of problems, you'd better consider redesigning. – Mehran Torki Feb 23 '16 at 13:01
  • 1
    Here is a link containing a code with those two solutions i said (unnecessary parts of your code are removed to just show the main ideas): http://www.edaplayground.com/x/WAT – Mehran Torki Feb 23 '16 at 13:10
  • Thanks a lot for your code. When `write_bool` is 1, doesn't your code update all the `mga[ ]` elements? But, I want to update only `mga[selected]`, leaving the rest unchanged. And also, I want to update it ONLY when `dispatcher` is called. I am providing my full code here, please tell me that if I put your modifications in it, will it work the same way (I'm new to verilog, infact this is my first verilog program), thanks in advance: [link](http://www.edaplayground.com/x/5tE) – user1637645 Feb 26 '16 at 14:22
  • 1
    Yours :) if you want to have only `mga[selected]` to be updated, then you should create an array of write conditions instead of just one `write_bool` : `reg write_bool [0:15];`. When `dispatcher` is called, `write_bool[i]` becomes `1` so it assigns `helper[i]` to `mga[selected]`. For the purpose of education, do the modifications yourself. – Mehran Torki Feb 26 '16 at 17:49
  • Yes yes, I'll make the modifications myself, thanks a lot :) – user1637645 Feb 27 '16 at 18:43