I am debugging some Verilog code and I'm having some difficulty understanding a bidirectional signal with multiple drivers:
The verilog code looks like this:
inout a;
assign a = b ? c : 1'bz
a=Stx b=St1 c=St0
assign (weak0, weak1) a = d ? 1'bz : (e ? 1'b0 : (f ? 1'b1 : 1'bz));
a=Stx d=St0 e=St0 f=St0
Signal c is the actual data that needs be transmitted to a (output pad). When I run the simulation using a commercial simulator, I get the values annotated above. I don't understand why a ends up being X throughout the simulation. b is toggling and c is also toggling. d/e/f are always 0. The 2nd statement is using a weak pull-up/pull-down but by setting it d/e/f=0, it should drive Z. So the other statement should win out?
With your code above, you are in essence creating a bidirectional buffer which is one input buffer from IO pad to internal signal, and an output buffer from internal signal to IO pad that is controlled by an enable. The b signal is the enable on one side and the d signal is the enable on the other side.
Remember that a bidirectional signal or bus must still have some kind of arbitration on it, something that understands the bidirectional transactions that are occurring as both sides should not be enabling their output buffers at the same time.
Related
I am new to the field of ASIC design. I am trying to synthesize my code but am facing a problem when synthesizing. The tools used are Openlane and technology node is GF180 nm. The issue is that when synthesizing verilog blocks such as following are not completely synthesized and only partially synthesized. e.g.
//a is a single bit value with value 0 or 1
//f is a 8 bit vector and fin is a 16 bit vector
//depending on the value of a, either the first half or the second half of the fin goes to f
case (a)
0: begin
f=fin[7:0];
end
1: begin
f=fin[15:8];
end
The problem is that after the net-list is generated only the first half of the fin is connected and the rest of fin is removed i.e. only the condition for 1st case block is synthesized rest is removed (in optimization pass I presume). I have confirmed this from the netlist as well as gds generated where the pins for fin[15:8] are unconnected.
I have tried to create illusions in the code by creating a dummy register and connecting the unused part of input fin to that register but to no avail. The net-list still does not connect the upper parts of fin to anything. The above sample code is part of a larger code block and there are more case and if statements on top of this block. I am expecting a chain of multiplexers to be used to synthesize the logic. I am hoping if anyone can tell what kind of coding style can be opted to avoid this problem? How can this logic be written so that this issue does not arise for other designs?
I'm writing Verilog code for a Sparatn-6 Xilinx FPGA in which I would like to reconfigure IO during 'runtime' specifically, between single ended and differential IO buffers.
I have read through the list of IO buffer primitives in UG381.pdf but all seem to be fixed single ended or differential (on the pad side)
I have tried instantiating an OBUF and an OBUFDS but have found no way to mux the outputs of the bufs to a single pad, or combine them before or as part of their association with a pad. The wiring of adjacent pads to form differential outputs/inputs seems to be entirely hidden away, as you might expect, but also therefore seems to prevent the use of the OBUF for anything other than the differential function which it doesn't need to as such...
What envisage I need is:
SELECTABLE_SINGLE_DIFF_OBUFDS #(
.IOSTANDARD ("LVDS_33")
) my_buf (
.I (my_signal), // logic input (fabric side)
.IO (diff_p_out), // Single ended o/p or Differential +ve (to pin)
.IOB (diff_n_out), // Differential -ve (to pin)
.MODE (my_mode == 1) // mode = 0, single ended output
// mode = 1, differential output
);
There must be something when you instantiate a OBUF or OBUFDS that configures the underlying SelectIO block's differential capabilities, I guess what I'm looking for is a way to access the underlying block from within Verilog so I can control the configuration of the IO Block from other logic in the FPGA.
As long as you only need differential outputs, you can probably get away with just using two single-ended registered outputs and drive the negative output inverted.
I've recently found a code like this in a Verilog code that I'm referring to write finite state machine.
reg [15:0]Bus;
Bus = 'bzzzzzzzzzzzz1111;
What is the meaning of z here?
From the IEEE Std 1800-2012, section "6.3.1 Logic values":
z—represents a high-impedance state
The SystemVerilog value set consists of the following four basic values:
0—represents a logic zero or a false condition
1—represents a logic one or a true condition
x—represents an unknown logic value
z—represents a high-impedance state
The values 0 and 1 are logical complements of one another.
Z represents a high impedance state, but why would you want that?
It basically means that you aren't driving the output of the bus, so that something else can drive it.
You're most likely to use this when driving the output ports of your device, say the FPGA is comunicating with another chip with the I2C protocol, you send your read request, then drive Z on the bus to allow the device to respond with the data you requested
I have my first verilog assignment due in a few days and for whatever reason these concepts are escaping me. I don't think I'm thinking in terms of parallelism and hardware or something.
My question is that I have to and a few switches and buttons together using wires and turn on 3 LEDs in array of 7. I'm pretty sure I know how to do the computational logic, but I can't figure out how to use assign and wire to properly turn on all 3 LEDs without writing 3 separate lines. It feels wrong to do:
assign Led[0] = output;
assign Led[1] = output;
assign Led[2] = output;
Also, it's weird because there are 7 LEDs on the board and I'm picking on LEDs 0,2,4.
Can someone walk me through how this is supposed to work the proper way? We don't have a textbook and I've been reading the basics online, but I just can't seem to figure out how this is supposed to work. Thanks!
Edit: This is my current code, but I am getting errors that say nothing is "driven". What gives?
module Lab2_1(input [5:0] sw, input btns, output [7:0] Led );
wire [2:0] leds;
wand out;
assign leds = {Led[0], Led[2], Led[4]};
and U1 (out, sw[0], sw[1]);
and U2 (out,~sw[2],~sw[3]);
xor U3 (out,sw[4],sw[5]);
assign out = btns;
assign leds[2:0] = {3{out}};
endmodule
Errors:
ERROR:PhysDesignRules:368 - The signal <Led<3>_OBUF> is incomplete. The signal
is not driven by any source pin in the design.
ERROR:PhysDesignRules:368 - The signal <Led<4>_OBUF> is incomplete. The signal
is not driven by any source pin in the design.
ERROR:PhysDesignRules:368 - The signal <Led<5>_OBUF> is incomplete. The signal
is not driven by any source pin in the design.
ERROR:PhysDesignRules:368 - The signal <Led<6>_OBUF> is incomplete. The signal
is not driven by any source pin in the design.
ERROR:PhysDesignRules:368 - The signal <Led<7>_OBUF> is incomplete. The signal
is not driven by any source pin in the design.
ERROR:PhysDesignRules:368 - The signal <Led<0>_OBUF> is incomplete. The signal
is not driven by any source pin in the design.
ERROR:PhysDesignRules:368 - The signal <Led<1>_OBUF> is incomplete. The signal
is not driven by any source pin in the design.
ERROR:PhysDesignRules:368 - The signal <Led<2>_OBUF> is incomplete. The signal
is not driven by any source pin in the design.
ERROR:PhysDesignRules:10 - The network <Led<3>_OBUF> is completely unrouted.
ERROR:PhysDesignRules:10 - The network <Led<4>_OBUF> is completely unrouted.
ERROR:PhysDesignRules:10 - The network <Led<5>_OBUF> is completely unrouted.
ERROR:PhysDesignRules:10 - The network <Led<6>_OBUF> is completely unrouted.
ERROR:PhysDesignRules:10 - The network <Led<7>_OBUF> is completely unrouted.
ERROR:PhysDesignRules:10 - The network <Led<0>_OBUF> is completely unrouted.
ERROR:PhysDesignRules:10 - The network <Led<1>_OBUF> is completely unrouted.
ERROR:PhysDesignRules:10 - The network <Led<2>_OBUF> is completely unrouted.
ERROR:Bitgen:25 - DRC detected 16 errors and 0 warnings. Please see the
previously displayed individual error or warning messages for more details.
What you have already seems perfectly fine, though if you wanted to do it in one line you could use a concatenation and or replication operators to assign multiple bits of Led. Both these statements are equivalent to your code sample:
assign Led[2:0] = {output, output, output};
or
assign Led[2:0] = {3{output}};
I don't know if these are any better or more proper than what you already have, but just writing them to show some examples of what is possible to do.
=== EDIT ===
You're getting errors because you're not driving any of the bits of Led.
This looks backward: assign leds = {Led[0], Led[2], Led[4]};
Led is the output of the module, so it should be assigned to, meaning it should be on the left hand side of the equal, so I would guess this should look like assign {Led[0], Led[2], Led[4]} = leds;
Your module has an 8-bit Led output, but you're only assigning 3 bits of it. You should assign the other 5 bits to either constant 1 or 0.
I found the following piece of code in the internet , while searching for good FIFO design. From the linkSVN Code FIFO -Author Clifford E. Cummings . I did some research , I was not able to figure out why there are three pointers in the design ?I can read the code but what am I missing ?
module sync_r2w #(parameter ADDRSIZE = 4)
(output reg [ADDRSIZE:0] wq2_rptr,
input [ADDRSIZE:0] rptr,
input wclk, wrst_n);
reg [ADDRSIZE:0] wq1_rptr;
always #(posedge wclk or negedge wrst_n)
if (!wrst_n) {wq2_rptr,wq1_rptr} <= 0;
else {wq2_rptr,wq1_rptr} <= {wq1_rptr,rptr};
endmodule
module sync_w2r #(parameter ADDRSIZE = 4)
(output reg [ADDRSIZE:0] rq2_wptr,
input [ADDRSIZE:0] wptr,
input rclk, rrst_n);
reg [ADDRSIZE:0] rq1_wptr;
always #(posedge rclk or negedge rrst_n)
if (!rrst_n) {rq2_wptr,rq1_wptr} <= 0;
else {rq2_wptr,rq1_wptr} <= {rq1_wptr,wptr};
endmodule
What you are looking at here is what's called a dual rank synchronizer. As you mentioned this is an asynchronous FIFO. This means that the read and write sides of the FIFO are not on the same clock domain.
As you know flip-flops need to have setup and hold timing requirements met in order to function properly. When you drive a signal from one clock domain to the other there is no way to guarantee this requirements in the general case.
When you violate these requirements FFs go into what is called a 'meta-stable' state where there are indeterminate for a small time and then (more or less) randomly go to 1 or 0. They do this though (and this is important) in much less than one clock cycle.
That's why the two layers of flops here. The first has a chance of going meta-stable but should resolve in time to be captured cleanly by the 2nd set of flops.
This on it's own is not enough to pass a multi-bit value (the address pointer) across clock domains. If more than one bit is changing at the same time then you can't be sure that the transition will be clean on the other side. So what you'll see often in these situations is that the FIFO pointers will by gray coded. This means that each increment of the counter changes at most one bit at a time.
e.g. Rather than 00 -> 01 -> 10 -> 11 -> 00 ... it will be 00 -> 01 -> 11 -> 10 -> 00 ...
Clock domain crossing is a deep and subtle subject. Even experienced designers very often mess them up without careful thought.
BTW ordinary Verilog simulations will not show anything about what I just described in a zero-delay sim. You need to do back annotated SDF simulations with real timing models.
In this example, the address is passed through the shift register in order for it to be delayed by one clock cycle. There could have been more “pointers” in order to delay the output even more.
Generally, it is easier to understand what is going on and why if you simulate the design and look at the waveform.
Also, here are some good FIFO implementations you can look at:
Xilinx FIFO Generator IP Core
Altera's single/double-clock FIFOs
OpenCores Generic FIFOs
Hope it helps. Good Luck!