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.
If your workflow allows you to use SystemVerilog then these can all become logic
instead of reg
or wire
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. Use reg
when you want to define the value in an always
block:
wire a_wire;
wire b_wire;
example_a_module(
.a( a_wire )
);
example_b_module(
.a( a_wire )
);
assign b_wire = ~a_wire ;
Regs
reg a_reg;
reg b_reg;
always @* begin
a_reg = something_else;
end
always @(posedge clk or negedge rst_n) begin
if (~rst_n) begin
b_reg <= 1'b0;
end
else begin
b_reg <= something_else;
end
end
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:
module example_a_module(
output a
);
endmodule
Here b is a 10 bit reg type:
module example_c_module(
output reg [9:0] b
);
endmodule
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?
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.
wire [14:0] connector_15;
wire [8:0] connector_9;
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(connector_9),
.ramouta(ramoutawire),
.romaddra(connector_15),
.ramaddra(ramaddra));
rom rom_instance (
.clka(mclk), // input clka
.addra(connector_15), // input [14 : 0] addra
.douta(connector_9), // output [7 : 0] douta
.clkb(ck), // input clkb
.addrb(romaddrbwire), // input [14 : 0] addrb
.doutb(romoutb) // output [7 : 0] doutb
);