I have this top module that instantiate two modules:
fillRam fillRam1(
.clk(mclk),
.ramaddrb(ramaddrb),
.romaddrb(romaddrb),
.romoutb(romoutbwire),
.raminb(raminb));
vga vgainst(
.ck(mclk),
.HS(HS),
.VS(VS),
.outRed(OutRed),
.outGreen(OutGreen),
.outBlue(OutBlue),
.sw(sw),
.romouta(romoutawire),
.ramouta(ramoutawire),
.romaddra(romaddra),
.ramaddra(ramaddra));
In this top module, i also have two module that makes the connections on the RAM and ROM.
rom rom_instance (
.clka(mclk), // input clka
.addra(romaddrawire), // input [14 : 0] addra
.douta(romouta), // output [7 : 0] douta
.clkb(ck), // input clkb
.addrb(romaddrbwire), // input [14 : 0] addrb
.doutb(romoutb) // output [7 : 0] doutb
);
The thing i want to do is, get the romaddra value from vga module, give it to rom_instance, and get the romouta value and give it back to vga module back. I declare two variables for that:
reg [14:0] romaddra;
wire [14:0] romaddrawire;
reg [7:0] romouta;
wire [7:0] romoutawire;
assign romaddrawire = romaddra;
assign romoutawire = romouta;
In every clock cycle, i get the romaddra value from vga instance, write it to romaddrawire and give it to the ROM instance. Then i take the romouta value, write it to romoutawire and give it back to the VGA instance.
I have similar declarations on other rom ports and ram ports. But in all of them i get this error.
ERROR:HDLCompilers:102 - "top.v" line 82 Connection to output port 'romaddra' must be a net lvalue
in vga verilog code:
output reg [14:0] romaddra;
and in rom verilog:
output [7 : 0] douta;
Im very confused about this whole reg and wire types. I would be glad if someone explain what is going wrong here and the reason aswell. Thanks.
At the top level, just declare bus wires and use those bus wires in the instantiations. Think of reg and assign as drivers, you don't want a driver, you want a wire, hence use 'wire'. When you do 'wire a=1' it's really an assign, which creates a driver. Bottom line, when you want to connect, use only a wire, not an assign or a reg.
You can think of regs as sticky, while wires just connect two points (like a physical wire). This doesn't necessarily mean that a reg will always be synthesized to a flip flop, but a reg will hold its previous value until a newer value is assigned. Wires, on the other hand, are memoryless.
Generally speaking, outputs of modules tend to be regs, and the interconnection between modules tend to be wires. This is because the logic for generating the proper output tends to be encapsulated in the module, so the instantiating module can just pass outputs along. Of course, in more complicated systems, this won't hold true where modules will be nested inside modules. But the concept stays the same -- if you're just trying to pass data along from one module to another, use a wire. If you need the data to be "sticky", use a reg.
With all that said, what was the reasoning behind making
romaddra
a reg and not a wire?If your workflow allows you to use SystemVerilog then these can all become
logic
instead ofreg
orwire
and your problem goes away.You can read up more on it later but for now use a
wire
for connectivity or as part of an assign statement. Usereg
when you want to define the value in analways
block:Regs
Output ports can be any type, if you hook them up by name (it looks like you have) rather than by order.
Output a is a wire type:
Here b is a 10 bit reg type: