module iso_main(reset,clk,in,eop_phy,
data_start,subact_gap,
isodat_len_latch,
isotcode_latch,
isodata_latch,phys_arb, async_data_strt, data_end, data_prefix,
async_enab,cycle_quad,cyc_src_id_latch,cyc_dest_off_latch,cyc_tim_data_latch);
input reset,clk,in,eop_phy,data_start,subact_gap,phys_arb, async_data_strt, data_end, data_prefix;
 
output [15:0] isodat_len_latch;
output async_enab;
output [31:0] isodata_latch;
output [3:0] isotcode_latch;
output [31:0] cycle_quad;
output [15:0] cyc_src_id_latch;
output [31:0] cyc_dest_off_latch;
output [31:0] cyc_tim_data_latch;
 
wire count0,crc_err,cyc_crc_err;
wire init_crc;
wire iso_end;
wire out;
 
 
reg [7:0] LOADVALUE;
 
reg [15:0] isodat_len_latch;
reg [31:0] isodata_latch;
reg [3:0] isotcode_latch;
reg [31:0] cycle_quad;
reg [15:0] cyc_src_id_latch;
reg [31:0] cyc_dest_off_latch;
reg [31:0] cyc_tim_data_latch;
 
reg [31:0] shift_out;
 
wire enab;
wire init;
// Internal variables
 
reg [31:0] crc ;
 
reg del_out;
 
reg cycload15,cycload31,load47, cycenable_crc,cycinit_crc, iso_start,latch_cyc_quad, async_enab,
latch_cyc_src_id, latch_cyc_dest_off, latch_cyc_tim_data;
reg [4:0] state,nextstate;
 
 
parameter async_ready=0, async_rx_pack=1, cyc_st_dec=2, cyc_src_id = 3,cyc_src_id2 = 4,
cyc_tim_data = 5, header_crc = 6, async_rx_pack2=7, cyc_dest_off = 8, cyc_dest_off2 = 9,
cyc_tim_data2 = 10, header_crc2 = 11, cyc_eop = 12, iso_wait = 13, idle = 14,
cyc_crc_check = 15,delay=16,delay4=17,delay5=18;
reg load15,load6,load3,load31,load30,latch_isodat_len,
latch_isotcode,enable_crc,latch_isodata, del_cnt;
 
reg [4:0] state_iso,nextstate_iso;
 
 
parameter idle1=0,iso_rdy=1,data_len=2,data_len2=3,data_len_dec=4,
tag_chan=5,tcode=6,tcode2=7,dec_tcode=8,sy=9,head_crc=10,
data=11,data2=12,data_crc=13,eop=14,tag_chan2=15,head_crc2=17,
data_crc2=18,crc_check=19,data_crc_check=20,delay1=21,delay2=22,
delay22=23,delay11=16,delay3=24;
//*******************************rx counter *********************************************************
 
 
always @(posedge clk)
begin
if(reset)
begin
LOADVALUE <= 0 ;
end
else
begin
if (cycload31)
LOADVALUE <= 30;
else if (cycload15)
LOADVALUE <= 11;
else if (load31)
LOADVALUE <= 30;
else if (load47)
LOADVALUE <= 46;
else if (load30)
LOADVALUE <= 30;
else if (load15)
LOADVALUE <= 14;
else if (load6)
LOADVALUE <= 3;
else if (load3)
LOADVALUE <= 2;
else
LOADVALUE <= LOADVALUE-1;
end
end
 
assign count0 = (LOADVALUE == 4'b0);
 
//********************************************************************************************************
 
//***************************** latchs *****************************
 
 
always @(posedge clk)
 
if (reset)
begin
isodat_len_latch<=16'b0;
isodata_latch<=32'b0;
isotcode_latch<=4'b0;
cycle_quad<=32'b0;
cyc_src_id_latch<=16'b0;
cyc_dest_off_latch<=32'b0;
cyc_tim_data_latch<=32'b0;
end
else
begin
if (latch_isodata)
isodata_latch <= shift_out;
else
isodata_latch <= isodata_latch;
if (latch_isotcode)
isotcode_latch <= shift_out[3:0];
else
isotcode_latch <= isotcode_latch;
if (latch_isodat_len)
isodat_len_latch <= shift_out[15:0];
else
isodat_len_latch <=isodat_len_latch;
if (latch_cyc_src_id)
cyc_src_id_latch <= shift_out[15:0];
else
cyc_src_id_latch <=cyc_src_id_latch;
if (latch_cyc_dest_off)
cyc_dest_off_latch <= shift_out[31:0];
else
cyc_dest_off_latch <=cyc_dest_off_latch;
if (latch_cyc_tim_data)
cyc_tim_data_latch<= shift_out[31:0];
else
cyc_tim_data_latch <=cyc_tim_data_latch;
if (latch_cyc_quad)
cycle_quad<= shift_out[31:0];
else
cycle_quad <=cycle_quad;
end
//*************** *************** *************** *************** ***************
 
 
//*************** *************** Serial to parallel *************** ***************
 
 
always @(posedge clk ) begin
if(reset)
shift_out[31:0]<=0;
else begin
shift_out [31:0] <= {shift_out[30:0],in};
end
end
 
//*************** ************** **************** *************** **************
 
 
//*************** ************** crc checker *************** **************
 
 
// CRC32_CHK -- This is a module that checks 32 bit CRC for firewire
//
// DATE: 6/29/97
//
// PURPOSE: The purpose of this routine is to check to make sure that
// there are no errors in the data packet
//
// Algorithm: The CRC used is 32 bits long.
// The generator polynomial is X32 + X26 + X23 + X22 + X16 + X12
// + X11 + X10 + X8 + X7 + X5 + X4 +
// X2 + X + 1
//
// Upon correct reception the output polynomial should be
// X31 + X30 + X26 + X25 + X24 + X18 + X15 + X14 + X12 + X11 + X10
// + X8 + X6 + X5 + X4 + X3 + X + 1
//
//
//
// INPUTS: DAT A-- This is a 1 bit input to the routine that
// contains the next bit to be processed into the
// CRC
//
// clk -- This is a signal that transitions from low to high
// when new data is present and ready to be input to
// the CRC module
//
// RESET_H -- This is an active high reset signal that is the reset
// from the system.
//
// init_crc -- This register starts the CRC processing. A low to high
// transition allows it to initialize the internal
// CRC registers. i.e. Sets all of the CRC registers
// to ones.
// NOTE: In order for this code to work. This signal must
// transition from how to high prior to the first data bit
// go back low prior to the first data bit coming in.
//
// enable_crc -- A 1 bit signal that enables the CRC when it is active high
//
// OUTPUTS: crc_err -- It is logic high if a CRC Error has occurred. It is logic low if no error
// has occurred.
//
//
// INTERNAL VARIABLES:
//
// crc0 through crc32 -- Each of these are 1 bit of the CRC
// polynomial. 0 is the low order bit. 31 is the high order bit
// The reason why they are separate variables is
// because synopsys sometimes has problems with synthesizing
// subscripted variables. i.e (CRC[0])
//
 
 
 
assign enab = enable_crc | cycenable_crc;
 
assign init = init_crc | cycinit_crc;
 
always @( posedge clk or posedge reset) // This portion of the code processes the CRC
begin
if(reset)
begin
crc <= 32'hFFFF_FFFF ;
end
else begin
if (~enab | init)
crc <= 32'hFFFF_FFFF ;
else begin
crc[0] <= (crc[31] ^ out); // The 1 term of the polynomial
crc[1] <= crc[0] ^ (crc[31] ^ out); // The x term of the polynomial
crc[2] <= crc[1] ^ (crc[31] ^ out); // The x**2 term of the polynomial
crc[3] <= crc[2] ;
crc[4] <= crc[3] ^ (crc[31] ^ out); // The x**4 term of the polynomial
crc[5] <= crc[4] ^ (crc[31] ^ out); // The x**5 term of the polynomial
crc[6] <= crc[5] ;
crc[7] <= crc[6] ^ (crc[31] ^ out); // The x**7 term of the polynomial
crc[8] <= crc[7] ^ (crc[31] ^ out); // The x**8 term of the polynomial
crc[9] <= crc[8] ;
crc[10] <= crc[9] ^ (crc[31] ^ out); // The x**10 term of the polynomial
crc[11] <= crc[10] ^ (crc[31] ^ out); // The x**11 term of the polynomial
crc[12] <= crc[11] ^ (crc[31] ^ out); // The x**12 term of the polynomial
crc[13] <= crc[12] ;
crc[14] <= crc[13] ;
crc[15] <= crc[14] ;
crc[16] <= crc[15] ^ (crc[31] ^ out); // The x**16 term of the polynomial
crc[17] <= crc[16] ;
crc[18] <= crc[17] ;
crc[19] <= crc[18];
crc[20] <= crc[19];
crc[21] <= crc[20];
crc[22] <= crc[21] ^ (crc[31] ^ out); // The x**22 term of the polynomial
crc[23] <= crc[22] ^ (crc[31] ^ out); // The x**23 term of the polynomial
crc[24] <= crc[23] ;
crc[25] <= crc[24] ;
crc[26] <= crc[25] ^ (crc[31] ^ out); // The x**26 term of the polynomial
crc[27] <= crc[26];
crc[28] <= crc[27];
crc[29] <= crc[28];
crc[30] <= crc[29];
crc[31] <= crc[30];
end
end
end
 
// Data flow assignment for the CRC error signal.
//It uses the output polynomial mentioned in the comments.
 
assign crc_err = ~(crc==32'hC704DD7B);
assign cyc_crc_err = ~(crc==32'hC704DD7B);
 
//********************************************************************************
 
 
//******************************* delay block *******************************
 
 
always@(posedge clk)
begin
del_out<=in;
end
 
assign out= (del_cnt)? del_out :in;
 
//*******************************************************************************
 
 
//********************************* cycle state machine *********************** *************************
 
 
always @(posedge clk) begin
if (reset)
state<=idle;
else
state<=nextstate;
end
 
 
always@(state or phys_arb or count0 or async_data_strt or data_end or
data_prefix or cyc_crc_err or iso_end or cycle_quad)
begin
cycload15 <= 0;
cycload31 <= 0;
load47 <= 0;
latch_cyc_src_id<= 0;
latch_cyc_dest_off <= 0;
latch_cyc_tim_data <= 0;
latch_cyc_quad <= 0;
cycinit_crc<=0;
cycenable_crc<= 0;
async_enab <= 0 ;
iso_start <= 0 ;
case (state)
idle:
begin
cycinit_crc<=1;
if(phys_arb) begin
nextstate<= async_ready;
end
else nextstate<=idle;
end
async_ready:
begin
if( async_data_strt) begin
nextstate<= async_rx_pack;
end
else
nextstate <= async_ready;
end
async_rx_pack:
begin
cycenable_crc<=1;
if(count0) begin
nextstate<=delay4;
cycload31<=0;
end
else begin
cycload31<=1;
nextstate<=async_rx_pack2;
end
end
async_rx_pack2:
begin
cycenable_crc<=1;
if (count0) begin
nextstate<=delay4;
cycload31<=0;
end
else begin
cycload31<=0;
nextstate<=async_rx_pack2;
end
end
delay4: begin
cycenable_crc<=1;
latch_cyc_quad<=1;
nextstate<=delay5;
end
 
delay5: begin
cycenable_crc<=1;
nextstate<=cyc_st_dec;
end
cyc_st_dec:
begin
cycenable_crc<=1;
if (cycle_quad ==32'hFFFF004F)
begin
nextstate <= cyc_src_id ;
latch_cyc_quad <= 0;
end
else
begin
nextstate <= idle;
async_enab <= 1;
end
end
cyc_src_id:
begin
cycenable_crc<=1;
if (count0) begin
nextstate<= cyc_dest_off;
cycload15<=0;
end
else begin
cycload15<=1;
nextstate<=cyc_src_id2;
end
end
cyc_src_id2:
begin
cycenable_crc<=1;
if (count0) begin
nextstate<=cyc_dest_off;
cycload15<=0;
end
else begin
cycload15<=0;
nextstate<=cyc_src_id2;
end
end
cyc_dest_off:
begin
cycenable_crc<=1;
latch_cyc_src_id <= 1;
if (count0) begin
nextstate<=cyc_tim_data;
load47<=0;
end
else begin
load47 <=1;
nextstate<=cyc_dest_off2;
end
end
cyc_dest_off2:
begin
cycenable_crc<=1;
if (count0) begin
nextstate<=cyc_tim_data;
load47<=0;
end
else begin
load47<=0;
nextstate<=cyc_dest_off2;
end
end
cyc_tim_data:
begin
cycenable_crc<=1;
latch_cyc_dest_off <= 1;
if (count0) begin
nextstate<=header_crc;
cycload31<=0;
end
else begin
cycload31<=1;
nextstate<=cyc_tim_data2;
end
end
cyc_tim_data2: begin
cycenable_crc<=1;
if (count0) begin
nextstate<=header_crc;
cycload31<=0;
end
else
begin
cycload31<=0;
nextstate<=cyc_tim_data2;
end
end
header_crc: begin
latch_cyc_tim_data <= 1;
cycenable_crc<=1;
if (count0) begin
nextstate<=cyc_crc_check;
cycload31<=0;
end
else
begin
cycload31<=1;
nextstate<=header_crc2;
end
end
header_crc2:
begin
cycenable_crc<=1;
if(count0) begin
cycload31<=0;
nextstate<=cyc_crc_check;
end
else begin
cycload31<=0;
nextstate<=header_crc2;
end
end
cyc_crc_check:
begin
cycenable_crc<=1;
if (cyc_crc_err==1) nextstate<= async_ready;
else begin
nextstate<=cyc_eop;
end
end
cyc_eop: begin
if(data_end | data_prefix)
begin
iso_start <=1'b1;
nextstate<= delay;
end
else
nextstate<= cyc_eop;
end
delay: begin
nextstate<=iso_wait;
iso_start <=1'b1;
end
iso_wait: begin
if(iso_end) begin
nextstate <= idle;
end
else
begin
nextstate <= iso_wait;
end
end
default : nextstate <= idle ;
endcase
end
//******************************************************************************************
 
//****************************** iso state machine ******************************
 
always @(posedge clk)
begin
if (reset) begin
enable_crc <=0;
state_iso <=idle1;
end
else begin
state_iso<=nextstate_iso;
 
if (nextstate_iso==data_len )
enable_crc <= 1'b1 ;
else if (nextstate_iso == eop)
enable_crc<= 1'b0 ;
 
end
end
 
assign init_crc = (state_iso==idle & iso_start) |
(state_iso==crc_check );
 
assign iso_end = ((state_iso==iso_rdy) & subact_gap) |
(state_iso==delay3);
 
always@(state_iso or iso_start or count0 or in or data_start or eop_phy or
crc_err or subact_gap or isotcode_latch or isodat_len_latch)
begin
load15 <=1'b0;
load6 <=1'b0;
load3 <=1'b0;
load31 <=1'b0;
load30 <=1'b0;
latch_isodat_len<=1'b0;
latch_isotcode <=1'b0;
latch_isodata <=1'b0;
case (state_iso)
idle1: begin
if(iso_start) begin
nextstate_iso<=iso_rdy;
end
else begin
nextstate_iso<=idle1;
end
end
iso_rdy:
begin
if(data_start) begin
nextstate_iso<=data_len;
end
else
begin
if (subact_gap)
begin
nextstate_iso<=delay3;
end
else nextstate_iso<=iso_rdy;
end
end
delay3:begin
nextstate_iso<=idle1;
end
data_len:
begin
if(count0) begin
nextstate_iso<=delay1;
load15<=0;
end
else begin
load15<=1;
nextstate_iso<=data_len2;
end
end
data_len2:
begin
if (count0) begin
nextstate_iso<=delay1;
load15<=0;
end
else begin
load15<=0;
nextstate_iso<=data_len2;
end
end
delay1: begin
latch_isodat_len<=1;
nextstate_iso<=delay11;
end
delay11:begin
nextstate_iso<=data_len_dec;
end
data_len_dec:
begin
if (isodat_len_latch ==16'b0) begin
nextstate_iso<=iso_rdy;
end
else
nextstate_iso<=tag_chan;
end
tag_chan:
begin
if (count0) begin
nextstate_iso<=tcode;
load6<=0;
end
else begin
load6<=1;
nextstate_iso<=tag_chan2;
end
end
tag_chan2:
begin
if (count0) begin
nextstate_iso<=tcode;
load6<=0;
end
else begin
load6<=0;
nextstate_iso<=tag_chan2;
end
end
tcode:
begin
if (count0) begin
nextstate_iso<=delay2;
load3<=0;
end
else begin
load3<=1;
nextstate_iso<=tcode2;
end
end
tcode2:
begin
if (count0) begin
nextstate_iso<=delay2;
load3<=0;
end
else begin
load3<=0;
nextstate_iso<=tcode2;
end
end
delay2:
begin
latch_isotcode<=1;
nextstate_iso<= delay22;
end
delay22:
begin
nextstate_iso<=dec_tcode;
end
dec_tcode:
begin
if(isotcode_latch==4'b1010) begin
nextstate_iso<=sy;
end
else
nextstate_iso<=iso_rdy;
end
sy: begin
nextstate_iso<=head_crc;
end
head_crc:
begin
if(count0) begin
load31<=0;
nextstate_iso<=crc_check;
end
else begin
load31<=1;
nextstate_iso<=head_crc2;
end
end
head_crc2:
begin
if(count0) begin
load31<=0;
nextstate_iso<=crc_check;
end
else begin
load31<=0;
nextstate_iso<=head_crc2;
end
end
crc_check:
begin
if (crc_err==1) nextstate_iso<=iso_rdy;
else begin
nextstate_iso<=data;
end
end
data:
begin
if(count0) begin
load30<=0;
nextstate_iso<=data_crc;
end
else begin
load30<=1;
nextstate_iso<=data2;
end
end
data2:
begin
if(count0) begin
load30<=0;
latch_isodata<=1;
nextstate_iso<=data_crc;
end
else begin
load30<=0;
nextstate_iso<=data2;
end
end
data_crc:
begin
if(count0) begin
load31<=0;
nextstate_iso<=data_crc_check;
end
else
begin
load31<=1;
nextstate_iso<=data_crc2;
end
end
data_crc2:
begin
if(count0) begin
load31<=0;
nextstate_iso<=data_crc_check;
end
else
begin
load31<=0;
nextstate_iso<=data_crc2;
end
end
data_crc_check:
begin
if (crc_err==1) nextstate_iso<=iso_rdy;
else nextstate_iso<=eop;
end
eop: begin
if(eop_phy)
nextstate_iso<=iso_rdy;
else
nextstate_iso<=eop;
end
default : nextstate_iso <= idle1 ;
endcase
end
 
//del_cnt is for the duration of data phase
// and data crc phase
always @(posedge clk or posedge reset )
begin
if (reset)
del_cnt <= 1'b0 ;
else begin
if (state_iso == crc_check )
del_cnt <= 1'b1 ;
else if (state_iso == data_crc_check)
del_cnt <= 1'b0 ;
end
end
//***************** ***************** ********************************* * *****************
 
endmodule