0

I have an issue for a system-verilog project. I simulate using Questasim, but this is more a language-related question, I actually have not been able to find any answer in more than 2 weeks of studying.

I have a collection of many (~1000s) almost identical modules, repeated and connected one another. This module is parametrized with an ID. Inside the module, some actions are performed depending on the value of this ID and everything looks working as expected.

The reason why these modules are not exactly identical is that, depending on the ID, some signals to and from the modules swap. What I mean is that, in pseudo code, I would like to have something like:

module test #(
    ID = 0
  )  (
    ...
    if(ID == 0) input wire A
    else if(ID == 1) output wire A
    ...

    ...

endmodule

does systemverilog support, in any way, something like this? I can work around this problem using a verilog generating script, but that is not so maintainable in my experience.

This is actually a semplification, I truly have ~10s of signal and they change from input to output in almost any possible way, therefore manual writing is hardly possible.

I know it may be possible to just work with inout and do everything inside, but at compile time I do know exactly what is an input and what is an output for every ID, therefore this solution does not look elegant at all to me.

2
  • Does this need to be synthesizable? Commented May 25, 2022 at 16:59
  • I actually wish it were synthesizable. Let's say a non-sinthesizable version can help me make some calculations but, at the end of the day, I would like to synthesize it. Commented May 26, 2022 at 8:10

2 Answers 2

1

I do not think that there is a way to redefine port direction this way. You can try to work with inout directions, as in the following example:

module mod#(P=1)(inout a,b,c);
  if (P) begin
    assign c = a | b;
  end
  else begin
   assign a = b | c;
  end
endmodule

module top;
  wire a,b,c,d, e, f;
  mod#(1) mod1(a,b,e);
  mod#(0) mod2(f,c,d);
endmodule
Sign up to request clarification or add additional context in comments.

1 Comment

I had this in mind, but I hoped I could do something better to skip inouts|. Anyway thank you, this of course works delightfully. If no better answers are given within this week I will mark this as accepted.
0

What you are trying to obtain is instantiate two different modules with completely different behavior (depending on ID parameter).

It would be cleaner using different modules for different purposes:

module test_ID0 (...)
  input wire A
  ...
endmodule

module test_ID1 (...)
  output wire A
  ...
endmodule

Shared parts of both modules could be encapsulated in lower level module.

In your top level, assuming you are using the generate construct, you can use the genvar to select module instantiation, not only as parameter:

module top
  ...
  generate
    for(genvar i=0; i<N; i++) begin
      if((i%2)==0) begin
        test_ID0 u_testID0(.a(a[i]),.b(b[i]),.c(c[i]));
      end
      else begin
        test_ID1 u_testID1(.a(a[i]),.b(b[i]),.c(c[i]));
      end
    end
  endgenerate
  ...
endmodule

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.