I have to design an infrared transmitter using a FPGA and Verilog.
One of the conditions is to send a packet every 10Hz , I have a counter that creates a secondary clock at 10Hz from the master clock (100MHz). The packet contains Start-Gap-Select-Gap-Right-Gap-Left-Gap-Forward-Gap-Backwards-Gap. I have a FSM that do this transition at the postive edge of the 10Hz secondary clock. Each of these blocks within the packet has its size, with Gap being just empty space that separates them. The direction blocks have bigger size when selected and smaller otherwise. With the condition that the receiver has a pulse frequency of 36kHz I have another counter that reduces the master clock to 36kHz which i use to generate the pulse sizes for the Start, Select etc. and make the output led 1 while the counter counts up to that size (for cases start, select..) and 0 for Gap state.
However when I look at the LED through my smartphone camera it shows it is on all the time which is what I expect to see as it should send packets 10 times per second.
The problem is that the car is not moving at all, my question is is this the correct logic of doing the things or I am missing something? Thanks
Requested code:
The counter for the 36kHz pulse
always@(posedge CLK) begin
if(RESET) begin
Counter <= 0;
SEC_CLK <= 0;
end
else if(Counter == 2778) begin
Counter <= 0;
SEC_CLK <= 1'b1;
end
else begin
Counter <= Counter + 1;
SEC_CLK <= 1'b0;
end
end
The 10Hz counter, don't know whether is good to reduce the 36kHz or use the Master Clock, but it is a nice round number so I used the Master CLock
always@(posedge CLK) begin
if(sec_counter == 100000) begin
sec_counter <= 0;
send <= 1;
end
else begin
sec_counter <= sec_counter +1;
send <= 0;
end
end`
The FSM LOGIC:
always@(Curr_State) begin
case(Curr_State)
1'd0: begin //START
Next_State <= 1'd1;
Previous_State <= Next_State;
max_count <= StartBurstSize;
flag <= 0;
end
1'd1: begin //GAP
if(Previous_State <= 1'd7)
Next_State<=1'd0;
else
Next_State <= Previous_State +1;
max_count <= GapSize;
flag <= 1;
IR_LED = 1'b1;
if(change)
Curr_State <= Next_State;
else
Next_State <= Curr_State;
end
1'd2: begin //SELECT
Next_State <= 1'd1;
Previous_State <= Curr_State;
max_count <= CarSelectBurstSize;
IR_LED = 1'b0;
flag <= 0;
if(change)
Curr_State <= Next_State;
else
Next_State <= Curr_State;
end
1'd3: begin //RIGHT
if(BTNR)
max_count <= AsserBurstSize;
else
max_count <= DeAssertBurstSize;
Next_State <= 1'd1;
Previous_State <= Curr_State;
flag <= 0;
if(change)
Curr_State <= Next_State;
else
Next_State <= Curr_State;
IR_LED = 1'b1;
end
1'd4: begin //LEFT
if(BTNL)
max_count <= AsserBurstSize;
else
max_count <= DeAssertBurstSize;
Next_State <= 1'd1;
Previous_State <= Curr_State;
flag <= 0;
if(change)
Curr_State <= Next_State;
else
Next_State <= Curr_State;
IR_LED = 1'b1;
end
1'd5: begin //FORWARD
if(BTNU)
max_count <= AsserBurstSize;
else
max_count <= DeAssertBurstSize;
Next_State <= 1'd1;
Previous_State <= Curr_State;
flag <= 0;
if(change)
Curr_State <= Next_State;
else
Next_State <= Curr_State;
IR_LED = 1'b1;
end
1'd6: begin //Backwards
if(BTND)
max_count <= AsserBurstSize;
else
max_count <= DeAssertBurstSize;
Next_State <= 1'd1;
Previous_State <= Curr_State;
flag <= 0;
if(change)
Curr_State <= Next_State;
else
Next_State <= Curr_State;
IR_LED = 1'b1;
end
endcase
end
SENDING THE PULSES TO THE IR LED
always@(posedge SEC_CLK) begin
if(send) begin
if(Pcounter == max_count) begin //COUNTING BLOCK SIZE
Pcounter <= 0;
IR_LED=1'b0;
end
else begin
if(flag)
IR_LED=1'b0; //GAP
else
IR_LED=1'b1;
Pcounter <= Pcounter+1;
end
end
end