//exp/microboone/study2011/verify_adc_interface_110316/ april1,2011 module adc32x12 ( rx_inclock,clk16, in0,in1,in2,in3, rxreset,align,rx_locked, out0,out1,out2,out3, alvalid ); input rx_inclock; input clk16; input [8:0] in0,in1,in2,in3; input rxreset; input align; output rx_locked; output [95:0] out0,out1,out2,out3; output alvalid; //sync align and rxreset to rx_outclock: wire outclock; reg [15:0] sr; reg [1:0] rxresets; wire start; wire reset; always @ (posedge outclock) begin sr[15:0] <= {sr[14:0],align}; rxresets[1:0] <= {rxresets[0],rxreset}; end assign reset = sr[1] & !sr[3]; assign start = sr[15]; wire [8:0] rs3,rs2,rs1,rs0; assign rs3 = rxresets[1] ? 9'b111111111 : 9'b000000000; assign rs2 = rxresets[1] ? 9'b111111111 : 9'b000000000; assign rs1 = rxresets[1] ? 9'b111111111 : 9'b000000000; assign rs0 = rxresets[1] ? 9'b111111111 : 9'b000000000; wire [35:0] alignx; reg al0,al1,al2,al3; assign alignx = al0 ? {9'b0,9'b0,9'b0,9'b111111111} : 36'b0 | al1 ? {9'b0,9'b0,9'b111111111,9'b0} : 36'b0 | al2 ? {9'b0,9'b111111111,9'b0,9'b0} : 36'b0 | al3 ? {9'b111111111,9'b0,9'b0,9'b0} : 36'b0 ; wire [53:0] rx3,rx2,rx1,rx0; wire rx_locked; rxadc4x9 adc4x9 ( .rx_inclock (rx_inclock), .rx_in ({in3,in2,in1,in0}), .rx_reset ({rs3,rs2,rs1,rs0}), .rx_channel_data_align (alignx), .rx_out ({rx3,rx2,rx1,rx0}), .rx_outclock (outclock), .rx_locked (rx_locked), .rx_dpa_locked () ); //frame the deserialized adc data: reg [53:0] rx3l,rx2l,rx1l,rx0l; reg [53:0] rx3m,rx2m,rx1m,rx0m; always @ (posedge outclock) begin rx3l <= rx3; rx3m <= rx3l; rx2l <= rx2; rx2m <= rx2l; rx1l <= rx1; rx1m <= rx1l; rx0l <= rx0; rx0m <= rx0l; end wire load3,load2,load1,load0; assign load3 = (rx3m[53:48]==6'b111111) & (rx3l[53:48]==6'b000000); assign load2 = (rx2m[53:48]==6'b111111) & (rx2l[53:48]==6'b000000); assign load1 = (rx1m[53:48]==6'b111111) & (rx1l[53:48]==6'b000000); assign load0 = (rx0m[53:48]==6'b111111) & (rx0l[53:48]==6'b000000); reg [95:0] adc3,adc2,adc1,adc0; always @ (posedge outclock) begin if (load3) adc3 <= {rx3m[47:0],rx3l[47:0]}; if (load2) adc2 <= {rx2m[47:0],rx2l[47:0]}; if (load1) adc1 <= {rx1m[47:0],rx1l[47:0]}; if (load0) adc0 <= {rx0m[47:0],rx0l[47:0]}; end //align the data to the adc frame[0]: reg alsync; reg [3:0] alcount; reg done0,done1,done2,done3; reg [1:0] sel; always @ (posedge outclock) begin if (!rx_locked) alsync <= 1'b0; else if (reset) alsync <= 1'b0; else if (start) alsync <= 1'b1; else if (done3 & load3 & (alcount>7)) alsync <= 1'b0; else alsync <= alsync; if (!rx_locked) done0 <= 1'b0; else if (!alsync) done0 <= 1'b0; else if (alsync & load0 & (sel==0) & (alcount>7)) done0 <= 1'b1; if (!rx_locked) done1 <= 1'b0; else if (!alsync) done1 <= 1'b0; else if (alsync & load1 & (sel==1) & (alcount>7)) done1 <= 1'b1; if (!rx_locked) done2 <= 1'b0; else if (!alsync) done2 <= 1'b0; else if (alsync & load2 & (sel==2) & (alcount>7)) done2 <= 1'b1; if (!rx_locked) done3 <= 1'b0; else if (!alsync) done3 <= 1'b0; else if (alsync & load3 & (sel==3) & (alcount>7)) done3 <= 1'b1; if (!rx_locked) sel <= 2'b00; else if (!alsync) sel <= 2'b00; else if ((sel==0) & load0 & (alcount>7)) sel <= 2'b01; else if ((sel==1) & load1 & (alcount>7)) sel <= 2'b10; else if ((sel==2) & load2 & (alcount>7)) sel <= 2'b11; else if ((sel==3) & load3 & (alcount>7)) sel <= 2'b00; if (!rx_locked) alcount <= 4'b0000; else if (!alsync) alcount <= 4'b0000; else if (alsync) alcount <= alcount + 4'b0001; if (!alsync) al0 <= 1'b0; else if ((alcount==1) & (sel==0) & !done0) al0 <= 1'b1; else if (alcount >2) al0 <= 1'b0; if (!alsync) al1 <= 1'b0; else if ((alcount==1) & (sel==1) & !done1) al1 <= 1'b1; else if (alcount >2) al1 <= 1'b0; if (!alsync) al2 <= 1'b0; else if ((alcount==1) & (sel==2) & !done2) al2 <= 1'b1; else if (alcount >2) al2 <= 1'b0; if (!alsync) al3 <= 1'b0; else if ((alcount==1) & (sel==3) & !done3) al3 <= 1'b1; else if (alcount >2) al3 <= 1'b0; end //synchronize to clk16: wire alvalid0; wire alvalid1; wire alvalid2; wire alvalid3; adcsync adcsync0 ( .outclock (outclock), .clk16 (clk16), .rx_locked (rx_locked), .alsync (alsync), .load (load0), .adc (adc0), .out (out0), .alvalid (alvalid0) ); adcsync adcsync1 ( .outclock (outclock), .clk16 (clk16), .rx_locked (rx_locked), .alsync (alsync), .load (load1), .adc (adc1), .out (out1), .alvalid (alvalid1) ); adcsync adcsync2 ( .outclock (outclock), .clk16 (clk16), .rx_locked (rx_locked), .alsync (alsync), .load (load2), .adc (adc2), .out (out2), .alvalid (alvalid2) ); adcsync adcsync3 ( .outclock (outclock), .clk16 (clk16), .rx_locked (rx_locked), .alsync (alsync), .load (load3), .adc (adc3), .out (out3), .alvalid (alvalid3) ); wire alvalid; assign alvalid = alvalid0 & alvalid1 & alvalid2 & alvalid3; endmodule