Problems using a Dual access on-chip memory module (QSYS) - Problems using a Dual access on-chip memory module (QSYS) Hello, I have a QSYS system using a Nios II/e processor along with some vhdl modules which should be able to display pixels on a LCD display using a VGA controller. I have already managed to get the Nios II code working as well as the VGA interface. I now seek to access the memory set by the Nios II code in VHDL to retrieve the pixel data and pass them onto the VGA interface, this should be possible with the dual access memory module in QSYS. This is the toplevel VHDL code: LIBRARY ieee; USE ieee.std_logic_1164.all; use ieee.numeric_std.all; ENTITY niosdisplay IS PORT( clk : IN STD_LOGIC; key : IN STD_LOGIC; pixel_clk : OUT STD_LOGIC; red : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '1'); --red magnitude output to DAC green : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '1'); --green magnitude output to DAC blue : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '1'); --blue magnitude output to DAC btn : IN STD_LOGIC_VECTOR(3 DOWNTO 0) := (OTHERS => '0'); --btn pio h_sync : OUT STD_LOGIC; v_sync : OUT STD_LOGIC; n_blank : OUT STD_LOGIC; n_sync : OUT STD_LOGIC ); END niosdisplay; ARCHITECTURE behavior OF niosdisplay IS COMPONENT vga_controller IS PORT( pixel_clk : IN STD_LOGIC; --pixel clock at frequency of VGA mode being used reset_n : IN STD_LOGIC; --active low asycnchronous reset h_sync : OUT STD_LOGIC; --horiztonal sync pulse v_sync : OUT STD_LOGIC; --vertical sync pulse disp_ena : OUT STD_LOGIC; --display enable ('1' = display time, '0' = blanking time) column : OUT INTEGER; --horizontal pixel coordinate row : OUT INTEGER; --vertical pixel coordinate n_blank : OUT STD_LOGIC; --direct blacking output to DAC n_sync : OUT STD_LOGIC --sync-on-green output to DAC ); END COMPONENT vga_controller; COMPONENT altpll0 IS PORT ( areset : IN STD_LOGIC := '0'; inclk0 : IN STD_LOGIC := '0'; c0 : OUT STD_LOGIC ); END COMPONENT altpll0; COMPONENT system is port ( btn_pio_export : in std_logic_vector(3 downto 0) := (others => '0'); -- btn_pio.export clk_clk : in std_logic := '0'; -- clk.clk frame_buf_address : in std_logic_vector(16 downto 0) := (others => '0'); -- frame_buf.address frame_buf_chipselect : in std_logic := '0'; -- .chipselect frame_buf_clken : in std_logic := '0'; -- .clken frame_buf_write : in std_logic := '0'; -- .write frame_buf_readdata : out std_logic_vector(31 downto 0); -- .readdata frame_buf_writedata : in std_logic_vector(31 downto 0) := (others => '0'); -- .writedata frame_buf_byteenable : in std_logic_vector(3 downto 0) := (others => '0'); -- .byteenable reset_reset_n : in std_logic := '0' -- reset.reset_n ); END COMPONENT system; --VGA Stuff signal clk_138 : std_logic; signal column : integer; signal row : integer; signal disp_ena : std_logic; --Nios II Stuff signal mem_data : std_logic_vector(31 downto 0) := (others => '0'); signal frame_buf_addr : natural range 0 to 65536 := 0; BEGIN u0: altpll0 port map('0', clk, clk_138); u1: vga_controller port map(clk_138, '1', h_sync,v_sync, disp_ena, column, row, n_blank, n_sync); u2: system port map(btn_pio_export => btn, clk_clk => clk_138, reset_reset_n => '1', frame_buf_address => std_logic_vector(to_unsigned(frame_buf_addr, 17)), frame_buf_readdata => mem_data, frame_buf_chipselect => '0' ); pixel_clk <= clk_138; draw_pixel : PROCESS(clk_138) variable count : natural range 0 to 4 := 0; BEGIN IF rising_edge(clk_138) then IF disp_ena = '1' then --IF((row > 256) and (row < 256+512) and (column > 320) and (column < 320+512)) THEN --Inside game screen case count is when 0 => red <= mem_data(31 downto 24); blue <= mem_data(31 downto 24); green <= mem_data(31 downto 24); count := 1; when 1 => red <= mem_data(23 downto 16); green <= mem_data(23 downto 16); blue <= mem_data(23 downto 16); count := 2; when 2 => red <= mem_data(15 downto 8); green <= mem_data(15 downto 8); blue <= mem_data(15 downto 8); count := 3; if(frame_buf_addr = 65535) then frame_buf_addr <= 0; else frame_buf_addr <= frame_buf_addr + 1; end if; when 3 => red <= mem_data(7 downto 0); green <= mem_data(7 downto 0); blue <= mem_data(7 downto 0); count := 0; when others => red <= mem_data(31 downto 24); green <= mem_data(31 downto 24); blue <= mem_data(31 downto 24); end case; --ELSE --Gray color to boundary --red <= "11111001"; --green <= "10101001"; --blue <= "10101001"; --END IF; ELSE red <= (OTHERS => '0'); green <= (OTHERS => '0'); blue <= (OTHERS => '0'); END IF; END IF; END PROCESS; END behavior; This is the Qsys system: The code increments the address every 4 accesses so it sets a single byte every 4 clock cycles. But for some reason the readdata port of the memory module is not changed whenever the address changes. It seems to be stuck at address 0, this results in the screen having the same 4 pixel pattern throughout the screen. Here is a screenshot of a signal tap I did: As is visible in the picture, the frame_buffer_readdata does not change its data to the corresponding frame_buf_addr. I have tried playing with the byteenable and chipselect signals but nothing seems to work getting the module to respond to the address change. Does anyone have any idea what is wrong or what I am missing here? Thanks, Mart Replies: Re: Problems using a Dual access on-chip memory module (QSYS) Great to hear that. Sorry that I am not able to help out. With that, I now transition this thread to community support. If you have a new question, Please login to ‘ https://supporttickets.intel.com’ , view details of the desire request, and post a feed/response within the next 15 days to allow me to continue to support you. After 15 days, this thread will be transitioned to community support. The community users will be able to help you on your follow-up questions. Thank you. Best Regards, Richard Tan p/s: If any answer from the community or Intel Support are helpful, please feel free to give best answer or rate 9/10 survey. Replies: Re: Problems using a Dual access on-chip memory module (QSYS) I now seek to access the memory set by the Nios II code in VHDL to retrieve the pixel data and pass them onto the VGA interface Replies: Re: Problems using a Dual access on-chip memory module (QSYS) So I finally solved the issue... The problem was that the frame_buffer address immediately changed back after 1 clock cycle. Since the memory has a delay it needs to be kept at their desired value for at least 2 clocks cycles, doing this will result in the readdata value changing in the third clock cycle. I have another post on reddit with a bit more context: https://www.reddit.com/r/FPGA/comments/y1fkb1/problem_accessing_sdram_from_nios_iie_and_vhdl/ Replies: Re: Problems using a Dual access on-chip memory module (QSYS) Just to inform you that Kelly has hand over this case to me and I will looking into this. Could you help to share your project .qar files so I can understand better on the design? Best Regards, Richard Tan Replies: Re: Problems using a Dual access on-chip memory module (QSYS) Hi Mart, I will get back to you on why it does not increment. Thank you. Regards, Kelly Replies: Re: Problems using a Dual access on-chip memory module (QSYS) Hosts use byte addressing, so you should be increasing your address by 4 each time for a 32 bit data bus, but that doesn't explain the lack of change on readdata. Hmm. Replies: Re: Problems using a Dual access on-chip memory module (QSYS) So, the pattern changes because I am setting the first byte of the memory (address 0). See this code snippet: int main(void) { u8* addr = FRAME_BUFFER_BASE; //Starting point of the video buffer u8 color = 255; *(addr) = 0xFF; *(addr+1) = 0; *(addr+2) = 0; *(addr+3) = 0xFF; while(1){} } this SHOULD result in pixel 1 = WHITE, pixel 2 = BLACK pixel 3 = BLACK pixel 4 = WHITE. But whenever I try to read from another address in memory, the output does not change. Because it is not responding to the address change (in VHDL). See this signal tap: The frame_buf_addr changes but readdata field does not change into the next 32 bits. Because it does not increment it just repeats the pattern of the first 4 pixels(32 bits) throughout the whole screen I want to cycle through the whole memory in VHDL so I can draw graphics like squares/circles. Regards, Mart Replies: Re: Problems using a Dual access on-chip memory module (QSYS) Hi, I see that you managed to get the pixel pattern changing on your screen now, so may I know what is the current issue that you have? Regards, Kelly Replies: Re: Problems using a Dual access on-chip memory module (QSYS) Read this discussion. May be this can help you here https://community.intel.com/t5/Intel-Quartus-Prime-Software/On-Chip- uk49s -Memory-in-Qsys-Quartus/td-p/126471 . If yes then please mentioned me here. Replies: Re: Problems using a Dual access on-chip memory module (QSYS) Thanks for reply, I am able to set the memory using the FRAME_BUFFER_BASE constant in the nios header files. When I set it you can even see the pattern on the screen changing. Replies: Re: Problems using a Dual access on-chip memory module (QSYS) Can you confirm the Nios is correctly writing data to the frame buffer? If you don't have the correct data in the RAM, then the data you read won't be what you expect. - 2022-10-18

external_document