I need to create mux block that works with inout pins.
My module has n inputs and n outputs, I want to be able to switch
between different outputs.
The problem that I am currently having is that I need to do that with
inout pins. So if my output pin is pulled down, the input pin of the
mux shall see that. This doesn't work with a common assign statement since
it will only write in one direction. I have tried an alias statement, which
works like a bidirectional assign, but I can not combine this with an if statement for the mux.
What I want to do:
alias net_out = (config) ? net1 : net2;
I have created an example on edaplayground
Thanks in advance,
Patrick
You can use the bidirectional tran primitives, which is exactly how one would implement this in MOS hardware.
tranif1(net_out, net1, config);
tranif0(net_out, net2, config);
If you are looking to do this in hardware, this has to be something your technology supports. Most FPGAs would not support this.
However, if this config signal was a parameter and not a variable, you could use the alias statement with a generate-if
if(config)
alias net_out = net1;
else
alias net_out = net2;
Related
I am learning Verilog with Vivado for the first time. I am trying to create simple buffer gate with it.
Here is the code I've tried. The first one is Design Source file with name 'inv.v'.
`timescale 1ns / 1ps
module inv(
input a,
output x
);
IBUF buffer(x, a);
endmodule
This code does create buffer gate, but it creates 2 of them.
I've also tried the following code.
`timescale 1ns / 1ps
module inv(
input a,
output x
);
assign x = a;
endmodule
However, this creates nothing. What I want is to create only one buffer gate, which is shown in above image. Does anyone know how?
p.s. I am using Vivado 2017.3 HLx Edition.
IBUF and OBUF are IO buffers: one drives into the logic array from the input pin; the other drives the output pin from the logic array. These are put in by the tool, because they are necessary for electrical reasons (ie reasons of voltage, current etc rather than reasons of boolean arithmetic).
This is why you are struggling to put in your own buffer. A buffer has no function at the boolean level, it is only necessary for electrical reasons. Your Verilog does not concern itself with such detail: such things are added automatically by logic synthesis/layout tools should they feel they are necessary for these electrical reasons (eg to drive a long track or to drive many inputs).
If you want to try something basic to see how your Verilog gets turned into (ie synthesised to) real gates, you'll need to try something that has some function at the boolean level, for example an AND gate. Or, if you want to make it as basic as possible, an invertor.
See the 7-series libraries guide for more info on ibuf & obuf primitives.
https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_3/ug953-vivado-7series-libraries.pdf
Here is a quote from around page 341 of the file at the link.
"In general, IBUFs are inferred by the synthesis tool for top-level input ports to the design, so it is not necessary to specify them in the source code. However, if desired, they can be manually instantiated by copying the code from the appropriate Libraries Guide HDL template and it into the top-level of your code.
Your first example is the instantiation referred to in the libraries guide. For your second example, there is no component instance and Vivado determined no buffer is needed.
I have a quick question.
How can I use the outputs of two other modules with a new module?
Example:
module test1(ans, X, Y)
output ans;
input X, Y;
do stuff
endmodule
module test2(ans2, X, Y)
output ans2;
input X, Y;
do stuff
endmodule
module result(final_ans, ans, ans2) <------- this is what I mean.
do stuff
endmodule
How would I go about this? How do I call the other two modules?
Thank you for the help.
You do not call modules. You instance modules. Verilog is not like normal programming languages, it is a hardware simulation language. If you stick to a subset of the language and you use that in the right way that language can also be converted to real hardware. That latter is called RTL (Register Transfer Language). I strongly suggest you find some existing Verilog code examples and study how people use it.
Thus what you do is you make an instance of each module and you connect
signals to the inputs and outputs. Compare it to placing an IC on a board and soldering wires to it. But then all in software.
test1 instance_of_test1 (
.X(signal_into_X),
.Y(signal_into_Y),
.ans(signal_outof_ans)
);
Then you can use the signals coming out of test1 and test2 to go into result:
result instance_of_result (
.ans(signal_outof_ans),
.ans2(signal_outof_ans2),
.final_ans(signal_outof_final_ans)
);
Just as a side note:
The example I use also shows that naming conventions using the port direction is general a bad idea. Signals come out of one module and go into another. Thus the name signal_outof_ans is fine for the module test1 but it is wrong for the module result as there it goes into the module. Here I wanted to emphasize what happens at the level of module test1. (I also know that some companies even prescribe it as the preferred coding style so I am waiting for the flak to arrive on this). In my own code I would never use this. So here is the correct way to code:
wire ans,ans2;
test1 instance_of_test1 (
.X(X),
.Y(Y),
.ans(ans)
);
...
...
result instance_of_result (
.ans(ans),
.ans2(ans2),
.final_ans(final_ans)
);
In a Verilog module, what is the proper terminology for arguments?
What does a variable default to when it's not defined?
A module in Verilog represents hierarchy that is only used for grouping objects by name and replicating those objects. When you run a simulation or synthesize to hardware, that hierarchy gets flattened. Ports of a module join two signal names together, and after flattening, there is only one signal with multiple names. So modules are structurally connected through ports.
The term argument is terminology from software that usually represents a object that gets copied or referenced when you procedurally call a routine like a function or task.
For your second question, if you refer to a variable without defining it, that is usually a compiler error. There is one exception to that for lazy engineers. If you refer to a undefined variable in a port connection, that variable is implicitly declared as a 1-bit wire. If nothing drives that wire, it has the default value 'z which is treated the same as 'x in any expression.
This feature was originally intended for automatically generated gate-level net-lists where every signal is a 1-bit wire, but causes many problems for RTL descriptions. We strongly recommend that use use the compiler directive `default_nettype none to prevent careless typos.
They are called ports . A Verilog module cannot be called like a function, as it is meant to represent a hardware module with input , output , bi-directional pins etc , so it can only be instanced. These instances can be connected to each other again via their ports. These ports bring in and take out data/value/signals into and out of the modules. Hence ports have direction associated with them. Unlike an arguments in a function which only passes on the value when the function is called , once a connection is made to a port ( via a wire/reg (register) / ...) any change to the connected variable is transferred to the module via the port automatically.
link to a module- port explanation.
http://www.asic-world.com/verilog/syntax2.html
Verilog does have functions and tasks which take arguments.
http://www.asic-world.com/verilog/task_func1.html
Uninitialized variables take on unknown value represented by "x" .
There are a few nuances to it
unconnected wire , tri will be tri-state represented by "z"
any 4 state logic - reg , integer , time will default to "x"
real type to 0 .
I have seen lots of system verilog program examples representing packets of data as a packed structure.
Does this data travel serially like a packet? How does a system verilog structure be realized in hardware?
A packed structure in SystemVerilog simply gives you an alternative way to access fields of a signal by name instead of by bit position. For example
typedef struct packed {
logic [2:0] field1; // 3-bits
logic [4:0] field2; // 5-bits
} signal_t; // 8-bits
You can now declare either a wire or variable with that type
wire signal_t sigA;
var signal_t sigB;
(the var keyword is implicit is most places except in a port declaration)
You can now access field1 as either sigA[7:5] or sigA.field1.
Unpacked structures, as nguthrie points out, provide a hierarchical grouping of variables, but they also provide a stronger types than Verilog. See my application note on this.
Structures are just a convenient way of encapsulating variables. It is a way to show that these variables should be operated on as a group. However, calling something a packet is not going to get the synthesizer to create the hardware that you want. It is up to you to create the logic for the protocol that you are dealing with.
I'm new to Verilog, and am having a lot of trouble with it. For example, I want to have an array with eight cells, each of which is 8 bits wide. The following doesn't work:
reg [7:0] transitionTable [0:7];
assign transitionTable[0] = 10;
neither does just doing transitionTable[0] = 10; or transitionTable[0] = 8'h10; Any ideas?
(In case it is not obvious and relevant: I want to make a finite state machine, and specify the state transitions in an array, since that seems easier than a massive case switch.)
When using assign you should declare the array as a wire instead of areg.
Since your goal is to design an FSM, there is no need to store the state values in an array. This is typically done using Verilog parameter's, a state register and a next_state with a case/endcase statement.
The following paper shows a complete example: FSM Fundamentals
If this is targeted towards synthesis:
A little beyond what was answered above, there are standard FSM coding styles that you should adhere to so the tools can perform better optimization. As described in the Cummings paper, one-hot is usually best for FPGA devices and in fact ISE(with default settings) will ignore your encoding and implement whatever it thinks will best utilize the resources on the device. This almost invariably results in a one-hot encoded FSM regardless of the state encoding you chose, provided it recognizes your FSM.
OK, so to answer your question, let's dig a little deeper into Verilog syntax.
First of all, to specify a range of bits, either do [MSB:LSB] or [LSB:MSB]. The standard is MSB:LSB but it is really up to you here, but try to be consistent.
Next, in array instantiation we have:
reg WIDTH reg_name NUMBER;
where WIDTH is the "size" of each element and NUMBER is the number of elements in the array.
So, you first want to do:
reg [7:0] transitionTable [7:0];
Then, to assign particular bytes (8 bits = 1 byte), do:
initial begin
transitionTable[0] = 8'h10;
end
A good book to learn Verilog from is FPGA Prototyping By Verilog Examples by Pong P. Chu.