[Oberon] RISC5 implementation issues.

Walter Gallegos walter at waltergallegos.com
Tue Feb 16 20:52:13 CET 2016


Magnus,

/always @ (posedge CLK50M) clk <= ~clk;

/This is also a bad practice.  clk edge are not aligned with CLK50M in a 
uncontrolled fashion. So, this is a kind of asynchronism for the rest of 
FPGA.

Walter


El 2016-02-16 a las 15:14, Magnus Karlsson escribió:
> Walter, be careful here.  The code you list is specific to 
> OberonStation, it does not look like this on the original Digilent 
> Spartan3 board nor on Pepino.
> This is the (somewhat messy) way OberonStation creates the 25 MHz CPU 
> clock and the 75 MHz pixel clock for a 60 MHz input clock.
>
> Both the Digilent board and Pepino uses a 50 MHz input clock and the 
> clock generation code is much simpler and looks like this:
>
> 25 MHz CPU clock (clk) is created by dividing the input clock by 2:
> /always @ (posedge CLK50M) clk <= ~clk;/
>
> 75 MHz Pixel clock (pclk) is generated by multiplying the CPU clock by 
> 3 using a DCM:
> /DCM #(.CLKFX_MULTIPLY(3), .CLK_FEEDBACK("NONE"), .CLKIN_PERIOD(40.000))//
> //  dcm(.CLKIN(clk), .CLKFB(1'b0), .RST(1'b0), .PSEN(1'b0),//
> //      .PSINCDEC(1'b0), .PSCLK(1'b0), .DSSEN(1'b0), .CLKFX(pclk));/
>
>
> Magnus
>
>
>
> On 2/16/2016 9:22 AM, Walter Gallegos wrote:
>> I've waited long time before post this topic because could be 
>> misunderstood, believe me this is a positive post. Try to address a 
>> methodology  issue in RISC 5 implementation.
>>
>> The gold rule is "FPGA design must be synchronous". Have a clock do 
>> not means synchronous.
>>
>> Building the hardware from Verilog description.
>>
>> DCM_SP #( .CLK_FEEDBACK("NONE"), .CLKDV_DIVIDE(2.0), .CLKFX_DIVIDE(2),
>>     .CLKFX_MULTIPLY(5), .CLKIN_DIVIDE_BY_2("FALSE"),
>>     .CLKIN_PERIOD(16.667), .CLKOUT_PHASE_SHIFT("NONE"),
>>     .DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"), .DFS_FREQUENCY_MODE("LOW"),
>>     .DLL_FREQUENCY_MODE("LOW"), .DUTY_CYCLE_CORRECTION("TRUE"),
>>     .FACTORY_JF(16'hC080), .PHASE_SHIFT(0), .STARTUP_WAIT("FALSE") )
>>   dcm ( .CLKIN(OSCIN), .CLKFX(clkfx), .CLKFB(1'b0), .RST(1'b0),
>>     .DSSEN(1'b0), .PSCLK(1'b0), .PSEN(1'b0), .PSINCDEC(1'b0),
>>     .CLKDV(), .CLKFX180(), .CLK0(), .CLK2X(), .CLK2X180(),
>>     .CLK90(), .CLK180(), .CLK270(), .LOCKED(), .PSDONE(), .STATUS());
>>
>> This implement a DCM with OSCIN as input clock to generate clkfx; for 
>> DCMs the XILINX recommend some period in reset with CLKIN active and 
>> stable. Work yes, recommended no. Is also a good practice rebuild the 
>> input clock with the DCM and not only generate a new one.
>>
>> always @(posedge clkfx) begin
>>   clk0 <= ~clk0 & ~clk1;     This implement a FF feeback = not clk0 
>> and not clk1.
>>   clk1 <= clk0;                       clk1 is also another FF taking 
>> clk0 as data.
>>   pclk <= ~pclk;                     pclk is a FF feedback Q in D
>> end
>>
>> Please note, clk0, clk1 and pclk are not aligned, they are different 
>> FF with different placement and routing.
>> If used as clock, this one of the worst cases, edges are closed, not 
>> the same, routed into uncontrolled skew general propose routing 
>> resources, don't forget of metastability.
>>
>> Next,
>>
>> always @(posedge clk0) clk <= ~clk;
>>
>> "posedge" force the implementation tool to use the clock edge 
>> detection available in each FPGA FF; so, this sentence force the tool 
>> to connect a general purpose interconnection network as FF output is 
>> to the clock distribution tree.
>>
>> And again a signal ( not a clock in the FPGA world ) is used as clock.
>>
>> always @(posedge clk)
>> ....
>> end
>>
>> There are also another hidden problem, the RISC clock clk, that was 
>> generated in the logic farm, is not aligned with clkfx by a variable 
>> unknown delay. This delay depend of several factor as temperature, 
>> power supply voltage and implementation run, that means in two 
>> implementation runs of same code as the tool could select different 
>> placement and routing  could result in different delays.
>>
>> The correct way to handle clock is with a clock manager; I strong 
>> recommend avoid clock dividers in logic. The challenge is select a 
>> correct oscillator and/or the appropriate multiply divide parameters.
>>
>> And after correct this problems don't forget to modify :
>>
>> assign SRwe0 = ~wr | clk, SRwe1 = SRwe0;
>>
>> Here clk is used as signal, so if clk is a clock must not be 
>> connected to a LUT input.
>>
>> Regards,
>>
>
>
>
> --
> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
> https://lists.inf.ethz.ch/mailman/listinfo/oberon

-- 

Walter Daniel Gallegos
Programmable Logic & Software
Consultoría, Diseño, Entrenamiento.
Montevideo, Uruguay
EMAIL walter at waltergallegos.com
Tel +598 26 23 44 60 | Cel +598 99 18 58 88

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.inf.ethz.ch/pipermail/oberon/attachments/20160216/f28d31f8/attachment.html>


More information about the Oberon mailing list