ts-7000
[Top] [All Lists]

Re: [ts-7000] Re: [TS7300] Finding registers or memory address correspon

To:
Subject: Re: [ts-7000] Re: [TS7300] Finding registers or memory address corresponding to CPU to FPGA bu
From: David Hawkins <>
Date: Wed, 23 Apr 2008 16:17:47 -0700
Hi Mugilan,

> I think that is an implementation of a dual port ram with
> 16 words (32 bits long each).
> Here is my implementation, tell me if I'm doing this right.
> 
> MEMORY : altsyncram
>     GENERIC MAP (
>       intended_device_family => "Cyclone II",
>       width_a          => 8,
>       widthad_a        => 10,
>       numwords_a       => 1024,
>       operation_mode   => "SINGLE_PORT",
>       outdata_reg_a    => "UNREGISTERED",
>       indata_aclr_a    => "NONE",
>       wrcontrol_aclr_a => "NONE",
>       address_aclr_a   => "NONE",
>       outdata_aclr_a   => "NONE",
>       init_file        => "SDStateMachineExample.mif",
>       lpm_hint         => "ENABLE_RUNTIME_MOD=NO",
>       lpm_type         => "altsyncram"
>     )
>     PORT MAP (
>       wren_a    => MW,
>       clock0    => NOT(CLOCK),
>       address_a => MemAdd,
>       data_a    => DataCMOSInternal,
>       q_a       => DataOutInternal
>     );
> 
>       
> DataCMOSInternal <= DataCMOS;
> DataOut <= DataOutInternal;

This isn't dual ported. Read the generics :)

Here's an example of a dual-ported RAM from a Stratix II design:

     u4: altsyncram
     GENERIC MAP (
         widthad_a                 => SYS_ADDR_WIDTH,
         widthad_b                 => SYS_ADDR_WIDTH,
         width_a                   => SYS_DATA_WIDTH,
         width_b                   => SYS_DATA_WIDTH,
         width_byteena_a           => SYS_BYTEEN_WIDTH,
         width_byteena_b           => SYS_BYTEEN_WIDTH,
         numwords_a                => 2**SYS_ADDR_WIDTH,
         numwords_b                => 2**SYS_ADDR_WIDTH,
         byte_size                 => SYS_DATA_WIDTH/SYS_BYTEEN_WIDTH,

         clock_enable_input_a      => "BYPASS",
         clock_enable_input_b      => "BYPASS",
         clock_enable_output_a     => "BYPASS",
         clock_enable_output_b     => "BYPASS",

         address_reg_b             => "CLOCK0",
         byteena_reg_b             => "CLOCK0",
         indata_reg_b              => "CLOCK0",
         outdata_aclr_a            => "CLEAR0",
         outdata_aclr_b            => "CLEAR0",
         outdata_reg_a             => "CLOCK0",
         outdata_reg_b             => "CLOCK0",
         wrcontrol_wraddress_reg_b => "CLOCK0",

         power_up_uninitialized             => "FALSE",
         read_during_write_mode_mixed_ports => "DONT_CARE",
         intended_device_family             => "Stratix II",
         operation_mode                     => "BIDIR_DUAL_PORT",
         lpm_type                           => "altsyncram"
     )
     PORT MAP (
         clock0 => clk,
         aclr0  => rst,

         -- Port A
         wren_a    => en(DECODE_RAM1),
         address_a => addr(SYS_ADDR_WIDTH-1 downto 0),
         byteena_a => byteen,
         data_a    => wrdata,
         q_a       => rddata_mux(DECODE_RAM1),

         -- Port B
         wren_b    => ram1_wren,
         address_b => ram1_addr,
         byteena_b => ram1_byteen,
         data_b    => ram1_d,
         q_b       => ram1_q
     );

The generics for a Cyclone II device will be different.

> Now, my DataCMOS are input signals connected to CMOS sensor using the
> DIO2 header on the FPGA. My DataOut are output signals connected to
> the FPGA pins that connects to the BD08-BD15. 
> 
> With this, I believe that using the CPU-FPGA bus (used only for
> reading from FPGA), I can immediately save all the data from FPGA
> memory to the CPU. For the addressing purposes, I was just going to
> use a counter that counts the address from beginning to end. Correct
> me if I'm wrong, but I think suppose we have 32 words (8 bits long
> each) memory block, the addressing for this will just run from 0-31.

Its not quite that simple, as during a read, the address will be
driven onto the bus, the FPGA will capture it and either drive it
onto the FPGA RAM directly, or use it to load a RAM address
counter (I don't know if the processor drives the address for
each data phase, or expects a burst). The FPGA will then need to
drive data onto the data bus 'at an appropriate time'. That timing is
processor specific, and is what you need to determine.

You can't arbitrarily drive the bus at any time, you can only
drive the bus when the FPGA is selected for read, and that is
the logic you need to extract from the opencores.org design.

> You mentioned:
> 
> "What you need to ensure is that the memory map of the CPU is
> configured to assert the correct read/write control signals to the
> FPGA. The opencores.org FPGA image will have that interface already."
> 
> I think what I need is:
> 
> 1) make sure the bus is set to read from FPGA when needed
> 
> 2) save the data from the bus into CPU memory
>  
> I don't know how to do all that.

Here's how the data gets to the CPU;

1. The ARM core reads from an address

2. The processor address decode logic (the memory controller)
    determines that the address is targeting the local bus,
    and the chip-select of the FPGA, and asserts the appropriate
    bus signals.

3. Depending on the controller setting, it will either assert
    the read signals for a predetermined amount of time, and
    at that time, complete the read, expecting valid data on
    the bus, or the processor can be stalled by a wait-state
    control input (I can't recall what the TS board has).
    When the data is ready on the bus, the CPU wait-control
    is deasserted, and the read completes.

There may be some additional decoding between the processor
and the FPGA too. There's a CPLD on the board that may share
the address space of the FPGA. You'll have to read the docs
and look at the address map.

> I hope I am making sense with this approach. My deadline is next
> Friday, May 2. So I am trying to make this work without complicated
> methods such that I can debug it easily if I run into any problem.
> What do you think?

I think you need to ignore your application for a day or so,
download the opencores.org design, and play with that design.
I'm pretty sure it has some registers in it for accessing the
opencore ethernet controller. If you can understand how two
different address registers are accessed, then you can understand
how to access a RAM block.

Don't stress too much :)

Cheers,
Dave

------------------------------------

Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/ts-7000/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/ts-7000/join
    (Yahoo! ID required)

<*> To change settings via email:
     
    

<*> To unsubscribe from this group, send an email to:
    

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/

<Prev in Thread] Current Thread [Next in Thread>
Admin

Disclaimer: Neither Andrew Taylor nor the University of NSW School of Computer and Engineering take any responsibility for the contents of this archive. It is purely a compilation of material sent by many people to the birding-aus mailing list. It has not been checked for accuracy nor its content verified in any way. If you wish to get material removed from the archive or have other queries about the archive e-mail Andrew Taylor at this address: andrewt@cse.unsw.EDU.AU