How to declare input and output types in verilog

2019-06-12 20:56发布

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.

3条回答
狗以群分
2楼-- · 2019-06-12 21:33

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
);
查看更多
等我变得足够好
3楼-- · 2019-06-12 21:36

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?

查看更多
小情绪 Triste *
4楼-- · 2019-06-12 21:50

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
查看更多
登录 后发表回答