Forum Discussion
Altera_Forum
Honored Contributor
14 years agoHelp with CIC decimation filter
Hi,
I wrote a Verilog code for a CIC decimation filter. I relied on a code written in the book 'digital signal processing with FPGA' . Here is the code: // cic decimation filter : R=64, M=1, N=3 module cicdecim64 (x_in,y_out,clk,reset); input clk,reset; input [7:0] x_in; output [7:0] y_out; parameter hold=0, sample=1; reg state; //sample or hold states reg [5:0] count; //count till 63 starting from 0 reg [7:0] x; //input wire [23:0] sx; //sign extended input reg [23:0] i0; //Integrator output section 0 reg [18:0] i1; //output section 1 under the consideration of Haugenauer's pruning reg [13:0] i2; reg [11:0] i2d1, c1, c0; // Integrator+COMB 0 reg [10:0] c1d1, c2; reg [9:0] c2d1, c3; always @(negedge clk) begin : FSM // finite state machine case (state) hold : begin if (count<63) // setting states for downsampling state <= hold; else state <=sample; end default: state <= hold; endcase end assign sx={{16{x[7]}},x_in}; // Integrator always @(posedge clk)begin if(reset) begin i0 <= 24'd0; i1 <= 19'd0; i2 <= 14'd0; end begin: I x <= x_in; i0 <= i0+sx; i1 <= i1+i0[23:7]; i2 <= i2+i1[18:5]; case (state) //downsample sample : begin c0 <= i2[13:1]; count <= 0; //reset counter once a sample has been fetched end default : count <= count+1; endcase end end // COMB always @(posedge clk) begin: COMB i2d1 <= c0; c1 <= c0-i2d1; c1d1 <= c1[11:1]; c2 <= c1[11:1]-c1d1; c2d1 <= c2[10:1]; c3 <= c2[10:1]-c2d1; end assign y_out=c3[9:2]; endmodule To test it, I wrote the following test bench: `timescale 1ns/1ps module test; reg clk,reset; wire [7:0] x; wire [7:0] y; assign x=8'd0; cicdecim64 cic (x,y,clk,reset); initial begin clk<=1'b0; reset <= 1'b0;# 3 reset=~reset;# 6 reset=~reset; end always# 4 clk=~clk; endmodule However, the simulation in modelsim shows the status of i0 changes to x at the first positive edge of the clock. Can anyone help me solve this problem? Thanks in advance13 Replies
- Altera_Forum
Honored Contributor
It could be because the very first value on input x is x so you need to initilise x just like your clock.
- Altera_Forum
Honored Contributor
Thanks for the reply. x is not the problem since it is defined at the 1st clock edge. However, I tried your suggestion and the result was the same. :/
- Altera_Forum
Honored Contributor
You should be able to trace the x state from the assignment:
i0 <= i0+sx; and assign sx={{16{x[7]}},x_in}; surely it must be either sx or x_in or x entering x state edit: or i0 first value is x state - Altera_Forum
Honored Contributor
I have been struggling in the past 4 days to get this to work and so far it is only getting worse. For instance :
always @(posedge clk)begin if(reset) begin i0 <= 24'd0; i1 <= 19'd0; i2 <= 14'd0; x <= 8'd0; simulation shows only x is becoming 0 when reset is high. The other have the status x from the beginning. Plus modelsim seems to have a problem updating my files from time to time, it kind of stores an older version of each file and uses it, whenever it feels like it. I'm so frustrated right now - Altera_Forum
Honored Contributor
I don't remember verilog well but just a thought, you need to insert reset in the sensitivity list as the clock
- Altera_Forum
Honored Contributor
--- Quote Start --- Body language is essential for an actress, even if you don't use your body in an athletic way. Just to be free, to use it like your voice. A body can be small and have incredible violence. A body talks. --- Quote End --- What the hell? Does this sort of spamming happen often here? - Altera_Forum
Honored Contributor
--- Quote Start --- I don't remember verilog well but just a thought, you need to insert reset in the sensitivity list as the clock --- Quote End --- Not really. It is not a must. I never used the reset in the sensitivity list in my old codes and they all worked normally. - Altera_Forum
Honored Contributor
Now that I have 5 posts, let me post the code and the simulation properly:
Code:
Test bench:// cic decimation filter : R=64, M=1, N=3 module cicdecim64 (x_in,y_out,clk,reset); input clk,reset; input x_in; output y_out; parameter hold=0, sample=1; reg state; //sample or hold states reg count; //count till 63 starting from 0 reg x; //input wire sx; //sign extended input reg i0; //Integrator output section 0 reg i1; //output section 1 under the consideration of Haugenauer's pruning reg i2; reg i2d1, c1, c0; // Integrator+COMB 0 reg c1d1, c2; reg c2d1, c3; always @(negedge clk) begin : FSM // finite state machine case (state) hold : begin if (count<63) // setting states for downsampling state <= hold; else state <=sample; end default: state <= hold; endcase end assign sx={{16{x}},x_in}; // Integrator always @(posedge clk)begin if(reset) begin i0 <= 24'd0; i1 <= 19'd0; i2 <= 14'd0; x <= 8'd0; end else x <= x_in; i0 <= i0+sx; i1 <= i1+i0; i2 <= i2+i1; case (state) //downsample sample : begin c0 <= i2; count <= 0; //reset counter once a sample has been fetched end default : count <= count+1; endcase end // COMB always @(posedge clk) begin: COMB i2d1 <= c0; c1 <= c0-i2d1; c1d1 <= c1; c2 <= c1-c1d1; c2d1 <= c2; c3 <= c2-c2d1; end assign y_out=c3; endmodule
Simulation results: http://s10.postimage.org/5g5m5xop5/sim.png As u can see, reset is only resetting x and ignoring the others. http://postimage.org/image/71oahgce5/`timescale 1ns/1ps module test; reg clk,reset; reg x; wire y; cicdecim64 cic (x,y,clk,reset); initial begin x <=8'd1; clk<=1'b0; reset <= 1'b0;# 4 reset=~reset;# 5 reset=~reset; end always# 4 clk=~clk; endmodule - Altera_Forum
Honored Contributor
I tried the following change and got rid of red undefined states:
i0 <= i0 + {{16{x[7]}},x_in}; //sx; - Altera_Forum
Honored Contributor
--- Quote Start --- I tried the following change and got rid of red undefined states: i0 <= i0 + {{16{x[7]}},x_in}; //sx; --- Quote End --- hmm, that did not change anything for me. I simply replaced i0 <= i0 + sx by i0 <= i0 + {{16{x[7]}},x_in} , but the result is still the same.