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.
Related
In the AXIS stream speck the ACLK is defined as:
The global clock signal. All signals are sampled on the rising edge of
ACLK.
Which means that it is assumed that AXIS master and slave are receiving the same ACLK.
Can you please help understand following:
1) If there is a ACLK slew on AXIS master and slave blocks,it is left under designer responsibility. Speck does not set any limitation on that. Is my understanding right?
2) The data transfer should be ACLK center aligned. So the developer should make the AXIS master to send clock center aligned data. Right?
3) How to make ACLK centric data transfer? Imagine you have global clock in the whole system, to make data to be transferred clock center aligned to that data, you need to generate new clock which has phase left shifted from your global clock. Any ideas how we can do it in FPGA?
I think the problem is in your understanding of English.
-centric is not the same as centre (or center).
Centric means here "The most important, where everything revolves around"
It does not mean that the data is in the middle (centre) of the clock.
Thus in an AXI/AMBA system you must make sure all components use the same clock signal and all logic should run from the rising clock edge. That is in the same, standard, requirement of all synchronous logic.
Now to answer your questions:
1) If there is a ACLK slew on AXIS master and slave blocks,it is left under designer responsibility. Speck does not set any limitation on that. Is my understanding right?
You should not have clock skew. If you have, your are in deep trouble and yes, you have to solve that. Avoid it at all cost!
2) The data transfer should be ACLK center aligned. So the developer should make the AXIS master to send clock center aligned data. Right?
No. Everything is clocked of the rising clock edge. Which means the data will start changing shortly after that rising clock edge. You can see this in all the timing diagrams which are in the AXI/AMBA standard.
3) How to make ACLK centric data transfer? Imagine you have global clock in the whole system, to make data to be transferred clock center aligned to that data, you need to generate new clock which has phase left shifted from your global clock. Any ideas how we can do it in FPGA?
All you do is use the same ACLK signal everywhere. Do not shift the clock, do not generate a new clock.
Here are some Verilog modules I designed:
module ahbl_arbiter
#(parameter MA = 4 // Number of masters 2..8
)
( input clk, // System clock
input reset_n, // System reset
input clken, // Clock enable
....
module ahbl_splitter
#(parameter SL = 4, // Number of slaves 2..32
L2BS = 10 // Log 2 of block size 10 = 1K
)
( input clk, // System clock
input reset_n, // System reset
input clken, // Clock enable
....
module apb_bridge
#(parameter
NS = 8, // Number of slaves
L2BS = 10, // Log2 Address block assigned each peripheral
REG = 1'b0 // Register in rdata return path
)
( input clk, // System clock
input reset_n, // System reset
input clken, // Clock enable
...
If you use these they all have the same clock:
ahbl_arbiter
ahbl_arbiter_0 (
.clk (aclk), // System clock
.reset_n (reset_n), // System reset
.clken (clken), // Clock enable
....
apb_bride
apb_bride_0 (
.clk (aclk), // System clock
.reset_n (reset_n), // System reset
.clken (clken), // Clock enable
....
ahbl_splitter
ahbl_splitter_0 (
.clk (aclk), // System clock
.reset_n (reset_n), // System reset
.clken (clken), // Clock enable
....
I've tried reading the book but I'm not sure exactly how to go about this. Anyone have an idea?
So in doing these problems its best to have the datapath in front of you and have the Register Transfer Language written down, you do these problems step by step, it is a little daunting, but following all of the Digital Logic you have learned it is all a matter of you being a pirate and the datapath being your treasure map.
To do this you just follow the wires in the diagram. I'm using this one which I'm sure is in the Patt/Patel textbook https://i.ytimg.com/vi/PeWbyffnkZ4/maxresdefault.jpg
Mem[PC + SEXT(IR[8:0])] = SR
Clock Cycle 1
So the first thing you need to do is SEXT(IR[8:0]) So where in the datapath is a sign extender and where is the IR. If you look at the ADDR2MUX you see it has 4 inputs each being bits from the IR and one with 0. So ADDR2MUX=IR[8:0]
Next we need to add the PC to it. So from the output of the ADDR2MUX will be the SEXT(IR[8:0]) So next we need to add the PC to that output. Well we see the output of the ADDR2MUX feeds into an adder. So ok we need to set the other adder up with the PC. The ADDR1MUX has an input from the register file and the PC. So ADDR1MUX=PC
Both of these inputs go into the adder and now the output of that adder has PC + SEXT(IR[8:0])
Next we need to store to memory, the address we want to store to is PC + SEXT(IR[8:0]), and what we want to store is SR. So how do we do that? To interface with memory we need to put the address in the MAR (Memory Address Register) and the data we want to store in the MDR. So lets do the MAR step first. So we need to put the result of the ADDER into the MAR. The only path we can take is the MARMUX. So MARMUX=ADDER. We need to Gate the MARMUX to put it out on the bus as well. So GateMARMUX.
The value of the MARMUX is now out onto the bus so we want to latch that into the MAR so LDMAR.
We need a new clock cycle now because we need to wait for the value to latch into the register which happens at the beginning of a new clock cycle.
Clock Cycle 1 Signals - ADDR2MUX=IR[8:0], ADDR1MUX=PC, MARMUX=ADDER, GateMARMUX, LDMAR
Clock Cycle 2
Now lets the source register into the MDR. Looking at the diagram we need a path from the register file to the BUS to get it into the MDR. There's actually two ways of doing this one going through ADDR1MUX and one going through the ALU.
I will take the ALU path as its slightly more correct.
First we need to make SR1 be the source register from the instruction so SR1MUX=[11:9]
The Source register from the instruction now comes out the register file from the SR1 output, this feeds into the ALU. So we must choose the operation the ALU does so, ALUK=PASSA. PASSA simply makes the output of the ALU the 'A' input.
We then need to put the ALU output on the bus so GateALU
Now the ALU output is on the bus and we want to store this in the MDR, however there is a MUX blocking that input. MIO.EN=0 to select the bus output to go into the MDR. Then we need to latch that value into the register so LDMDR
We just tried to load a value into a register so it will not be available in the output until the start of the next clock cycle so..
Clock Cycle 2 Signals - SR1MUX=[11:9], ALUK=PASSA, GateALU, MIO.EN=0, LDMDR
Clock Cycle 3
All we need to do is give memory a good ol kick to store the value in the MDR at the address in the MAR so... MIO.EN=1, R/W=W
Clock Cycle 3 signals - MIO.EN=1, R/W=W
So this concludes the ST instruction it takes 3 clock cycles and the signals to assert each clock cycle are indicated at the end of each clock cycle. All of those signals per clock cycle can be turned on at the same time.
I have a Spartan-6/ISE design where I'm generating 8-bit data # 70MHz to feed the FIFO of a Cypress FX3 USB3 controller. I also generate a 70MHz o/p clock and /WR strobe that clock data into the USB controller. The 70MHz is derived from halving the 140MHz system clock, divided by 2 in a process rather than using a DPLL, though the 140MHz system clock is produced using a DPLL.
I want to ensure the 8-bit data meets the set-up & hold time requirements of the USB controller and, although the data, o/p clock and /WR are derived from the 140MHz, I don't really care about their relationship to it. What I'm really concerned about is ensuring the set-up & hold times for data & /WR w.r.t the 70MHz o/p clock are within the USB controller limits.
My question is: how do I go about specifying timing constraints between FPGA outputs rather than w.r.t. to the internal system clock ?
Thanks
Dave
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.
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.