What does Z in Verilog stand for? - verilog

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

Related

Verilog: Understanding multiple driver on bidirectional signal

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.

Creating a `RAM` chip in `Verilog` with single in/out data port

I want to create a RAM chip in verilog to learn how Verilog, modern chips like RAM and EEPROM allow reading and writing to the chip over a single address port and a single data port.(Data port being the input and output port)
I want to do the same thing in Verilog, and I think I need the inout type, but I don't know how it works.
I google it, but all RAM examples I can find have a separate data write and data read port.
Since the inout type requires both sides to be connected to a wire, I need to connect one wire from one side to a reg chosen by the address.(so no assign).But I don't know how to do that.
This is what I tried and doesn't work:
wire [7:0] a;
wire rw;// 0 if read, 1 if write
reg [7:0] mem [16];
initial begin
if (rw == 1) begin
#1 a = mem[0];// 0 would be the address wire, but excluding it for clarity
end
if (rw == 0) begin
#1 mem[0] = a;// 0 would be the address wire, but excluding it for clarity
end
end
Can anyone help?
Thanks
all RAM examples I can find have a separate data write and data read port.
The reason is a combination of two facts:
A true bi-directional data bus would requires tri-state drivers.
FPGA or ASIC chips no longer have on-chip tri-state drivers.
The only place where a bi-directional data is possible is at I/O where you have tri-state pads.
Thus internally everybody will use the two data buses as any real memory will have at its core a separate read-data and write-data bus. Then at the edge (at the pads) they will switch to bi-directional mode.
To write your own Verilog bi-directional bus you should use tri-state signal assignments. Something along the line of:
inout[7:0] data_bus,
// This assignment is inside the memory model:
// Driving the read data out of the memory device
assign data_bus = mem_read ? mem_read_data : 8'hzz;
// This assignment is outside the memory model
// Driving the write data into the memory device
assign data_bus = mem_read ? 8'hzz : external_driver;

Using single ended port in logic expecting diff-pair?

The logic that I am using is set up to expect a diff-pair clock port. However, for one specific application, I can only input a single ended clock (due to hardware limitation). Modifying the logic to accept single ended clock is not an option as there are many files and lines of code involved. Is there a way I can input a single ended port and somehow feed it to diff-pair ports of modules? So for example in my top level I want to have a port like this:
input single_ended_clk
And I want to feed this to a module that takes the following ports:
input diff_pair_clk_p;
input diff_pair_clk_n;
A very naïve approach would be to do this:
mymodule m_i (
.diff_pair_clk_p(single_ended_clk),
.diff_pair_clk_n(~single_ended_clk),
);
but I don't think this is the proper way to do this.
Most chip designs, either ASICs or FPGAs explicitly instantiate clock buffers rather than infer them. In the FPGA world, the synthesis engines usually aren't smart enough to recognize a clock and hook the buffer outputs to the dedicated clock routing resources. So you really probably need to explicitly instantiate a clock buffer.
Now as to the case where sometimes you want a single ended clock buffer and sometimes you want a double edge clock buffer. While you can use generate statements referencing a parameter to decide which buffer to instantiate, you can't control the port list of the chip this way. You can keep the clock buffer inside the lower level module.
I would not recommend recreating a differential signal inside the chip. There are several problems with this. First, a differential clock buffer expects to be connected to external pins, not internally buffered signals. Secondly, there is a timing mismatch between the positive and negative clock which could create glitches on your resulting clock post-buffer which would make a real mess of your design.
Instead, keep both _n and _p inputs to your sub-module, and use a generate to select the type of clock buffer to be instantiated. In the case of a single ended clock, the _n input is left unconnected and only the _p input is used.
Here's an example for a Xilinx FPGA. The buffer primatives will be named differently in other types of FPGAs or ASIC libraries.
module clock_buffer (
input pin_clk_p,
input pin_clk_n,
output clk_int
);
parameter DIFF = 0;
generate
if (DIFF = 1)
clk_buf IBUFGDS(
.I (pin_clk_p),
.IB (pin_clk_n),
.O (clk_int)
);
else
clk_buf IBUFG(
.I (pin_clk_p),
.O (clk_int)
);
endgenerate
endmodule
There will be a phase offset, it might be within tolerance. It is hard to say without knowing timing requirements for the differential paired clock and single clock, how the clock tree is being handled, timing of buffers and inverters. You may be able to handle this from within the synthesizer by identifying the clocks and there relation. To do this, assign the clocks individually at the appropriate hierarchy level, maybe its own sub-module. diff_pair_clk_p and single_ended_clk are functionally the same, but they should be separated for load balancing and clock-tree balancing.
assign diff_pair_clk_p = single_ended_clk;
assign diff_pair_clk_n = ~single_ended_clk;
Sometime there are predefined modules that are part of the standard/macro cell library which are intend for solving or simplifying specific design challenges. Instantiate these modules where needed, a dont_touch pragma may be needed. Specifically look for cells described as symmetrical buffers and inverters. You may still need to give additional guidance to the synthesizer.

Verilog Tri-State Issue (Xilinx Spartan 6)

Referring to my earlier question here, I've been utilizing tri-states to work with a common bus. I still appear to have some implementation issues.
The tri-states use this type of code:
assign io [width-1:0] = (re)?rd_out [width-1:0]:{width{1'bz}};
Synthesis and translation goes well. No warnings or errors I wasn't expecting (I was expecting some since this is only a trial run and most of the components don't do anything and will hence be left unconnected). But when I actually try to implement it, all busses (there are three) output a 1111111111111111, or a -1, as converted by my binary to BCD converter. I checked if it really the case by instructing the control matrix to halt if the instruction received on the bus is -1, and it did halt.
The warning I receive for the tri-state being converted to logic is:
Xst:2040 - Unit Neptune_I: 16 multi-source signals are replaced by logic (pull-up yes)
Xst:2042 - Unit alu: 16 internal tristates are replaced by logic (pull-up yes):
And so on. Neptune_I is the top module, and I believe the multi-source signals it's referring to are the busses.
I have a doubt whether the pull-up yes is the root of this problem. Is it simply pulling everything up, causing it to be -1 all the time? But this does not make sense to me, because when the tri-state is activated, the signal should be controlled by whatever entity it is supposed to be controlled by.
I would like to take the time to replace the code with logic instead of the tri-states, but I'm unsure how to proceed.
Any help would be appreciated.
Are these signals going off-chip? Or are they internal to your FPGA? If the answer is the latter, you need to change your code. Modern FPGAs (like Spartan 6) no longer support internal tri-state buffers. They only exist for off-chip signals.
You need to write all of you internal code to avoid tri-state buffers. Create dedicated paths between components, no bidirectional interfaces.

Verilog: Common bus implementation issue

I've been coding a 16-bit RISC microprocessor in Verilog, and I've hit yet another hurdle. After the code writing task was over, I tried to synthesize it. Found a couple of accidental mistakes and I fixed them. Then boom, massive error.
The design comprises of four 16-bit common buses. For some reason, I'm getting a multiple driver error for these buses from the synthesis tool.
The architecture of the computer is inspired by and is almost exactly the same as the Magic-1 by Bill Buzzbee, excluding the Page Table mechanism. Here's Bill's schematics PDF: Click Here. Scroll down to page 7 for the architecture.
The control matrix is responsible for handling when the buses and driven, and I am absolutely sure that there is only one driver for each bus at any given instance. I was wondering whether this could be the problem, since the synthesis tool probably doesn't know this.
Tri-state statements enable writing to a bus, for example:
assign io [width-1:0] = (re)?rd_out [width-1:0]:0; // Assign IO Port the value of memory at address add if re is true.
EDIT: I forgot to mention, the io port is bidirectional (inout) and is simply connected to the bus. This piece of code is from the RAM, single port. All other registers other than the RAM have separate input and output ports.
The control matrix updates a 30-bit state every negative edge, for example:
state [29:0] <= 30'b100000000010000000000000100000; // Initiate RAM Read, Read ALU, Write PC, Update Instruction Register (ins_reg).
The control matrix is rather small, since I only coded one instruction to test out the design before I spent time on coding the rest.
Unfortunately, it's illogical to copy-paste the entire code over here.
I've been pondering over this for quite a few days now, and pointing me over to the right direction would be much appreciated.
When re is low, the assign statement should be floating (driving Zs).
// enable ? driving : floating
assign io [width-1:0] = (re) ? rd_out [width-1:0] : {width{1'bz}};
If it is driving any other value then the synthesizer will treat is as a mux and not a tri-state. This is where the conflicting driver message come from.

Resources