mirror of
				https://github.com/marqs85/ossc
				synced 2025-10-31 07:56:03 +03:00 
			
		
		
		
	 f502b2e46c
			
		
	
	
		f502b2e46c
		
	
	
	
	
		
			
			- Code cleanup - Some project files added - PAL linetriple added - FPGA PLL parameters optimized - Reduced jitter on low video clock sources
		
			
				
	
	
		
			169 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Verilog
		
	
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Verilog
		
	
	
	
	
	
| //
 | |
| // Copyright (C) 2015-2016  Markus Hiienkari <mhiienka@niksula.hut.fi>
 | |
| //
 | |
| // This file is part of Open Source Scan Converter project.
 | |
| //
 | |
| // This program is free software: you can redistribute it and/or modify
 | |
| // it under the terms of the GNU General Public License as published by
 | |
| // the Free Software Foundation, either version 3 of the License, or
 | |
| // (at your option) any later version.
 | |
| //
 | |
| // This program is distributed in the hope that it will be useful,
 | |
| // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| // GNU General Public License for more details.
 | |
| //
 | |
| // You should have received a copy of the GNU General Public License
 | |
| // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | |
| //
 | |
| 
 | |
| `define STATE_IDLE              2'b00
 | |
| `define STATE_LEADVERIFY        2'b01
 | |
| `define STATE_DATARCV           2'b10
 | |
| 
 | |
| module ir_rcv (
 | |
|     input clk27,
 | |
|     input reset_n,
 | |
|     input ir_rx,
 | |
|     output reg [15:0] ir_code,
 | |
|     output reg ir_code_ack
 | |
| );
 | |
| 
 | |
| // ~37ns clock period
 | |
| 
 | |
| parameter LEADCODE_LO_THOLD     = 226800;  //8.4ms
 | |
| parameter LEADCODE_HI_THOLD     = 118800;  //4.4ms
 | |
| parameter LEADCODE_HI_RPT_THOLD = 54000;   //2.0ms
 | |
| parameter RPT_RELEASE_THOLD     = 3240000; //120ms
 | |
| parameter BIT_ONE_THOLD         = 27000;   //1.0ms
 | |
| parameter BIT_DETECT_THOLD      = 10800;   //0.4ms
 | |
| parameter IDLE_THOLD            = 141480;  //5.24ms
 | |
| 
 | |
| reg [1:0] state;            // 3 states
 | |
| reg [31:0] databuf;         // temp. buffer
 | |
| reg [5:0] bits_detected;    // max. 63, effectively between 0 and 33
 | |
| reg [17:0] act_cnt;         // max. 5.2ms
 | |
| reg [17:0] leadvrf_cnt;     // max. 5.2ms
 | |
| reg [17:0] datarcv_cnt;     // max. 5.2ms
 | |
| reg [22:0] rpt_cnt;         // max. 166ms
 | |
| 
 | |
| // activity when signal is low
 | |
| always @(posedge clk27 or negedge reset_n)
 | |
| begin
 | |
|     if (!reset_n)
 | |
|         act_cnt <= 0;
 | |
|     else
 | |
|     begin
 | |
|         if ((state == `STATE_IDLE) & (~ir_rx))
 | |
|             act_cnt <= act_cnt + 1'b1;
 | |
|         else
 | |
|             act_cnt <= 0;
 | |
|     end
 | |
| end
 | |
| 
 | |
| // lead code verify counter
 | |
| always @(posedge clk27 or negedge reset_n)
 | |
| begin
 | |
|     if (!reset_n)
 | |
|         leadvrf_cnt <= 0;
 | |
|     else
 | |
|     begin
 | |
|         if ((state == `STATE_LEADVERIFY) & ir_rx)
 | |
|             leadvrf_cnt <= leadvrf_cnt + 1'b1;
 | |
|         else
 | |
|             leadvrf_cnt <= 0;
 | |
|     end
 | |
| end
 | |
| 
 | |
| 
 | |
| // '0' and '1' are differentiated by high phase duration preceded by constant length low phase
 | |
| always @(posedge clk27 or negedge reset_n)
 | |
| begin
 | |
|     if (!reset_n)
 | |
|     begin
 | |
|         datarcv_cnt <= 0;
 | |
|         bits_detected <= 0;
 | |
|         databuf <= 0;
 | |
|     end
 | |
|     else
 | |
|     begin
 | |
|         if (state == `STATE_DATARCV)
 | |
|         begin
 | |
|             if (ir_rx)
 | |
|                 datarcv_cnt <= datarcv_cnt + 1'b1;
 | |
|             else
 | |
|                 datarcv_cnt <= 0;
 | |
| 
 | |
|             if (datarcv_cnt == BIT_DETECT_THOLD)
 | |
|                 bits_detected <= bits_detected + 1'b1;
 | |
|                 
 | |
|             if (datarcv_cnt == BIT_ONE_THOLD)
 | |
|                 databuf[32-bits_detected] <= 1'b1;
 | |
|         end
 | |
|         else
 | |
|         begin
 | |
|             datarcv_cnt <= 0;
 | |
|             bits_detected <= 0;
 | |
|             databuf <= 0;
 | |
|         end
 | |
|     end
 | |
| end
 | |
| 
 | |
| // read and validate data after 32 bits detected (last bit may change to '1' at any time)
 | |
| always @(posedge clk27 or negedge reset_n)
 | |
| begin
 | |
|     if (!reset_n)
 | |
|     begin
 | |
|         ir_code_ack <= 1'b0;
 | |
|         ir_code <= 16'h00000000;
 | |
|     end
 | |
|     else
 | |
|     begin
 | |
|         if ((bits_detected == 32) & (databuf[31:24] == ~databuf[23:16]) & (databuf[15:8] == ~databuf[7:0]))
 | |
|         begin
 | |
|             ir_code <= {databuf[31:24], databuf[15:8]};
 | |
|             ir_code_ack <= 1'b1;
 | |
|         end
 | |
|         else if (rpt_cnt >= RPT_RELEASE_THOLD)
 | |
|         begin
 | |
|             ir_code <= 16'h00000000;
 | |
|             ir_code_ack <= 1'b0;
 | |
|         end
 | |
|         else
 | |
|             ir_code_ack <= 1'b0;
 | |
|     end
 | |
| end
 | |
| 
 | |
| always @(posedge clk27 or negedge reset_n)
 | |
| begin
 | |
|     if (!reset_n)
 | |
|     begin
 | |
|         state <= `STATE_IDLE;
 | |
|         rpt_cnt <= 0;
 | |
|     end
 | |
|     else
 | |
|     begin
 | |
|         rpt_cnt <= rpt_cnt + 1'b1;
 | |
|     
 | |
|         case (state)
 | |
|             `STATE_IDLE:
 | |
|                 if (act_cnt >= LEADCODE_LO_THOLD)
 | |
|                     state <= `STATE_LEADVERIFY;
 | |
|             `STATE_LEADVERIFY:
 | |
|             begin
 | |
|                 if (leadvrf_cnt == LEADCODE_HI_RPT_THOLD)
 | |
|                     rpt_cnt <= 0;
 | |
|                 if (leadvrf_cnt >= LEADCODE_HI_THOLD)
 | |
|                     state <= `STATE_DATARCV;
 | |
|             end    
 | |
|             `STATE_DATARCV:
 | |
|                 if ((datarcv_cnt >= IDLE_THOLD) | (bits_detected >= 33))
 | |
|                     state <= `STATE_IDLE;
 | |
|             default:
 | |
|                 state <= `STATE_IDLE;
 | |
|         endcase
 | |
|     end
 | |
| end
 | |
| 
 | |
| endmodule
 |