I'm new to Verilog (and HDL at all) and working with a Cyclone II EP2C5 Mini Dev Board in Quartus II (version 13sp1 to be compatible with my cheap FPGA).
I use the below two modules (one mostly just a container) to try and generate an extremely basic i2s waveform. The output is a 1411200Hz bit clock signal (with expected jitter) and a rock solid 44.1kHz LRClk / Word select signal. See the below image and compare with the hard-coded sample values I'm using.
module i2sTest(
input CLK50MHZ, //crystal input
output BitClk, //1.411200 MHz, or very close at least
output LrClk, //44.1 kHz aligned with BitClk falling edge
output i2sData
);
i2sOutput i2s(
.CLK50MHZ (CLK50MHZ),
.sampleL (16'b1000000000000000),
.sampleR (16'b1000000000000000),
.LrClk (LrClk),
.i2sData (i2sData),
.BitClk (BitClk)
);
endmodule
module i2sOutput (
input CLK50MHZ,
input [15:0] sampleL,
input [15:0] sampleR,
output wire BitClk,
output wire LrClk,
output reg i2sData
);
//generate the bit clock
reg [7:0] BitClkAccumulator; //counts up to alternating 35/36 master clock cycles
reg BitClkAccToggle; //tracks the alternation
always @(posedge CLK50MHZ) begin
if ((BitClkAccumulator + 1) == (35+BitClkAccToggle)) begin
BitClkAccumulator <= 0;
BitClkAccToggle <= ~BitClkAccToggle;
end
else
BitClkAccumulator <= BitClkAccumulator + 1;
end
assign BitClk = (BitClkAccumulator < 18); //50% duty cycle
//generate the lr clock
reg [7:0] audioClkGenAcc; //counts up to 64
always @(negedge BitClk) begin
if (audioClkGenAcc + 1 == 32)
audioClkGenAcc <= 0;
else
audioClkGenAcc <= audioClkGenAcc + 1;
case (audioClkGenAcc + 1)
32: i2sData <= sampleL[ 0]; //I know this isn't accounting for every bit of the inputs, please ignore this for now
1: i2sData <= sampleR[15];
2: i2sData <= sampleR[14];
16: i2sData <= sampleR[ 0];
17: i2sData <= sampleL[15];
18: i2sData <= sampleL[14];
endcase
end
assign LrClk = (audioClkGenAcc < 16);
endmodule
However, making one of any number of slight adjustments to this code, the LrClk frequency becomes extremely unstable. My favorite example of this is as follows: if I change the i2sTest module to connect this literal to the i2sOutput module:
.sampleR (16'b0000000000000000),
Then I get this output:
Have I discovered a bug in this older version of Quartus? Am I violating a Verilog rule? What's going on here?