In VHDL I can make my modules arbitrary. Bus sizes flow from higher levels. That way I don't need to edit all my code every time I reuse a module.
Consider the following (incomplete) examples (This is a toy example to try to illustrate a point.)
In both examples:
The size of bus is implicit and late defined
The structure of displaystruct is made elsewhere.
The definition of decoder function is made elsewhere.
library IEEE;
use IEEE.std_logic_1164.all;
use work.displaylib.all;
-- In writing like this I can instance 'm' on any size bus without changing it.
entity m is
port (
clk : in std_logic;
bus : in std_logic_vector;
display : out displaystruct
);
end entity;
architecture example of m is
begin
if rising_edge(clk) then
display <= decoder(bus);
end if;
end architure;
library IEEE;
use IEEE.std_logic_1164.all;
use work.displaylib.all;
entity top is
end entity;
architecture example of top is
signal clk : std_logic;
signal bus : std_logic_vector(15 downto 0); --Late definition of bus
signal display : displaystruct;
begin
controller : m port map (
clk => clk,
bus => bus,
display => display);
end architecture;
I would like to do the same in SystemVerilog but I don't see how. You can't have arrays of undefined size (e.g. [])
`include "displaylib"
// Non working example as the array size of bus needs to be known
module m (
input logic clk,
input logic [] bus,
output displaystruct display
)
always @(posedge clk)
begin
display = decoder(bus);
end
endmodule;
module top;
logic clk;
logic [15:0] bus; //Late definition of bus
displaystruct display;
controller m (
.clk(clk),
.bus(bus),
.display(display)
);
endmodule;
1 Answer 1
You can do this in verilog by defining parameters in the module. You can override these parameters when you instantiate module inside top. Here is the example using your code:
module controller #(parameter BUS_WIDTH=16) //Here 16 is default value.
( input logic clk,
input logic[BUS_WIDTH-1:0] bus,
output displaystruct display
)
always @(posedge clk)
begin
display = decoder(bus);
end
endmodule
module top;
parameter FINAL_BUS_WIDTH = 32;
logic clk;
logic [BUS_WIDTH-1:0] bus; //Late definition of bus
displaystruct display;
controller m #(BUS_WIDTH = FINAL_BUS_WIDTH) // THis will create module with bus width 32
.clk(clk),
.bus(bus),
.display(display)
);
controller m2 // THis will create module with bus width 16
.clk(clk),
.bus(bus),
.display(display)
);
controller m3 #(BUS_WIDTH = 4) // THis will create module with bus width 4
.clk(clk),
.bus(bus),
.display(display)
);
endmodule
In this example, I created BUS_WIDTH parameter in the module m whose default value is 16. This parameter can be overridden whenever you are instantiating the module m.
displaystruct
is never defined. It has to be defined somewhere. \$\endgroup\$