Having trouble with Verilog inout wires - verilog

For the record, I'm a complete Verilog newbie. I'm writing a module that uses a few bidirectional buses.
inout wire [KEY_SIZE-1:0] prevKey;
inout wire [TAG_SIZE-1:0] prevTag;
inout wire [KEY_SIZE-1:0] nextKey;
inout wire [TAG_SIZE-1:0] nextTag;
I know how I read things off of the bus, but how do I write something onto it? If I use an assign statement to a reg, will the value of the reg get clobbered when new data comes onto the wire? Is dealing with an inout port worth the hassle, or should I just make an input and and output bus for each?

If I use an assign statement to a reg...
This statement doesn't really make sense, you don't do assignments to regs, you do assignments to wires.
Simple example of driving an inout wire:
inout wire bidir_wire;
reg drive_value;
reg drive_enable;
reg something;
assign bidir_wire = drive_enable ? drive_value : 1'bz;
always #(posedge clk) begin
drive_value <= ... ; //assign a drive value based on some criteria
drive_enable <= ...;
something <= bidir_wire; //do something with the input value
end

Related

How to use regs to modify wires?

I am kind of new to Verilog and was wondering how I can modify wires. I know that you cannot modify wires inside always blocks.
I've seen something like this where you can declare some regs and assign the wire to those regs (which you can then modify the reg to modify the wire?)
module something
#(parameter D_W = 8)
(
input wire clk,
input wire rst,
output wire valid,
output wire [D_W-1:0] data,
);
reg valid_rg = 0;
reg [D_W-1:0] data_rg = 0;
assign valid = valid_rg;
assign data = data_rg;
I was wondering how to do something like that for a wire like:
wire [7:0] wire_a [7:0];
Initially my guess would be to have something like this
reg [7:0] wire_a_rg [7:0];
assign wire_a[7:0] = wire_a_rg[7:0];
But I have a feeling it might be wrong. How could I approach this?
There's no need to use wires in SystemVerilog unless you need to model bi-directional buses, or any kind of circuitry with multiple drivers. You can write
module something
#(parameter D_W = 8)
(
input logic clk,
input logic rst,
output logic valid,
output logic [D_W-1:0] data,
);
And then you can make procedural assigmemnts to valid/data in an always block, or a continuous assign statement (but not both).
BTW, SystemVerilog prefers the use of logic keyword over synonym reg.
You should read my post about the difference between nets and variables.

Verilog module instantiation reg input output

While implementing Verilog code in behavioral modeling we are using reg as output. But, when I have to use module instantiation and connect it using a wire, it's showing an error while implementation. Is there any other way where I can use module instantiation to connect outputs of different module instances to implement combinational logic as it's illegal to connect the reg output of the previous model to a wire? Note that I have to apply behavioral modeling hence no assignment statements are allowed. This is an example to connect two half adders to one full adder.
module half_adder(input wire a,b,output reg sum,output reg carry);
always#(a or b)
begin
sum = a^b ;
carry= a & b ;
end
endmodule
module full_adder(input wire a,b,c,output reg sum,output reg carry);
wire s1,c1,c2;
half_adder gate1(a,b,s1,c1);
half_adder gate2(s1,c,sum,c2);
always#(a or b or c)
begin
carry = c1|c2;
end
endmodule
Error (10663): Verilog HDL Port Connection error at full_adder.v(14):
output or inout port "sum" must be connected to a structural net
expression
In standard old verilog a reg cannot be connected to a reg using module connection or a continuous assignment. System verilog allows it. So, one of the solutions could be to switch to system verilog.
As for verilog, in half_adder port sum is declared as a reg. Instance gate2 connects variable of type reg to the port of type reg. This is illegal. This type of an assignment can only happen inside a procedural (i.e. always) block. Instance gate1 bypasses this issue by connecting port to the wire s1.
So, you can follow the similar path. Create another wire s2 as in the following example.
module full_adder(input wire a,b,c,output reg sum,output reg carry);
wire s1,c1, s2, c2;
half_adder gate1(a,b,s1,c1);
half_adder gate2(s1,c,s2,c2); // use s2 here
always#*
carry = c1|c2;
always #*
sum = s2; // now you can s2 assign to the 'sum' port
endmodule
Another way is to declare the 'sum' port as a wire. A register can be connected to a wire, using port connections or continuous assignment.
module full_adder(input wire a,b,c,
output sum, // declares it as a wire
output reg carry);
...
half_adder gate2(s1,c,sum,c2); // now it works this way.
And btw, do not use #(a,b,c). It is always error prone and is just wrong in your case. It should be #(c1,c2). But it is much better to use #*.
You should not declare sum as a reg in the full_adder module because it is not being assigned inside a procedural block (such as always). A reg is not a "net" type. Change:
module full_adder(input wire a,b,c,output reg sum,output reg carry);
to:
module full_adder(input wire a,b,c,output sum,output reg carry);
You also have an incorrect sensitivity list. Change:
always#(a or b or c)
to:
always #*
Now, the always block will trigger when the signals on the RHS of the assignments change.

inout with reg type in verilog

I have used inout with c, but for c to be on the LHS of procedural assignment, it needs to be a reg type variable. Can anyone help me out with this code?
module multiedgeclk(input clk ,[7:0] a,b,d, inout [7:0] c, output reg [7:0]f);
always #(posedge clk)
c <= a + b;
always #(negedge clk)
f = c & d;
endmodule
In verilog inout is the direction of the port. wire or reg is the type of the signal.
If you want to drive a bi-directional port, it should be declare as inout wire or inout and drive it with enable signal
Here is a example of bi-directional port.
module ABC( inout [7:0] c );
reg [7:0] c_out;
reg out_en;
assign c = out_en ? 8'hz : c_out;
/* something here
...
*/
endmodule
An inout port cannot be procedurally assigned. There is nothing to indicate how long to hold that value on the port. This is the problem for any wire. But wires have a strength mechanism for multiple continuous drivers, the highest strength wins. So you can use a continuous assignment to selectively drive a value or turn it off by driving a z value.
wire c;
reg c_reg;
assign c = c_reg;
Now you can procedurally assign c_reg to a value or 8'bz
See my article for more info about wires and reg types.

Verilog Reg/Wire Confusion

I'm making a Multicycle CPU in Verilog that consists of a Datapath and a Control. The outputs of the control (state machine) are registers, but the connections between the datapath are wires. If a wire signal is supposed to be (in psuedo-code): wire = OR(wire coming from a mux, reg output from control), how do I do this? Can you OR a wire with a reg in Verilog? If not is there a better way to implement this? Can the control signal outputs be registers in the control module, but wires in the top module?
Update with picture for clarification:
Yes, you can or a wire and a reg output in Verilog.
Yes, each sub-module's outputs, which are essentially wires, can be directly or indirectly internally connected to a reg within the sub-module.
I think that is a fine way to do it.
Now, you can even declare the outputs of a module to be "reg", but that is just semantic sugar over declaring the output and reg separately. I like the explicit way better (i.e. q1_o and q1_reg).
module Submod(input clk_i, intput d_i, output q1_o, output reg q2_o);
reg q1_reg;
always #(posedge clk_i) begin
q1_reg <= d_i;
q2_o <= ~d_i;
end
assign q1_o = q1_reg;
endmodule
module Main(input clk_i, input [3:0]ext_i, output [1:0]ext_o)
wire mux, x1, x2;
Submod Submod_inst(clk_i, ext_i[0], x1, x2);
assign ext_o[0] = x1;
assign mux = ext_i[1] ? ext_i[2] : ext_i[3];
assign ext_o[1] = mux | x2; /* something like this */
endmodule

How to store input into reg from wire in verilog?

I' trying to store value from wire named 'in' into reg 'a'.
But, the problem is value of reg 'a' is showing 'xxxx' in simulator. However, value of wire 'in' is showing correctly.
My target is just to read value from input wire and store it into a register.
module test(
input [3:0] in,
output [3:0] out
);
reg [3:0] a;
initial
begin
a = in;
end
endmodule
The reason why the value of a is 'xxxx' in the simulation is probably that a is set to the value of in only a single time initially, and a may not yet have been set to any specific value at this time in the simulation.
Declaring a reg in Verilog does not necessarily mean that a hardware register is described by the code. That usually involves the use of a clock signal:
module test(
input clk,
input [3:0] in,
output [3:0] out
);
// this describes a register with input "in" and output "a"
reg [3:0] a;
always #(posedge clk) begin
a <= in;
end
// I assume you want "a" to be the output of the module
assign out = a;
endmodule
Here is a counter example where a reg is used to describe something which is not a register, but only a simple wire:
module not_a_register(
input in,
output out
);
reg a;
always #(in) begin
a <= in;
end
assign out = a;
endmodule
Also note that I have used the non-blocking assignment operator <= inside the always block, which is good practice when describing synchronous logic. You can read more about it here.

Resources