Overriding a clock pin with manual control, then clocking again - origen-sdk

An interesting issue arose with a device whose SWD_CLK pin is shared as a 'device boot mode' pin (ROM/Flash boot, etc.). The specification states that the SWD_CLK should be held high for some time before functioning as SWD_CLK.
The origen_swd plugin drives the clock high to 'enable' it, so the timeset for this pin must be 'return low' in order to clock. But, when I try to drive this high and hold it high, it begins clocking. Is there a way to disable the timeset for some time, then re-enable it when ready?
The workaround is to change the origen_swd to accept an option to either drive high or drive low to enable, then change the timeset in my application to return high.
Using metaprogramming to just grab and edit instance variables of the timeset may also be a solution, but is there a supported API to handle the tasks like the above?
Thanks

The way to do this would be by making two timing options for the given pin, one with the return low and one without.
tester.set_timeset "mode_entry", 40
pin(:swd_clk).drive!(1)
# Sometime later once in mode
tester.set_timeset "func_swd", 40
If the tester supports (e.g. V93K) you can also define multiple wave forms for a pin within the same timeset, as shown at the end of this guide section - http://origen-sdk.org/origen/guides/pattern/timing/#Complex_Timing
Then you would just have a single timeset selection and control the wave you want on the pin like this:
pin(:swd_clk).drive!(1) # Would be defined in the timing as always high
pin(:swd_clk).drive!('P') # Now start the clk pulse
Both of these approaches will work in the generated ATE patterns, however at the time of writing I believe that OrigenSim does not yet support the second approach, so you will have to use the multiple timesets.
As an aside, you sound like you are only looking for a solution that works in simulation and not necessarily required to have the two types of waves within the final ATE pattern.
In that case, you could also try poking the testbench's pin driver force data bit, though I haven't tried this:
tester.simulator.poke('origen.pins.swd_clk.force_data[1]', 1);
If you have success with that, we should think about adding a convenience API to do this kind of thing in simulation:
pin(:swd_clk).force!(1)

Related

How to set a signal high X-time before rising edge of clock cycle?

I have a signal that checks if the data is available in memory block and does some computation/logic (Which is irrelevant).
I want a signal called "START_SIG" to go high X-time (nanoseconds) before the first rising edge of the clock cycle that is at 10 MHz Frequency. This only goes high if it detects there is data available and does further computation as needed.
Now, how can this be done? Also, I cannot set a delay since this must be RTL Verilog. Therefore, it must be synthensizable on an FPGA (Artix7 Series).
Any suggestions?
I suspect an XY problem, if start sig is produced by logic in the same clock domain as your processing then timing will likely be met without any work on your part (10MHz is dead slow in FPGA terms), but if you really needed to do something like this there are a few ways (But seriously you are doing it wrong!).
FPGA logic is usually synchronous to one or more clocks,generally needing vernier control within a clock period is a sign of doing it wrong.
Use a {PLL/MCM/Whatever} to generate two clocks, one dead slow at 10Mhz, and something much faster, then count the fast one from the previous edge of the 10MHz clock to get your timing.
Use an MCMPLL or such (platform dependent) to generate two 10Mhz clocks with a small phase shift, then gate one of em.
Use a long line of inverter pairs (attribute KEEP (VHDL But verilog will have something similar) will be your friend), calibrate against your known clock periodically (it will drift with temperature, day of the week and sign of the zodiac), this is neat for things like time to digital converters, possibly combined with option two for fine trimming. Shades of ring oscs about this one, but whatever works.

What do the ALSA timestamping function return and how do the result relate to each other?

There are several "hi-res" timestamping functions in ALSA:
snd_pcm_status_get_trigger_htstamp
snd_pcm_status_get_audio_htstamp
snd_pcm_status_get_driver_htstamp
snd_pcm_status_get_htstamp
I would like to understand what points in time the resulting functions represent.
My current understanding is that trigger_htstamp represents the time when stream was started/stopped/paused. snd_pcm_status_get_trigger_htstamp returns a constant value and when I add audio_htstamp to that value the result is very close to the current system time.
audio_htstamp seems to start from zero on my system and it is incremented by a value that is equal to the period size I use. Hence on my system it is a simple frame counter. If I understand ALSA correctly audio_htstamp can also work in different more accurate way depending on the system capabilities.
driver_htstamp I guess by the name is a timestamp generated by the audio driver.
Question 1: When is the timestamp driver_htstamp usually generated?
With htstamp I am really unsure where and when it is generated. I have a hunch that it may be related to DMA.
Question 2: Where is htstamp generated?
Question 3: When is htstamp generated?
Question 4: Is the assumption audio_htstamp < htstamp < driver_htstamp generally correct?
It seems like this with a little test program I wrote, but I want to verify my assumption.
I can not find this information in the ALSA documentation.
I just dug through the code for this stuff for my own purposes, so I figured I would share what I found.
The purpose of these timestamps is to allow you to determine subtle differences in the rate of different clocks; most importantly in this case the main system clock that Linux uses for general timekeeping compared with the different clock that determines the rate at which samples move in and out of the sound device. This can be very important for applications that need to keep audio from different hardware devices in sync, since the rates of different physical clocks are never exactly the same.
The technique used is sometimes called "cross-timestamping"; you capture timestamps from the clocks you want to compare as close to simultaneously as possible, and repeat this at regular intervals. There is usually some measurement error introduced, but some relatively simple filtering can get you a good characterization of the difference in the rate at which the clocks count.
The core PCM driver arranges to take a system clock timestamp as closely as possible to when an audio stream starts, and then it does a cross-timestamp between the system clock and audio clock (which can be measured in different ways) whenever it is asked to check the state of the hardware pointers for the DMA engine that moves samples around.
The default method of measuring the audio clock is via DMA hardware pointer comparsion. This isn't terribly precise, but over longer periods of time you can still get a good measure of the rate difference. At the start of snd_pcm_update_hw_ptr0, a system timestamp is captured; this will end up being htstamp. The DMA pointers are then checked, and if it's determined that they've moved since the last check, audio_htstamp is calculated based on the number of frames DMA has copied and the nominal frequency of the audio clock. Then, once all the DMA pointer update is done and right before snd_pcm_update_hw_ptr0 returns, another system timestamp is captured in driver_htstamp. This isn't meant to be used when you're using the DMA hw_ptr method of calculating the audio_htstamp though.
If you happen to have an audio device using the HDAudio driver, you can use an alternate and much more precise method of measuring the audio clock. It supplies an extra operation callback called get_time_info that is used instead of the default method of capturing the system and audio timestamps. It the HDAudio case, it takes a system timestamp for htstamp as close to possible to when it reads an interal counter driven by the same clock source as the audio clock; this forms the audio_htstamp. Afterwards, the same DMA hw_ptr bookkeeping is done, but the code that translates the pointer movement into time is skipped. The driver_htstamp is still taken right before the routine ends, though; this is "to let apps detect if the reference tstamp read by low-level hardware was provided with a delay" as the comment says in the code. This is because there's no guarantee that the get_time_info callback is going to take a new system timestamp; it may have previously recorded an audio timestamp along with a system timestamp as part of an interrupt handler. In this case, the timestamps you get might not match with the available frames and delay frames counts calculated by hw_ptr bookkeeping, but the driver_htstamp will let you know the closest system time to when those calculations were made.
In any case, the code is designed in both cases to capture htstamp and audio_htstamp as closely together as possible, and for htstamp - trigger_htstamp to represent the amount of system time that passed during the period measured by audio_htstamp of the audio clock. You mostly shouldn't need to use driver_htstamp, but I guess it might be used with the USB Audio driver, as I think it and HDAudio are the only ones that do anything special with these interfaces right now.
The documentation for this, although it doesn't contain all the details you might want to know, is part of the kernel documentation: http://lxr.free-electrons.com/source/Documentation/sound/alsa/timestamping.txt?v=4.9

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.

Xilinx Virtex5 Simple I/O

I'm using a Virtex 5 FPGA and want to have a few +5/0 I/O pins to communicate with a microcontroller. The only peripherials I've used on the board so far are pushbuttons and switches and no one I've asked seems to know the simplest way to do this I/O. I've looked around the board specification but haven't found any simple way of doing it. I would appreciate any advice you might have.
This is not an easy thing to do. If you don't have the schematic of the board, then you need to get volt meter with some fine pitch probes and reverse engineer the board.
It is pretty easy if you have 2 boards, with one board it can be really hard since the BGA signals may not be connected to a via and therefore not available on the bottom of the board, and even if they are, then you don't know exactly which pin they are connected to. But with some luck, you can find them since the VIA can only be connected to 4 possible pins surrounding it!
The first thing you need to do is to identify your chip, find the BGA print of the IC from Xilin'x web site.
If your board has some buttons already, then if you are lucky, those signals may be routed to the pins of the FPGA that are available on the bottom of your board. Here are the things you need to do:
Make sure you have good ESD protection to perform these test
Put your voltmeter into 'buzzer' mode
Check the pins of your connector and find out how it is connected, see if there is a pull-up and/or pull-down resistors on the board
when you find the 'active' pin of your connector, start connecting the other probe to the VIAs one by one
When you hear a buzz, make a note of the position (guess or measure the distance between the side of t he IC and the location of the via)
Identify the 4 possible pins that the signal can be connected to
Write a code to get all those 4 signals and connect them to ChipScope
In Chip Scope, capture all 4 signals and see which one is the one with the right connection!
alternative, you can create a design with inputs only, capture all the inputs and put them into a memory block and create a trigger logic to capture all the signals whenever any of the inputs changes, after lots of work and analysis, you will find the correct pins.
Anyway, these are just crazy ideas since this is a really difficult thing to do without having the PCB info of the board.
Good luck with your hacking.

Resources