VHDL: input signal timing variations - Page 1
Forum section: electronics / general

author: JBourke
author_rank: Contributor
timestamp: November 09, 2021, 10:42:17 pm
content: Hi all,VHDL newbie here; I am trying to solve a problem with an existing CPLD project (based on a Xilinx XC95144XL). The project in question is an plug-in cartridge for a vintage home computer, adding additional functionality.The interesting problem is that this cartridge runs fine on the initial version of this home computer but not on a subsequent revision, in which a substantial amount of 74LS logic was replaced by a PLA. No other incompatibility problems exist between the two versions.I traced the problem down to the following code:Code:PROM: process(CS)variable newAddr : std_logic_vector(2 downto 0);beginif falling_edge(CS) then -- chip selectif DBR = '0' and BUS_AX(1) = '1' then -- databus input, A12 = writenewAddr := Addr(7 downto 5); -- get ROM bankRSelect <= newAddr; -- save ROM bankAddr <= Addr(4 downto 0) & BUS_DX; -- new addressend if;end process;The problem lies with the last statement, where the databus byte (BUS_DX) is added to Addr (BTW Addr is 13bits wide). I have been able to determine this is always 0xFF (databus has +5 V pull-ups). Initially I thought this could be some incompatibility between vintage logic and the CPLD, but I know it has no problem with reading or writing to the databus in other scenarios.The only other thing I can think of is timing; using DSO and logic analyzer, I can see small timing differences (100 ns) here and there between the two home computer revisions; not much for a vintage platform where timing is defined in uS, but probably significant for a modern-ish CPLD.My question: Would there a synthesizable approach to let signals stabilize (BUS_DX in the example) before further processing?Much appreciated!John

author: nctnico
author_rank: Super Contributor
timestamp: November 10, 2021, 02:51:48 am
content: What kind of home computer is it? And is chip select used for accessing memory exclusively or can it also be used to address I/O memory? And how about read & write signals? I have come across systems where CS is not valid when read and write are not active.

author: JBourke
author_rank: Contributor
timestamp: November 10, 2021, 04:02:30 am
content: As I mentioned, the cartridge works fine in the initial version of this home computer but not in the final version which had a PLA replacing a bunch of 74LS logic. I have spent quite a bit of time comparing both revisions with DSO/logic analyser and there are only minor differences in timing. There are no other incompatibilities known between the two revisions, everything else including exotic HW and 100's of extension cartridges work fine.I am certain that the problem is at the indicated statement. I can't be the first trying to interface a fast CPLD to old, sluggish hardware so hopefully there are some useful tips out there.Groet,John

author: Someone
author_rank: Super Contributor
timestamp: November 10, 2021, 04:15:13 am
content: Quote from: JBourke on November 10, 2021, 04:02:30 amOk, so what are the specifications of the bus interface? particularly the timing relationships between CS, DBR, BUS_AX, and Addr? (is that also an external signal to the design?). It's likely the first party/authorised products work so well together because they had the specifications correct.Once you have the specifications, how do your timing constraints match up?Reverse engineering from single example(s) it likely to miss these sorts of real world variations.

author: JBourke
author_rank: Contributor
timestamp: November 10, 2021, 04:43:30 am
content: DBR and BUS_AX(1) are external signals, Addr is internally declared; I have verified that the CPLD detects DBR and BUS_AX(1) properly.Your point of specifications is exactly my question; I have them, can verify them with DSO/logic analyser and I need to anticipate on them so how can I vary the timing of reading certain signals in VHDL? Unfortunately "wait for 1uS" does not synthesise ;-)

author: miken
author_rank: Regular Contributor
timestamp: November 10, 2021, 06:28:34 am
content: The usual way to delay something synchronously is to make pipeline registers. That only works if you have a clock handy and enough registers to spare. Depending on how full your CPLD is, it may not be workable.I think it would be more fruitful to look at the technology view of the mapped design and see if the suspect portion is implemented in an unexpected way.

author: fourfathom
author_rank: Super Contributor
timestamp: November 10, 2021, 06:33:06 am
content: So is CS an enable that works with a clock signal? If so do you have that clock as in input to the CPLD, or is CS all you've got? If the latter, do you have any other high-speed clocks coming in to the CPLD that you could use to delay the CS? What about DBR, should you be using the edge of that instead, qualified by the CS?

author: emece67
author_rank: Frequent Contributor
timestamp: November 10, 2021, 06:40:24 am
content: .

author: Someone
author_rank: Super Contributor
timestamp: November 10, 2021, 07:08:27 am
content: Quote from: JBourke on November 10, 2021, 04:43:30 amYou don't have specifications, you have observations of some examples.Quote from: JBourke on November 10, 2021, 04:43:30 amIts not "unfortunately" but because you are missing the fundamental basics of digital logic/system design. This isnt some option or language feature you're missing.... even when prompted you've ignored the advice:Quote from: Someone on November 10, 2021, 04:15:13 am1) come up with specifications2) produce timing constraints from the specifications3) ? ? ??4) profit!Time to start learning, many books and courses are out there on the topic.

author: JBourke
author_rank: Contributor
timestamp: November 10, 2021, 08:32:29 am
content: Quote from: emece67 on November 10, 2021, 06:40:24 amAh yes that makes sense, time for further experiments; thanks!

author: JBourke
author_rank: Contributor
timestamp: November 10, 2021, 08:36:33 am
content: Quote from: fourfathom on November 10, 2021, 06:33:06 amCould you elaborate on using a clock to delay CS? There is a clock coming into the CPLD that I could utilise.

author: mfro
author_rank: Regular Contributor
timestamp: November 10, 2021, 08:57:12 am
content: It would certainly help if you could disclose what you are really trying to achieve with what - people have asked what machine you are working on but you didn't answer?I could guess you are working on a TI99/4A and are trying to implement a command module port interface?Anyway, you are using the chip select as a clock which is almost certainly not what you want.

author: emece67
author_rank: Frequent Contributor
timestamp: November 10, 2021, 12:54:14 pm
content: .

author: fourfathom
author_rank: Super Contributor
timestamp: November 10, 2021, 04:37:43 pm
content: Quote from: JBourke on November 10, 2021, 08:36:33 amHere's a Verilog module I use to re-time an input (d) from a slower asynchronous clock domain, transferring it in to a higher-speed clock (clk) domain. This module also gives me single-cycle enable signals in the high-speed clock domain that go active on the rising and falling edges of the input signal. You don't usually want to use a single clocked register (flipflop) to sample an asynchronous signal, because of "metastability" (please look it up, it's important!). Here I am clocking the input through two stages, so the output (q) should be stable. The "rising" and "falling" outputs may be glitchy due to metastability, but they should be stable by the next clock edge, which is where I need to be stable in the rest of my synchronous design. The "q" output will follow the "d" input with a one or two clk delay. This design only works if "clk" is at least twice as fast as the width of the "d" high or low state.//////////////////////////module synch2(input clk,input d,output q,output rising,output falling);reg [1:0] sr;assign rising = (sr == 2'b01);assign falling = (sr == 2'b10);assign q = sr;always @(posedge clk) sr <= {sr, d};endmodule//////////////////////So this should give you a delay of one or two "clk" cycles. Even if your design is not synchronous, the "q" output should be glitch-free. If you need more delay, just add a third stage to the two-stage shift registeer ("reg [1:0] sr;").

author: SiliconWizard
author_rank: Super Contributor
timestamp: November 10, 2021, 06:10:34 pm
content: So yeah, mastering asynchronous logic in FPGAs is usually a bitch, as we talked about in another thread recently.I would personally use a clock (the freq. of which is significantly higher than your min time constraint), resynchronize every external input to this clock domain and do everything synchronously after that. Much easier to get it right.

author: mfro
author_rank: Regular Contributor
timestamp: November 10, 2021, 06:26:28 pm
content: Quote from: SiliconWizard on November 10, 2021, 06:10:34 pmWhile I would certainly agree in general, the OP might be required to compromise considering the rather small CPLD utilised.

author: JBourke
author_rank: Contributor
timestamp: November 10, 2021, 08:32:13 pm
content: really appreciate all the replies everyone; lots of things to follow-up, test and learn; great stuff.