I have 2 modules using the same clock but in different files, when I sample signal that come from module A in module B , in the Waveform simulation it doesn't get samples after one clock cycle like it should , it shows that is samples in the same rising edge(behavior that fit to asynchronous instasiation) .
I have been told it happens because Active-HDL consider it to 2 differnet clock because of the different component and thats why it sample in the same rising edge(because of the delta time that the signal goes from A to B).
how can i define that Active-HDL will understand they both use the same clock in same area ?
This has nothing to do with your simulator. I assume that you're doing something like this:
+----------+ +----------+
| |-- clk --->| |
clk --->| Module A | | Module B |
| |-- data -->| |
+----------+ +----------+
where you should be doing something like that:
+----------+ +----------+
| | | |
clk -+->| Module A |-- data -->| Module B |
| | | | |
| +----------+ | |
| | |
+-----------------------> | |
+----------+
The problem with the first configuration is that your clock signal gets delayed by one or more delta cycles when it goes through module A. It may thus toggle in the same, or in a later delta cycle than the data signal. This is something that you will not see in the simulator's waveform view (unless it has an option to expand delta cycles) but you can have a look at the list view to see exactly what happens in delta-time.
The handling of clock within your chip and within your simulation environment requires the same type of care you take in doing a board design. In particular clock skew must always be smaller than the smallest propagation delay.
In an RTL simulation environment, all of the delays on signals are measured in terms of delta cycles (the default delay for any signal assignment when you are not using after). Going through a port does not incur any delta cycles. However, every assignment to a signal causes a delta cycle delay.
One method to insure successful data transfer is to make sure all clocks in the design are delta cycle aligned when they are used. The simplest way to make sure this happens is to make sure that none of the blocks do an assignment to the clock they use. Hence, do not do any of the following:
LocalClk <= PortClk ; -- each assignment causes a delta cycle of clock skew
GatedClk <= Clk and Enable ; -- clock gates are bad. See alternative below
Generally we rarely use clock gates - and then we only do it when it is an approved part of our methodology (usually not for FPGAs). In place of using gated clocks in your design, use data path enables:
process (Clk)
begin
if rising_edge(Clk) then
if Enable = '1' then
Q <= D ;
end if ;
end if ;
end process ;
There are other methodologies to sort this out.
Related
We are working on a pipelined processor written in VHDL, and we have some issues with timing, synchronization and registers on the simulator (the code does not need to be synthesizable, because we going to run it only on the simulator).
Imagine we have two processor stages, A and B, with a pipeline register in the middle:
Processor stage A is combinatorial and does not depend on clock
The pipeline register R, is a register, and therefor, changes its state at clock rising edge.
Processor stage B is a complex stage and has its own state machine, and, therefor, changes its state and does operations inside a VHDL process, governed by clock rising edge.
The configuration would be as follows
_______ ___ _______
| | | | | |
---| A |---|R|---| B |---
|_____| |_| |_____|
With this configuration, there is a timing problem:
t = 0: A gets data, and does its operations
t = 1: At rising edge, R updates its data with the output of A.
t = 2: At rising edge, B gets the values of R, and updates its status and gives an output.
We would like to have B changing its state and generating an output at t = 1, but we also need the register in the middle to make the pipeline work.
A solution would be to update the R register on falling edge. But then, we are assuming that all processor stages run in half a clock cycle, and the other half is a bit useless.
How is this problem usually solved in pipelines?
First of all, just saying from personal experience in this field: never develop your own cpu, unless you are a freaking genius and have another few of your kind to verify your work and port a compiler.
To your problem:
a) A cutset technique is usually used to insert pipeline stages in the design. When implemented properly, you only need to solve control hazards
b) Model your stages not with registers inbetween but with 1-deep transparent FIFOs - you will get automatic stall management for free and it is easier to reason about pipelines
c) Bypass register R. Use data from A to register it in R and in B.
If none above helped, redesign B and/or hire a hardware developer that is used to reason about concurrent hardware.
After talking to quite a few people, I think we found the proper solution to the problem.
The stage B, which has its own state machine, should not have a VHDL process activated on rising edge. It should have the state of the state machine as a signal that is stored on register R.
In more detail, these new signals should be added:
state: current state of the state machine, output from R, input to B
state_next: next state of the state machine, input to R, output from B
Which means that state is changed for state_next each rising edge, and B can now work without a process.
I've got a problem with i2c master acknowledgment for the slave that the data sent were ok. In my test bench i give a Z on SDA bus so that master could do the acknowledgment, but after the ack from master (it's 0) i sand a nother part of data and when i go from master ack 0 on the SDA bus to '1' as the first bit to be sent form the slave, I get an X state od the first bit. It's like it wouldn't appear if the bus was Z. Is it the simulation problem or am I just doing it wrong that i get that result? Will it appear in reality or the slave will give a Z on the SDA bus for longer? Belowe i give the simulation code and the waveforms.
sda <='Z',
'0' after 3200 ps,
'Z' after 3400 ps,
'0' after 5800 ps,
'Z' after 6000 ps,
'0' after 8600 ps,
'Z' after 8800 ps,
'0' after 11600 ps,
'1' after 11850 ps,------ start first byte
'1' after 12150 ps,
'0' after 13050 ps,
'1' after 13350 ps,
'0' after 13650 ps, ----- end first byte
'Z' after 14250 ps,------ Z for master ack
'1' after 14550 ps,------ start second byte
'0' after 14850 ps,
'1' after 16650 ps,------ end second byte
'Z' after 16950 ps,------ Z for master ack
'1' after 17250 ps,------ start third byte
'1' after 17550 ps,
'0' after 18150 ps,
'1' after 18750 ps,
'0' after 19350 ps,------ end third byte
'Z' after 19650 ps;------ Z for master ack
That testbench doesn't simulate I2C signalling correctly.
I2C uses open-collector drivers which can never drive the bus strongly high, and a weak pullup resistor. To simulate that you can do:
sda <= 'H'; -- weak pullup always in effect
sda <='Z',
'0' after 3200 ps,
'Z' after 3400 ps,
'0' after 5800 ps,
'Z' after 6000 ps,
'0' after 8600 ps,
'Z' after 8800 ps,
'0' after 11600 ps,
'Z' after 11850 ps,------ want to send '1', but open-collector cannot drive high!
'Z' after 12150 ps,
When reading from the signal, you can use e.g.
IF TO_X01(sda) = '1'
to resolve the wire-AND nature of multiple open-collector drivers.
You still will need to resolve the setup and hold timing issues that Russell mentioned.
As others have pointed out your issue is due to multiple conflicting drivers that are momentarily active during the same delta cycle. This creates cascade effects in your logic that begins to propagate 'X' values stemming from the conflict.
Even though this is an open-collector/drain system where driver contention can't happen you shouldn't ignore flaws like this. Moreover you shouldn't paper over the problem by making the testbench act differently than a real I2C slave.
When simulating open-collector drivers you should never drive the shared bus signals with a '1'. Instead, when you want a '1' you should simulate the effect of the pull-up resistor by driving SDA/SCL to 'Z' with a third dedicated driver putting a constant 'H' on the signal (or, less accurately, by driving 'H' directly from the master or slave). This creates a weak driver that can be overridden by a strong '0' without conflict. You can use the to_X01() function on your input port signals to prevent 'H' values from propagating through your logic inside the master or slave. It will convert 'H' to '1' internally so you only ever see a logical '1' or '0' on the bus signals.
The small red and green part at the end of your 3-bit pattern is caused when there are two places driving the same signal in that delta time. This happens when the simulator is unable to resolve the two drives on the line.
In order to not have this happen, you should write your testbench such that it uses the same clock that your master i2c module uses. Right now, your testbench is using fixed simulator time. There is probably a 1 picosecond time where the simulator sees that the master i2c and the testbench are both driving the line.
The other option is for you to wait some small amount of time after the clock edge to actually look at the data, maybe use the negative edge for the master and the positive edge for the slave, for example.
Either way, this should not actually be a problem after synthesis, so the third option is just to ignore it.
I recently bought myself a Zybo Zync-7000 dev board so I could do some schoolwork & fiddling around with it at home, but when I was going to pick out my clock out of my UCF for the first time I came across this.
## Clock signal
#NET "clk" LOC=L16 | IOSTANDARD=LVCMOS33; #IO_L11P_T1_SRCC_35
#NET "clk" TNM_NET = sys_clk_pin;
#TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 125 MHz HIGH 50%;
I know I probably just have to take the first line to get my clk signal working but what is the rest for? Or am I mistaken and do I need all of it?
We got different hardware back in school and its a bit more straightforward there.
Thanks in advance.
I assume you are using ISE and not the new Vivado since only ISE uses UCF constraint files.
## Clock signal
This line is a comment about what the following lines pertain to.
#NET "clk" LOC=L16 | IOSTANDARD=LVCMOS33; #IO_L11P_T1_SRCC_35
This line specifies which physical pin (LOC=L16) on the FPGA the clock input (the input net named "clk" in the VHDL top level) from off-chip is connected to. It also specifies that the signal uses low voltage CMOS 3.3v signaling.
#NET "clk" TNM_NET = sys_clk_pin;
This just assigns a timing name to the net. For timing specific constraints, the timing name will be used instead of the (VHDL internal) net name.
#TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 125 MHz HIGH 50%;
This specifies that the timing of "sys_clk_pin" (resolves to the VHDL net "clk") should have a frequency of 125 MHz and a duty cycle of 50%. The tool needs to know this to determine how to route the signals without violating flip flop setup or hold times. The name "TS_sys_clk_pin" is just an identifier for this particular constraint.
Properly constraining a design is very important when you are near to filling up a part or if you want to run it at a higher clock speed. You can find a great wealth of information in the Xilinx constraint guide for ISE: https://www.xilinx.com/content/dam/xilinx/support/documents/sw_manuals/xilinx14_7/cgd.pdf
If you don't give your design timing constraints, the tools will typically throw a warning about the lack of constraints and it will tell you how fast you can run it at the end without causing errors. Timing constraints for the clocks are the most important. You typically only need other timing constraints on synchronous inputs and cross clock boundaries.
Note that all 4 lines are, in fact, currently commented out (prepended with a #). If you want to use the 3 functional lines, you need to remove the comment designation.
Waveform link included I have a confusion regarding the value assignment to signal in VHDL.
Confusion is that I have read that values to signal gets assigned at end of process.
Does the value get assigned right when the process finishes or when the process is triggered the next time?
If it is assigned at the end of the process then consider this scenario (3 flip flops in series i.e output of one flip flop is input to another) then if D1 is 1 at time 0 will not the output Q3 be 1 at the same time?
(1) Right when the process finishes. More precisely, right after this and ALL processes running alongside this process have finished, and before any processes are subsequently started. So when any signal assignment happens, no process is running.
(2) Q3 will become the value on D1 three clock cycles earlier. Whether that value was '1' or not I can't tell from your question!
The signal assignment is done only at the end of the process. After signal assignment, there may exist signal updates and because of the signal updates, the process itself or maybe other processes which are sensitive to some of the updated signals will be triggered. This is the concept of delta-cycle. It happens in a zero simulation time.
signal updates -> triggers process->at the end of the process, signals are updated
----------------------------------- -----------------------------------
this is one delta cycle starting of the second delta cycle
when there will be no signal update, the process finishes and the the simulation time increments.
Is it possible to set an inout pin to specific value when after monitoring the value in same pin.ie if we have an inout signal then if value on that signal is one then after doing specific operation can we set value of that pin to zero in vhdl.
What you are describing doesn't make a lot of sense. Are you sure you are understanding the requirements correctly?
Your load signal sounds like an external control signal that is an input into your module. You should not be trying to change the value of that signal - whoever is controlling your module should do that instead.
As long as the load signal is asserted (1), you should probably be loading your shift register with whatever value is presumably being provided on a different input signal (e.g., parallel_data). When the load signal is deasserted (0) by the external logic, you should probably start shifting out one bit of the loaded data per clock cycle to your output signal (e.g., serial_data).
Note that there is no need for bidirectional signals!
This is all based on what I would consider typical behavior for a shift register, and may or may not match what you are trying to achieve.
This doesn't sound like a good plan, and I'm not entirely sure you want to do it, but I guess if you can set things up such that:
you have a resistor pulling the wire down to ground.
your outside device drives the wire high
the FPGA captures the pin going high and then also drives it high
The outside source goes tristate once it has seen the pin go high
the FPGA can then set the pin tristate when it wants to flag it has finished (or whatever), and the resistor will pull it low again
repeat
I imagine one use for this would be for the outside device to trigger some processing and the FPGA to indicate when it has finished, in which case, the FPGA code could be something like:
pin_name <= '1' when fpga_is_processing = '1' else 'Z';
start_processing <= '1' when pin_name = '1' and pin_name_last = '0';
pin_name_last <= pin_name when rising_edge(clk);
start processing will produce a single clock pulse on the rising edge of the pin_name signal. fpga_is_processing would be an output from your processing block, which must "come back" before he external device has stopped driving the pin high.
You may want to "denoise" the edge-detector on the pin_name signal to reduce the chances of external glitches triggering your processing. There are various ways to achieve that also.