6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Tue May 14, 2024 4:35 pm

All times are UTC




Post new topic Reply to topic  [ 31 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
 Post subject:
PostPosted: Tue Nov 09, 2010 3:06 am 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
HiassofT wrote:
Having an FD8CP would help a lot (there seems to be only an FDCP in the xilinx library...


Hiassoft, thanks for posting, but you only see a FD8CP in your library? What device are you using?...

I think I may have made abit of progress INIT'ing a FD8CE....

I was right clicking on the FD8CE, which is an 8-bit D Flip Flop w/ clear enable controlling the ROMBANK A14-A18 (using 5 of 8 bits) in my PWA project, and selected "Object Properties". Then chose "NEW", then "Attribute Name": INIT. It then prompts you for a string by default. And I tried many selections, and many value entries. This is what has not worked in ISE 10.1, schematic entry.

I posted on the Xilinx forums a couple days ago and got no response. sniff, sniff, heh.
Probably means my question is self evident, which got me searching the ISE10.1's help index.

...This morning (11/8/10), I actually read the Help, and searched for "Initialize flip flops and latches".
It describes how to initialize flip flops and latches using a constraints file.
I successfully made one this morning, but can't test it till tomorrow!

(11/9/10) Making a constraints file worked! It gives you the choice to assign 1 or 0 to each bit of any flip flop or latch in the design on powerup.

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Nov 09, 2010 2:09 pm 
Offline

Joined: Thu Sep 02, 2010 12:34 am
Posts: 36
Location: Salzburg, Austria
ElEctric_EyE wrote:
HiassofT wrote:
Having an FD8CP would help a lot (there seems to be only an FDCP in the xilinx library...

Hiassoft, thanks for posting, but you only see a FD8CP in your library? What device are you using?...

Ah, no. I'm using ISE 12.3 and checked the "CPLD Libraries Guide" (cpld_all_scm.pdf). It lists, amongst others, FDCE, FD4/8/16CE and FDCP, but no FD4/8/16CPs.

I also have to say that I haven't used the schematic entry feature yet, I prefer VHDL :-)

Some 5 or 6 years ago I had a similar problem, I wanted to init registers on a Lattice Mach4A5, using ispLever 4 or so, but couldn't get it to work. I'm not sure what went wrong, the datasheet explicitly mentioned asynchronous reset/preset plus powerup logic in the macrocell description. Maybe I did something wrong, maybe ispLever had some bug (I wouldn't rule that out, I already ran into several ispLever oddities before).

So I added a powerup/reset input to my logic and implemented it like this:
Code:
if (powerup == '0') then
    register <= init_value;
else
    if (rising_edge(clk)) then
        register <= databus;
    end if;
end if;

So the init-logic is contained in the VHDL code and I had no problems synthesizing the code for Lattice Mach4 and Xilinx XC95xx/XC95xxXL CPLDs.

so long,

Hias


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Dec 22, 2010 6:41 pm 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 993
Location: near Heidelberg, Germany
fachat wrote:
BigDumbDinosaur wrote:
Code:
entity RB65 is
...


A more readable version of his VHDL.


I am pretty sure I tried something like this in a Xilinx CPLD (9572), to define a bidirectional in/out port. But the pins were always pulled low, so I had to remove the read feature and make that port write-only.

Might have been an error in my code though.



Wow, finally I confirmed that this code actually work on the Xilinx XC95108 CPLD :-) I don't know what I did different the other times before, but now I have this code in a CPLD-based device (not a CPU - note it sends data when r/-w is high):

Code:
   datain <= data when (phi2 = '1');
   data <= dataout when (phi2 = '1' and Nsel = '0' and rNw = '1')
               else "ZZZZZZZZ";

with data being the inout port signal, and datain and dataout the internal input (write) and output (read) data busses.

Maybe just the compiler wasn't intelligent enough on my earlier tries to detect this logic or whatever. I did separate the two internal busses (read bus "datain" and write bus "dataout" this time though)

Thanks Ruud!

André


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Dec 23, 2010 8:46 am 
Offline

Joined: Wed Feb 03, 2010 2:48 pm
Posts: 9
Hello all,

Quote:

Code:
 datain <= data when (phi2 = '1');




I think it is not desired to write a when condition for the input side.The CPLDs I have worked with (Xilinx/Altera) route the I/O Pin directly into the switch matrix.
Also most of them do not have an enable on the input side buffer in the io cell.I do not want to tristate the input into the switchmatrix.Only the output to the pin.I use a clockenable on the datain signal to selective clock datain into registers.

I just write:
Code:
data <= dataout when ( condition ) else (others => 'Z');
-- Always read the input,it does not hurt!
datain <= data;


EDIT: Also a drawback of the original code is,that it could create a latch under some circumstances.The signal data is transfered into datain when phi2 = '1' but it does not say what will happen to datain when phi2 is not = '1'.The VHDL semantic is that the signal should hold its state so maybe a latch will be synthesised.But I have not try this out.

Greetings,
Vassilis


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Dec 26, 2010 1:01 pm 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 993
Location: near Heidelberg, Germany
Yes, thanks for your comment. I know about the latching, I just was happy that I actually managed to make it work at all. I'll gradually be moving back to my original solution to find out what the real problem is/was - and in the process I'll be optimizing as well.

I'll keep you posted

André


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Dec 28, 2010 7:05 pm 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 993
Location: near Heidelberg, Germany
Quote:
I just write:
Code:
data <= dataout when ( condition ) else (others => 'Z');
-- Always read the input,it does not hurt!
datain <= data;


EDIT: Also a drawback of the original code is,that it could create a latch under some circumstances.The signal data is transfered into datain when phi2 = '1' but it does not say what will happen to datain when phi2 is not = '1'.The VHDL semantic is that the signal should hold its state so maybe a latch will be synthesised.But I have not try this out.


Yes, you are absolutely right. ISE gives a warning that it creates a latch for the datain signal ("Found 8-bit latch for signal <datain>") when there is a condition on the input. Removing my original "when (phi2 = '1')" thus saves 8 macrocells.

André


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Dec 28, 2010 7:24 pm 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 993
Location: near Heidelberg, Germany
I've been tampering around with the VHDL for the data bus I/O and found something interesting. First I'll show you what works, then below what breaks the system.

What I am trying to do is a DRAM controller, with 4 registers - "data", "byte", "page" and "bank". The latter three are implemented in the CPLD, while the first one is done with a '245 that connects the system data bus with the DRAM data lines. Thus when accessing the data register, the CPLD must not interfere with the data bus itself.

The "usual" signals:
Code:
entity dramctrl is
    Port ( data : inout  STD_LOGIC_VECTOR (7 downto 0);
           regsel : in  STD_LOGIC_VECTOR (3 downto 0);
           Nphi2 : in  STD_LOGIC;
           Nsel : in  STD_LOGIC;
           rNw : in  STD_LOGIC;
           Nres : in  STD_LOGIC;
           ...
      );
end dramctrl;


"regsel" is the lowest 4 address bits (might do some extensions later). "Nphi2" is the inverted phi2 and will internally be inverted again. "Nsel" is the active-low chip select.

Code:
   signal dataRegister: std_logic;
        ...
   dataRegister <= not(regsel(0) or regsel(1) or regsel(2) or regsel(3));

A helper signal for the data register address.

Code:
   dataP: process(dataout, phi2, Nsel, rNw, dataRegister)
   begin
    -- removing any one of those if conditions (except phi2='1') break the system
    -- removing Nsel='0' holds the complete system (pulls system data bus low all the time)
    -- the others mangle the data
    if (phi2 = '1'
      and Nsel = '0'
      and rNw = '1'
      and dataRegister = '0'
      ) then
      data <= dataout;
    else
      data <= "ZZZZZZZZ";
    end if;
   end process;

This process defines the "data" as "dataout" during phi2, when the chip is selected (Nsel) for a read access (rNw) and it is not the data register. Otherwise the data bus is set to high-Z.

dataout is defined as such:
Code:
   -- read any of the registers
   ReadReg : process(...)
      begin
         case regsel is
            when "0001" =>
               dataout <= byte;
            when "0010" =>
               dataout <= page;
            when "0011" =>
               dataout <= bank;
            when others =>
               -- this must be high-Z, all-zeros breaks (mangles data)
               dataout <= "ZZZZZZZZ";
         end case;
   end process ReadReg;


The code above works fine. What is interesting is what breaks it:

1) setting the dataout not to high-Z but to all-zeros in process ReadReg breaks the system. Data passed to/from(?) DRAM is mangled. It seems the high-Z is not passed on to the "data" bus.

2) combining the two processes by moving the case statement into the dataP process:
Code:
--   dataP: process(...)
--   begin
--    if (phi2 = '1'
--      and Nsel = '0'
--      and rNw = '1'
--      and dataRegister = '0'
--      ) then
--         case regsel is
--            when "0001" =>
--               data <= byte;
--            when "0010" =>
--               data <= page;
--            when "0011" =>
--               data <= bank;
--            when others =>
--               data <= "ZZZZZZZZ";
--         end case;
--    else
--      data <= "ZZZZZZZZ";
--    end if;
--   end process;

This code is actually broken - at least for ISE. it uses 8 macrocells less than the working solution above, but again mangles the data being transferred to/from the DRAM.

What I find disturbing is that ISE does not give any indication or warning about what is going on here.

André


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Dec 29, 2010 12:52 pm 
Offline

Joined: Wed Feb 03, 2010 2:48 pm
Posts: 9
Hello fachat,

first I would like to point out that I am a self educated hobbyist in all this and not a specialist! I have only tried to get an SRAM working an I am also not completely ready with it.There are many possibilities to write a state machine...

For my designs with tristates I try to keep the tristate buffer in only one place in the toplevel entity.If I understand right,in your design this is the signal "data".

This is the only signal I would tristate:

Code:
data   <= dataout when (data_en = '1') else (others => 'Z');
datain <= data;


To control the tristate buffer in the i/o cells I would introduce a data enable signal data_en.This way you do not need to use the tristate 'Z' signal state anyway else in your code.

Code:

  -- This should synthesize a pure combinatorial circuit.

 dataP: process(phi2, Nsel, rNw, dataRegister)
   begin
    if (phi2 = '1' and Nsel = '0' and rNw = '1' and dataRegister = '0') then
      data_en = '1';
    else
      data_en = '0';
    end if;
   end process;



Now, dataout is an internal signal that need not be tristated.I would just write:

Code:

  -- read any of the registers
   ReadReg : process(...)
      begin
         case regsel is
            when "0001" => dataout <= byte;
            when "0010" => dataout <= page;
            when "0011" => dataout <= bank;
            when others => dataout <= (others => '0');
         end case;
   end process ReadReg;



Why would you tristate dataout ? Tristates only exist in the i/o cells on the output side.Old FPGAs had also internal tristates ( BUFT components) but modern components and design only uses tristates at the output buffer.The synthesis tool tries to rewrite internal tristates with multiplexers,so I think something similar would happen here,because there is only one physical tristate buffer and this is occupied by the data signal,so the dataout has no tristate.Maybe the tool tries to put the dataout also on output io cells and uses the input side into the switchmatrix ? I do not know what happens!

So,if I want to read data into the CPLD I set the data_en to '0' to tristate the output buffer and I am reading the data with datain.
If I want to write data out of the CPLD I set data_en to '1' and output the dataout signal.Internal I do split the data and I am keeping the data split into datain and dataout.I try to have only one process to control the data_en depending on conditions I define elsewhere and I only use the tristate signal 'Z' at only one place in the top level design.

I do not know your exact design, a LS245 is just a buffer and not a register.Of course you have to control the oe of the 245 also from the CPLD!?

This is really a topic that is also interesting for me,hope to have some more time to try things out myself on my CPLD/FPGA board.

Greetings,
Vassilis


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Dec 29, 2010 7:27 pm 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 993
Location: near Heidelberg, Germany
nichtsnutz wrote:
Why would you tristate dataout ?


That is a good question and indeed I do not know why I should - except that it does not work without it. But I only educated myself on that, I'm not doing this as a professional either.

This is what I have now:

Code:
   data <= dataout when (dataout_en = '1') else (others => 'Z');
   
   dataP: process(dataout, phi2, Nsel, rNw, dataRegister)
   begin
    if (phi2 = '1'
      and Nsel = '0'
      and rNw = '1'
      and dataRegister = '0'
      ) then
      dataout_en <= '1';
    else
      dataout_en <= '0';
    end if;
   end process;

   -- read any of the registers

   ReadReg : process(phi2, muxInt, Nsel, dataRegister, rNw, regsel, byte, page, bank)

      begin
         case regsel is

            when "0001" =>

               dataout <= byte;

            when "0010" =>

               dataout <= page;

            when "0011" =>

               dataout <= bank;

            when others =>
               -- this must be high-Z, all-zeros breaks (mangles data)

               dataout <= "ZZZZZZZZ";
               --dataout <= (others => '0');

         end case;
   end process ReadReg;


As you can see this is what you suggested, except for the others clause in the ReadReg process. If I don't tri-state dataout, the CPLD pulls the data bus low when the data register (regsel="0000") is selected.

I'm currently using ISE WebPack 11.1. I'll try it with 12.4 hopefully soon (12.3 failed for me as it did not detect the Linux libusb driver for the parallel programming cable, I hope 12.4 fixes that)

André


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Dec 29, 2010 10:30 pm 
Offline

Joined: Wed Feb 03, 2010 2:48 pm
Posts: 9
Hello Andre,

Ok,so there must be something else wrong!? If you tristate the dataout then you get something like :

Code:

   data <= "ZZZZZZZZ" when (dataout_en = '1') else (others => 'Z');



This would always tristate data independent of the status of the dataout_en signal.
So I would try to find out why the data is enabled where it should not.There are some more combinations of the regsel signal that are not being used but can enable the data.
Maybe some of these combinations cause the problem ?

Also I have not understood this external register.You wrote from a 245 which is a bidirectional tristate buffer.When is that enabled ?

Getting tristate buffer working reliable with a CPLD/FPGA is a topic I am also very interested in because you need it always when interfacing with other components.

Greetings,
Vassilis


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Dec 30, 2010 6:38 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
This is looking more and more like a bug in the synthesis tool.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Dec 31, 2010 1:36 am 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 993
Location: near Heidelberg, Germany
As a reference, I just updated my web page with the board and full VHDL. See http://www.6502.org/users/andre/csa/ramdisk/index.html for my current CPLD-based RAM-disk, using 30 pin SIMM modules I had laying around. It is based on an older pure TTL design, but moved almost everything into the CPLD.

The "bypass" buffer mentioned above is the 74LS245 that bypasses the CPLD when the data register is accessed, which transfers the data between system bus and DRAM data bus.

André


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Jan 01, 2011 10:16 pm 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 993
Location: near Heidelberg, Germany
The same problem also occurs with ISE WebPack 12.4 :-(

André


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Jan 02, 2011 6:31 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10800
Location: England
Hi André
You mention "the same problem" but I'm not sure exactly what that is. Anyhow... I think this is a case where one must be aware of what the implementation can do, and also (maybe) use some standard idioms.

Only external interface signals can be tristate, and they should be tristated with a simple expression. Your
Code:
data <= dataout when (dataout_en = '1') else (others => 'Z');
should be fine.

Then, there should be no other Z in your design. And yet you have this code, with a comment:
Code:
-- read any of the registers
ReadReg : process(phi2, muxInt, Nsel, dataRegister, rNw, regsel, byte, page, bank)
   begin
      case regsel is
         [snip]
         when others =>
            -- this must be high-Z, all-zeros breaks (mangles data)
            dataout <= "ZZZZZZZZ";
            --dataout <= (others => '0');
      end case;
end process ReadReg;
that all-zeros is broken, which is highly suspicious. Because you have internal Zs, I wouldn't be surprised to see this code synthesise poorly. In this case you should be in don't-care territory - zeros or all ones should work equally well. So what does "mangles data" mean here - what did you see? If you put a specific bit pattern in for this case, when does it appear?

In hardware terms, the first statement - the one-liner - is the tristate driver, and the big ReadReg process is the multiplexer which drives it - if you see the wrong data then you need to check that this mux is described correctly. (Actually it looks like nichtsnutz has already said all this...)

Cheers
Ed


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Jan 09, 2011 6:11 pm 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 993
Location: near Heidelberg, Germany
Hi Ed,

I've been tinkering around a bit more with that board.

BigEd wrote:
Hi André
You mention "the same problem" but I'm not sure exactly what that is.

The problem is that the CPLD pulls the CPU data bus low at inappropriate times. The board is selected in a 16 byte address space, and one of the addresses is not served by the CPLD, but by a '245 buffer. So once that single address is selected, the CPLD pulls low the data bus.
(Edit: the version posted here only uses 3 addresses in the CPLD and has all the others but the one for the '245 unused - I checked that only this single address for the '245 is affected by setting this to Z and all others addresses to all-zeros and it's still working)
Quote:
Only external interface signals can be tristate, and they should be tristated with a simple expression. Your
Code:
data <= dataout when (dataout_en = '1') else (others => 'Z');
should be fine.

Then, there should be no other Z in your design. And yet you have this code, with a comment:
Code:
-- read any of the registers
ReadReg : process(phi2, muxInt, Nsel, dataRegister, rNw, regsel, byte, page, bank)
   begin
      case regsel is
         [snip]
         when others =>
            -- this must be high-Z, all-zeros breaks (mangles data)
            dataout <= "ZZZZZZZZ";
            --dataout <= (others => '0');
      end case;
end process ReadReg;
that all-zeros is broken, which is highly suspicious.

In the meantime I also tried all-ones, and this actually works out ok (similar to the Zs)! So it seems there is some kind of open-collector going on internally. This also justifies my "pulls the databus low" from above.

I tried some patterns in that dataout assignment, and only when a bit is set to zero here, the data bus is pulled low. one and Z are ok.
Quote:
Because you have internal Zs, I wouldn't be surprised to see this code synthesise poorly.

Yes, there is an extra set of cells used when the value is set to Z. But when I set the value to all-ones, I get the same lower number of cells used as with all-zeros, but it works.
Quote:
In this case you should be in don't-care territory - zeros or all ones should work equally well.

That's what I thought and that's why I am asking here, because my observations say otherwise. Might really be something wrong, or I am missing an important point, after all I'm new to CPLDs.
Quote:
So what does "mangles data" mean here - what did you see? If you put a specific bit pattern in for this case, when does it appear?

see above, thanks for the hint!
Quote:
In hardware terms, the first statement - the one-liner - is the tristate driver, and the big ReadReg process is the multiplexer which drives it - if you see the wrong data then you need to check that this mux is described correctly. (Actually it looks like nichtsnutz has already said all this...)

And here I need some help. How would I check that? I tried to generate a schematics in ISE Webpack, but did not see anything suspicious, but I am not sure if I can read that.

Many thanks for your help!
André


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

All times are UTC


Who is online

Users browsing this forum: No registered users and 4 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: