Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17254 Discussions

create circular buffer form RAM ????

Altera_Forum
Honored Contributor II
1,957 Views

i read about circulr buffer in wiki and i want to use RAM to create a circular buffer, so what should i do i will choose what kind of ram( dual ram or single ram ) ???? 

Read / Write Countsedit]Another solution is to keep counts of the number of items written to and read from the circular buffer. Both counts are stored in signed integer variables with numerical limits larger than the number of items that can be stored and are allowed to wrap freely. The unsigned difference (write_count - read_count) always yields the number of items placed in the buffer and not yet retrieved. This can indicate that the buffer is empty, partially full, completely full (without waste of a storage location) or in a state of overrun. The advantage is: The source and sink of data can implement independent policies for dealing with a full buffer and overrun while adhering to the rule that only the source of data modifies the write count and only the sink of data modifies the read count. This can result in elegant and robust circular buffer implementations even in multi-threaded environments. The disadvantage is: You need two additional variables. Absolute indicesedit]It is possible to optimize the previous solution by using indices instead of pointers: indices can store read/write counts instead of the offset from start of the buffer, the separate variables in the above solution are removed and relative indices are obtained on the fly by division modulo the buffer's length. The advantage is: No extra variables are needed. The disadvantages are: Every access needs an additional modulo operation. If counter wrap is possible, complex logic can be needed if the buffer's length is not a divisor of the counter's capacity. On binary computers, both of these disadvantages disappear if the buffer's length is a power of two—at the cost of a constraint on possible buffers lengths. here is the way i want to do
0 Kudos
4 Replies
Altera_Forum
Honored Contributor II
917 Views

Why do you want a circular buffer? what is the application? what have you done so far?

0 Kudos
Altera_Forum
Honored Contributor II
917 Views

 

--- Quote Start ---  

Why do you want a circular buffer? what is the application? what have you done so far? 

--- Quote End ---  

 

i want to bult a FIR filter, and on the internet they suggest use circular buffer, and because the circular buffer need to be buffering the signal from the audio codec (data stream ). before i try to use flip-flip d for my filter but i doesnt work so i change the way to think about buffer
0 Kudos
Altera_Forum
Honored Contributor II
917 Views

Are you sure the circular buffer isnt intended for a software approach? On an FPGA the data stream is constant, and the FIR is just a pipe delay, so there is no need for any buffering, unless you are trying to do some sort of time delay filtering...

0 Kudos
Altera_Forum
Honored Contributor II
917 Views

 

--- Quote Start ---  

Are you sure the circular buffer isnt intended for a software approach? On an FPGA the data stream is constant, and the FIR is just a pipe delay, so there is no need for any buffering, unless you are trying to do some sort of time delay filtering... 

--- Quote End ---  

 

// -------------------------------------------------------------------- assign TD_RESET = 1'b1; // Allow 27 MHz assign AUD_ADCLRCK = AUD_DACLRCK; assign AUD_XCK = AUD_CTRL_CLK; Reset_Delay r0 ( .iCLK(CLOCK_50),.oRESET(DLY_RST) ); VGA_Audio_PLL p1 ( .areset(~DLY_RST),.inclk0(CLOCK_27),.c0(VGA_CTRL_CLK),.c1(AUD_CTRL_CLK),.c2(VGA_CLK) ); I2C_AV_Config u3 ( // Host Side .iCLK(CLOCK_50), .iRST_N(KEY), // I2C Side .I2C_SCLK(I2C_SCLK), .I2C_SDAT(I2C_SDAT) ); AUDIO_DAC_ADC u4 ( // Audio Side .oAUD_BCK(AUD_BCLK), .oAUD_DATA(AUD_DACDAT), .oAUD_LRCK(AUD_DACLRCK), .oAUD_inL(audio_inL), // audio data from ADC .oAUD_inR(audio_inR), // audio data from ADC .iAUD_ADCDAT(AUD_ADCDAT), .iAUD_extL(audio_outL), // audio data to DAC .iAUD_extR(audio_outR), // audio data to DAC // Control Signals //.iSrc_Select(SW), .iCLK_18_4(AUD_CTRL_CLK), .iRST_N(DLY_RST) ); /// reset ////////////////////////////////////// //state machine start up wire reset; // reset control assign reset = ~KEY; /////////////////////////////////////////////// // state variable reg state ; //oneshot gen to sync to audio clock reg last_clk ; // output to audio DAC reg signed audio_outL, audio_outR ; // input from audio ADC wire signed audio_inL, audio_inR; /// memory for phase shifter ///////////////////////////////////////// //memory control reg we; //write enable--active high wire read_data; reg write_data; reg addr_reg; //pointers into the shift register //200 samples at 48kHz for 1/4 cycle 60 Hz noise reg ptr_in, ptr_out; //make the phase shift register ram_infer PhaseShifter(read_data, addr_reg, write_data, we, CLOCK_50); ////////////////////////////////////////////////////////////////////// /// LMS ///////////////////////////////////////////////////////////// // LMS registers // 2 weights reg signed w1, w2; // 2 inputs reg signed ref60, shifted_ref60 ; // error output (main output) wire signed error_out ; // two product terms wire signed w1_x_ref, w2_x_shifted_ref; // mult for weight times ref and weight times phase-shifted ref signed_mult w1xRef(w1_x_ref, w1, ref60); signed_mult w2xRefShifted(w2_x_shifted_ref, w2, shifted_ref60) ; //assume noisy signal is on right channel, ref on left channel assign error_out = {audio_inR, 2'h0} - (w1_x_ref + w2_x_shifted_ref); ////////////////////////////////////////////////////////////////////// /* // loopback test always @ (posedge AUD_DACLRCK) begin audio_outL <= audio_inL; audio_outR <= audio_inR; end */ //debug readouts assign LEDG = state; assign LEDR = ptr_out; //Run the state machine FAST so that it completes in one //audio cycle always @ (posedge CLOCK_27) begin if (reset) begin ptr_out <= 8'h1 ; // beginning of shift register ptr_in <= 8'h0 ; we <= 1'h0 ; state <= 4'd8 ; //turn off the state machine //last_clk <= 1'h1; end else begin case (state) 1: begin // set up read ptr_out data addr_reg <= ptr_out; we <= 1'h0; // next state state <= 4'd2; end 2: begin //get ptr_out data shifted_ref60 <= {read_data, 2'h0} ; // set up write ptr_in data addr_reg <= ptr_in; we <= 1'h1; write_data <= audio_inL ; // store current ref channel ref60 <= {audio_inL, 2'h0} ; // make some output // original signal in R channel // denoised signal in L channel // audio seems to negate signal, so invert it audio_outR <= -audio_inR ; audio_outL <= -error_out; // next state state <= 4'd3; end 3: begin // turn off memroy write we <= 1'h0; // update weights w1 <= w1 + (((ref60)? -error_out : error_out)>>>10) ; w2 <= w2 + (((shifted_ref60)? -error_out : error_out)>>>10) ; // next state state <= 4'd5; end 5: begin // phase shifter pointer control // update write pointer if (ptr_in == 8'd200) //200 ptr_in <= 8'h0; else ptr_in <= ptr_in + 8'h1 ; // update read pointer if (ptr_out == 8'd200) ptr_out <= 8'h0; else ptr_out <= ptr_out + 8'h1 ; //next state is end state state <= 4'd8; end 8: begin // wait for the audio clock and one-shot it if (AUD_DACLRCK && last_clk==1) begin state <= 4'd1 ; last_clk <= 1'h0 ; end // reset the one-shot memory else if (~AUD_DACLRCK && last_clk==0) begin last_clk <= 1'h1 ; end end default: begin // default state is end state state <= 4'd8 ; end endcase end end endmodule ////////////////////////////////////////////////// //// M4k ram for circular buffer ///////////////// ////////////////////////////////////////////////// // Synchronous RAM // modified for 16 bit access // of 200 words to tune for 1/4 cycle at 60 Hz module ram_infer (q, a, d, we, clk); output reg q; input d; input a; input we, clk; reg mem ; always @ (posedge clk) begin if (we) mem <= d; q <= mem ; end endmodule ////////////////////////////////////////////////// ////////////////////////////////////////////////// //// signed mult of 2.16 format 2'comp//////////// ////////////////////////////////////////////////// module signed_mult (out, a, b); output out; input signed a; input signed b; wire signed out; wire signed mult_out; assign mult_out = a * b; //assign out = mult_out; assign out = {mult_out, mult_out}; endmodule ////////////////////////////////////////////////// 

here is the verilog code search from the internet, they use circular buffer, now i want to do it with VHDL code
0 Kudos
Reply