Prev: mux behavior
Next: Software bloat (Larkin was right)
From: Rob Gaddi on 28 May 2010 13:37 On 5/28/2010 10:17 AM, rickman wrote: > On May 28, 6:32 am, John_H<newsgr...(a)johnhandwork.com> wrote: >> On May 27, 2:05 pm, rickman<gnu...(a)gmail.com> wrote: >> >> >> >>> How can a sync ram be used at all if an async reset is specified in >>> the HDL? There is no way to "add" an async reset to a sync memory. >> >>> Rick >> >> From the original poster 2 messages before yours: "The reset logic was >> sequential, i.e. reset address 0, then reset address >> 1, one per clock until the entire thing was done." Nothing >> asynchronous here. > > That shouldn't prevent a memory from being used then. That's just > logic driving the RAM. I would guess there was something about the > code that couldn't be done with a ram. Actually, looking at his code, > I don't see where he is writing to the ram ram_dat. fir_cascade is > written, but I don't see where it is initialized. I don't get his > code. It looks more like software than hardware. I'm used to > debugging hardware... > > Rick ram_dat gets written in the IIR state and the RESET state. --- if msd_rdy then -- Update the stored data and advance the -- write pointer. Also decrement the FIR index, which -- we're just using to count IIR stages at this point. ram_dat(TO_INTEGER(write_idx)) <= y; --- when RESET => -- Initialize the states for both filters ram_dat(TO_INTEGER(write_idx)) <= (others => '0'); -- Looking through the XST report, it was definitely generating ram_dat as a RAM. But it for some reason it was insisting that the reset implementation happen on it's very own dedicated write port, which was exploding the logic requirements 4-fold. Ultimately the answer was just to trust the Xilinx global reset on powerup to zero out the RAMs and forgo the runtime reset. Which will work, it's just a little less elegant/portable. -- Rob Gaddi, Highland Technology Email address is currently out of order
From: rickman on 28 May 2010 16:45 On May 28, 1:37 pm, Rob Gaddi <rga...(a)technologyhighland.com> wrote: > On 5/28/2010 10:17 AM, rickman wrote: > > > > > On May 28, 6:32 am, John_H<newsgr...(a)johnhandwork.com> wrote: > >> On May 27, 2:05 pm, rickman<gnu...(a)gmail.com> wrote: > > >>> How can a sync ram be used at all if an async reset is specified in > >>> the HDL? There is no way to "add" an async reset to a sync memory. > > >>> Rick > > >> From the original poster 2 messages before yours: "The reset logic was > >> sequential, i.e. reset address 0, then reset address > >> 1, one per clock until the entire thing was done." Nothing > >> asynchronous here. > > > That shouldn't prevent a memory from being used then. That's just > > logic driving the RAM. I would guess there was something about the > > code that couldn't be done with a ram. Actually, looking at his code, > > I don't see where he is writing to the ram ram_dat. fir_cascade is > > written, but I don't see where it is initialized. I don't get his > > code. It looks more like software than hardware. I'm used to > > debugging hardware... > > > Rick > > ram_dat gets written in the IIR state and the RESET state. > --- > if msd_rdy then > > -- Update the stored data and advance the > -- write pointer. Also decrement the FIR index, which > -- we're just using to count IIR stages at this point. > > ram_dat(TO_INTEGER(write_idx)) <= y; > --- > when RESET => > -- Initialize the states for both filters > ram_dat(TO_INTEGER(write_idx)) <= (others => '0'); Not sure what is wrong, I can't find this code in your post. But I if this is your code, then yes, I guess it is being written. > Looking through the XST report, it was definitely generating ram_dat as > a RAM. But it for some reason it was insisting that the reset > implementation happen on it's very own dedicated write port, which was > exploding the logic requirements 4-fold. > > Ultimately the answer was just to trust the Xilinx global reset on > powerup to zero out the RAMs and forgo the runtime reset. Which will > work, it's just a little less elegant/portable. I was thinking about this the other day. Yes, the RAM is initialized when the bitstream is loaded, but that is different than the FFs being set/cleared on GSR. If you want the ram reinitialized, you have to reconfigure the part. BTW, I expect you know you can init the RAM to arbitrary values, right? But I guess anything other than zero in the data ram is not too useful. It can load default filter coeffs for you though. Rick
From: Brian Drummond on 28 May 2010 18:29
On Fri, 28 May 2010 10:37:28 -0700, Rob Gaddi <rgaddi(a)technologyhighland.com> wrote: > >ram_dat gets written in the IIR state and the RESET state. >--- > if msd_rdy then > > -- Update the stored data and advance the > -- write pointer. Also decrement the FIR index, which > -- we're just using to count IIR stages at this point. > > ram_dat(TO_INTEGER(write_idx)) <= y; >--- > when RESET => > -- Initialize the states for both filters > ram_dat(TO_INTEGER(write_idx)) <= (others => '0'); >-- > >Looking through the XST report, it was definitely generating ram_dat as >a RAM. But it for some reason it was insisting that the reset >implementation happen on it's very own dedicated write port, which was >exploding the logic requirements 4-fold. > >Ultimately the answer was just to trust the Xilinx global reset on >powerup to zero out the RAMs and forgo the runtime reset. Which will >work, it's just a little less elegant/portable. Another answer would be to write ram_dat(TO_INTEGER(write_idx)) <= y_zero; in both states (trusting ... but verify!) synthesis to combine them; but to mux either Y or 0 onto y_zero according to the state. e.g. process (...) variable y_zero : signed_48; variable wr_idx : integer; begin if rising_edge(clk) then wr_idx := TO_INTEGER(write_idx); -- write the ugliness once! y_zero := y; -- default value, eliminates latches! case state is when FIR => ram_dat(wr_idx) <= y_zero; when RESET => y_zero := (others => '0'); ram_dat(wr_idx) <= y_zero; .... Hopefully synthesis can't mess that up too badly! - Brian |