Lattice XP2 DCS issues - Page 1
Forum section: electronics / general

author: Joanna_H
author_rank: Regular Contributor
timestamp: August 15, 2019, 07:10:54 pm
content: Hi all,I was wondering if anyone can help me, not quite sure why this is happening.I have a higher level APU module that has 2 clocks comming in a slow clock and a fast clock ... (it's going to be a step by step processor or a full run at 40Mhz CPU).I have the following code at the APU level:DCS dc (.CLK0(clock),.CLK1(slowClock),.SEL(clockSelect),.DCSOUT(cpuClock));// Link reset to the GLOBAL RESET LINE.GSR u1 (.GSR(reset));CPU #(.DATA_BUS_WIDTH(DATA_BUS_WIDTH),.ADDRESS_BUS_WIDTH(ADDRESS_BUS_WIDTH),.MONITOR_WIDTH(MONITOR_WIDTH),.MONITOR_ADDRESS_WIDTH(MONITOR_ADDRESS_WIDTH))CP1(.clock(cpuClock),.reset(reset),the rest of the CPU stuff ... not important.I'm using the DCS to ensure that there are no nasties when switching from the fast clock (40Mhz) to the slow clock, as low as 1Hz.In the CPU there is a 4 phase clock that takes the incomming clock (160Mhz max) and splits it into 4 to create non overlapping internal action and decode clks....// Clock Generation, 4 phase clock.// They are non overlappingreg clk0 = 1;reg decodeClk = 1;reg[1:0] phase = 2'b00;always @(posedge clock)beginif(reset)beginclk0 <= 1;decodeClk <= 1;phase <= 2'b00;endelse if(clock)beginif(phase == 2'b00)decodeClk <= ~decodeClk;else if(phase == 2'b01)beginclk0 <= ~clk0;endelse if(phase == 2'b10)decodeClk <= ~decodeClk;else if(phase == 2'b11)beginclk0 <= ~clk0;endphase <= phase + 2'b01;if(phase > 2'b11)phase <= 2'b00;end;endbut when I simulate it.. I get the cpuClock doing what I want it to do .. but the clk0 and decodeClocks are both dead..... very very confused.The top of the CPU declarationis as follows:module CPU(clock,reset,monitor_idx, monitor_data,cpuAddressBusOut, cpuDataBusInOut, RW,eepromCtrlLines,eepromDataAddress,oe);My clock definitions are:and my Freqency definitions are:

author: Joanna_H
author_rank: Regular Contributor
timestamp: August 15, 2019, 07:34:38 pm
content: Forgot to say, if I drive the CPU .clock from either the main clock or slowClock then it all works fine ... :/ It's only when I pass cpuClock to it. I've also tried various DCS setttings for clock defintions, including blank to let it figure it out.For some reason even though the DCS is ouputting to cpuClock the CPU itself never detects any changes on the passed in clock ... always @(posedge clock) .. so nothing happens

author: SiliconWizard
author_rank: Super Contributor
timestamp: August 15, 2019, 11:24:45 pm
content: Just a guess from reading the "LatticeXP2 sysCLOCK PLL" guide.You may need to set the DCSMODE parameter in addition to instantiating a DCS.In your case, something like:Code:defparam dc.DCSMODE = “POS”;

author: Joanna_H
author_rank: Regular Contributor
timestamp: August 16, 2019, 07:22:04 am
content: Tried that... It's defauil is NEG mode. It's generating a signal as it can be seen on the output cpuClock.but that signal doesn't got any further down .... :/

author: Joanna_H
author_rank: Regular Contributor
timestamp: August 16, 2019, 07:36:01 am
content: Well, I woke up this morning, took another look at it and found the issue buried in that phase decode...Change "else if(clock)" to just "else" and bingo ....So it turned out to not be a DCS issue, it turned out to be a brain falling apart issue.It all works

author: SiliconWizard
author_rank: Super Contributor
timestamp: August 16, 2019, 02:08:40 pm
content: OK, your title and my relative lack of interest for Verilog - sorry about that, more of a VHDL guy, no war intended - (coupled to a not-so-clear description of the problem) made me focus on the DCS and not on your piece of code.Now I still know a little bit of Verilog, and assuming your reset signal is asynchronous, I think it should be typically written like so:Code:always @(posedge clock or posedge reset)beginif (reset)beginendelsebeginendendI'm no Verilog specialist, but I think the 'else if(clock)' would make it consider the clock signal is actually not a clock. (Can Verilog users confirm this?)

author: AndyC_772
author_rank: Super Contributor
timestamp: August 16, 2019, 02:18:39 pm
content: Where possible, I tend to latch any asynchronous reset signal on each active clock edge, then use the latched version as a synchronous reset.Doing it this way keeps all the logic strictly synchronous, which ensures the outputs don't glitc. Perhaps more importantly, it also ensures that all the logic comes out of reset cleanly and on the same clock edge, regardless of the exact timing of the reset signal. If the reset isn't synchronous, then the behaviour of the logic can be poorly defined if the reset edge is close to a clock edge.(VHDL / Altera user here - so no, I've not read through all the code).

author: Joanna_H
author_rank: Regular Contributor
timestamp: August 16, 2019, 05:39:26 pm
content: Quote from: SiliconWizard on August 16, 2019, 02:08:40 pmlol.. I just picked a language to learn last week.. it happened to be verilog.

author: davep238
author_rank: Contributor
timestamp: September 04, 2019, 03:06:51 pm
content: QuoteI learned VHDL because the contractor we used, used VHDL. If they had used Verilog, I would have learned that instead. I don't think it matters which language you chose.

author: MorgothCreator
author_rank: Contributor
timestamp: September 04, 2019, 06:50:09 pm
content: if(phase > 2'b11)phase <= 2'b00;"phase" will never be bigger than 2'b11, because is two bits width. "phase" will never go back to 0.correct code is:// Clock Generation, 4 phase clock.// They are non overlappingreg clk0 = 1;reg decodeClk = 1;reg[1:0] phase = 2'b00;always @(posedge clock)beginif(reset)beginclk0 <= 1;decodeClk <= 1;phase <= 2'b00;endelse if(clock)beginphase <= phase + 2'b01;if(phase == 2'b00)decodeClk <= ~decodeClk;else if(phase == 2'b01)clk0 <= ~clk0;else if(phase == 2'b10)decodeClk <= ~decodeClk;else if(phase == 2'b11)clk0 <= ~clk0;end;endor try using a shift register is faster:reg clk0;reg decodeClk;reg[2:0] phase;always @(posedge clock)beginif(reset)beginclk0 <= 1;decodeClk <= 1;phase <= 4'b0011;endelse if(clock)beginphase <= {phasephase[3:1]};decodeClk <= |phase[1:0];clk0 <= |phase[3:2];end;end

author: Joanna_H
author_rank: Regular Contributor
timestamp: September 04, 2019, 07:17:56 pm
content: Thanks, this is all old code now, was replaced a long time ago.