OpenCores
URL https://opencores.org/ocsvn/scct/scct/trunk

Subversion Repositories scct

[/] [scct/] [trunk/] [verilog/] [scct_channel.v] - Rev 2

Compare with Previous | Blame | View Log

// $Id: scct_channel.v 2 2015-06-15 13:52:02Z fkluge $
// Simple timer channel
 
`include "scct_constants.v"
 
module scct_channel (
		 clk, rst, counter, counter_changed,
		 icoc_select_i, icoc_select_i_wen,
		 icoc_action_i, icoc_action_i_wen,
		 i_cc_reg, i_cc_reg_wen,
		 irq_enable_i, irq_enable_i_wen,
		 irq_status_i, irq_status_i_wen,
		 force_oc_i, force_oc_i_wen,
		 icoc_select_o, icoc_action_o, cc_reg_o, irq_enable_o, irq_status_o,
		 pin_i, pin_o
		 );
 
   input 			     clk;
   input 			     rst;
   input [`SCCT_COUNTER_CTR_WIDTH-1:0] counter;
   input 			       counter_changed;
 
   // TODO: replace single-bit X_i, X_i_wen signals by a single signal
   input 			       icoc_select_i;
   input 			       icoc_select_i_wen;
   input [1:0] 			       icoc_action_i;
   input 			       icoc_action_i_wen;
   input [`SCCT_COUNTER_CTR_WIDTH-1:0] i_cc_reg;
   input 			       i_cc_reg_wen;
   input 			       irq_enable_i;
   input 			       irq_enable_i_wen;
   input 			       irq_status_i; // write 1 to clear flag
   input 			       irq_status_i_wen;
   input 			       force_oc_i;
   input 			       force_oc_i_wen;
 
   output 			       icoc_select_o;
   output [1:0] 		       icoc_action_o;
   output [`SCCT_COUNTER_CTR_WIDTH-1:0] cc_reg_o;
   output 				irq_enable_o;
   output 				irq_status_o;
   input 				pin_i;
   output 				pin_o;
 
   reg 					outval;
   reg 					icoc_select;
   reg [1:0] 				icoc_action;
   reg 					irq_enable;
   reg 					irq_status;
 
   reg 					icirq; // set when IC detects an edge that is interesting according to icoc_action
   reg 					ocirq; // set when counter matches cc_reg
   wire 				intistat;
 
   // Capture/Compare Register
   reg [`SCCT_COUNTER_CTR_WIDTH-1:0] 	cc_reg;
   wire 				oc_match;
 
   reg 					last_input_state;
 
 
 
 
   assign icoc_select_o = icoc_select;
   assign icoc_action_o = icoc_action;
   assign cc_reg_o = cc_reg;
   assign irq_enable_o = irq_enable;
   assign irq_status_o = irq_status;
 
 
   //assign pin = (icoc_select == `SCCT_CH_MS_IC) ? 1'bz : outval;
   assign pin_o = outval;
 
 
 
   assign intistat = (icoc_select == `SCCT_CH_MS_IC) ? icirq : ocirq;
 
   assign oc_match = (cc_reg == counter) && counter_changed;
 
 
   always @(posedge clk or posedge rst)
     begin
	if (rst)
	  begin
	     cc_reg <= `SCCT_COUNTER_CTR_WIDTH'b0;
	     icoc_select <= `SCCT_CH_MS_IC;
	     icoc_action <= `SCCT_IC_NONE;
	     irq_enable <= 1'b0;
	     icirq <= 1'b0;
	     ocirq <= 1'b0;
	     irq_status <= 1'b0;
	     outval <= 1'b0;
	     last_input_state <= 1'b0;	     
	  end
	else
	  begin
	     // write
	     if (icoc_select_i_wen)
	       begin
		  icoc_select <= icoc_select_i;
		  // reset old irq states
		  case (icoc_select_i)
		    `SCCT_CH_MS_IC: icirq <= 0;
		    `SCCT_CH_MS_OC: ocirq <= 0;
		  endcase // case (icoc_select_i)
	       end
	     if (icoc_action_i_wen)
	       icoc_action <= icoc_action_i;
	     if (i_cc_reg_wen)
	       cc_reg <= i_cc_reg;
	     if (irq_enable_i_wen)
	       irq_enable <= irq_enable_i;
	     if ( (irq_status_i_wen) && (irq_status_i == 1) )
	       begin
		  icirq <= 0;
		  ocirq <= 0;
		  irq_status <= 0;
	       end
	     else
 	       irq_status <= irq_enable ? intistat : 0;
 
	     //if (force_oc_i_wen)
	       //outval <= force_oc_i;
 
	     if (icoc_select == `SCCT_CH_MS_OC)
	       begin
		  if ( oc_match || (force_oc_i_wen && force_oc_i) )
		    begin
		       case (icoc_action)
			 `SCCT_OC_HIGH: outval = 1;
			 `SCCT_OC_LOW: outval = 0;
			 `SCCT_OC_TOGGLE: outval = !outval;
		       endcase
		       if (oc_match) ocirq <= 1;
		    end
	       end // if (icoc_select == `SCCT_CH_MS_OC)
	     else if (icoc_select == `SCCT_CH_MS_IC)
	       begin
		  if ( (icoc_action[`SCCT_IC_POSEDGE_BIT] == 1) && (last_input_state == 0) && (pin_i == 1) )
		    begin
		       cc_reg <= counter;
		       icirq <= 1;
		    end
		  else if ( (icoc_action[`SCCT_IC_NEGEDGE_BIT] == 1) && (last_input_state == 1) && (pin_i == 0) )
		    begin
		       cc_reg <= counter;
		       icirq <= 1;
 
		    end
	       end
	     last_input_state = pin_i;
	  end
 
     end
 
 
endmodule // channel
 
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.