Peripheral in RAM Space


Guest thefloe

Recommended Posts

Guest thefloe

Hi Jack,

Instead of porting the core and everything I decided to by a Papilio One 500k. And first tests were successful, great board!

Now I want to integrate my LED matrix driver I wrote in VHDL with the core. The matrix driver has some 6kB of dual port RAM that I want to access somehow from the AVR. First I thought about hijacking the RAM adds and muxing between the RAM and my component based on the address. Then I read the papilio_core_template. Is seems everything is in there but to avoid hours of debugging I have some questions.

Would it be safe to place my RAM at io_base_address  0x1FE0-0x37E0 (0x2000-0x3800) ?

When its in IO Space I would access it using IN and OUT instructions right?

Thank you.

Tobias

Link to comment
Share on other sites

Hello Tobias,

It's been a while since I looked at this particular code but, it looks like the address space you are proposing to use is in the External SRAM space so it should fit just fine and would be safe there.

When it is in address space you would use the _sfr_IO8 macros to access it. I'm not sure exactly what instructions those use, might be IN and OUT instructions. :)

Here is a link to a script showing how to access the address space.

This sounds very exciting! Please keep us posted here in the forum.

Thanks,

Jack.

Link to comment
Share on other sites

Guest thefloe

Hi,

a first test using the supplied templates (vhdl template and the arduino sketch) went good. Then I changed the address to 0x1FE0. And nothing happened.

I then checked the generated arduino code to see how the reg is accessed:

- For write access the STS instruction is used. No out, because only the lower 64 byte of IO space can be accessed with it.

- For read a LD (LDD using Z register) is used.

Now I read though pm_fetch_dec and recognized that the iore and iowe signals will not be set at that address range. So I will need to add "const_ram_to_io_d" on line 771 right? I'm not at home right now, I will check later.

Tobias

Link to comment
Share on other sites

Guest thefloe

Got the interface working by adding changing line 183 in file pm_fetch_dec to:

[tt]constant const_ram_to_io_d  : std_logic_vector := "001";  -- LD/LDS/LDD/ST/STS/STD ADDRESSING GENERAL I/O PORT 0x1000 0x3FFF [/tt]

and in line 771 where the write access signal is generated and around line 854 where the read signal is generated I added a check for const_ram_to_io_d:

771:

[tt]or ramadr_reg_in(15 downto 13)=const_ram_to_io_d [/tt]

around 854:

[tt]and ramadr_reg_in(15 downto 13)/=const_ram_to_io_d [/tt]

that made me access the registers at address 0x8000 (MEM).

So let's see if I have the time to connect my matrix core.

-Tobias

Link to comment
Share on other sites

Guest thefloe

not to forget line 892 here we need to add that memory region as well:

[tt]

and ramadr_reg_in(15 downto 13)/=const_ram_to_io_d

[/tt]

That region starts at 0x2000, so this is also the IO! address! As i want to put there some memory I generated a dual port RAM with coregen (true dual port ram, with enable on the interface you want to connect to the AVR) and connected it like that:

Interface B is connected to the AVR core via the template interface definitions:

[tt]

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

-- Company: Gadget Factory

-- Engineer: Jack Gassett

--

-- Create Date:    3/21/2010

-- Design Name:

-- Module Name:    papilio-core-template - Behavioral

-- Project Name:

-- Target Devices:

-- Tool versions:

-- Description:

--

-- Dependencies:

--

-- Revision:

-- Revision 0.01 - File Created

-- Additional Comments:

-- Use this template as the basis for making your own VHDL cores that plug into the AVR8 Soft Processor.

--

-- License Creative Commons Attribution

-- Please give attribution to the original author and Gadget Factory (www.gadgetfactory.net)

-- This work is licensed under the Creative Commons Attribution 3.0 United States License. To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/us/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.

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

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity papilio_core_template is

Generic (

--Default base location in the I/O address space for this core.

matrix_base_adr : STD_LOGIC_VECTOR (15 downto 0) := x"2000" -- _SFR_IO8(0x2000) / _SFR_MEM8(0x2020)

); 

Port (

-- begin Signals required by AVR8 for this core, do not modify.

nReset : in  STD_LOGIC;

clk : in  STD_LOGIC;

adr : in  STD_LOGIC_VECTOR (15 downto 0);

dbus_in : in  STD_LOGIC_VECTOR (7 downto 0);

dbus_out : out  STD_LOGIC_VECTOR (7 downto 0);

iore : in  STD_LOGIC;

iowe : in  STD_LOGIC;

out_en : out STD_LOGIC;

-- end Signals required by AVR8 for this core, do not modify.

);

end papilio_core_template;

architecture Behavioral of papilio_core_template is

--Define the registers and signals that will be used inside the Core.

signal matrix_byte : std_logic_vector(7 downto 0):= "00000000";

signal matrix_sel : std_logic;

component frame_ram

PORT (

clka : IN STD_LOGIC;

wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);

addra : IN STD_LOGIC_VECTOR(12 DOWNTO 0);

dina : IN STD_LOGIC_VECTOR(7 DOWNTO 0);

douta : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);

clkb : IN STD_LOGIC;

enb : IN STD_LOGIC;

web : IN STD_LOGIC_VECTOR(0 DOWNTO 0);

addrb : IN STD_LOGIC_VECTOR(12 DOWNTO 0);

dinb : IN STD_LOGIC_VECTOR(7 DOWNTO 0);

doutb : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)

);

end component;

signal wea, web : std_logic_vector(0 downto 0);

begin

wea(0) <= '0';

web(0) <= iowe;

extram: frame_ram

port map(

clka => clk,

wea => wea,

addra => adr(12 downto 0),

dina => (others => '0'),

douta => open,

clkb => clk,

enb => matrix_sel,

web => web,

addrb => adr(12 downto 0),

dinb => dbus_in,

doutb => matrix_byte

);

matrix_sel <= '1' when adr >= matrix_base_adr else '0';

dbus_out <= matrix_byte when matrix_sel='1' else "ZZZZZZZZ";

out_en <= '1' when matrix_sel='1' and iore='1' else '0';

end Behavioral;

[/tt]

To access that memory from the arduino part I defined it as an array

[tt]

// matrix_base_adr = IO address of component

#define matrix_base_adr  0x2000         

// this is more or less the SFR_IO8 macro, except that the variable is an array now

#define matrix_ram ((volatile uint8_t *) (matrix_base_adr + 0x20))

[/tt]

[tt]

// write to index 10

matrix_ram[10] = 0xAA;

// read from index 0x200

tmp = matrix_ram[0x200];

[/tt]

yeah now I can connect my matrix core to the other port ;)

Link to comment
Share on other sites

[tt]dbus_out <= matrix_byte when matrix_sel='1' else "ZZZZZZZZ";[/tt]
[tt]

Are you connecting this port "dbus_out" to external pins ? You cannot have high-Z signals inside the FPGA, I wonder if you know that.

In case you just meant "I don't care about dbus_out value when matrix_sel /= 1", use "(others => 'X') instead of 'Z'.

[/tt]

Link to comment
Share on other sites

Guest thefloe

Are you connecting this port "dbus_out" to external pins ? You cannot have high-Z signals inside the FPGA, I wonder if you know that.

In case you just meant "I don't care about dbus_out value when matrix_sel /= 1", use "(others => 'X') instead of 'Z'.

Nope, nothing connected to the outside world here. Everything up to here stays inside the silicon.

Link to comment
Share on other sites

  • 2 weeks later...

Archived

This topic is now archived and is closed to further replies.