Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

SOPC and beginbursttransfer

I am creating a custom Avalon MM Master that will need to speak to a HPCII DDR2 controller. Rather than generating the core in the SOPC tool, we are generating it using the Megawizard in Quartus.

The core generated in Quartus instantiates the beginbursttransfer signal as an input. Other posts in the forum indicate that in reality this signal is not really necessary, but if that is the case why does the Megawizard put it in? If my custom Master does not support the signal, what state should I tie the signal to in the DDR2 instantiation?

4 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Historically that signal was used by the memory controller (not sure if it still does). That said you don't need to worry about it since it's a signal generated by the fabric and not the master. The fabric will know when a burst is starting drive it to the memory controller. So following the Avalon-MM spec you only need to include the subset of signals needed by your master and you let the fabric take care of the rest.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    This thread is pretty old, but since I'm having the same problem and I see no solution, I'll resurrect it:

    pinscore said that he generated the ddr2 controller via megawizard (read - outside of sopc or qsys). Therefore, the exported signals from sopc and the ddr2 controller are joined in HDL. But the exported signals do not include beginbursttransfer, and the ddr2 controller needs it. Well, in my case, I'm using mpfe, which also needs it to work properly. So, how to tell sopc/qsys to generate it? Right now I'm using the "Avalon-MM Master Translator", but it seems like overkill. I was also considering generating it by it being a positive edge detector of (read or write), but I'm not sure if it would be correct.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You would need a burst counter too since you could have two back to back bursts and so there is no edge to detect. So you could have something like (burst_counter == 0) & (read | write) and then do an edge detect on that assuming that the counter being 0 is when it's ready for a new burst. This signal doesn't heed waitrequest, so if the local_ready is low when burst begin is high you don't continue to hold burst begin high like you would with say read or write.

    Alternatively you could just make a bridging component where the slave port is in the system and you expose all the wires to the top level with a conduit. One of the slave lines could be the burstbegin signal and the fabric will drive it for you. This all assume that this signal still works.... I have no clue since I have always avoided using it.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I wrote the following and seems to be working so far.

     -- This module:
    -- * generates the beginbursttransfer signal, which is blatantly missing in qsys when exporting avalon-mm ports.
    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    entity beginburst_gen is
    port (
        rst        : in  std_logic;
        clk        : in  std_logic;
        burstcount : in  std_logic_vector;
        readreq    : in  std_logic;
        writereq   : in  std_logic;
        rdatavalid : in  std_logic;
        waitreq    : in  std_logic;
        beginburst : out std_logic
    );
    end entity;
    architecture rtl of beginburst_gen is
    type     state_t        is (st_idle, st_wburst, st_rburstwait, st_rburst);
    signal   state          : state_t;
    signal   bcnt           : unsigned(burstcount'length-1 downto 0);
    constant one_burstcount : std_logic_vector(burstcount'length-1 downto 0) := (0 => '1', others => '0');
    begin
    syn_proc : process(clk)
    begin
        if rising_edge(clk) then
            if rst = '1' then
                state <= st_idle;
            else
                case state is
                
                    when st_idle =>
                    
                        if readreq = '1' then
                        
                            bcnt <= unsigned(burstcount);
                            if waitreq = '0' then
                                state <= st_rburst;
                            else
                                state <= st_rburstwait;
                            end if;
                            
                         elsif writereq = '1' then
                         
                            if waitreq = '1' then
                                bcnt  <= unsigned(burstcount);
                                state <= st_wburst;
                            else
                                bcnt <= unsigned(burstcount)-1;
                                if burstcount /= one_burstcount then
                                    state <= st_wburst;
                                end if;
                            end if;
                            
                         end if;
                        
                    when st_wburst =>
                        
                        if writereq = '1' and waitreq = '0' then
                            bcnt <= bcnt-1;
                            if bcnt = 1 then
                                state <= st_idle;
                            end if;
                        end if;
                    
                    when st_rburstwait =>
                        
                        if waitreq = '0' then
                            state <= st_rburst;
                        end if;
                    
                    when st_rburst =>
                        if rdatavalid = '1' then
                            bcnt <= bcnt-1;
                            if bcnt = 1 then
                                state <= st_idle;
                            end if;
                        end if;
                                    
                    when others =>
                        state <= st_idle;
                end case;
            end if;
        end if;
        
    end process;
    comb_proc : process(state, readreq, writereq)
    begin
        beginburst <= '0';
        
        if (state = st_idle) and (readreq or writereq) = '1' then
            beginburst <= '1';
        end if;
            
    end process;
    end architecture;