I'm trying to simulate the following code block in Verilog testbench but the data doesn't get read at the desired clock frequency.
always #(CLK_PERIOD/2) adc_clk = ~adc_clk;
always #((CLK_PERIOD/2)*ratio) fpga_clk = ~fpga_clk; // fpga_clk = adc_clk/8
fdin = $fopen ("signaldata.txt", "r");
nend_file=1;
while(nend_file)
begin
nend_file = $fgets(string, fdin);
unused = $sscanf(string, "%d", txt_in);
begin
adc_data_in_vld = 1'b1;
@(posedge adc_clk)
adc_data_in = txt_in; // this data should be read at every posedge of adc_clk
end
end
This is the main code:
module raw_sp(fpga_clk, adc_clk, rst, adc_data_in_vld, adc_data_in, start, I_out, Q_out, done);
parameter ADC_DATA_WIDTH = 16;
parameter ratio = 8;
parameter shift_reg_size = ADC_DATA_WIDTH * ratio;
input fpga_clk;
input adc_clk;
input rst;
input adc_data_in_vld;
input signed [ADC_DATA_WIDTH-1:0] adc_data_in;
input start;
output [47:0] I_out;
output [47:0] Q_out;
output done;
localparam READOUT_SIGNAL_FREQ = 1000000;
localparam ADC_SAMPLE_SIZE = 65536;
localparam ADC_SR = 1966080000;
localparam SAMPLE_COUNT = ADC_SAMPLE_SIZE/ratio;
localparam NCO_BITS = 20;
localparam s0=2'd0, s1=2'd1, s2=2'd2, s3=2'd3;
real PHASE_WORD = (READOUT_SIGNAL_FREQ * (2**(NCO_BITS)))/(ADC_SR/ratio);
reg [NCO_BITS-1:0] phase_word [ratio-1:0];
reg [15:0] sample_count;
reg [NCO_BITS-1:0] temp;
reg adc_data_in_vld_dly0;
reg adc_data_in_vld_dly1;
reg start_dly0;
reg done_int;
reg [1:0] state;
always @(posedge fpga_clk or negedge rst)
begin
if(~rst)
begin
adc_data_in_vld_dly0 <= 1'b0;
adc_data_in_vld_dly1 <= 1'b0;
end
else
begin
adc_data_in_vld_dly0 <= adc_data_in_vld;
adc_data_in_vld_dly1 <= adc_data_in_vld_dly0;
end
end
always @(posedge fpga_clk or negedge rst)
begin
if(~rst)
start_dly0 <= 1'b0;
else
start_dly0 <= start;
end
// PHASE WORD GENERATION
integer i;
always @(posedge fpga_clk or negedge rst)
begin
if (~rst | (sample_count == SAMPLE_COUNT))
begin
temp <= PHASE_WORD;
for (i = 0; i < ratio; i = i + 1)
begin
phase_word[i] <= 0;
end
end
else
begin
phase_word[0] = temp;
for (i = 1; i < ratio; i = i + 1)
begin
phase_word[i] = phase_word[i-1] + PHASE_WORD;
end
temp = phase_word[ratio-1] + PHASE_WORD;
end
end
wire [15:0] sin_out [ratio-1:0];
wire [15:0] cos_out [ratio-1:0];
wire [15:0] sin_data [ratio-1:0];
wire [15:0] cos_data [ratio-1:0];
// CORDIC Module Instantiation
genvar k;
generate
for (k = 0; k < ratio; k = k + 1)
begin
ddfs CDC(fpga_clk, rst, phase_word[k], sin_out[k], cos_out[k]);
end
endgenerate
// Assign Sin and Cos Values
genvar l;
generate
for (l = 0; l < ratio; l = l + 1)
begin
assign sin_data[l] = sin_out[l];
assign cos_data[l] = cos_out[l];
end
endgenerate
//reg signed [shift_reg_size-1:0] shift_reg;
reg signed [ADC_DATA_WIDTH-1:0] adc_sample [ratio-1:0];
reg signed [ADC_DATA_WIDTH-1:0] data_reg [ratio-1:0];
integer count;
// Shift register to input incoming ADC Data
always @(posedge adc_clk or negedge rst)
begin
if (~rst)
begin
count = 0;
for (i = 0; i < ratio; i = i + 1)
begin
data_reg[i] <= 0;
end
end
else
if (count == ratio)
count = 0;
else
begin
data_reg[count] = adc_data_in;
count = count + 1;
end
end
always @(posedge fpga_clk or negedge rst)
begin
if (~rst | sample_count == SAMPLE_COUNT)
begin
for (i = 0; i < ratio; i = i + 1)
begin
adc_sample[i] <= 0;
end
end
else
begin
for (i = 0; i < ratio; i = i + 1)
begin
adc_sample[i] <= data_reg[i];
end
end
end
reg [47:0] accu_I [ratio-1:0];
reg [47:0] accu_Q [ratio-1:0];
reg [47:0] temp_I, temp_Q;
// I, Q data processing
always @(posedge fpga_clk or negedge rst)
begin
if (~rst | (sample_count == SAMPLE_COUNT))
begin
temp_I <= 0;
temp_Q <= 0;
for (i = 0; i < ratio; i = i + 1)
begin
accu_I[i] <= 0;
accu_Q[i] <= 0;
end
end
else
begin
if (adc_data_in_vld_dly1)
begin
accu_I[0] <= temp_I + cos_data[0] * adc_sample[0];
accu_Q[0] <= temp_Q + sin_data[0] * adc_sample[0];
for (i = 1; i < ratio; i = i + 1)
begin
accu_I[i] = accu_I[i-1] + cos_data[i] * adc_sample[i];
accu_Q[i] = accu_Q[i-1] + sin_data[i] * adc_sample[i];
end
temp_I <= accu_I[ratio-1];
temp_Q <= accu_Q[ratio-1];
end
end
end
assign I_out = temp_I;
assign Q_out = temp_Q;
always @(posedge fpga_clk or negedge rst)
begin
if (~rst)
sample_count <= 0;
else if (adc_data_in_vld_dly0)
sample_count <= sample_count + ratio;
end
always @(posedge fpga_clk or negedge rst)
begin
if(~rst)
begin
state <= s0;
done_int <= 1'b0;
end
else
begin
case (state)
s0: begin
done_int <= 1'b0;
if(adc_data_in_vld_dly0 & start_dly0)
state <= s1;
else
state <= s0;
end
s1: begin
if(sample_count == SAMPLE_COUNT)
begin
state <= s2;
done_int <= 1'b1;
sample_count <= 0;
end
else
begin
state <= s1;
done_int <= 1'b0;
end
end
s2: begin
state <= s0;
done_int <= 1'b0;
end
s3: begin
state <= s0;
done_int <= 1'b0;
end
default: state <= s0;
endcase
end
end
assign done = done_int;
endmodule
Simulation output: