5

Part 1:

I was always told to use functions in Verilog to avoid code duplication. But can't I do that with a module? If my understanding is correct, all functions can be re-written as modules in Verilog except that modules cannot be instantiated from the inside of an always block. Except, in this case, I can always stick with modules. Am I correct?

Part 2:

If I am correct, why can't the Verilog compiler be written in such a way that the modules get the treatment of a function? I mean, why can't the compiler allow the programmer to instantiate a module inside n block and stop supporting functions?

user3219492
  • 774
  • 1
  • 10
  • 18
  • Actually, you can create recursive modules using `parameters` and `generate` blocks. Check out this [32-bit ALU I wrote for computer architecture using a recursively defined LAC](https://gist.github.com/patrickroberts/3908606ece975eb4c20b4cd8f8b25dd6). – Patrick Roberts Dec 23 '17 at 18:56
  • @PatrickRoberts thanks for the link. I have edited the question – user3219492 Dec 23 '17 at 19:05
  • I added some screenshots of the specification for the top-level module in the link for clarification. I'm glad you checked it out. Out of curiosity, were you told to use functions to avoid code duplication explicitly **instead of modules**? Or just in general? Because it's good advice if just applied in general, but I also feel that modules do make more sense in certain contexts, and it's not clear whether this advice was presented to you with an implication to actively discourage the use of modules in favor of functions. – Patrick Roberts Dec 23 '17 at 19:08
  • 1
    Also, a compiler can't instantiate _declarative_ hardware in `always` blocks, because it doesn't make any sense to have it in the context of _sequential_ logic. I hope that at least answers part of your question. – Patrick Roberts Dec 23 '17 at 19:13
  • @PatrickRoberts Thanks for your comments. I was asked to use functions in general. And for the second comment: I guess you are correct. A module can represent a sequential or combinational logic. Whereas functions can represent only combinational logic. So instantiating a module within an always block doesn't sound meaningful (as the nested module might contain sequential logic). So probably a different "code block" (which strictly allows only combinational logic) was chosen to solve the issue and people named it as "function". Please add it as an answer. – user3219492 Dec 23 '17 at 19:32
  • I think you're conflating "declarative" and "combinational". To be fair, I'm probably also conflating "sequential" and "imperative". My point was that you can't mix declarative and imperative syntax in the same block. That is why you can't instantiate a module in an `always` block. It has nothing to do with whether modules support sequential logic or combinational logic. – Patrick Roberts Dec 23 '17 at 19:40
  • @PatrickRoberts Are you saying that functions return some value which can be assigned to a reg inside an always block whereas modules don't return anything, so will look odd inside an always block? – user3219492 Dec 23 '17 at 19:48
  • It doesn't just "look odd", it makes no sense. You can state what something does (declarative), or how it does it (imperative), but you can't do both at the same time. – Patrick Roberts Dec 23 '17 at 20:44
  • @PatrickRoberts Your example of recursive modules is interesting but they are hardly recursive. Every module with different set of params is really a different module and this "recursion" is resolved at compilation time. Unlike in functions. – Serge Dec 23 '17 at 21:40

1 Answers1

5
  1. module != function. Their usage in verilog is completely different.

Functions are actually extended expressions and it is used in expressions. It can be used in rhs expression of the 'assign' statement or in expressions inside any procedural block.

  • Functions cannot consume time.

  • Functions must return a value.


Modules are used to express hardware hierarchy and contain concurrent procedural blocks (which might contain functions).

  • Modules may consume time.

  • Modules cannot return value. (output ports are not return values)


Potentially you can create a function which replaces internals of a single always block and write an equivalent module with an always block which returns function. But this is it.

  1. You are not correct :). Verilog compiler cannot be written in such a way, because there is a verilog standard which every verilog compiler must follow. Otherwise it will not be verilog.
Serge
  • 11,616
  • 3
  • 18
  • 28