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)
);
Related
I've been using Verilog and SystemVerilog for many years, but I just came across something which seems weird.
I don't know if it's something I just never noticed or if there is something special about this I am missing.
Basically I have a module which has a 16-bit input, to which I connected an 8-bit signal. This seems like no big deal to me, in fact it's one of the things I love about Verilog/SystemVerilog, since unlike VHDL, you are allowed to do things like that.
I would expect the signal connected to the input port of my module to be right-aligned and zero-padded on the left, but instead it is being padded with Zs.
That causes my simulation to not work, because for example I use that signal to initialize a counter after substracting one from it, which leads XXXX.
Is this behaviour expected? Can I change something in my code to get the behaviour I expected?
This behavior seems reasonable. I ran a simulation on several simulators on EDA Playground, and I got a mix of results: some had the MSBs as 0, others had them as z.
The best approach is to explicitly drive the inputs with the value you desire. For example, if you want the MSBs to be 0, use something like:
module tb;
reg [7:0] data;
// ...
dut i1 ({ {8{1'b0}}, data });
endmodule
This creates a 16-bit expression which is connected to the module input port. The expression is a concatenation of an 8-bit constant and the 8-bit data signal.
If there is a size mismatch happening in your design or testbench, there should be a warning (if not an error) raised from your compiler/simulation tool. There is no default behavior defined to pad with 0 or undriven z, therefore it can be 0-padded or unknown depending on your tool, and you are on your own risk. The best practice is to watch carefully if there is such warning/error already reported, and try to resolve it during compilation/elaboration phase, or better to run a linting tool before compilation.
Say I have a Verilog module that's parameterizable like the below example:
// Crunches numbers using lots of parallel cores
module number_cruncher
#(parameter NUMBER_OF_PARALLEL_CORES = 4)
(input clock, ..., input [31:0] data, ... etc);
// Math happens here
endmodule
Using Verilog 1364-2005, I want to write a testbench that runs tests on this module with many different values NUMBER_OF_PARALLEL_CORES.
One option that I know will work is to use a generate block to create a bunch of different number_crunchers with different values for NUMBER_OF_PARALLEL_CORES. This isn't very flexible, though - the values need to be chosen at compile time.
Of course, I could also explicitly instantiate a lot of different modules, but that is time consuming and won't work for the sort of "fuzz" testing I want to do.
My questions:
Is there a way to do this by using a plusarg passed in from the command line using $value$plusargs? (I strongly suspect the answer is 'no' for Verilog 1364-2005).
Is there another way to "fuzz" module parameterizations in a testbench, or is using a generate block the only way?
Since $value$plusargs is evaluated at runtime, it can not be used to set parameter values, which must be done at compile-time.
However, if you use generate to instantiate multiple instances of the design with different parameter settings, you might be able to use $value$plusargs to selectively activate or enable one instance at a time. For example, in the testbench, you could use the runtime argument to only drive the inputs of a specific instance.
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.
Is it possible to use assign keyword with module instances?
Lets assume I have a module logarithm which works as it's intended. In some other module, I want to have: A = log(B) + log(C).
Is there any efficient way other than the following to do so?
wire [3:0] logB;
wire [3:0] logC;
Logarithm log(logB, B);
Logarithm log(logC, C);
assign A = logB + logC;
And is it known as a gate-level design or a data-flow one?
If it is not data-flow, would you please present a data-flow alternative to this code?
Well your assign keyword in the code is not working on module instances. Rather, it is working on the outputs of those module instances.
The way you are assigning to A should help you get the desired output provided you have set its width accordingly. And it is a data flow representation
There is one mistake in your given lines of code though. You can not use the same instance name log for both the instantiations of the module Logarithm. They have to be unique.
I am having a bit of trouble instantiating a module in verilog. I am using the Altera Quartus platform to develop and simulate the verilog code.
I have followed this example (among several others):
http://www.asic-world.com/verilog/verilog_one_day4.html
I have written a module (maximum) which finds the maximum between two signed inputs.
Another module I am developing is a systolic array for genetic sequence alignment. The details are not important, however when I try to instantiate a maximum module I get an error.
This is my code so far:
module maximum (a, b, out);
input signed [15:0] a;
input signed [15:0] b;
output reg signed [15:0] out;
always #* begin
if (a>b)
assign out = a;
else
assign out = b;
end
endmodule
and I instantiate in another module systolic_PE (all of this is in the same file seqalign.v)
maximum m0(.a(tempB), .b(diag), .out(tempA));
And I get the error :
'Verilog HDL syntax error at seqalign.v(139) near text "m0"; expecting
"<=" or "="'
I checked everything I have done so far, and I cant seem to see anything I have missed out on.. could anyone be kind enough to guide me?
Also on a side note:
Instantiation of a module in verilog
I was trying to instantiate my module in a if statement, so I tried outside of the if statement in a always #(posedge clk) block, and I get the error
HDL syntax error at seqalign.v(88) near text "("; expecting ";"
Looking over the code you posted in your comment, the issue is from instantiating your module inside your always #(posedge clk) block on line 70. You never instantiate modules inside of procedural blocks (always, initial, etc).
As Verilog is a Hardware Descriptive Language, you have to be in the mindset of designing hardware when writing your code. Module instantiation is like soldering a chip onto a PCB, at design time you either do it, or you dont, and that component stays there for all time. You dont say, well, I want this chip here some of the time, but take it off the PCB when the system gets into these states. In your code, you conditionally instantiate your module if state is 3. However, state changes over time. So that is akin to saying, when the register containing state reads 3, place down this chip into the system, otherwise, it doesnt exist and take it out. On a code level, think of instantiated modules as their own procedural blocks, just as you dont put always inside of other always, dont put modules in always blocks (of course, module definitions/declarations can have always blocks inside them).
Modules are persistent and compile time constant, so you can use generates to conditionally instantiate modules at compile time (ie, decide whether or not to include the module in the design when building the system). But in your code, you are conditionally instantiating at simulation time, which is not allowed as described above.
You can do one of two things to solve your problem. One would be to move your task from your submodule maximum into the systolic_PE module and use it to get the maximum of your variables tby calling it (line 123 would become something like tempA <= convert(.a(0), .b(diag+match)); with a and b added as inputs to your task). Or, instantiate the module outside the always block, but youll need to change your task to be a procedural block like you have in the actual post.