- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Why do you want a circular buffer? what is the application? what have you done so far?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page