6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri May 10, 2024 1:51 pm

All times are UTC




Post new topic Reply to topic  [ 27 posts ]  Go to page Previous  1, 2
Author Message
PostPosted: Mon Mar 03, 2014 6:22 am 
Offline

Joined: Tue May 05, 2009 2:49 pm
Posts: 108
I figured it out, but it took forever. I will post in hopes that someone else does not have fits like I did.

In the GUI, I thought "Design Goals and Strategies" was the link (under Project) I should choose. I went in, edited the strategy, saved it under a new name, and applied the changes (or so I thought).

But, it did not do anything. I am not sure what that menu item actually does, but it does not change these items.

To change them, I finally found the properties under "Process Properties", and changed them there. I then created a TCL script from Project menu item.

I found out the following items had been changed:

project set "Resource Sharing" "false" -process "Synthesize - XST"
project set "Macro Preserve" "false" -process "Synthesize - XST"
project set "XOR Preserve" "false" -process "Synthesize - XST"
project set "Collapsing Pterm Limit (1-90)" "5" -process "Fit"
project set "Collapsing Input Limit (2-54)" "28" -process "Fit"
project set "Implementation Template" "Optimize Speed" -process "Fit"
project set "Equivalent Register Removal" "false" -process "Synthesize - XST"

I would love to understand the rationale behind these changes. I understand the Pterm/INput ones, and the Macro/XOR ones I think I understand, but resource sharing one seems odd to me.

Jim


Top
 Profile  
Reply with quote  
PostPosted: Mon Mar 03, 2014 6:28 am 
Offline

Joined: Tue May 05, 2009 2:49 pm
Posts: 108
MichaelM wrote:
(2) Like you, your project synthesizes rather easily for me in an XC95C144XL. However, it uses all of the FBs. I played around with the fitting parameters that I referred to in an earlier post, and I got your project to fit. I made one change, but I don't think that it had any affect. I changed the equation for your reset_en signal; I converted it into a FF:
Code:
reg reset_en = 0;
always @(negedge clock) reset_en <= (cart_config1_reg_ce & data[7]);


Since I am trying to learn how to do these equations better, could you clarify the intent of this change? Is it to clean up the edge of this signal, or was there a fitting reason? I can verify it does not affect the fitting, but I am curious.

Jim


Top
 Profile  
Reply with quote  
PostPosted: Mon Mar 03, 2014 1:45 pm 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
brain:

The issue was the combinational sensitivity of the reset_en signal to the low period of the clock in your original equation:
Code:
wire reset_en;
assign reset_en = (cart_config1_reg_ce & !clock & data[7]);

If possible, I like to have signals such as these generated in a synchronous manner to avoid race conditions as much as possible. In most of you design is synchronous, so I reasoned that it would not disrupt the reset operation you intended to occur if the enable signal was held for a full cycle. (I did assume that clock was equivalent to Phi2 of a 6502 processor.)

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Mon Mar 03, 2014 2:15 pm 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
brain wrote:
I found out the following items had been changed:

project set "Resource Sharing" "false" -process "Synthesize - XST"
project set "Macro Preserve" "false" -process "Synthesize - XST"
project set "XOR Preserve" "false" -process "Synthesize - XST"
project set "Collapsing Pterm Limit (1-90)" "5" -process "Fit"
project set "Collapsing Input Limit (2-54)" "28" -process "Fit"
project set "Implementation Template" "Optimize Speed" -process "Fit"
project set "Equivalent Register Removal" "false" -process "Synthesize - XST"

I would love to understand the rationale behind these changes. I understand the Pterm/Input ones, and the Macro/XOR ones I think I understand, but resource sharing one seems odd to me.

In the process properties windows, there's a default button and a help button. I expect the default button to set all properties, not otherwise set/controlled by a Design Goals and Strategies setting, to the default. Selecting the help button pops up a window the defines each property and provides some guidance on how to set its value.

Resource sharing is an option intended to minimize the amount of logic used to implement a logic function. Common subexpressions are identified, and shared among the various logic functions. I tend to disable it. Although I tend to synthesize speed and par/fit for area, I have found that resource sharing does not reduce my final logic footprint very much, and it does tend to decrease overall speed by an amount I'm generally not willing to accept.

I turned off Macro Preserve without reading about it. I can't say if it helped or not in getting your project to fit.

I turned off XOR Preserve because XOR functions in CPLDs are generally constructed from two or more Pterms. I reasoned that your project did not make use of, or require XOR functions. Since it was not obvious to me from reading through your code that XOR functions would be needed, I simply turned it off and never went back to check if this property had an affect on your project's fit.

I set the Implementation Template property to Optimize Speed as a result of reading through the last example in XAPP444, "CPLD Fitting Tips and Tricks". (I've attached a number of app notes that I've found useful for CPLDs.)

I set Equivalent Register Removal because I reasoned that too much sharing of Pterms from other FBs was causing placement and signal routing issues. There is a limit to the benefit that logic reduction will have. In particular, when the number of inputs into a FB/macrocell are at issue, logic duplication in other function blocks can result in a fitted design. One the problems that the fitter has to resolve is the distribution of the logic. The inputs required for those logic elements may be sourced in one FB and needed in another. The input limits of the Pterm array may preclude routing signals from one FB to another. One solution is to allow the logic to be distributed or replicated across multiple FBs. Another may be to duplicate the inputs to the CPLD and assign different names to each replicated signal.

Hope this helps.
Attachment:
wp214 - The TTL Burn Rate for Xilinx CPLDs.pdf [1.35 MiB]
Downloaded 94 times

Attachment:
xapp105 - A CPLD VHDL Introduction.pdf [334.88 KiB]
Downloaded 93 times

Attachment:
xapp143 - Using Verilog to Create CPLD Designs.pdf [377.36 KiB]
Downloaded 99 times

Attachment:
xapp444 - CPLD Fitting Tips and Tricks.pdf [431.25 KiB]
Downloaded 97 times

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Sat Mar 08, 2014 4:34 am 
Offline

Joined: Tue May 05, 2009 2:49 pm
Posts: 108
Sorry for the late response, but a heartfelt thanks for this. I had seen xap444, but not the rest. The FF is a great idea. I added reset logic at the very end, and wasn't thinking.

Jim


Top
 Profile  
Reply with quote  
PostPosted: Wed Sep 30, 2015 5:03 am 
Offline

Joined: Tue May 05, 2009 2:49 pm
Posts: 108
I know this is an old thread, but I wanted to update with some additional information I learned.

The idea: Allow a write to a special bit in a memory location to "soft reset" the system, but not reset the registers when doing so. The original code:

Code:
wire reset_en;
assign reset_en = (cart_config1_reg_ce & !clock & data[7]);
assign reset    = (reset_en ? 0 : 1'bz);
assign reset_in = (reset_en ? 0 : !reset);

with a register defined as:

Code:
register cart_config1_reg(!clock, reset_in, ce, data, cart_config1);


The suggestion was to synchronize reset_en:

Code:
reg reset_en = 0;

always @(negedge clock) reset_en <= (cart_config1_reg_ce & data[7]);


I found that this also contained a race condition, in that reset_en would go high for the clock cycle, which would bring reset low, but at the same time set reset_in to 0. But, if reset was faster logic, it would go low before reset_in could be protected. I found the following addresses the issue:

Code:
reg [1:0]reset_ctr = 2'b0;
always @(negedge clock)
  begin
    if(cart_config1_reg_ce & data_in[7])
      reset_ctr <= 1;
    else if (reset_ctr != 0)
      reset_ctr <= reset_ctr + 1;
  end
 
assign reset =               (reset_ctr == 2'b10 ? 0 : 1'bz);
assign reset_in =               (reset_ctr != 0 ? 0 : !reset);


There are probably even neater ways to handle this, but I found this to work well.

Jim


Top
 Profile  
Reply with quote  
PostPosted: Wed Dec 09, 2015 2:10 pm 
Offline

Joined: Wed Nov 04, 2015 11:10 am
Posts: 51
Quote:
I try very hard to limit bidirectional access on a data bus to registers within an XC9500XL CPLD. Their internal architectures are just not designed to function in this manner.


I just use the schematic entry method in ISE. Does this mean I shouldn't use bidirectional IO markers?


Top
 Profile  
Reply with quote  
PostPosted: Sat Dec 12, 2015 3:14 pm 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
XC9500 CPLDs have a limited number of product terms (AND array components) and summing terms (OR array components). Further, these components are all associated with the function blocks of the device. This means that building bidirectional buses to read back user programmed registers in this type of device will consume scarce logic resources.

These devices are fast and flexible, and can be used to implement bidirectional buses. I don't recommend that use because of the poor utilization of the logic function blocks that occurs. When I need to modify bits in a register that I've allocated to a CPLD, I use a shadow copy of the last value written to that register kept in processor-accessible RAM. I will agree that this approach is much less satisfying than reading back the actual value from the CPLD register, modifying the value read, and writing it back to the CPLD.

However, it's been my experience that using the limited logic resources of the CPLD for reading back internal registers with a bidirectional bus will generally require a larger CPLD. If you have unused function blocks in which to implement the required data multiplexers, then implementing bidirectional access to CPLD registers is appropriate.

I've attached a diagram below from XAPP212 that shows the internal architecture of the XC9500 CPLD function blocks. Notice that the output enable for the tri-state buffer associated with a bidirectional bus is a single product term. This means that one of more function blocks will be consumed if the output enable of the buffer requires more than one product term. Also, the single FF available is lost whenever the function block is used to implement an asynchronous logic function. A total of 54 logic signals are available to the AND array, but the limiting factor for the XC9500 CPLD family is the width of the OR gate. The width of the OR gate is not 54 product terms, and this limit is one that frequently requires the sharing of OR gates from adjacent function blocks, which reduces the logic function capability of those function blocks to single product term functions.

It is instructive to periodically expand (or view) seemingly simple logic equations into the sum of products representation that CPLDs are designed to implement. It can be somewhat disconcerting to see the explosion in the number of AND-OR terms needed to implement counters and arithmetic functions. This is especially true for arithmetic functions since the XC9500 CPLDs do not include built-in carry logic as is available in most FPGAs.
Attachment:
XC9500XL_MacroCell.JPG
XC9500XL_MacroCell.JPG [ 39.17 KiB | Viewed 1207 times ]

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Sat Dec 12, 2015 3:52 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3354
Location: Ontario, Canada
MichaelM wrote:
When I need to modify bits in a register that I've allocated to a CPLD, I use a shadow copy of the last value written to that register kept in processor-accessible RAM. I will agree that this approach is much less satisfying than reading back the actual value from the CPLD register, modifying the value read, and writing it back to the CPLD.

Here's a suggestion; apologies if I've misunderstood anything -- haven't been following this thread closely. If you can arrange for the RAM shadow copy and the CPLD register to reside at the same address then it won't be less satisfying, coding-wise, and also there'll be no need to make the CPLD logic bidirectional. The CPLD register gets written every time a certain byte (or range of bytes) in RAM gets written. Reads access only RAM -- but it's as though you were reading the CPLD. Of course the idea isn't 100% cost-free. You do have to provide a decoder for the magic address... :)

-- Jeff

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Sat Dec 12, 2015 8:49 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8178
Location: Midwestern USA
Dr Jefyll wrote:
Here's a suggestion; apologies if I've misunderstood anything -- haven't been following this thread closely. If you can arrange for the RAM shadow copy and the CPLD register to reside at the same address then it won't be less satisfying, coding-wise, and also there'll be no need to make the CPLD logic bidirectional. The CPLD register gets written every time a certain byte (or range of bytes) in RAM gets written. Reads access only RAM -- but it's as though you were reading the CPLD. Of course the idea isn't 100% cost-free. You do have to provide a decoder for the magic address... :)

Also, at initial system start, the CPLD register and the corresponding RAM location won't be in agreement. So the reset handler would have to write something to the CPLD register to get the shadow RAM location in sync.

I've sort of been following this topic and probably missed where the matter of making a CPLD register read/write came up. I do that in the CPLD for my POC V2 unit, and the code to do so wasn't at all difficult. Here's an excerpt in CUPL:

Code:
/*
============================
HMU REGISTER READ STATEMENTS
============================
*/
[D0..3].oe = mcfgsel & rhflag;                    /* enable output on D0-D3   */
[D0..3]    = mcfgsel & [hmumcfg0..3] & rhflag;    /* HMU bit pattern on D0-D3 */

/*
=============================
HMU REGISTER WRITE STATEMENTS
=============================
*/
[hmumcfg0..3].LE = mcfgsel & wdflag & PHI2;       /* open HMU latches         */
[hmumcfg0..3].L  = mcfgsel & [D0..3] &            /* D0-D3 bit pattern on HMU */
                   wdflag & PHI2;

In the above, mcfgsel is a flag that is true when the configuration register has been selected via earlier address decoding statements (not shown), rhflag is true when a read is in progress and wdflag is true when a write is in progress.

hmumcfg0..3 refers to the four registers that make up the HMU (hardware management unit). They are defined and initialized at reset as follows (again, in CUPL):

Code:
pinnode   = [hmumcfg0..3];                        /* define hardware management unit */

$REPEAT i = [0..3]
    hmumcfg{i}.AR = !RESB;
    hmumcfg{i}.AP = 'b'0;
$REPEND

In the above, RESB is the 65C816's reset line, hence the asynchronous reset of the HMU registers will occur when RESB goes low.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 13, 2015 8:56 am 
Offline

Joined: Mon Aug 05, 2013 10:43 pm
Posts: 258
Location: Southampton, UK
MichaelM wrote:
XC9500 CPLDs have a limited number of product terms (AND array components) and summing terms (OR array components). Further, these components are all associated with the function blocks of the device. This means that building bidirectional buses to read back user programmed registers in this type of device will consume scarce logic resources.


That's interesting. I've implemented my own glue+peripheral on an XC9108 which had half a dozen or so 8 bit registers, with readback, and didn't notice any particular resource hit in doing so.

I guess the point is that this should only be a factor once the resource limits are reached? Designs, like Dary's 65SPI, do exactly this and manage to function ok.

_________________
8 bit fun and games: https://www.aslak.net/


Top
 Profile  
Reply with quote  
PostPosted: Tue Jan 12, 2016 3:48 am 
Offline

Joined: Tue May 05, 2009 2:49 pm
Posts: 108
I appreciate the concern, but it's a conscious decision to implement R/W registers. Folks on the SW side greatly appreciate that, and emulating older devices tends to mandate it.

Jim


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 27 posts ]  Go to page Previous  1, 2

All times are UTC


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: