dakies/OSS_Verilog huggingface dataset:
module pci_sync_module
(
					set_clk_in,
					delete_clk_in,
					reset_in,
					delete_set_out,
					block_set_out,
					delete_in
);

// system inputs from two clock domains
input	set_clk_in;
input	delete_clk_in;
input	reset_in;
// control outputs
output	delete_set_out;
output	block_set_out;
// control input
input	delete_in;

// internal signals
reg		del_bit;
wire	meta_del_bit;
reg		sync_del_bit;
reg		delayed_del_bit;
wire	meta_bckp_bit;
reg		sync_bckp_bit;
reg		delayed_bckp_bit;


// DELETE_IN input FF - when set must be active, until it is sinchronously cleared
always@(posedge delete_clk_in or posedge reset_in)
begin
	if (reset_in)
		del_bit <= 1'b0;
	else
	begin
		if (!delayed_bckp_bit && sync_bckp_bit)
			del_bit <= 1'b0;
		else if (delete_in)
			del_bit <= 1'b1;
	end
end
assign	block_set_out = del_bit;

// interemediate stage to clk synchronization flip - flops - this ones are prone to metastability
pci_synchronizer_flop	#(1, 0) delete_sync
(
    .data_in        (del_bit),
    .clk_out        (set_clk_in),
    .sync_data_out  (meta_del_bit),
    .async_reset    (reset_in)
) ;

// Final synchronization of del_bit signal to the set clock domain
always@(posedge set_clk_in or posedge reset_in)
begin
	if (reset_in)
		sync_del_bit <= 1'b0;
	else
		sync_del_bit <= meta_del_bit;
end

// Delayed sync_del_bit signal for one clock period pulse generation
always@(posedge set_clk_in or posedge reset_in)
begin
	if (reset_in)
		delayed_del_bit <= 1'b0;
	else
		delayed_del_bit <= sync_del_bit;
end

assign	delete_set_out = !delayed_del_bit && sync_del_bit;

// interemediate stage to clk synchronization flip - flops - this ones are prone to metastability
pci_synchronizer_flop	#(1, 0) clear_delete_sync
(
    .data_in        (sync_del_bit),
    .clk_out        (delete_clk_in),
    .sync_data_out  (meta_bckp_bit),
    .async_reset    (reset_in)
) ;

// Final synchronization of sync_del_bit signal to the delete clock domain
always@(posedge delete_clk_in or posedge reset_in)
begin
	if (reset_in)
		sync_bckp_bit <= 1'b0;
	else
		sync_bckp_bit <= meta_bckp_bit;
end

// Delayed sync_bckp_bit signal for one clock period pulse generation
always@(posedge delete_clk_in or posedge reset_in)
begin
	if (reset_in)
		delayed_bckp_bit <= 1'b0;
	else
		delayed_bckp_bit <= sync_bckp_bit;
end

endmodule
module pci_target32_devs_crit
(
    devs_w,
    devs_w_frm,
    devs_w_frm_irdy,
    pci_frame_in,
    pci_irdy_in,
    pci_devsel_out
);

input       devs_w ;			// devsel signal (composed without critical signals) that do not need critical inputs
input       devs_w_frm ;		// devsel signal (composed without critical signals) that needs AND with critical FRAME input
input       devs_w_frm_irdy ;	// devsel signal (composed without critical signals) that needs AND with critical FRAME and
								// IRDY inputs
input       pci_frame_in ;		// critical constrained input signal
input		pci_irdy_in ;		// critical constrained input signal

output		pci_devsel_out ;	// PCI devsel output

// PCI devsel output with preserved hierarchy for minimum delay!
assign 	pci_devsel_out = ~(devs_w || (devs_w_frm && ~pci_frame_in) || (devs_w_frm_irdy && ~pci_frame_in && pci_irdy_in)) ;


endmodule
module pci_mas_ch_state_crit
(
    change_state_out,
    ch_state_med_in,
    sm_data_phases_in,
    pci_trdy_in,
    pci_stop_in
) ;

output  change_state_out ;
input   ch_state_med_in,
        sm_data_phases_in,
        pci_trdy_in,
        pci_stop_in ;

assign change_state_out = ch_state_med_in || sm_data_phases_in && (~(pci_trdy_in && pci_stop_in)) ;

endmodule
module pci_in_reg
(    
    reset_in,
    clk_in,
    init_complete_in,

    pci_gnt_in,
    pci_frame_in,
    pci_irdy_in,
    pci_trdy_in,
    pci_stop_in,
    pci_devsel_in,
    pci_idsel_in,
    pci_ad_in,
    pci_cbe_in,

    pci_gnt_reg_out,
    pci_frame_reg_out,
    pci_irdy_reg_out,
    pci_trdy_reg_out,
    pci_stop_reg_out,
    pci_devsel_reg_out,
    pci_idsel_reg_out,
    pci_ad_reg_out,
    pci_cbe_reg_out

);

input			reset_in, clk_in, init_complete_in  ;

input           pci_gnt_in ;
input           pci_frame_in ;
input           pci_irdy_in ;
input           pci_trdy_in ;
input           pci_stop_in ;
input           pci_devsel_in ;
input			pci_idsel_in ;
input [31:0]    pci_ad_in ;
input [3:0]     pci_cbe_in ;

output          pci_gnt_reg_out ;
output          pci_frame_reg_out ;
output          pci_irdy_reg_out ;
output          pci_trdy_reg_out ;
output          pci_stop_reg_out ;
output          pci_devsel_reg_out ;
output			pci_idsel_reg_out ;
output [31:0]   pci_ad_reg_out ;
output [3:0]    pci_cbe_reg_out ;


reg             pci_gnt_reg_out ;
reg             pci_frame_reg_out ;
reg             pci_irdy_reg_out ;
reg             pci_trdy_reg_out ;
reg             pci_stop_reg_out ;
reg             pci_devsel_reg_out ;
reg				pci_idsel_reg_out ;
reg    [31:0]   pci_ad_reg_out ;
reg    [3:0]    pci_cbe_reg_out ;

always@(posedge reset_in or posedge clk_in)
begin
    if ( reset_in )
    begin
		pci_gnt_reg_out		<= #`FF_DELAY 1'b1 ;
		pci_frame_reg_out	<= #`FF_DELAY 1'b0 ;
		pci_irdy_reg_out	<= #`FF_DELAY 1'b1 ;
		pci_trdy_reg_out	<= #`FF_DELAY 1'b1 ;
		pci_stop_reg_out	<= #`FF_DELAY 1'b1 ;
		pci_devsel_reg_out	<= #`FF_DELAY 1'b1 ;
		pci_idsel_reg_out	<= #`FF_DELAY 1'b0 ; // active high!
		pci_ad_reg_out      <= #`FF_DELAY 32'h0000_0000 ;
		pci_cbe_reg_out     <= #`FF_DELAY 4'h0 ;
    end
    else if (init_complete_in)
	begin
		pci_gnt_reg_out		<= #`FF_DELAY pci_gnt_in ;
		pci_frame_reg_out	<= #`FF_DELAY pci_frame_in ;
		pci_irdy_reg_out	<= #`FF_DELAY pci_irdy_in ;
		pci_trdy_reg_out	<= #`FF_DELAY pci_trdy_in ;
		pci_stop_reg_out	<= #`FF_DELAY pci_stop_in ;
		pci_devsel_reg_out	<= #`FF_DELAY pci_devsel_in ;
		pci_idsel_reg_out	<= #`FF_DELAY pci_idsel_in ;
		pci_ad_reg_out      <= #`FF_DELAY pci_ad_in ;
		pci_cbe_reg_out     <= #`FF_DELAY pci_cbe_in ;
	end
end

endmodule
module pci_target32_stop_crit
(
    stop_w,
    stop_w_frm,
    stop_w_frm_irdy,
    pci_frame_in,
    pci_irdy_in,
    pci_stop_out
);

input       stop_w ;			// stop signal (composed without critical signals) that do not need critical inputs
input       stop_w_frm ;		// stop signal (composed without critical signals) that needs AND with critical FRAME input
input       stop_w_frm_irdy ;	// stop signal (composed without critical signals) that needs AND with critical FRAME and
								// IRDY inputs
input       pci_frame_in ;		// critical constrained input signal
input		pci_irdy_in ;		// critical constrained input signal

output		pci_stop_out ;		// PCI stop output

// PCI stop output with preserved hierarchy for minimum delay!
assign 	pci_stop_out = ~(stop_w || (stop_w_frm && ~pci_frame_in) || (stop_w_frm_irdy && ~pci_frame_in && ~pci_irdy_in)) ;


endmodule
module pci_cbe_en_crit
(
    pci_cbe_en_out,
    cbe_en_slow_in,
    cbe_en_keep_in,
    pci_stop_in,
    pci_trdy_in
) ;

output  pci_cbe_en_out ;
input   cbe_en_slow_in,
        cbe_en_keep_in,
        pci_stop_in,
        pci_trdy_in ;

assign pci_cbe_en_out = cbe_en_slow_in || cbe_en_keep_in && pci_stop_in && pci_trdy_in ;

endmodule
module pci_par_crit
(
    par_out,
    par_out_in,
    pci_cbe_en_in,
    data_par_in,
    pci_cbe_in
) ;

output par_out ;

input   par_out_in,
        pci_cbe_en_in,
        data_par_in ;

input   [3:0] pci_cbe_in ;

assign par_out = pci_cbe_en_in ? par_out_in : ( pci_cbe_in[3] ^ pci_cbe_in[2] ^ pci_cbe_in[1] ^ pci_cbe_in[0] ^ data_par_in) ;

endmodule
module pci_frame_en_crit
(
    pci_frame_en_out,
    frame_en_slow_in,
    frame_en_keep_in,
    pci_stop_in,
    pci_trdy_in
) ;

output  pci_frame_en_out ;
input   frame_en_slow_in,
        frame_en_keep_in,
        pci_stop_in,
        pci_trdy_in ;

assign pci_frame_en_out = frame_en_slow_in || frame_en_keep_in && pci_stop_in && pci_trdy_in ;

endmodule
module pci_perr_crit
(
    perr_out,
    perr_n_out,
    non_critical_par_in,
    pci_par_in,
    perr_generate_in
) ;

output  perr_out,
        perr_n_out;

input   non_critical_par_in,
        pci_par_in,
        perr_generate_in ;

assign perr_out     = (non_critical_par_in ^ pci_par_in) && perr_generate_in ;
assign perr_n_out   = ~perr_out ;

endmodule
module pci_target32_clk_en
(
    addr_phase,
    config_access,
    addr_claim_in,
    pci_frame_in,
    state_wait,
    state_transfere,
    state_default,
    clk_enable
);

input           addr_phase ;			// indicates registered address phase on PCI bus
input           config_access ;			// indicates configuration access
input           addr_claim_in ;			// indicates claimed input PCI address
input           pci_frame_in ;			// critical constrained input signal
input			state_wait ;			// indicates WAIT state of FSM
input 			state_transfere ;		// indicates TRANSFERE state of FSM
input			state_default ;			// indicates DEFAULT state of FSM

output			clk_enable ;			// FSM clock enable output


// clock enable signal when FSM is in IDLE state
wire s_idle_clk_en	=	((addr_phase && config_access) ||
						(addr_phase && ~config_access && addr_claim_in)) ;

// clock enable signal when FSM is in WAIT state or in DEFAULT state
wire s_wait_clk_en	=	(state_wait || state_default) ;

// clock enable signal when FSM is in TRANSFERE state
wire s_tran_clk_en	=	(state_transfere && pci_frame_in) ;


// Clock enable signal for FSM with preserved hierarchy for minimum delay!
assign clk_enable	=	(s_idle_clk_en || s_wait_clk_en || s_tran_clk_en) ;


endmodule
module pci_async_reset_flop (
  data_in, clk_in, async_reset_data_out, reset_in
);

input      data_in;
input      clk_in;
output     async_reset_data_out;
input      reset_in;

reg        async_reset_data_out;

always @(posedge clk_in or posedge reset_in)
begin
  if (reset_in)
  begin
    async_reset_data_out <= #`FF_DELAY 1'b0;
  end
  else
  begin
    async_reset_data_out <= #`FF_DELAY data_in;
  end
end

endmodule
module pci_target32_trdy_crit
(
    trdy_w,
    trdy_w_frm,
    trdy_w_frm_irdy,
    pci_frame_in,
    pci_irdy_in,
    pci_trdy_out
);

input       trdy_w ;			// trdy signal (composed without critical signals) that do not need critical inputs
input       trdy_w_frm ;		// trdy signal (composed without critical signals) that needs AND with critical FRAME input
input       trdy_w_frm_irdy ;	// trdy signal (composed without critical signals) that needs AND with critical FRAME and
								// IRDY inputs
input       pci_frame_in ;		// critical constrained input signal
input		pci_irdy_in ;		// critical constrained input signal

output		pci_trdy_out ;		// PCI trdy output

// PCI trdy output with preserved hierarchy for minimum delay!
assign 	pci_trdy_out = ~(trdy_w || (trdy_w_frm && ~pci_frame_in) || (trdy_w_frm_irdy && ~pci_frame_in && pci_irdy_in)) ;


endmodule
module pci_irdy_out_crit
(
    pci_irdy_out,
    irdy_slow_in,
    pci_frame_out_in,
    pci_trdy_in,
    pci_stop_in
) ;

output  pci_irdy_out ;
input   irdy_slow_in,
        pci_frame_out_in,
        pci_trdy_in,
        pci_stop_in ;

assign pci_irdy_out = irdy_slow_in || (pci_frame_out_in && ~(pci_trdy_in && pci_stop_in)) ;

endmodule
module pci_frame_load_crit
(
    pci_frame_load_out,
    sm_data_phases_in,
    frame_load_slow_in,
    pci_trdy_in,
    pci_stop_in
) ;

output  pci_frame_load_out ;
input   sm_data_phases_in,
        frame_load_slow_in,
        pci_trdy_in,
        pci_stop_in ;

assign pci_frame_load_out = frame_load_slow_in || sm_data_phases_in && (~(pci_trdy_in && pci_stop_in)) ;

endmodule
module pci_delayed_write_reg
(
	reset_in,
	req_clk_in,
	comp_wdata_out,
	req_we_in,
	req_wdata_in
);

// system inputs
input reset_in,
	  req_clk_in ; // request clock input

output [31:0] comp_wdata_out ; // data output

input req_we_in ; // write enable input
input [31:0] req_wdata_in ; // data input - latched with posedge of req_clk_in when req_we_in is high

reg [31:0] comp_wdata_out ;

// write request operation
always@(posedge req_clk_in or posedge reset_in)
begin
	if (reset_in)
		comp_wdata_out <= #`FF_DELAY 32'h0000_0000 ;
	else
	if (req_we_in)
		comp_wdata_out <= #`FF_DELAY req_wdata_in ;
end

endmodule // DELAYED_WRITE_REG
module pci_serr_en_crit
(
    serr_en_out,
    non_critical_par_in,
    pci_par_in,
    serr_generate_in
);

output  serr_en_out ;

input   non_critical_par_in,
        pci_par_in,
        serr_generate_in ;

assign serr_en_out = serr_generate_in && ( non_critical_par_in ^ pci_par_in ) ;

endmodule
module pci_mas_ad_en_crit
(
    pci_ad_en_out,
    ad_en_slow_in,
    ad_en_on_grant_in,
    pci_gnt_in
) ;

output pci_ad_en_out ;
input  ad_en_slow_in,
       ad_en_on_grant_in,
       pci_gnt_in ;

assign pci_ad_en_out = ad_en_slow_in || (ad_en_on_grant_in && !pci_gnt_in) ;

endmodule
module pci_serr_crit
(
    serr_out,
    non_critical_par_in,
    pci_par_in,
    serr_check_in
);

output  serr_out ;

input   non_critical_par_in,
        pci_par_in,
        serr_check_in ;

assign serr_out = ~(serr_check_in && ( non_critical_par_in ^ pci_par_in )) ;

endmodule
module pci_synchronizer_flop (
  data_in, clk_out, sync_data_out, async_reset
);
parameter               width = 1 ;
parameter               reset_val = 0 ;

  input   [width-1:0]   data_in;
  input                 clk_out;
  output  [width-1:0]   sync_data_out;
  input                 async_reset;

  reg     [width-1:0]   sync_data_out;

  always @(posedge clk_out or posedge async_reset)
  begin
    if (async_reset == 1'b1)
    begin
      sync_data_out <= reset_val;
    end
    else
    begin
// In gate-level simulation, must only go to 1'bX if the input is 1'bX or 1'bZ.
// This should NEVER go to 1'bX due to setup or hold violations.
      sync_data_out <= data_in;
    end
  end
endmodule
module usb_phy(clk, rst, phy_tx_mode, usb_rst,
	
		// Transciever Interface
		txdp, txdn, txoe,	
		rxd, rxdp, rxdn,

		// UTMI Interface
		DataOut_i, TxValid_i, TxReady_o, RxValid_o,
		RxActive_o, RxError_o, DataIn_o, LineState_o
		);

input		clk;
input		rst;
input		phy_tx_mode;
output		usb_rst;
output		txdp, txdn, txoe;
input		rxd, rxdp, rxdn;
input	[7:0]	DataOut_i;
input		TxValid_i;
output		TxReady_o;
output	[7:0]	DataIn_o;
output		RxValid_o;
output		RxActive_o;
output		RxError_o;
output	[1:0]	LineState_o;

///////////////////////////////////////////////////////////////////
//
// Local Wires and Registers
//

reg	[4:0]	rst_cnt;
reg		usb_rst;
wire		fs_ce;
wire		rst;

///////////////////////////////////////////////////////////////////
//
// Misc Logic
//

///////////////////////////////////////////////////////////////////
//
// TX Phy
//

usb_tx_phy i_tx_phy(
	.clk(		clk		),
	.rst(		rst		),
	.fs_ce(		fs_ce		),
	.phy_mode(	phy_tx_mode	),

	// Transciever Interface
	.txdp(		txdp		),
	.txdn(		txdn		),
	.txoe(		txoe		),

	// UTMI Interface
	.DataOut_i(	DataOut_i	),
	.TxValid_i(	TxValid_i	),
	.TxReady_o(	TxReady_o	)
	);

///////////////////////////////////////////////////////////////////
//
// RX Phy and DPLL
//

usb_rx_phy i_rx_phy(
	.clk(		clk		),
	.rst(		rst		),
	.fs_ce(		fs_ce		),

	// Transciever Interface
	.rxd(		rxd		),
	.rxdp(		rxdp		),
	.rxdn(		rxdn		),

	// UTMI Interface
	.DataIn_o(	DataIn_o	),
	.RxValid_o(	RxValid_o	),
	.RxActive_o(	RxActive_o	),
	.RxError_o(	RxError_o	),
	.RxEn_i(	txoe		),
	.LineState(	LineState_o	)
	);

///////////////////////////////////////////////////////////////////
//
// Generate an USB Reset is we see SE0 for at least 2.5uS
//

`ifdef USB_ASYNC_REST
always @(posedge clk or negedge rst)
`else
always @(posedge clk)
`endif
	if(!rst)			rst_cnt <= 5'h0;
	else
	if(LineState_o != 2'h0)		rst_cnt <= 5'h0;
	else	
	if(!usb_rst && fs_ce)		rst_cnt <= rst_cnt + 5'h1;

always @(posedge clk)
	usb_rst <= (rst_cnt == 5'h1f);

endmodule
module tv80_reg (/*AUTOARG*/
  // Outputs
  DOBH, DOAL, DOCL, DOBL, DOCH, DOAH, 
  // Inputs
  AddrC, AddrA, AddrB, DIH, DIL, clk, CEN, WEH, WEL
  );
    input  [2:0] AddrC;
    output [7:0] DOBH;
    input  [2:0] AddrA;
    input  [2:0] AddrB;
    input  [7:0] DIH;
    output [7:0] DOAL;
    output [7:0] DOCL;
    input  [7:0] DIL;
    output [7:0] DOBL;
    output [7:0] DOCH;
    output [7:0] DOAH;
    input  clk, CEN, WEH, WEL;

  reg [7:0] RegsH [0:7];
  reg [7:0] RegsL [0:7];

  always @(posedge clk)
    begin
      if (CEN)
        begin
          if (WEH) RegsH[AddrA] <= DIH;
          if (WEL) RegsL[AddrA] <= DIL;
        end
    end
          
  assign DOAH = RegsH[AddrA];
  assign DOAL = RegsL[AddrA];
  assign DOBH = RegsH[AddrB];
  assign DOBL = RegsL[AddrB];
  assign DOCH = RegsH[AddrC];
  assign DOCL = RegsL[AddrC];

  // break out ram bits for waveform debug
  wire [7:0] H = RegsH[2];
  wire [7:0] L = RegsL[2];
  
// synopsys dc_script_begin
// set_attribute current_design "revision" "$Id: tv80_reg.v,v 1.1 2004/05/16 17:39:57 ghutchis Exp $" -type string -quiet
// synopsys dc_script_end
endmodule
module fifo4(clk, rst, clr,  din, we, dout, re, full, empty);

parameter dw = 8;

input		clk, rst;
input		clr;
input   [dw:1]	din;
input		we;
output  [dw:1]	dout;
input		re;
output		full, empty;


////////////////////////////////////////////////////////////////////
//
// Local Wires
//

reg     [dw:1]	mem[0:3];
reg     [1:0]   wp;
reg     [1:0]   rp;
wire    [1:0]   wp_p1;
wire    [1:0]   wp_p2;
wire    [1:0]   rp_p1;
wire		full, empty;
reg		gb;

////////////////////////////////////////////////////////////////////
//
// Misc Logic
//

always @(posedge clk or negedge rst)
        if(!rst)	wp <= #1 2'h0;
        else
        if(clr)		wp <= #1 2'h0;
        else
        if(we)		wp <= #1 wp_p1;

assign wp_p1 = wp + 2'h1;
assign wp_p2 = wp + 2'h2;

always @(posedge clk or negedge rst)
        if(!rst)	rp <= #1 2'h0;
        else
        if(clr)		rp <= #1 2'h0;
        else
        if(re)		rp <= #1 rp_p1;

assign rp_p1 = rp + 2'h1;

// Fifo Output
assign  dout = mem[ rp ];

// Fifo Input
always @(posedge clk)
        if(we)	mem[ wp ] <= #1 din;

// Status
assign empty = (wp == rp) & !gb;
assign full  = (wp == rp) &  gb;

// Guard Bit ...
always @(posedge clk)
	if(!rst)			gb <= #1 1'b0;
	else
	if(clr)				gb <= #1 1'b0;
	else
	if((wp_p1 == rp) & we)		gb <= #1 1'b1;
	else
	if(re)				gb <= #1 1'b0;

endmodule
module eth_crc (Clk, Reset, Data, Enable, Initialize, Crc, CrcError);


parameter Tp = 1;

input Clk;
input Reset;
input [3:0] Data;
input Enable;
input Initialize;

output [31:0] Crc;
output CrcError;

reg  [31:0] Crc;

wire [31:0] CrcNext;


assign CrcNext[0] = Enable & (Data[0] ^ Crc[28]); 
assign CrcNext[1] = Enable & (Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29]); 
assign CrcNext[2] = Enable & (Data[2] ^ Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29] ^ Crc[30]); 
assign CrcNext[3] = Enable & (Data[3] ^ Data[2] ^ Data[1] ^ Crc[29] ^ Crc[30] ^ Crc[31]); 
assign CrcNext[4] = (Enable & (Data[3] ^ Data[2] ^ Data[0] ^ Crc[28] ^ Crc[30] ^ Crc[31])) ^ Crc[0]; 
assign CrcNext[5] = (Enable & (Data[3] ^ Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29] ^ Crc[31])) ^ Crc[1]; 
assign CrcNext[6] = (Enable & (Data[2] ^ Data[1] ^ Crc[29] ^ Crc[30])) ^ Crc[ 2]; 
assign CrcNext[7] = (Enable & (Data[3] ^ Data[2] ^ Data[0] ^ Crc[28] ^ Crc[30] ^ Crc[31])) ^ Crc[3]; 
assign CrcNext[8] = (Enable & (Data[3] ^ Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29] ^ Crc[31])) ^ Crc[4]; 
assign CrcNext[9] = (Enable & (Data[2] ^ Data[1] ^ Crc[29] ^ Crc[30])) ^ Crc[5]; 
assign CrcNext[10] = (Enable & (Data[3] ^ Data[2] ^ Data[0] ^ Crc[28] ^ Crc[30] ^ Crc[31])) ^ Crc[6]; 
assign CrcNext[11] = (Enable & (Data[3] ^ Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29] ^ Crc[31])) ^ Crc[7]; 
assign CrcNext[12] = (Enable & (Data[2] ^ Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29] ^ Crc[30])) ^ Crc[8]; 
assign CrcNext[13] = (Enable & (Data[3] ^ Data[2] ^ Data[1] ^ Crc[29] ^ Crc[30] ^ Crc[31])) ^ Crc[9]; 
assign CrcNext[14] = (Enable & (Data[3] ^ Data[2] ^ Crc[30] ^ Crc[31])) ^ Crc[10]; 
assign CrcNext[15] = (Enable & (Data[3] ^ Crc[31])) ^ Crc[11]; 
assign CrcNext[16] = (Enable & (Data[0] ^ Crc[28])) ^ Crc[12]; 
assign CrcNext[17] = (Enable & (Data[1] ^ Crc[29])) ^ Crc[13]; 
assign CrcNext[18] = (Enable & (Data[2] ^ Crc[30])) ^ Crc[14]; 
assign CrcNext[19] = (Enable & (Data[3] ^ Crc[31])) ^ Crc[15]; 
assign CrcNext[20] = Crc[16]; 
assign CrcNext[21] = Crc[17]; 
assign CrcNext[22] = (Enable & (Data[0] ^ Crc[28])) ^ Crc[18]; 
assign CrcNext[23] = (Enable & (Data[1] ^ Data[0] ^ Crc[29] ^ Crc[28])) ^ Crc[19]; 
assign CrcNext[24] = (Enable & (Data[2] ^ Data[1] ^ Crc[30] ^ Crc[29])) ^ Crc[20]; 
assign CrcNext[25] = (Enable & (Data[3] ^ Data[2] ^ Crc[31] ^ Crc[30])) ^ Crc[21]; 
assign CrcNext[26] = (Enable & (Data[3] ^ Data[0] ^ Crc[31] ^ Crc[28])) ^ Crc[22]; 
assign CrcNext[27] = (Enable & (Data[1] ^ Crc[29])) ^ Crc[23]; 
assign CrcNext[28] = (Enable & (Data[2] ^ Crc[30])) ^ Crc[24]; 
assign CrcNext[29] = (Enable & (Data[3] ^ Crc[31])) ^ Crc[25]; 
assign CrcNext[30] = Crc[26]; 
assign CrcNext[31] = Crc[27]; 


always @ (posedge Clk or posedge Reset)
begin
  if (Reset)
    Crc <= #1 32'hffffffff;
  else
  if(Initialize)
    Crc <= #Tp 32'hffffffff;
  else
    Crc <= #Tp CrcNext;
end

assign CrcError = Crc[31:0] != 32'hc704dd7b;  // CRC not equal to magic number

endmodule
module eth_register(DataIn, DataOut, Write, Clk, Reset, SyncReset);

parameter WIDTH = 8; // default parameter of the register width
parameter RESET_VALUE = 0;

input [WIDTH-1:0] DataIn;

input Write;
input Clk;
input Reset;
input SyncReset;

output [WIDTH-1:0] DataOut;
reg    [WIDTH-1:0] DataOut;



always @ (posedge Clk or posedge Reset)
begin
  if(Reset)
    DataOut<=#1 RESET_VALUE;
  else
  if(SyncReset)
    DataOut<=#1 RESET_VALUE;
  else
  if(Write)                         // write
    DataOut<=#1 DataIn;
end



endmodule   // Register
module eth_random (MTxClk, Reset, StateJam, StateJam_q, RetryCnt, NibCnt, ByteCnt, 
                   RandomEq0, RandomEqByteCnt);

parameter Tp = 1;

input MTxClk;
input Reset;
input StateJam;
input StateJam_q;
input [3:0] RetryCnt;
input [15:0] NibCnt;
input [9:0] ByteCnt;
output RandomEq0;
output RandomEqByteCnt;

wire Feedback;
reg [9:0] x;
wire [9:0] Random;
reg  [9:0] RandomLatched;


always @ (posedge MTxClk or posedge Reset)
begin
  if(Reset)
    x[9:0] <= #Tp 0;
  else
    x[9:0] <= #Tp {x[8:0], Feedback};
end

assign Feedback = ~(x[2] ^ x[9]);

assign Random [0] = x[0];
assign Random [1] = (RetryCnt > 1) ? x[1] : 1'b0;
assign Random [2] = (RetryCnt > 2) ? x[2] : 1'b0;
assign Random [3] = (RetryCnt > 3) ? x[3] : 1'b0;
assign Random [4] = (RetryCnt > 4) ? x[4] : 1'b0;
assign Random [5] = (RetryCnt > 5) ? x[5] : 1'b0;
assign Random [6] = (RetryCnt > 6) ? x[6] : 1'b0;
assign Random [7] = (RetryCnt > 7) ? x[7] : 1'b0;
assign Random [8] = (RetryCnt > 8) ? x[8] : 1'b0;
assign Random [9] = (RetryCnt > 9) ? x[9] : 1'b0;


always @ (posedge MTxClk or posedge Reset)
begin
  if(Reset)
    RandomLatched <= #Tp 10'h000;
  else
    begin
      if(StateJam & StateJam_q)
        RandomLatched <= #Tp Random;
    end
end

// Random Number == 0      IEEE 802.3 page 68. If 0 we go to defer and not to backoff.
assign RandomEq0 = RandomLatched == 10'h0; 

assign RandomEqByteCnt = ByteCnt[9:0] == RandomLatched & (&NibCnt[6:0]);

endmodule
module eth_clockgen(Clk, Reset, Divider, MdcEn, MdcEn_n, Mdc);

parameter Tp=1;

input       Clk;              // Input clock (Host clock)
input       Reset;            // Reset signal
input [7:0] Divider;          // Divider (input clock will be divided by the Divider[7:0])

output      Mdc;              // Output clock
output      MdcEn;            // Enable signal is asserted for one Clk period before Mdc rises.
output      MdcEn_n;          // Enable signal is asserted for one Clk period before Mdc falls.

reg         Mdc;
reg   [7:0] Counter;

wire        CountEq0;
wire  [7:0] CounterPreset;
wire  [7:0] TempDivider;


assign TempDivider[7:0]   = (Divider[7:0]<2)? 8'h02 : Divider[7:0]; // If smaller than 2
assign CounterPreset[7:0] = (TempDivider[7:0]>>1) - 1'b1;           // We are counting half of period


// Counter counts half period
always @ (posedge Clk or posedge Reset)
begin
  if(Reset)
    Counter[7:0] <= #Tp 8'h1;
  else
    begin
      if(CountEq0)
        begin
          Counter[7:0] <= #Tp CounterPreset[7:0];
        end
      else
        Counter[7:0] <= #Tp Counter - 8'h1;
    end
end


// Mdc is asserted every other half period
always @ (posedge Clk or posedge Reset)
begin
  if(Reset)
    Mdc <= #Tp 1'b0;
  else
    begin
      if(CountEq0)
        Mdc <= #Tp ~Mdc;
    end
end


assign CountEq0 = Counter == 8'h0;
assign MdcEn = CountEq0 & ~Mdc;
assign MdcEn_n = CountEq0 & Mdc;

endmodule
module eth_shiftreg(Clk, Reset, MdcEn_n, Mdi, Fiad, Rgad, CtrlData, WriteOp, ByteSelect, 
                    LatchByte, ShiftedBit, Prsd, LinkFail);


parameter Tp=1;

input       Clk;              // Input clock (Host clock)
input       Reset;            // Reset signal
input       MdcEn_n;          // Enable signal is asserted for one Clk period before Mdc falls.
input       Mdi;              // MII input data
input [4:0] Fiad;             // PHY address
input [4:0] Rgad;             // Register address (within the selected PHY)
input [15:0]CtrlData;         // Control data (data to be written to the PHY)
input       WriteOp;          // The current operation is a PHY register write operation
input [3:0] ByteSelect;       // Byte select
input [1:0] LatchByte;        // Byte select for latching (read operation)

output      ShiftedBit;       // Bit shifted out of the shift register
output[15:0]Prsd;             // Read Status Data (data read from the PHY)
output      LinkFail;         // Link Integrity Signal

reg   [7:0] ShiftReg;         // Shift register for shifting the data in and out
reg   [15:0]Prsd;
reg         LinkFail;




// ShiftReg[7:0] :: Shift Register Data
always @ (posedge Clk or posedge Reset) 
begin
  if(Reset)
    begin
      ShiftReg[7:0] <= #Tp 8'h0;
      Prsd[15:0] <= #Tp 16'h0;
      LinkFail <= #Tp 1'b0;
    end
  else
    begin
      if(MdcEn_n)
        begin 
          if(|ByteSelect)
            begin
              case (ByteSelect[3:0])  // synopsys parallel_case full_case
                4'h1 :    ShiftReg[7:0] <= #Tp {2'b01, ~WriteOp, WriteOp, Fiad[4:1]};
                4'h2 :    ShiftReg[7:0] <= #Tp {Fiad[0], Rgad[4:0], 2'b10};
                4'h4 :    ShiftReg[7:0] <= #Tp CtrlData[15:8];
                4'h8 :    ShiftReg[7:0] <= #Tp CtrlData[7:0];
              endcase
            end 
          else
            begin
              ShiftReg[7:0] <= #Tp {ShiftReg[6:0], Mdi};
              if(LatchByte[0])
                begin
                  Prsd[7:0] <= #Tp {ShiftReg[6:0], Mdi};
                  if(Rgad == 5'h01)
                    LinkFail <= #Tp ~ShiftReg[1];  // this is bit [2], because it is not shifted yet
                end
              else
                begin
                  if(LatchByte[1])
                    Prsd[15:8] <= #Tp {ShiftReg[6:0], Mdi};
                end
            end
        end
    end
end


assign ShiftedBit = ShiftReg[7];


endmodule
module eth_outputcontrol(Clk, Reset, InProgress, ShiftedBit, BitCounter, WriteOp, NoPre, MdcEn_n, Mdo, MdoEn);

parameter Tp = 1;

input         Clk;                // Host Clock
input         Reset;              // General Reset
input         WriteOp;            // Write Operation Latch (When asserted, write operation is in progress)
input         NoPre;              // No Preamble (no 32-bit preamble)
input         InProgress;         // Operation in progress
input         ShiftedBit;         // This bit is output of the shift register and is connected to the Mdo signal
input   [6:0] BitCounter;         // Bit Counter
input         MdcEn_n;            // MII Management Data Clock Enable signal is asserted for one Clk period before Mdc falls.

output        Mdo;                // MII Management Data Output
output        MdoEn;              // MII Management Data Output Enable

wire          SerialEn;

reg           MdoEn_2d;
reg           MdoEn_d;
reg           MdoEn;

reg           Mdo_2d;
reg           Mdo_d;
reg           Mdo;                // MII Management Data Output



// Generation of the Serial Enable signal (enables the serialization of the data)
assign SerialEn =  WriteOp & InProgress & ( BitCounter>31 | ( ( BitCounter == 0 ) & NoPre ) )
                | ~WriteOp & InProgress & (( BitCounter>31 & BitCounter<46 ) | ( ( BitCounter == 0 ) & NoPre ));


// Generation of the MdoEn signal
always @ (posedge Clk or posedge Reset)
begin
  if(Reset)
    begin
      MdoEn_2d <= #Tp 1'b0;
      MdoEn_d <= #Tp 1'b0;
      MdoEn <= #Tp 1'b0;
    end
  else
    begin
      if(MdcEn_n)
        begin
          MdoEn_2d <= #Tp SerialEn | InProgress & BitCounter<32;
          MdoEn_d <= #Tp MdoEn_2d;
          MdoEn <= #Tp MdoEn_d;
        end
    end
end


// Generation of the Mdo signal.
always @ (posedge Clk or posedge Reset)
begin
  if(Reset)
    begin
      Mdo_2d <= #Tp 1'b0;
      Mdo_d <= #Tp 1'b0;
      Mdo <= #Tp 1'b0;
    end
  else
    begin
      if(MdcEn_n)
        begin
          Mdo_2d <= #Tp ~SerialEn & BitCounter<32;
          Mdo_d <= #Tp ShiftedBit | Mdo_2d;
          Mdo <= #Tp Mdo_d;
        end
    end
end



endmodule
module eth_rxstatem (MRxClk, Reset, MRxDV, ByteCntEq0, ByteCntGreat2, Transmitting, MRxDEq5, MRxDEqD, 
                     IFGCounterEq24, ByteCntMaxFrame, StateData, StateIdle, StatePreamble, StateSFD, 
                     StateDrop
                    );

parameter Tp = 1;

input         MRxClk;
input         Reset;
input         MRxDV;
input         ByteCntEq0;
input         ByteCntGreat2;
input         MRxDEq5;
input         Transmitting;
input         MRxDEqD;
input         IFGCounterEq24;
input         ByteCntMaxFrame;

output [1:0]  StateData;
output        StateIdle;
output        StateDrop;
output        StatePreamble;
output        StateSFD;

reg           StateData0;
reg           StateData1;
reg           StateIdle;
reg           StateDrop;
reg           StatePreamble;
reg           StateSFD;

wire          StartIdle;
wire          StartDrop;
wire          StartData0;
wire          StartData1;
wire          StartPreamble;
wire          StartSFD;


// Defining the next state
assign StartIdle = ~MRxDV & (StateDrop | StatePreamble | StateSFD | (|StateData));

assign StartPreamble = MRxDV & ~MRxDEq5 & (StateIdle & ~Transmitting);

assign StartSFD = MRxDV & MRxDEq5 & (StateIdle & ~Transmitting | StatePreamble);

assign StartData0 = MRxDV & (StateSFD & MRxDEqD & IFGCounterEq24 | StateData1);

assign StartData1 = MRxDV & StateData0 & (~ByteCntMaxFrame);

assign StartDrop = MRxDV & (StateIdle & Transmitting | StateSFD & ~IFGCounterEq24 &  MRxDEqD 
                         |  StateData0 &  ByteCntMaxFrame
                           );

// Rx State Machine
always @ (posedge MRxClk or posedge Reset)
begin
  if(Reset)
    begin
      StateIdle     <= #Tp 1'b0;
      StateDrop     <= #Tp 1'b1;
      StatePreamble <= #Tp 1'b0;
      StateSFD      <= #Tp 1'b0;
      StateData0    <= #Tp 1'b0;
      StateData1    <= #Tp 1'b0;
    end
  else
    begin
      if(StartPreamble | StartSFD | StartDrop)
        StateIdle <= #Tp 1'b0;
      else
      if(StartIdle)
        StateIdle <= #Tp 1'b1;

      if(StartIdle)
        StateDrop <= #Tp 1'b0;
      else
      if(StartDrop)
        StateDrop <= #Tp 1'b1;

      if(StartSFD | StartIdle | StartDrop)
        StatePreamble <= #Tp 1'b0;
      else
      if(StartPreamble)
        StatePreamble <= #Tp 1'b1;

      if(StartPreamble | StartIdle | StartData0 | StartDrop)
        StateSFD <= #Tp 1'b0;
      else
      if(StartSFD)
        StateSFD <= #Tp 1'b1;

      if(StartIdle | StartData1 | StartDrop)
        StateData0 <= #Tp 1'b0;
      else
      if(StartData0)
        StateData0 <= #Tp 1'b1;

      if(StartIdle | StartData0 | StartDrop)
        StateData1 <= #Tp 1'b0;
      else
      if(StartData1)
        StateData1 <= #Tp 1'b1;
    end
end

assign StateData[1:0] = {StateData1, StateData0};

endmodule
module eth_fifo (data_in, data_out, clk, reset, write, read, clear, almost_full, full, almost_empty, empty, cnt);

parameter DATA_WIDTH    = 32;
parameter DEPTH         = 8;
parameter CNT_WIDTH     = 4;

parameter Tp            = 1;

input                     clk;
input                     reset;
input                     write;
input                     read;
input                     clear;
input   [DATA_WIDTH-1:0]  data_in;

output  [DATA_WIDTH-1:0]  data_out;
output                    almost_full;
output                    full;
output                    almost_empty;
output                    empty;
output  [CNT_WIDTH-1:0]   cnt;

`ifdef ETH_FIFO_XILINX
`else
  `ifdef ETH_ALTERA_ALTSYNCRAM
  `else
    reg     [DATA_WIDTH-1:0]  fifo  [0:DEPTH-1];
    reg     [DATA_WIDTH-1:0]  data_out;
  `endif
`endif

reg     [CNT_WIDTH-1:0]   cnt;
reg     [CNT_WIDTH-2:0]   read_pointer;
reg     [CNT_WIDTH-2:0]   write_pointer;


always @ (posedge clk or posedge reset)
begin
  if(reset)
    cnt <=#Tp 0;
  else
  if(clear)
    cnt <=#Tp { {(CNT_WIDTH-1){1'b0}}, read^write};
  else
  if(read ^ write)
    if(read)
      cnt <=#Tp cnt - 1'b1;
    else
      cnt <=#Tp cnt + 1'b1;
end

always @ (posedge clk or posedge reset)
begin
  if(reset)
    read_pointer <=#Tp 0;
  else
  if(clear)
    read_pointer <=#Tp { {(CNT_WIDTH-2){1'b0}}, read};
  else
  if(read & ~empty)
    read_pointer <=#Tp read_pointer + 1'b1;
end

always @ (posedge clk or posedge reset)
begin
  if(reset)
    write_pointer <=#Tp 0;
  else
  if(clear)
    write_pointer <=#Tp { {(CNT_WIDTH-2){1'b0}}, write};
  else
  if(write & ~full)
    write_pointer <=#Tp write_pointer + 1'b1;
end

assign empty = ~(|cnt);
assign almost_empty = cnt == 1;
assign full  = cnt == DEPTH;
assign almost_full  = &cnt[CNT_WIDTH-2:0];



`ifdef ETH_FIFO_XILINX
  xilinx_dist_ram_16x32 fifo
  ( .data_out(data_out), 
    .we(write & ~full),
    .data_in(data_in),
    .read_address( clear ? {CNT_WIDTH-1{1'b0}} : read_pointer),
    .write_address(clear ? {CNT_WIDTH-1{1'b0}} : write_pointer),
    .wclk(clk)
  );
`else   // !ETH_FIFO_XILINX
`ifdef ETH_ALTERA_ALTSYNCRAM
  altera_dpram_16x32	altera_dpram_16x32_inst
  (
  	.data             (data_in),
  	.wren             (write & ~full),
  	.wraddress        (clear ? {CNT_WIDTH-1{1'b0}} : write_pointer),
  	.rdaddress        (clear ? {CNT_WIDTH-1{1'b0}} : read_pointer ),
  	.clock            (clk),
  	.q                (data_out)
  );  //exemplar attribute altera_dpram_16x32_inst NOOPT TRUE
`else   // !ETH_ALTERA_ALTSYNCRAM
  always @ (posedge clk)
  begin
    if(write & clear)
      fifo[0] <=#Tp data_in;
    else
   if(write & ~full)
      fifo[write_pointer] <=#Tp data_in;
  end
  

  always @ (posedge clk)
  begin
    if(clear)
      data_out <=#Tp fifo[0];
    else
      data_out <=#Tp fifo[read_pointer];
  end
`endif  // !ETH_ALTERA_ALTSYNCRAM
`endif  // !ETH_FIFO_XILINX


endmodule
module wb_conmax_pri_dec(valid, pri_in, pri_out);

////////////////////////////////////////////////////////////////////
//
// Module Parameters
//

parameter [1:0]	pri_sel = 2'd0;

////////////////////////////////////////////////////////////////////
//
// Module IOs
//

input		valid;
input	[1:0]	pri_in;
output	[3:0]	pri_out;

////////////////////////////////////////////////////////////////////
//
// Local Wires
//

wire	[3:0]	pri_out;
reg	[3:0]	pri_out_d0;
reg	[3:0]	pri_out_d1;

////////////////////////////////////////////////////////////////////
//
// Priority Decoder
//

// 4 Priority Levels
always @(valid or pri_in)
	if(!valid)		pri_out_d1 = 4'b0001;
	else
	if(pri_in==2'h0)	pri_out_d1 = 4'b0001;
	else
	if(pri_in==2'h1)	pri_out_d1 = 4'b0010;
	else
	if(pri_in==2'h2)	pri_out_d1 = 4'b0100;
	else			pri_out_d1 = 4'b1000;

// 2 Priority Levels
always @(valid or pri_in)
	if(!valid)		pri_out_d0 = 4'b0001;
	else
	if(pri_in==2'h0)	pri_out_d0 = 4'b0001;
	else			pri_out_d0 = 4'b0010;

// Select Configured Priority

assign pri_out = (pri_sel==2'd0) ? 4'h0 : ( (pri_sel==1'd1) ? pri_out_d0 : pri_out_d1 );

endmodule
module wb_conmax_pri_enc(
		valid,
		pri0, pri1, pri2, pri3,
		pri4, pri5, pri6, pri7,
		pri_out
		);

////////////////////////////////////////////////////////////////////
//
// Module Parameters
//

parameter	[1:0]	pri_sel = 2'd0;

////////////////////////////////////////////////////////////////////
//
// Module IOs
//

input	[7:0]	valid;
input	[1:0]	pri0, pri1, pri2, pri3;
input	[1:0]	pri4, pri5, pri6, pri7;
output	[1:0]	pri_out;

////////////////////////////////////////////////////////////////////
//
// Local Wires
//

wire	[3:0]	pri0_out, pri1_out, pri2_out, pri3_out;
wire	[3:0]	pri4_out, pri5_out, pri6_out, pri7_out;
wire	[3:0]	pri_out_tmp;
reg	[1:0]	pri_out0, pri_out1;
wire	[1:0]	pri_out;

////////////////////////////////////////////////////////////////////
//
// Priority Decoders
//

wb_conmax_pri_dec #(pri_sel) pd0(
		.valid(		valid[0]	),
		.pri_in(	pri0		),
		.pri_out(	pri0_out	)
		);


wb_conmax_pri_dec #(pri_sel) pd1(
		.valid(		valid[1]	),
		.pri_in(	pri1		),
		.pri_out(	pri1_out	)
		);

wb_conmax_pri_dec #(pri_sel) pd2(
		.valid(		valid[2]	),
		.pri_in(	pri2		),
		.pri_out(	pri2_out	)
		);

wb_conmax_pri_dec #(pri_sel) pd3(
		.valid(		valid[3]	),
		.pri_in(	pri3		),
		.pri_out(	pri3_out	)
		);

wb_conmax_pri_dec #(pri_sel) pd4(
		.valid(		valid[4]	),
		.pri_in(	pri4		),
		.pri_out(	pri4_out	)
		);

wb_conmax_pri_dec #(pri_sel) pd5(
		.valid(		valid[5]	),
		.pri_in(	pri5		),
		.pri_out(	pri5_out	)
		);

wb_conmax_pri_dec #(pri_sel) pd6(
		.valid(		valid[6]	),
		.pri_in(	pri6		),
		.pri_out(	pri6_out	)
		);

wb_conmax_pri_dec #(pri_sel) pd7(
		.valid(		valid[7]	),
		.pri_in(	pri7		),
		.pri_out(	pri7_out	)
		);

////////////////////////////////////////////////////////////////////
//
// Priority Encoding
//

assign pri_out_tmp =	pri0_out | pri1_out | pri2_out | pri3_out |
			pri4_out | pri5_out | pri6_out | pri7_out;

// 4 Priority Levels
always @(pri_out_tmp)
	if(pri_out_tmp[3])	pri_out1 = 2'h3;
	else
	if(pri_out_tmp[2])	pri_out1 = 2'h2;
	else
	if(pri_out_tmp[1])	pri_out1 = 2'h1;
	else			pri_out1 = 2'h0;

// 2 Priority Levels
always @(pri_out_tmp)
	if(pri_out_tmp[1])	pri_out0 = 2'h1;
	else			pri_out0 = 2'h0;

////////////////////////////////////////////////////////////////////
//
// Final Priority Output
//

// Select configured priority

assign pri_out = (pri_sel==2'd0) ? 2'h0 : ( (pri_sel==2'd1) ? pri_out0 : pri_out1 );

endmodule
module spi_clgen (clk_in, rst, go, enable, last_clk, divider, clk_out, pos_edge, neg_edge); 

  parameter Tp = 1;
  
  input                            clk_in;   // input clock (system clock)
  input                            rst;      // reset
  input                            enable;   // clock enable
  input                            go;       // start transfer
  input                            last_clk; // last clock
  input     [`SPI_DIVIDER_LEN-1:0] divider;  // clock divider (output clock is divided by this value)
  output                           clk_out;  // output clock
  output                           pos_edge; // pulse marking positive edge of clk_out
  output                           neg_edge; // pulse marking negative edge of clk_out
                            
  reg                              clk_out;
  reg                              pos_edge;
  reg                              neg_edge;
                            
  reg       [`SPI_DIVIDER_LEN-1:0] cnt;      // clock counter 
  wire                             cnt_zero; // conter is equal to zero
  wire                             cnt_one;  // conter is equal to one
  
  
  assign cnt_zero = cnt == {`SPI_DIVIDER_LEN{1'b0}};
  assign cnt_one  = cnt == {{`SPI_DIVIDER_LEN-1{1'b0}}, 1'b1};
  
  // Counter counts half period
  always @(posedge clk_in or posedge rst)
  begin
    if(rst)
      cnt <= #Tp {`SPI_DIVIDER_LEN{1'b1}};
    else
      begin
        if(!enable || cnt_zero)
          cnt <= #Tp divider;
        else
          cnt <= #Tp cnt - {{`SPI_DIVIDER_LEN-1{1'b0}}, 1'b1};
      end
  end
  
  // clk_out is asserted every other half period
  always @(posedge clk_in or posedge rst)
  begin
    if(rst)
      clk_out <= #Tp 1'b0;
    else
      clk_out <= #Tp (enable && cnt_zero && (!last_clk || clk_out)) ? ~clk_out : clk_out;
  end
   
  // Pos and neg edge signals
  always @(posedge clk_in or posedge rst)
  begin
    if(rst)
      begin
        pos_edge  <= #Tp 1'b0;
        neg_edge  <= #Tp 1'b0;
      end
    else
      begin
        pos_edge  <= #Tp (enable && !clk_out && cnt_one) || (!(|divider) && clk_out) || (!(|divider) && go && !enable);
        neg_edge  <= #Tp (enable && clk_out && cnt_one) || (!(|divider) && !clk_out && enable);
      end
  end
endmodule
module vga_cur_cregs (
	clk_i, rst_i, arst_i,
	hsel_i, hadr_i, hwe_i, hdat_i, hdat_o, hack_o,
	cadr_i, cdat_o
	);

	//
	// inputs & outputs
	//

	// wishbone signals
	input         clk_i;         // master clock input
	input         rst_i;         // synchronous active high reset
	input         arst_i;        // asynchronous active low reset

	// host interface
	input         hsel_i;        // host select input
	input  [ 2:0] hadr_i;        // host address input
	input         hwe_i;         // host write enable input
	input  [31:0] hdat_i;        // host data in
	output [31:0] hdat_o;        // host data out
	output        hack_o;        // host acknowledge out

	reg [31:0] hdat_o;
	reg        hack_o;
	
	// cursor processor interface
	input  [ 3:0] cadr_i;        // cursor address in
	output [15:0] cdat_o;        // cursor data out

	reg [15:0] cdat_o;


	//
	// variable declarations
	//
	reg  [31:0] cregs [7:0];  // color registers
	wire [31:0] temp_cdat;

	//
	// module body
	//


	////////////////////////////
	// generate host interface

	// write section
	always@(posedge clk_i)
		if (hsel_i & hwe_i)
			cregs[hadr_i] <= #1 hdat_i;

	// read section
	always@(posedge clk_i)
		hdat_o <= #1 cregs[hadr_i];

	// acknowledge section
	always@(posedge clk_i)
		hack_o <= #1 hsel_i & !hack_o;


	//////////////////////////////
	// generate cursor interface

	// read section
	assign temp_cdat = cregs[cadr_i[3:1]];

	always@(posedge clk_i)
		cdat_o <= #1 cadr_i[0] ? temp_cdat[31:16] : temp_cdat[15:0];

endmodule
module vga_vtim(clk, ena, rst, Tsync, Tgdel, Tgate, Tlen, Sync, Gate, Done);
	// inputs & outputs
	input clk; // master clock
	input ena; // count enable
	input rst; // synchronous active high reset

	input [ 7:0] Tsync; // sync duration
	input [ 7:0] Tgdel; // gate delay
	input [15:0] Tgate; // gate length
	input [15:0] Tlen;  // line time / frame time

	output Sync; // synchronization pulse
	output Gate; // gate
	output Done; // done with line/frame
	reg Sync;
	reg Gate;
	reg Done;

	//
	// module body
	//

	// generate timing statemachine
	reg  [15:0] cnt, cnt_len;
	wire [16:0] cnt_nxt, cnt_len_nxt;
	wire        cnt_done, cnt_len_done;

	assign cnt_nxt = {1'b0, cnt} -17'h1;
	assign cnt_done = cnt_nxt[16];

	assign cnt_len_nxt = {1'b0, cnt_len} -17'h1;
	assign cnt_len_done = cnt_len_nxt[16];

	reg [4:0] state;
	parameter [4:0] idle_state = 5'b00001;
	parameter [4:0] sync_state = 5'b00010;
	parameter [4:0] gdel_state = 5'b00100;
	parameter [4:0] gate_state = 5'b01000;
	parameter [4:0] len_state  = 5'b10000;

	always @(posedge clk)
	  if (rst)
	    begin
	        state   <= #1 idle_state;
	        cnt     <= #1 16'h0;
	        cnt_len <= #1 16'b0;
	        Sync    <= #1 1'b0;
	        Gate    <= #1 1'b0;
	        Done    <= #1 1'b0;
	    end
	  else if (ena)
	    begin
	        cnt     <= #1 cnt_nxt[15:0];
	        cnt_len <= #1 cnt_len_nxt[15:0];

	        Done    <= #1 1'b0;

	        case (state) // synopsys full_case parallel_case
	          idle_state:
	            begin
	                state   <= #1 sync_state;
	                cnt     <= #1 Tsync;
	                cnt_len <= #1 Tlen;

	                Sync    <= #1 1'b1;
	            end

	          sync_state:
	            if (cnt_done)
	              begin
	                  state <= #1 gdel_state;
	                  cnt   <= #1 Tgdel;

	                  Sync  <= #1 1'b0;
	              end

	          gdel_state:
	            if (cnt_done)
	              begin
	                  state <= #1 gate_state;
	                  cnt   <= #1 Tgate;

	                  Gate  <= #1 1'b1;
	              end

	          gate_state:
	            if (cnt_done)
	              begin
	                  state <= #1 len_state;

	                  Gate  <= #1 1'b0;
	              end

	          len_state:
	            if (cnt_len_done)
	              begin
	                  state   <= #1 sync_state;
	                  cnt     <= #1 Tsync;
	                  cnt_len <= #1 Tlen;

	                  Sync    <= #1 1'b1;
	                  Done    <= #1 1'b1;
	              end

	        endcase
	    end
endmodule
module vga_tgen(
	clk, clk_ena, rst,
	Thsync, Thgdel, Thgate, Thlen, Tvsync, Tvgdel, Tvgate, Tvlen,
	eol, eof, gate, hsync, vsync, csync, blank
	);

	// inputs & outputs
	input clk;
	input clk_ena;
	input rst;

	// horizontal timing settings inputs
	input [ 7:0] Thsync; // horizontal sync pule width (in pixels)
	input [ 7:0] Thgdel; // horizontal gate delay
	input [15:0] Thgate; // horizontal gate (number of visible pixels per line)
	input [15:0] Thlen;  // horizontal length (number of pixels per line)

	// vertical timing settings inputs
	input [ 7:0] Tvsync; // vertical sync pule width (in pixels)
	input [ 7:0] Tvgdel; // vertical gate delay
	input [15:0] Tvgate; // vertical gate (number of visible pixels per line)
	input [15:0] Tvlen;  // vertical length (number of pixels per line)

	// outputs
	output eol;  // end of line
	output eof;  // end of frame
	output gate; // vertical AND horizontal gate (logical AND function)

	output hsync; // horizontal sync pulse
	output vsync; // vertical sync pulse
	output csync; // composite sync
	output blank; // blank signal

	//
	// variable declarations
	//
	wire Hgate, Vgate;
	wire Hdone;

	//
	// module body
	//

	// hookup horizontal timing generator
	vga_vtim hor_gen(
		.clk(clk),
		.ena(clk_ena),
		.rst(rst),
		.Tsync(Thsync),
		.Tgdel(Thgdel),
		.Tgate(Thgate),
		.Tlen(Thlen),
		.Sync(hsync),
		.Gate(Hgate),
		.Done(Hdone)
	);


	// hookup vertical timing generator
	wire vclk_ena = Hdone & clk_ena;

	vga_vtim ver_gen(
		.clk(clk),
		.ena(vclk_ena),
		.rst(rst),
		.Tsync(Tvsync),
		.Tgdel(Tvgdel),
		.Tgate(Tvgate),
		.Tlen(Tvlen),
		.Sync(vsync),
		.Gate(Vgate),
		.Done(eof)
	);

	// assign outputs
	assign eol  = Hdone;
	assign gate = Hgate & Vgate;
	assign csync = hsync | vsync;
	assign blank = ~gate;
endmodule