For a lab I must create the logic to use on a Digilent PMOD ALS. In the lab requirenment I cannot use the sclk signal on the sensitivity list and therefore use a state machine to create the 2.5 MHz clk signal to send to the PMOD ALS. See the code below:
module sens_interface(
input clk, //clk 10Mhz
input reset_n,
input [15:0] delay,
input datain,
output reg sclk,
output reg cs_n,
output reg [3:0] Cout,
output reg [3:0] Dout,
output reg [5:0] cnt
);
//params
//state machine 1
parameter SA0 = 3'b000;
parameter SA1 = 3'b001;
parameter SA2 = 3'b010;
parameter SA3 = 3'b011;
parameter SD0 = 3'b100;
parameter SD1 = 3'b101;
//state machine 2
parameter SR0 = 2'b00;
parameter SR1 = 2'b01;
parameter SR2 = 2'b10;
parameter SR3 = 2'b11;
//pmod als registers
//reg sclk; //2.5Mhz clk
//reg cs_n; //
reg [14:0] data_reg;
//count registers
//reg [5:0] cnt;
reg [15:0] cnt_d;
reg [5:0] cnt_r;
//state registers
reg [2:0] state_sclk;
reg [1:0] state_data;
//State Machine 1
always @ (posedge clk)begin
if(reset_n == 1'b0)begin
cs_n <= 1'b1;
sclk <= 0;
cnt <= 6'd0;
cnt_d <= 16'd0;
end
else
case(state_sclk)
SA0:begin
sclk <= 1'b1;
state_sclk <= SA1;
if (cnt <= 6'd17)
cs_n <= 1'b0;
else
cs_n <= 1'b1;
end
SA1:begin
state_sclk <= SA2;
end
SA2:begin
sclk <= 1'b0;
cnt <= cnt + 1;
state_sclk <= SA3;
end
SA3:begin
if(cnt == 6'd21)begin
cnt <= 0;
state_sclk <= SD0;
end
else
state_sclk <= SA0;
end
SD0:begin
cnt_d <= delay;
state_sclk <= SD1;
end
SD1:begin
if (cnt_d == 0)
state_sclk <= SA0;
else
cnt_d <= cnt_d - 1;
end
default:begin
state_sclk <= SA0;
end
endcase
end
always @ (posedge clk)begin
if (reset_n == 1'b0)begin
cnt_r <= 0;
data_reg <= 0;
end
else begin
case (state_data)
SR0:begin
if (cs_n == 1'b1 && sclk == 1'b1)
state_data <= SR1;
end
SR1: begin
if (cs_n == 1'b1)begin
state_data <= SR0;
cnt_r <= 0;
end
else if (sclk == 1'b0)
state_data <= SR2;
end
SR2:begin
if (cs_n == 1'b1)begin
state_data <= SR0;
cnt_r <= 0;
end
else if (cnt_r == 15)
state_data <= SR3;
else if (sclk == 1'b1)begin
data_reg [14-cnt_r] <= datain;
cnt_r <= cnt_r + 1;
state_data <= SR1;
end
end
SR3:begin
if (cs_n == 1) begin
Cout <= data_reg [11:8];
Dout <= data_reg [7:4];
state_data <= SR0;
end
end
default:begin
state_data <= SR0;
end
endcase
end
end
endmodule
I tried to make a simulation of it and the simulation indicates that after my cnt register reaches 15 it just cuts out and goes to 0.
That behavior is caused by your SA3 state.
When your
cnt == 6'd21(which is6'h15) thecntis set to zero.The generic variable names and lack of comments makes it difficult to see why this is not the expected behavior.