How to treat useless outputs in Verilog? - verilog
Apology the title does not explain the question very well, I'll explain it in detail down below.
I'm new to verilog and got painfully stuck with my first lab assignment. One task is to make a 4*4 carry save multiplier, which is made of two types of multipliers, which are in turn made of full adders and AND gates, full adders are made of half adders. I built from the simplest half adders all the way up to the carry save multiplier.
two types of multipliers: http://i129.photobucket.com/albums/p205/Jack_Tianyu_Yang/Capture1_zpsf34b724c.png
hand-drawing of the carry save multiplier
http://i129.photobucket.com/albums/p205/Jack_Tianyu_Yang/photo_zps905f2c13.jpg
The code for the carry save multiplier is here. I instantiated the two types of multipliers and use a lot of internal wires for connections. (I admit it's pretty naive but this is the best i can do for the time being, I'll keep practicing and get better at it.) My QUESTION is this: refer to the "hand-drawing" ,the most left module on the top row, you can see there are two ports---q0_out and q1_out, that are outputs of this multiplier module BUT not part of the outputs in the main output list. Actually, q0_out,q1_out,q2_out,q3_out and m0_out,m1_out,m2_out,m3_out are all not in the output list. They are actually the same value of q0 to q3 and m0 to m3,respectively. (This can be verified by the first image)
When I synthesized the code I pasted below, Xilinx ISE gave me a bunch of same warnings saying for example :"Assignment to q3_out ignored, since the identifier is never used".
When I ask the TA, he said I should "treat the 4*4 carry save multiplier as a black box and the only inputs are m3m2m1m0, q3q2q1q0 and the only output is p7p6p5p4p3p2p1. Outputs like q3_out are 'internal' and should not be presented in the final output list". I don't how to deal with this situation. As you can see, I simply assign q3 to q3_out because q3_out is the same value propagated all the way from q3.
Please feel free to comment on my codes (what to improve, what's a bad coding style) and ask me for more elaboration of the question, also, if possible, please please share some ideas of how to solve this problem. Thank you all in advance.
`timescale 1ns / 1ps
module multiplier44_OMG(
input m0,m1,m2,m3,q0,q1,q2,q3,
output p0,p1,p2,p3,p4,p5,p6,p7
);
wire w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20;
wire w21,w22,w23,w24,w25,w26,w27,w28,w29,w30,w31,w32,w33,w34,w35,w36,w37; //Internal wires
wire cin0,cin1,cin2,mk1_mul2_3; //These inputs are feeding into the carry save multiplier and are all zeroes.
wire q0_out,q1_out,q2_out,q3_out,m0_out,m1_out,m2_out,m3_out;
assign cin0=1'b0;
assign cin1=1'b0;
assign cin2=1'b0;
assign mk1_mul2_3=1'b0;// Inputs are assigned to zero.
assign q0_out=q0;
assign q1_out=q1;
assign q2_out=q2;
assign q3_out=q3;
assign m0_out=m0;
assign m1_out=m1;
assign m2_out=m2;
assign m3_out=m3;//THIS IS THE PART I DON'T KNOW HOW TO DEAL WITH
and (p0,m0,q0);
multiplier2 mul2_0(m1,m0,q0,q1,cin0,w1,w2,w3,w4,p1);
multiplier2 mul2_1(m2,m1,w1,w2,w3,w5,w6,w7,w8,w9);
multiplier2 mul2_2(m3,m2,w5,w6,w7,w10,w11,w12,w13,w14);
multiplier2 mul2_3(mk1_mul2_3,m3,w10,w11,w12,q0_out,q1_out,w15,w16,w17);
multiplier mul_0(w9,w4,q2,cin1,w18,w19,w20,p2);
multiplier mul_1(w14,w8,w18,w19,w21,w22,w23,w24);
multiplier mul_2(w17,w13,w21,w22,w25,w26,w27,w28);
multiplier mul_3(w15,w16,w25,w26,q2_out,w29,w30,w31);
multiplier mul_4(w24,w20,q3,cin2,w32,w33,m0_out,p3);
multiplier mul_5(w28,w23,w32,w33,w34,w35,m1_out,p4);
multiplier mul_6(w31,w27,w34,w35,w36,w37,m2_out,p5);
multiplier mul_7(w29,w30,w36,w37,q3_out,p7,m3_out,p6);
endmodule
It's does not feel any good staring at the code alone in the lab on a friday night.(Plus it's Spring festival.) I know my question is quite elementary, but even though I need help, GREAT help from the GREAT netizens.
A warning is just a warning, it's not an error. If you have a signal that is generated that has no load, then the synthesizer warns you, but there's nothing really there to 'fix'.
Also, since q3_out is output from mul_7, you shouldn't be driving it with a separate assign statement. Each wire should only have one driver.
Related
How to create buffer gate with Vivado Schematic?
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.
Verilog design - input is "unused" warning
When attempting to synthesize a Verilog design (I want to generate a schematic), I get the following warning: Synthesizing Unit <rising>. Related source file is "C:\PPM\PPM_encoder\detectors.v". WARNING:Xst:647 - Input <in> is never used. This port will be preserved and left unconnected if it belongs to a top-level block or it belongs to a sub-block and the hierarchy of this sub-block is preserved. Summary: no macro. Unit <rising> synthesized. The relevant module is simply: module rising (in, out); output out; input in; not #(2,3) (ininv, in); and #(2,3) (out, in, ininv); endmodule And I call it in several different locations, including: rising startdetect( .in(start), .out(or01a)); When I complete the synthesis and then choose to "View schematic", only one component is actually present. Expanding that component, I see only the output being connected to ground, which is the initial condition. Nothing else is present. This is with my testbench as my "top module". When I select my actual main project (below the testbench, it's called ppmencode) as the top module, I get those same warnings, plus additional warnings for every single module instance: WARNING:Xst:1290 - Hierarchical block <startdetect> is unconnected in block <ppmencode>. It will be removed from the design. What is the cause of these two warnings, and how can I fix them and be able to generate a correct schematic? Edited to add: The whole thing simulates perfectly, it's just when trying to make a schematic (to try to explain this thing that I just made to my team) that I run into problems. This image shows the schematic that I get.
It's not enough to have a signal named as an input to a module...it needs to actually be connected to a pin on the FPGA. On the other hand, your rising module is taking the AND of the input and its complement...the synthesizer might have figured out a way to simplify that logic that is contrary to your wishes.
Synthesis is optimizing all the logic out because it ignores the delays. Functionally you have in & ~in which is always 0. What you intend is a pulse generator. One way to achieve this is to use the dont_touch attribute, which tell the synthesizer that it must keep a particular module instantiation in the design. See this Properties Reference Guide for more. module rising (in, out); output out; input in; (* DONT_TOUCH = "TRUE" *) not #(2,3) (ininv, in); and #(2,3) (out, in, ininv); endmodule Be warned that even with the dont_touch your synthesize result may not match simulation. Synthesis ignores the artificial timing in your netlist. The actual pulse width could be longer, more likely shorter or to small to be registered. Check your standard cell library and look for a delay cell to apply to ininv, this will increase the pulse width. The library may already have a pulse generator cell already defined.
BCD to Excess 3 verilog code (case)
I got my code to work. I did not set my output to 3'b000 before running the case statements. it compiles and gives me desired outputs i think still verifying . I still have trouble with rtl compiler to take a shapshot of the circuit. Im sure every compiler is slightly diffrent so im not sure if anyone can help with this. I'm not sure why it hates everything. will re-post when done or if someones interested in helping thanks
First things that I see are that you need to use semicolon, not comma, to separate your statements. Also, if you want to set the value of X during procedural statement (always block), then it needs to be a reg type. Signals declared as output are implicitly wire type, unless you declare it as output reg [3:0] X.
Using blocking assignments to infer flip-flops in Verilog
I have read "Nonblocking Assignments in Verilog Synthesis, Coding Styles that Kill!" by Clifford Cummings. He says that the following code (page 12, simplified) is a correct implementation of a flip-flop often used in textbooks, even if not exactly the kind that anyone should use. The document won a best paper award, so I assume the claim is true. module ff (q, d, clk) output q; input d, clk; reg q; always #(posedge clk) q = d; endmodule I would like to know why this would continue to work correctly if two or more of these flip-flops were connected in series. Say module two_ffs (q, d, clk) input d, clk; output q; wire tmp; ff firstff (tmp, d, clk); ff secondff (q, tmp, clk); endmodule The way I see it, it's possible that the value of tmp is updated before it is used by secondff, thus resulting in one flip-flop rather than two. Can someone please tell me what part of the standard says that cannot happen? Many thanks. [not that I would ever contemplate writing code like that, I just want to understand the blocking/nonblocking behavior even in cases when poor coding style makes the meaning non-obvious] Added later: I now think the paper is unlikely to be correct. Section 5 "Scheduling Semantics" of the 1364-2201 Verilog standard explains what happens. In particular, section 5.6.6 "Port connections" on page 68 says that unidirectional ports are just like continuous assignments. In turn, a continuous assignment is just an always block sensitive to everything. So the bottom line is that that the two instantiations of an ff in my example below are equivalent to a module with multiple always clauses, which everyone would agree is broken. Added after Clive Cummings answered the question: I am grateful to CC for pointing out that that the statements above taken out of section 5 of the standard only refer to the timing of update events, and do not imply literal equivalence between e.g. some continuous assignments and always blocks. Nevertheless, I think they explain why some simulators (e.g. Icarus Verilog) will produce different simulation results with a blocking and a non-blocking assignment in the "flip-flop". [On a larger example, I got 2 apparent ffs with a blocking assignment, and the correct five with a non-blocking one.] Other simulators (e.g. Modelsim with default options or Cver) seem to produce the same result no matter which form of assignment is used.
All - A few corrections and updates. Section 5.6.6 of the 2001 Verilog Standard does not say that "unidirectional ports are just like continuous assignments," it says "Ports connect processes through implicit continuous assignment statements." There is a difference that I will note below. Second, "a continuous assignment is just an always block sensitive to everything," is not true. Continuous assignments Drive values onto nets that can be driven by other sources with pre-defined resolution functions as described in the Verilog Standard. Always blocks Change values of variables and last procedural change wins (no resolution). Regarding my description of the 1-always block flip-flop, my description in the paper is not 100% accurate (but is usually accurate). The 2-instantiated flip-flop model in theory does have a race condition, though it is rarely seen. The race is rarely seen because when you make an always block assignment to a variable that is declared as an output, Verilog compilers automatically throw in an "implicit continuous assignment statement" (IEEE-1364-2001, Section 5.6.6, 1st paragraph) to convert the procedural variable into a net-Driving assignment (you never see this happen!) This conversion is typically sufficient to introduce the equivalent of a nonblocking assignment delay on the port, so the simulation works. I have experimented in the past with compiler optimization switches that effectively remove the module ports between the flip-flops and have observed the unwanted race conditions, so technically, my description of an okay 1-always, blocking-assignment flip-flop is not 100% correct; hence, you should still use the nonblocking assignments described in the paper. The 2-always blocking-assignment example in the same module has a definite race condition. As written, it will probably work because most compilers execute the code top-down, but if you reverse the order of the always blocks, you will probably see a race. Regards - Cliff Cummings - Verilog & SystemVerilog Guru
Reading Version 1.3 of the paper, Section 9 Example 13. The text under it explains that it is OK if the module only contains a single always block. My current understanding is that it is not an issue between separate modules. Allowing your example to work. However if a module contained multiple always blocks then the order of execution is undefined and will lead to the race conditions talked about in section 2 of the paper. The example below is almost the same as the 2 flop example in the question, except it is in 1 module and so has an undefined order of execution, this will likely not work. module ff (q, d, clk) output reg q; input d, clk; reg d_delay ; always #(posedge clk) d_delay = d; always #(posedge clk) q = d_delay; endmodule
Verilog array syntax
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.