Forum Discussion
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
Honored 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
Honored 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
Honored 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
Honored 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;