6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Jun 16, 2024 5:30 pm

All times are UTC




Post new topic Reply to topic  [ 31 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject:
PostPosted: Sun Oct 31, 2010 11:54 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
Andre,
I can only speak from my use ot FPGA's and CPLD's using schematic entry as I have not crossed the bridge to HDL yet, but I can say this: That link I had posted has given me insight to problems I've been having.
This what I have learned about implementing bidirectional buses inside CPLD's & FPGA's:

When working with CPLD's, you can have a bidirectional bus that goes to each of your internal ports.
RE, WE are Read Enable & Write Enable signals decoded with Address and R/W.
Image

When working with FPGA's however, you can have only 1 point within the entire IC that is bidirectional (i.e. high impedance "Z" state). So, in that link to the Xilinx forums I mentioned earlier, Gabor stated "... it is best to have this bidirectional entry point at the highest level in your design...".

Below is a module similar to one I'm currently using successfully to interface the 6502 databus to multiple, readable output ports inside the FPGA. The only difference is, I've renamed some assignments and added more ports to express the idea more fully.

Databus(7:0) on the left, is assigned to pins on the FPGA. They connect directly to the 6502.
DataIn(7:0) on the top right is common to all the inputs of all the 8-bit PORTs, present inside other modules.
The PORTxRE (read enable) signals from each PORT are NOR'd, to put the data from the corresponding PORT onto the Databus.
Image

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


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Nov 05, 2010 2:47 am 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
So now I have a 7-bit (A14-A20) RAMBANK PORT and a 5-bit (A14-A18) ROMBANK PORT that I can perform INC/DEC on. At least I have proven it on the RAMBANK.

The past few days I've been trying to figure out how to INIT an FD8CE for the ROMBANK as it needs to start out with upper bank selected. I need to INIT the 8-bit port for $FF on powerup.
Sounds easy, but I've been having no luck.

Everything else is working.
I know this because when I disconnect the ROMBANK pins (A14-A18 going to the 512Kx8 EEPROM), inside the FPGA, from the PORT and connect each of these pins individually to VCC, the system works.

Can anyone help with Flip Flop INIT values?

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


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Nov 05, 2010 2:42 pm 
Offline

Joined: Thu Sep 02, 2010 12:34 am
Posts: 36
Location: Salzburg, Austria
ElEctric_EyE wrote:
The past few days I've been trying to figure out how to INIT an FD8CE for the ROMBANK as it needs to start out with upper bank selected. I need to INIT the 8-bit port for $FF on powerup.
Sounds easy, but I've been having no luck.

Having an FD8CP would help a lot (there seems to be only an FDCP in the xilinx library, but no multi-port versions), then you could connect a reset/powerup input to the preset input of the registers.

If you don't want to place a ton of FDCPs, there's a simple workaround: place an INV8 directly before and after the FD8CP. The register will then store inverted data, and the powerup value will be $FF instead of $00.

so long,

Hias


Top
 Profile  
Reply with quote  
 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: 1006
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: 1006
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: 1006
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: 1006
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: 1006
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: 1006
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  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 31 posts ]  Go to page 1, 2, 3  Next

All times are UTC


Who is online

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