Merge branch 'atr_fix_fpga' into atr_fix

This commit is contained in:
Josh Blum 2011-07-28 15:03:12 -07:00
commit cf606156a0
13 changed files with 196 additions and 563 deletions

View File

@ -37,71 +37,57 @@
module nsgpio
(input clk_i, input rst_i,
input cyc_i, input stb_i, input [3:0] adr_i, input we_i, input [31:0] dat_i,
input cyc_i, input stb_i, input [4:0] adr_i, input we_i, input [31:0] dat_i,
output reg [31:0] dat_o, output reg ack_o,
input [31:0] atr, input [31:0] debug_0, input [31:0] debug_1,
inout [31:0] gpio
input tx, input rx, inout [31:0] gpio
);
reg [63:0] ctrl;
reg [31:0] line;
reg [31:0] lgpio; // LatchedGPIO pins
reg [31:0] ddr;
integer n;
reg [31:0] ddr;
reg [31:0] idle_out, rx_out, tx_out, fdx_out;
reg [31:0] rgpio, igpio;
wire wb_acc = cyc_i & stb_i; // WISHBONE access
wire wb_wr = wb_acc & we_i; // WISHBONE write access
always @(posedge clk_i or posedge rst_i)
if (rst_i)
begin
ctrl <= 64'h0;
line <= 0;
end
ddr <= 0;
else if (wb_wr)
case( adr_i[3:2] )
2'b00 :
line <= dat_i;
2'b01 :
ddr[31:0] <= dat_i;
2'b10 :
ctrl[63:32] <= dat_i;
2'b11 :
ctrl[31:0] <= dat_i;
endcase // case( adr_i[3:2] )
case( adr_i[4:2] )
3'b000 :
idle_out <= dat_i;
3'b001 :
rx_out <= dat_i;
3'b010 :
tx_out <= dat_i;
3'b011 :
fdx_out <= dat_i;
3'b100 :
ddr <= dat_i;
endcase // case ( adr_i[4:2] )
always @(posedge clk_i)
case (adr_i[3:2])
2'b00 :
dat_o <= lgpio;
2'b01 :
dat_o <= ddr;
2'b10 :
dat_o <= ctrl[63:32];
2'b11 :
dat_o <= ctrl[31:0];
endcase // case(adr_i[3:2])
dat_o <= gpio;
always @(posedge clk_i or posedge rst_i)
if (rst_i)
ack_o <= 1'b0;
else
ack_o <= wb_acc & !ack_o;
// latch GPIO input pins
always @(posedge clk_i)
lgpio <= gpio;
case({tx,rx})
2'b00 : rgpio <= idle_out;
2'b01 : rgpio <= rx_out;
2'b10 : rgpio <= tx_out;
2'b11 : rgpio <= fdx_out;
endcase // case ({tx,rx})
// assign GPIO outputs
integer n;
reg [31:0] igpio; // temporary internal signal
always @(ctrl or line or debug_1 or debug_0 or atr or ddr)
always @*
for(n=0;n<32;n=n+1)
igpio[n] <= ddr[n] ? (ctrl[2*n+1] ? (ctrl[2*n] ? debug_1[n] : debug_0[n]) :
(ctrl[2*n] ? atr[n] : line[n]) )
: 1'bz;
igpio[n] <= ddr[n] ? rgpio[n] : 1'bz;
assign gpio = igpio;
endmodule

View File

@ -1,6 +1,7 @@
module rx_frontend
#(parameter BASE = 0)
#(parameter BASE = 0,
parameter IQCOMP_EN = 0)
(input clk, input rst,
input set_stb, input [7:0] set_addr, input [31:0] set_data,
@ -16,7 +17,6 @@ module rx_frontend
wire [17:0] adc_i_ofs, adc_q_ofs;
wire [35:0] corr_i, corr_q; wire [17:0] mag_corr,phase_corr;
wire swap_iq;
wire [23:0] i_final, q_final;
setting_reg #(.my_addr(BASE), .width(1)) sr_8
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
@ -35,39 +35,44 @@ module rx_frontend
setting_reg #(.my_addr(BASE+2),.width(18)) sr_2
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out(phase_corr),.changed());
rx_dcoffset #(.WIDTH(18),.ADDR(BASE+3)) rx_dcoffset_i
(.clk(clk),.rst(rst),.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
.in({adc_i,2'b00}),.out(adc_i_ofs));
rx_dcoffset #(.WIDTH(18),.ADDR(BASE+4)) rx_dcoffset_q
(.clk(clk),.rst(rst),.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
.in({adc_q,2'b00}),.out(adc_q_ofs));
MULT18X18S mult_mag_corr
(.P(corr_i), .A(adc_i_ofs), .B(mag_corr), .C(clk), .CE(1), .R(rst) );
MULT18X18S mult_phase_corr
(.P(corr_q), .A(adc_i_ofs), .B(phase_corr), .C(clk), .CE(1), .R(rst) );
generate
if(IQCOMP_EN == 1)
begin
rx_dcoffset #(.WIDTH(18),.ADDR(BASE+3)) rx_dcoffset_i
(.clk(clk),.rst(rst),.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
.in({adc_i,2'b00}),.out(adc_i_ofs));
rx_dcoffset #(.WIDTH(18),.ADDR(BASE+4)) rx_dcoffset_q
(.clk(clk),.rst(rst),.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
.in({adc_q,2'b00}),.out(adc_q_ofs));
MULT18X18S mult_mag_corr
(.P(corr_i), .A(adc_i_ofs), .B(mag_corr), .C(clk), .CE(1), .R(rst) );
MULT18X18S mult_phase_corr
(.P(corr_q), .A(adc_i_ofs), .B(phase_corr), .C(clk), .CE(1), .R(rst) );
add2_and_clip_reg #(.WIDTH(24)) add_clip_i
(.clk(clk), .rst(rst),
.in1({adc_i_ofs,6'd0}), .in2({{4{corr_i[35]}},corr_i[35:16]}), .strobe_in(1'b1),
.sum(i_out), .strobe_out());
add2_and_clip_reg #(.WIDTH(24)) add_clip_q
(.clk(clk), .rst(rst),
.in1({adc_q_ofs,6'd0}), .in2({{4{corr_q[35]}},corr_q[35:16]}), .strobe_in(1'b1),
.sum(q_out), .strobe_out());
end // if (IQCOMP_EN == 1)
else
begin
rx_dcoffset #(.WIDTH(24),.ADDR(BASE+3)) rx_dcoffset_i
(.clk(clk),.rst(rst),.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
.in({adc_i,8'b00}),.out(i_out));
rx_dcoffset #(.WIDTH(24),.ADDR(BASE+4)) rx_dcoffset_q
(.clk(clk),.rst(rst),.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
.in({adc_q,8'b00}),.out(q_out));
end // else: !if(IQCOMP_EN == 1)
endgenerate
add2_and_clip_reg #(.WIDTH(24)) add_clip_i
(.clk(clk), .rst(rst),
.in1({adc_i_ofs,6'd0}), .in2({{4{corr_i[35]}},corr_i[35:16]}), .strobe_in(1'b1),
.sum(i_final), .strobe_out());
add2_and_clip_reg #(.WIDTH(24)) add_clip_q
(.clk(clk), .rst(rst),
.in1({adc_q_ofs,6'd0}), .in2({{4{corr_q[35]}},corr_q[35:16]}), .strobe_in(1'b1),
.sum(q_final), .strobe_out());
assign i_out = i_final;
assign q_out = q_final;
/*
round_sd #(.WIDTH_IN(24),.WIDTH_OUT(18)) round_i
(.clk(clk), .reset(rst), .in(i_final), .strobe_in(1'b1), .out(i_out), .strobe_out());
round_sd #(.WIDTH_IN(24),.WIDTH_OUT(18)) round_q
(.clk(clk), .reset(rst), .in(q_final), .strobe_in(1'b1), .out(q_out), .strobe_out());
*/
endmodule // rx_frontend

View File

@ -1,7 +1,8 @@
module tx_frontend
#(parameter BASE=0,
parameter WIDTH_OUT=16)
parameter WIDTH_OUT=16,
parameter IQCOMP_EN=0)
(input clk, input rst,
input set_stb, input [7:0] set_addr, input [31:0] set_data,
input [23:0] tx_i, input [23:0] tx_q, input run,
@ -37,30 +38,44 @@ module tx_frontend
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out(mux_ctrl),.changed());
// IQ Balance
MULT18X18S mult_mag_corr
(.P(corr_i), .A(tx_i[23:6]), .B(mag_corr), .C(clk), .CE(1), .R(rst) );
MULT18X18S mult_phase_corr
(.P(corr_q), .A(tx_i[23:6]), .B(phase_corr), .C(clk), .CE(1), .R(rst) );
add2_and_clip_reg #(.WIDTH(24)) add_clip_i
(.clk(clk), .rst(rst),
.in1(tx_i), .in2({{4{corr_i[35]}},corr_i[35:16]}), .strobe_in(1'b1),
.sum(i_bal), .strobe_out());
add2_and_clip_reg #(.WIDTH(24)) add_clip_q
(.clk(clk), .rst(rst),
.in1(tx_q), .in2({{4{corr_q[35]}},corr_q[35:16]}), .strobe_in(1'b1),
.sum(q_bal), .strobe_out());
generate
if(IQCOMP_EN==1)
begin
// IQ Balance
MULT18X18S mult_mag_corr
(.P(corr_i), .A(tx_i[23:6]), .B(mag_corr), .C(clk), .CE(1), .R(rst) );
MULT18X18S mult_phase_corr
(.P(corr_q), .A(tx_i[23:6]), .B(phase_corr), .C(clk), .CE(1), .R(rst) );
add2_and_clip_reg #(.WIDTH(24)) add_clip_i
(.clk(clk), .rst(rst),
.in1(tx_i), .in2({{4{corr_i[35]}},corr_i[35:16]}), .strobe_in(1'b1),
.sum(i_bal), .strobe_out());
add2_and_clip_reg #(.WIDTH(24)) add_clip_q
(.clk(clk), .rst(rst),
.in1(tx_q), .in2({{4{corr_q[35]}},corr_q[35:16]}), .strobe_in(1'b1),
.sum(q_bal), .strobe_out());
// DC Offset
add2_and_clip_reg #(.WIDTH(24)) add_dco_i
(.clk(clk), .rst(rst), .in1(i_dco), .in2(i_bal), .strobe_in(1'b1), .sum(i_ofs), .strobe_out());
// DC Offset
add2_and_clip_reg #(.WIDTH(24)) add_dco_i
(.clk(clk), .rst(rst), .in1(i_dco), .in2(i_bal), .strobe_in(1'b1), .sum(i_ofs), .strobe_out());
add2_and_clip_reg #(.WIDTH(24)) add_dco_q
(.clk(clk), .rst(rst), .in1(q_dco), .in2(q_bal), .strobe_in(1'b1), .sum(q_ofs), .strobe_out());
end // if (IQCOMP_EN==1)
else
begin
// DC Offset
add2_and_clip_reg #(.WIDTH(24)) add_dco_i
(.clk(clk), .rst(rst), .in1(i_dco), .in2(tx_i), .strobe_in(1'b1), .sum(i_ofs), .strobe_out());
add2_and_clip_reg #(.WIDTH(24)) add_dco_q
(.clk(clk), .rst(rst), .in1(q_dco), .in2(tx_q), .strobe_in(1'b1), .sum(q_ofs), .strobe_out());
end // else: !if(IQCOMP_EN==1)
endgenerate
add2_and_clip_reg #(.WIDTH(24)) add_dco_q
(.clk(clk), .rst(rst), .in1(q_dco), .in2(q_bal), .strobe_in(1'b1), .sum(q_ofs), .strobe_out());
// Rounding
round_sd #(.WIDTH_IN(24),.WIDTH_OUT(WIDTH_OUT)) round_i
(.clk(clk), .reset(rst), .in(i_ofs),.strobe_in(1'b1), .out(i_final), .strobe_out());

View File

@ -7,7 +7,6 @@
##################################################
SIMPLE_GEMAC_SRCS = $(abspath $(addprefix $(BASE_DIR)/../simple_gemac/, \
simple_gemac_wrapper.v \
simple_gemac_wrapper19.v \
simple_gemac.v \
simple_gemac_wb.v \
simple_gemac_tx.v \

View File

@ -161,19 +161,19 @@ module simple_gemac_wb
always @(posedge wb_clk)
case(wb_adr[7:2])
0 : wb_dat_o <= misc_settings;
1 : wb_dat_o <= ucast_addr[47:32];
2 : wb_dat_o <= ucast_addr[31:0];
3 : wb_dat_o <= mcast_addr[47:32];
4 : wb_dat_o <= mcast_addr[31:0];
5 : wb_dat_o <= {NoPre,Divider};
6 : wb_dat_o <= MIIADDRESS;
7 : wb_dat_o <= CtrlData;
//0 : wb_dat_o <= misc_settings;
//1 : wb_dat_o <= ucast_addr[47:32];
//2 : wb_dat_o <= ucast_addr[31:0];
//3 : wb_dat_o <= mcast_addr[47:32];
//4 : wb_dat_o <= mcast_addr[31:0];
//5 : wb_dat_o <= {NoPre,Divider};
//6 : wb_dat_o <= MIIADDRESS;
//7 : wb_dat_o <= CtrlData;
8 : wb_dat_o <= MIICOMMAND;
9 : wb_dat_o <= MIISTATUS;
10: wb_dat_o <= MIIRX_DATA;
11: wb_dat_o <= pause_time;
12: wb_dat_o <= pause_thresh;
//11: wb_dat_o <= pause_time;
//12: wb_dat_o <= pause_thresh;
endcase // case (wb_adr[7:2])
endmodule // simple_gemac_wb

View File

@ -18,7 +18,8 @@
module simple_gemac_wrapper
#(parameter RXFIFOSIZE=9,
parameter TXFIFOSIZE=9)
parameter TXFIFOSIZE=9,
parameter RX_FLOW_CTRL=0)
(input clk125, input reset,
// GMII
output GMII_GTX_CLK, output GMII_TX_EN, output GMII_TX_ER, output [7:0] GMII_TXD,
@ -60,7 +61,7 @@ module simple_gemac_wrapper
.GMII_TX_ER(GMII_TX_ER), .GMII_TXD(GMII_TXD),
.GMII_RX_CLK(GMII_RX_CLK), .GMII_RX_DV(GMII_RX_DV),
.GMII_RX_ER(GMII_RX_ER), .GMII_RXD(GMII_RXD),
.pause_req(pause_req), .pause_time_req(pause_time_req),
.pause_req(RX_FLOW_CTRL ? pause_req : 1'b0), .pause_time_req(RX_FLOW_CTRL ? pause_time_req : 16'd0),
.pause_respect_en(pause_respect_en),
.ucast_addr(ucast_addr), .mcast_addr(mcast_addr),
.pass_ucast(pass_ucast), .pass_mcast(pass_mcast), .pass_bcast(pass_bcast),
@ -149,10 +150,13 @@ module simple_gemac_wrapper
.tx_data(tx_data), .tx_valid(tx_valid), .tx_error(tx_error), .tx_ack(tx_ack));
// Flow Control
flow_ctrl_rx flow_ctrl_rx
(.pause_request_en(pause_request_en), .pause_time(pause_time), .pause_thresh(pause_thresh),
.rx_clk(rx_clk), .rx_reset(rx_reset), .rx_fifo_space(rx_fifo_space),
.tx_clk(tx_clk), .tx_reset(tx_reset), .pause_req(pause_req), .pause_time_req(pause_time_req));
generate
if(RX_FLOW_CTRL==1)
flow_ctrl_rx flow_ctrl_rx
(.pause_request_en(pause_request_en), .pause_time(pause_time), .pause_thresh(pause_thresh),
.rx_clk(rx_clk), .rx_reset(rx_reset), .rx_fifo_space(rx_fifo_space),
.tx_clk(tx_clk), .tx_reset(tx_reset), .pause_req(pause_req), .pause_time_req(pause_time_req));
endgenerate
wire [31:0] debug_tx, debug_rx;

View File

@ -1 +0,0 @@
iverilog -Wimplict -Wportbind -y ../fifo/ -y ../models/ -y . -y miim -y ../coregen/ -y ../control_lib/ -o simple_gemac_wrapper19_tb simple_gemac_wrapper19_tb.v

View File

@ -1,174 +0,0 @@
//
// Copyright 2011 Ettus Research LLC
//
// 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/>.
//
module simple_gemac_wrapper19
#(parameter RXFIFOSIZE=9,
parameter TXFIFOSIZE=6)
(input clk125, input reset,
// GMII
output GMII_GTX_CLK, output GMII_TX_EN, output GMII_TX_ER, output [7:0] GMII_TXD,
input GMII_RX_CLK, input GMII_RX_DV, input GMII_RX_ER, input [7:0] GMII_RXD,
// Client FIFO Interfaces
input sys_clk,
output [18:0] rx_f19_data, output rx_f19_src_rdy, input rx_f19_dst_rdy,
input [18:0] tx_f19_data, input tx_f19_src_rdy, output tx_f19_dst_rdy,
// Wishbone Interface
input wb_clk, input wb_rst, input wb_stb, input wb_cyc, output wb_ack, input wb_we,
input [7:0] wb_adr, input [31:0] wb_dat_i, output [31:0] wb_dat_o,
// MIIM
inout mdio, output mdc,
output [31:0] debug);
wire clear = 0;
wire [7:0] rx_data, tx_data;
wire tx_clk, tx_valid, tx_error, tx_ack;
wire rx_clk, rx_valid, rx_error, rx_ack;
wire [47:0] ucast_addr, mcast_addr;
wire pass_ucast, pass_mcast, pass_bcast, pass_pause, pass_all;
wire pause_req;
wire pause_request_en, pause_respect_en;
wire [15:0] pause_time, pause_thresh, pause_time_req, rx_fifo_space;
wire [31:0] debug_state;
wire tx_reset, rx_reset;
reset_sync reset_sync_tx (.clk(tx_clk),.reset_in(reset),.reset_out(tx_reset));
reset_sync reset_sync_rx (.clk(rx_clk),.reset_in(reset),.reset_out(rx_reset));
simple_gemac simple_gemac
(.clk125(clk125), .reset(reset),
.GMII_GTX_CLK(GMII_GTX_CLK), .GMII_TX_EN(GMII_TX_EN),
.GMII_TX_ER(GMII_TX_ER), .GMII_TXD(GMII_TXD),
.GMII_RX_CLK(GMII_RX_CLK), .GMII_RX_DV(GMII_RX_DV),
.GMII_RX_ER(GMII_RX_ER), .GMII_RXD(GMII_RXD),
.pause_req(pause_req), .pause_time_req(pause_time_req),
.pause_respect_en(pause_respect_en),
.ucast_addr(ucast_addr), .mcast_addr(mcast_addr),
.pass_ucast(pass_ucast), .pass_mcast(pass_mcast), .pass_bcast(pass_bcast),
.pass_pause(pass_pause), .pass_all(pass_all),
.rx_clk(rx_clk), .rx_data(rx_data),
.rx_valid(rx_valid), .rx_error(rx_error), .rx_ack(rx_ack),
.tx_clk(tx_clk), .tx_data(tx_data),
.tx_valid(tx_valid), .tx_error(tx_error), .tx_ack(tx_ack),
.debug(debug_state)
);
simple_gemac_wb simple_gemac_wb
(.wb_clk(wb_clk), .wb_rst(wb_rst),
.wb_cyc(wb_cyc), .wb_stb(wb_stb), .wb_ack(wb_ack), .wb_we(wb_we),
.wb_adr(wb_adr), .wb_dat_i(wb_dat_i), .wb_dat_o(wb_dat_o),
.mdio(mdio), .mdc(mdc),
.ucast_addr(ucast_addr), .mcast_addr(mcast_addr),
.pass_ucast(pass_ucast), .pass_mcast(pass_mcast), .pass_bcast(pass_bcast),
.pass_pause(pass_pause), .pass_all(pass_all),
.pause_respect_en(pause_respect_en), .pause_request_en(pause_request_en),
.pause_time(pause_time), .pause_thresh(pause_thresh) );
// RX FIFO Chain
wire rx_ll_sof, rx_ll_eof, rx_ll_src_rdy, rx_ll_dst_rdy;
wire [7:0] rx_ll_data;
wire [18:0] rx_f19_data_int1, rx_f19_data_int2;
wire rx_f19_src_rdy_int1, rx_f19_dst_rdy_int1, rx_f19_src_rdy_int2, rx_f19_dst_rdy_int2;
rxmac_to_ll8 rx_adapt
(.clk(rx_clk), .reset(rx_reset), .clear(0),
.rx_data(rx_data), .rx_valid(rx_valid), .rx_error(rx_error), .rx_ack(rx_ack),
.ll_data(rx_ll_data), .ll_sof(rx_ll_sof), .ll_eof(rx_ll_eof), .ll_error(), // error also encoded in sof/eof
.ll_src_rdy(rx_ll_src_rdy), .ll_dst_rdy(rx_ll_dst_rdy));
ll8_to_fifo19 ll8_to_fifo19
(.clk(rx_clk), .reset(rx_reset), .clear(0),
.ll_data(rx_ll_data), .ll_sof(rx_ll_sof), .ll_eof(rx_ll_eof),
.ll_src_rdy(rx_ll_src_rdy), .ll_dst_rdy(rx_ll_dst_rdy),
.f19_data(rx_f19_data_int1), .f19_src_rdy_o(rx_f19_src_rdy_int1), .f19_dst_rdy_i(rx_f19_dst_rdy_int1));
fifo19_rxrealign fifo19_rxrealign
(.clk(rx_clk), .reset(rx_reset), .clear(0),
.datain(rx_f19_data_int1), .src_rdy_i(rx_f19_src_rdy_int1), .dst_rdy_o(rx_f19_dst_rdy_int1),
.dataout(rx_f19_data_int2), .src_rdy_o(rx_f19_src_rdy_int2), .dst_rdy_i(rx_f19_dst_rdy_int2) );
fifo_2clock_cascade #(.WIDTH(36), .SIZE(RXFIFOSIZE)) rx_2clk_fifo
(.wclk(rx_clk), .datain(rx_f19_data_int2),
.src_rdy_i(rx_f19_src_rdy_int2), .dst_rdy_o(rx_f19_dst_rdy_int2), .space(rx_fifo_space),
.rclk(sys_clk), .dataout(rx_f19_data),
.src_rdy_o(rx_f19_src_rdy), .dst_rdy_i(rx_f19_dst_rdy), .occupied(), .arst(reset));
// TX FIFO Chain
wire tx_ll_sof, tx_ll_eof, tx_ll_src_rdy, tx_ll_dst_rdy;
wire tx_ll_sof2, tx_ll_eof2, tx_ll_src_rdy2, tx_ll_dst_rdy2;
wire tx_ll_sof2_n, tx_ll_eof2_n, tx_ll_src_rdy2_n, tx_ll_dst_rdy2_n;
wire [7:0] tx_ll_data, tx_ll_data2;
wire [18:0] tx_f19_data_int1;
wire tx_f19_src_rdy_int1, tx_f19_dst_rdy_int1;
fifo_2clock_cascade #(.WIDTH(19), .SIZE(4)) tx_2clk_fifo
(.wclk(sys_clk), .datain(tx_f19_data),
.src_rdy_i(tx_f19_src_rdy), .dst_rdy_o(tx_f19_dst_rdy), .space(),
.rclk(tx_clk), .dataout(tx_f19_data_int1),
.src_rdy_o(tx_f19_src_rdy_int1), .dst_rdy_i(tx_f19_dst_rdy_int1), .occupied(), .arst(rx_reset));
fifo19_to_ll8 fifo19_to_ll8
(.clk(tx_clk), .reset(tx_reset), .clear(clear),
.f19_data(tx_f19_data_int1), .f19_src_rdy_i(tx_f19_src_rdy_int1), .f19_dst_rdy_o(tx_f19_dst_rdy_int1),
.ll_data(tx_ll_data2), .ll_sof_n(tx_ll_sof2_n), .ll_eof_n(tx_ll_eof2_n),
.ll_src_rdy_n(tx_ll_src_rdy2_n), .ll_dst_rdy_n(tx_ll_dst_rdy2_n));
assign tx_ll_sof2 = ~tx_ll_sof2_n;
assign tx_ll_eof2 = ~tx_ll_eof2_n;
assign tx_ll_src_rdy2 = ~tx_ll_src_rdy2_n;
assign tx_ll_dst_rdy2_n = ~tx_ll_dst_rdy2;
ll8_shortfifo tx_sfifo
(.clk(tx_clk), .reset(tx_reset), .clear(clear),
.datain(tx_ll_data2), .sof_i(tx_ll_sof2), .eof_i(tx_ll_eof2),
.error_i(0), .src_rdy_i(tx_ll_src_rdy2), .dst_rdy_o(tx_ll_dst_rdy2),
.dataout(tx_ll_data), .sof_o(tx_ll_sof), .eof_o(tx_ll_eof),
.error_o(), .src_rdy_o(tx_ll_src_rdy), .dst_rdy_i(tx_ll_dst_rdy));
ll8_to_txmac ll8_to_txmac
(.clk(tx_clk), .reset(tx_reset), .clear(clear),
.ll_data(tx_ll_data), .ll_sof(tx_ll_sof), .ll_eof(tx_ll_eof),
.ll_src_rdy(tx_ll_src_rdy), .ll_dst_rdy(tx_ll_dst_rdy),
.tx_data(tx_data), .tx_valid(tx_valid), .tx_error(tx_error), .tx_ack(tx_ack));
// Flow Control
flow_ctrl_rx flow_ctrl_rx
(.pause_request_en(pause_request_en), .pause_time(pause_time), .pause_thresh(pause_thresh),
.rx_clk(rx_clk), .rx_reset(rx_reset), .rx_fifo_space(rx_fifo_space),
.tx_clk(tx_clk), .tx_reset(tx_reset), .pause_req(pause_req), .pause_time_req(pause_time_req));
wire [31:0] debug_tx, debug_rx;
assign debug_tx = { { tx_ll_data },
{ tx_ll_sof, tx_ll_eof, tx_ll_src_rdy, tx_ll_dst_rdy,
tx_ll_sof2, tx_ll_eof2, tx_ll_src_rdy2, tx_ll_dst_rdy2 },
{ tx_valid, tx_error, tx_ack, tx_f19_src_rdy_int1, tx_f19_dst_rdy_int1, tx_f19_data_int1[18:16]},
{ tx_data} };
assign debug_rx = { { rx_f19_src_rdy, rx_f19_dst_rdy, debug_state[5:0] },
{ rx_ll_sof, rx_ll_eof, rx_ll_src_rdy, rx_ll_dst_rdy, 4'b0 },
{ rx_valid, rx_error, rx_ack, rx_f19_src_rdy_int1, rx_f19_dst_rdy_int1, rx_f19_data_int1[18:16]},
{ rx_data} };
assign debug = debug_rx;
endmodule // simple_gemac_wrapper19

View File

@ -1,226 +0,0 @@
//
// Copyright 2011 Ettus Research LLC
//
// 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/>.
//
module simple_gemac_wrapper19_tb;
`include "eth_tasks_f19.v"
reg reset = 1;
initial #1000 reset = 0;
wire wb_rst = reset;
reg eth_clk = 0;
always #50 eth_clk = ~eth_clk;
reg wb_clk = 0;
always #173 wb_clk = ~wb_clk;
reg sys_clk = 0;
always #77 sys_clk = ~ sys_clk;
wire GMII_RX_DV, GMII_RX_ER, GMII_TX_EN, GMII_TX_ER, GMII_GTX_CLK;
wire [7:0] GMII_RXD, GMII_TXD;
wire rx_valid, rx_error, rx_ack;
wire tx_ack, tx_valid, tx_error;
wire [7:0] rx_data, tx_data;
reg [15:0] pause_time;
reg pause_req = 0;
wire GMII_RX_CLK = GMII_GTX_CLK;
reg [7:0] FORCE_DAT_ERR = 0;
reg FORCE_ERR = 0;
// Loopback
assign GMII_RX_DV = GMII_TX_EN;
assign GMII_RX_ER = GMII_TX_ER | FORCE_ERR;
assign GMII_RXD = GMII_TXD ^ FORCE_DAT_ERR;
wire [31:0] wb_dat_o;
reg [31:0] wb_dat_i;
reg [7:0] wb_adr;
reg wb_stb=0, wb_cyc=0, wb_we=0;
wire wb_ack;
reg [19:0] tx_f19_data=0;
reg tx_f19_src_rdy = 0;
wire tx_f19_dst_rdy;
wire [35:0] rx_f19_data;
wire rx_f19_src_rdy;
wire rx_f19_dst_rdy = 1;
simple_gemac_wrapper19 simple_gemac_wrapper19
(.clk125(eth_clk), .reset(reset),
.GMII_GTX_CLK(GMII_GTX_CLK), .GMII_TX_EN(GMII_TX_EN),
.GMII_TX_ER(GMII_TX_ER), .GMII_TXD(GMII_TXD),
.GMII_RX_CLK(GMII_RX_CLK), .GMII_RX_DV(GMII_RX_DV),
.GMII_RX_ER(GMII_RX_ER), .GMII_RXD(GMII_RXD),
//.pause_req(pause_req), .pause_time(pause_time),
.sys_clk(sys_clk), .rx_f19_data(rx_f19_data), .rx_f19_src_rdy(rx_f19_src_rdy), .rx_f19_dst_rdy(rx_f19_dst_rdy),
.tx_f19_data(tx_f19_data), .tx_f19_src_rdy(tx_f19_src_rdy), .tx_f19_dst_rdy(tx_f19_dst_rdy),
.wb_clk(wb_clk), .wb_rst(wb_rst), .wb_stb(wb_stb), .wb_cyc(wb_cyc), .wb_ack(wb_ack), .wb_we(wb_we),
.wb_adr(wb_adr), .wb_dat_i(wb_dat_i), .wb_dat_o(wb_dat_o),
.mdio(), .mdc(),
.debug() );
initial $dumpfile("simple_gemac_wrapper19_tb.vcd");
initial $dumpvars(0,simple_gemac_wrapper19_tb);
integer i;
reg [7:0] pkt_rom[0:65535];
reg [1023:0] ROMFile;
initial
for (i=0;i<65536;i=i+1)
pkt_rom[i] <= 8'h0;
initial
begin
@(negedge reset);
repeat (10)
@(posedge wb_clk);
WishboneWR(0,6'b111101);
WishboneWR(4,16'hA0B0);
WishboneWR(8,32'hC0D0_A1B1);
WishboneWR(12,16'h0000);
WishboneWR(16,32'h0000_0000);
@(posedge eth_clk);
SendFlowCtrl(16'h0007); // Send flow control
@(posedge eth_clk);
#30000;
@(posedge eth_clk);
SendFlowCtrl(16'h0009); // Increase flow control before it expires
#10000;
@(posedge eth_clk);
SendFlowCtrl(16'h0000); // Cancel flow control before it expires
@(posedge eth_clk);
repeat (1000)
@(posedge sys_clk);
SendPacket_to_fifo19(32'hA0B0C0D0,10); // This packet gets dropped by the filters
repeat (1000)
@(posedge sys_clk);
SendPacket_to_fifo19(32'hAABBCCDD,100); // This packet gets dropped by the filters
repeat (10)
@(posedge sys_clk);
/*
SendPacketFromFile_f36(60,0,0); // The rest are valid packets
repeat (10)
@(posedge clk);
SendPacketFromFile_f36(61,0,0);
repeat (10)
@(posedge clk);
SendPacketFromFile_f36(62,0,0);
repeat (10)
@(posedge clk);
SendPacketFromFile_f36(63,0,0);
repeat (1)
@(posedge clk);
SendPacketFromFile_f36(64,0,0);
repeat (10)
@(posedge clk);
SendPacketFromFile_f36(59,0,0);
repeat (1)
@(posedge clk);
SendPacketFromFile_f36(58,0,0);
repeat (1)
@(posedge clk);
SendPacketFromFile_f36(100,0,0);
repeat (1)
@(posedge clk);
SendPacketFromFile_f36(200,150,30); // waiting 14 empties the fifo, 15 underruns
repeat (1)
@(posedge clk);
SendPacketFromFile_f36(100,0,30);
*/
#100000 $finish;
end
// Force a CRC error
initial
begin
#90000;
@(posedge eth_clk);
FORCE_DAT_ERR <= 8'h10;
@(posedge eth_clk);
FORCE_DAT_ERR <= 8'h00;
end
// Force an RX_ER error (i.e. link loss)
initial
begin
#116000;
@(posedge eth_clk);
FORCE_ERR <= 1;
@(posedge eth_clk);
FORCE_ERR <= 0;
end
/*
// Cause receive fifo to fill, causing an RX overrun
initial
begin
#126000;
@(posedge clk);
rx_ll_dst_rdy2 <= 0;
repeat (30) // Repeat of 14 fills the shortfifo, but works. 15 overflows
@(posedge clk);
rx_ll_dst_rdy2 <= 1;
end
*/
// Tests: Send and recv flow control, send and receive good packets, RX CRC err, RX_ER, RX overrun, TX underrun
// Still need to test: CRC errors on Pause Frames, MDIO, wishbone
task WishboneWR;
input [7:0] adr;
input [31:0] value;
begin
wb_adr <= adr;
wb_dat_i <= value;
wb_stb <= 1;
wb_cyc <= 1;
wb_we <= 1;
while (~wb_ack)
@(posedge wb_clk);
@(posedge wb_clk);
wb_stb <= 0;
wb_cyc <= 0;
wb_we <= 0;
end
endtask // WishboneWR
/*
always @(posedge clk)
if(rx_ll_src_rdy2 & rx_ll_dst_rdy2)
begin
if(rx_ll_sof2 & ~rx_ll_eof2)
$display("RX-PKT-START %d",$time);
$display("RX-PKT SOF %d EOF %d ERR%d DAT %x",rx_ll_sof2,rx_ll_eof2,rx_ll_error2,rx_ll_data2);
if(rx_ll_eof2 & ~rx_ll_sof2)
$display("RX-PKT-END %d",$time);
end
*/
endmodule // simple_gemac_wrapper19_tb

View File

@ -23,10 +23,11 @@ module time_64bit
(input clk, input rst,
input set_stb, input [7:0] set_addr, input [31:0] set_data,
input pps,
output [63:0] vita_time,
output reg [63:0] vita_time,
output reg [63:0] vita_time_pps,
output pps_int,
input exp_time_in, output exp_time_out,
output reg good_sync,
output [31:0] debug
);
@ -39,7 +40,10 @@ module time_64bit
reg [31:0] seconds, ticks;
wire end_of_second;
assign vita_time = {seconds,ticks};
always @(posedge clk)
vita_time <= {seconds,ticks};
wire [63:0] vita_time_rcvd;
wire [31:0] next_ticks_preset, next_seconds_preset;
@ -164,5 +168,11 @@ module time_64bit
assign debug = { { 24'b0} ,
{ 2'b0, exp_time_in, exp_time_out, mimo_sync, mimo_sync_now, sync_rcvd, send_sync} };
always @(posedge clk)
if(rst)
good_sync <= 0;
else if(sync_rcvd)
good_sync <= 1;
endmodule // time_64bit

View File

@ -187,7 +187,6 @@ module u2plus_core
wire [3:0] uart_tx_int, uart_rx_int;
wire [31:0] debug_gpio_0, debug_gpio_1;
wire [31:0] atr_lines;
wire [31:0] debug_rx, debug_mac, debug_mac0, debug_mac1, debug_tx_dsp, debug_txc,
debug_serdes0, debug_serdes1, debug_serdes2, debug_rx_dsp, debug_udp, debug_extfifo, debug_extfifo2;
@ -196,7 +195,7 @@ module u2plus_core
wire ser_rx_full, ser_tx_full, dsp_rx_full, dsp_tx_full, eth_rx_full, eth_tx_full, eth_rx_full2;
wire ser_rx_empty, ser_tx_empty, dsp_rx_empty, dsp_tx_empty, eth_rx_empty, eth_tx_empty, eth_rx_empty2;
wire serdes_link_up;
wire serdes_link_up, good_sync;
wire epoch;
wire [31:0] irq;
wire [63:0] vita_time, vita_time_pps;
@ -418,17 +417,17 @@ module u2plus_core
// /////////////////////////////////////////////////////////////////////////
// GPIOs -- Slave #4
nsgpio nsgpio(.clk_i(wb_clk),.rst_i(wb_rst),
.cyc_i(s4_cyc),.stb_i(s4_stb),.adr_i(s4_adr[3:0]),.we_i(s4_we),
.cyc_i(s4_cyc),.stb_i(s4_stb),.adr_i(s4_adr[4:0]),.we_i(s4_we),
.dat_i(s4_dat_o),.dat_o(s4_dat_i),.ack_o(s4_ack),
.atr(atr_lines),.debug_0(debug_gpio_0),.debug_1(debug_gpio_1),
.gpio({io_tx,io_rx}) );
.rx(run_rx0_d1 | rx_rx1_d1), .tx(run_tx), .gpio({io_tx,io_rx}) );
// /////////////////////////////////////////////////////////////////////////
// Buffer Pool Status -- Slave #5
//compatibility number -> increment when the fpga has been sufficiently altered
localparam compat_num = {16'd7, 16'd0}; //major, minor
localparam compat_num = {16'd7, 16'd1}; //major, minor
wb_readback_mux buff_pool_status
(.wb_clk_i(wb_clk), .wb_rst_i(wb_rst), .wb_stb_i(s5_stb),
@ -436,7 +435,7 @@ module u2plus_core
.word00(32'b0),.word01(32'b0),.word02(32'b0),.word03(32'b0),
.word04(32'b0),.word05(32'b0),.word06(32'b0),.word07(32'b0),
.word08(status),.word09({sim_mode,27'b0,clock_divider[3:0]}),.word10(vita_time[63:32]),
.word08(status),.word09(32'b0),.word10(vita_time[63:32]),
.word11(vita_time[31:0]),.word12(compat_num),.word13(irq),
.word14(vita_time_pps[63:32]),.word15(vita_time_pps[31:0])
);
@ -499,7 +498,7 @@ module u2plus_core
// In Rev3 there are only 6 leds, and the highest one is on the ETH connector
wire [7:0] led_src, led_sw;
wire [7:0] led_hw = {run_tx, (run_rx0_d1 | run_rx1_d1), clk_status, serdes_link_up, 1'b0};
wire [7:0] led_hw = {run_tx, (run_rx0_d1 | run_rx1_d1), clk_status, serdes_link_up & good_sync, 1'b0};
setting_reg #(.my_addr(SR_MISC+3),.width(8)) sr_led (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out(led_sw),.changed());
@ -536,12 +535,12 @@ module u2plus_core
// /////////////////////////////////////////////////////////////////////////
// Simple Timer interrupts
/*
simple_timer #(.BASE(SR_SIMTIMER)) simple_timer
(.clk(wb_clk), .reset(wb_rst),
.set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
.onetime_int(onetime_int), .periodic_int(periodic_int));
*/
// /////////////////////////////////////////////////////////////////////////
// UART, Slave #10
@ -555,11 +554,13 @@ module u2plus_core
// /////////////////////////////////////////////////////////////////////////
// ATR Controller, Slave #11
/*
atr_controller atr_controller
(.clk_i(wb_clk),.rst_i(wb_rst),
.adr_i(sb_adr[5:0]),.sel_i(sb_sel),.dat_i(sb_dat_o),.dat_o(sb_dat_i),
.we_i(sb_we),.stb_i(sb_stb),.cyc_i(sb_cyc),.ack_o(sb_ack),
.run_rx(run_rx0_d1 | run_rx1_d1),.run_tx(run_tx),.ctrl_lines(atr_lines) );
*/
// //////////////////////////////////////////////////////////////////////////
// Time Sync, Slave #12
@ -730,8 +731,7 @@ module u2plus_core
time_64bit #(.TICKS_PER_SEC(32'd100000000),.BASE(SR_TIME64)) time_64bit
(.clk(dsp_clk), .rst(dsp_rst), .set_stb(set_stb_dsp), .set_addr(set_addr_dsp), .set_data(set_data_dsp),
.pps(pps_in), .vita_time(vita_time), .vita_time_pps(vita_time_pps), .pps_int(pps_int),
.exp_time_in(exp_time_in), .exp_time_out(exp_time_out),
.debug(debug_sync));
.exp_time_in(exp_time_in), .exp_time_out(exp_time_out), .good_sync(good_sync), .debug(debug_sync));
// /////////////////////////////////////////////////////////////////////////////////////////
// Debug Pins

View File

@ -193,7 +193,6 @@ module u2_core
wire uart_tx_int, uart_rx_int;
wire [31:0] debug_gpio_0, debug_gpio_1;
wire [31:0] atr_lines;
wire [31:0] debug_rx, debug_mac, debug_mac0, debug_mac1, debug_tx_dsp, debug_txc,
debug_serdes0, debug_serdes1, debug_serdes2, debug_rx_dsp, debug_udp, debug_extfifo, debug_extfifo2;
@ -202,7 +201,7 @@ module u2_core
wire ser_rx_full, ser_tx_full, dsp_rx_full, dsp_tx_full, eth_rx_full, eth_tx_full, eth_rx_full2;
wire ser_rx_empty, ser_tx_empty, dsp_rx_empty, dsp_tx_empty, eth_rx_empty, eth_tx_empty, eth_rx_empty2;
wire serdes_link_up;
wire serdes_link_up, good_sync;
wire epoch;
wire [31:0] irq;
wire [63:0] vita_time, vita_time_pps;
@ -423,17 +422,17 @@ module u2_core
// /////////////////////////////////////////////////////////////////////////
// GPIOs -- Slave #4
nsgpio nsgpio(.clk_i(wb_clk),.rst_i(wb_rst),
.cyc_i(s4_cyc),.stb_i(s4_stb),.adr_i(s4_adr[3:0]),.we_i(s4_we),
.cyc_i(s4_cyc),.stb_i(s4_stb),.adr_i(s4_adr[4:0]),.we_i(s4_we),
.dat_i(s4_dat_o),.dat_o(s4_dat_i),.ack_o(s4_ack),
.atr(atr_lines),.debug_0(debug_gpio_0),.debug_1(debug_gpio_1),
.gpio({io_tx,io_rx}) );
.rx(run_rx0_d1 | rx_rx1_d1), .tx(run_tx), .gpio({io_tx,io_rx}) );
// /////////////////////////////////////////////////////////////////////////
// Buffer Pool Status -- Slave #5
//compatibility number -> increment when the fpga has been sufficiently altered
localparam compat_num = {16'd7, 16'd0}; //major, minor
localparam compat_num = {16'd7, 16'd1}; //major, minor
wb_readback_mux buff_pool_status
(.wb_clk_i(wb_clk), .wb_rst_i(wb_rst), .wb_stb_i(s5_stb),
@ -441,7 +440,7 @@ module u2_core
.word00(32'b0),.word01(32'b0),.word02(32'b0),.word03(32'b0),
.word04(32'b0),.word05(32'b0),.word06(32'b0),.word07(32'b0),
.word08(status),.word09({sim_mode,27'b0,clock_divider[3:0]}),.word10(vita_time[63:32]),
.word08(status),.word09(32'b0),.word10(vita_time[63:32]),
.word11(vita_time[31:0]),.word12(compat_num),.word13(irq),
.word14(vita_time_pps[63:32]),.word15(vita_time_pps[31:0])
);
@ -502,7 +501,7 @@ module u2_core
// In Rev3 there are only 6 leds, and the highest one is on the ETH connector
wire [7:0] led_src, led_sw;
wire [7:0] led_hw = {run_tx, (run_rx0_d1 | run_rx1_d1), clk_status, serdes_link_up, 1'b0};
wire [7:0] led_hw = {run_tx, (run_rx0_d1 | run_rx1_d1), clk_status, serdes_link_up & good_sync, 1'b0};
setting_reg #(.my_addr(SR_MISC+3),.width(8)) sr_led (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out(led_sw),.changed());
@ -524,7 +523,7 @@ module u2_core
assign irq= {{8'b0},
{8'b0},
{3'b0, periodic_int, clk_status, serdes_link_up, uart_tx_int, uart_rx_int},
{2'b0, good_sync, periodic_int, clk_status, serdes_link_up, uart_tx_int, uart_rx_int},
{pps_wb,overrun_wb,underrun_wb,PHY_INTn,i2c_int,spi_int,onetime_int,buffer_int}};
pic pic(.clk_i(wb_clk),.rst_i(wb_rst),.cyc_i(s8_cyc),.stb_i(s8_stb),.adr_i(s8_adr[4:2]),
@ -539,12 +538,12 @@ module u2_core
// /////////////////////////////////////////////////////////////////////////
// Simple Timer interrupts
/*
simple_timer #(.BASE(SR_SIMTIMER)) simple_timer
(.clk(wb_clk), .reset(wb_rst),
.set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
.onetime_int(onetime_int), .periodic_int(periodic_int));
*/
// /////////////////////////////////////////////////////////////////////////
// UART, Slave #10
@ -558,11 +557,13 @@ module u2_core
// /////////////////////////////////////////////////////////////////////////
// ATR Controller, Slave #11
/*
atr_controller atr_controller
(.clk_i(wb_clk),.rst_i(wb_rst),
.adr_i(sb_adr[5:0]),.sel_i(sb_sel),.dat_i(sb_dat_o),.dat_o(sb_dat_i),
.we_i(sb_we),.stb_i(sb_stb),.cyc_i(sb_cyc),.ack_o(sb_ack),
.run_rx(run_rx0_d1 | run_rx1_d1),.run_tx(run_tx),.ctrl_lines(atr_lines) );
*/
// //////////////////////////////////////////////////////////////////////////
// Time Sync, Slave #12
@ -572,16 +573,16 @@ module u2_core
// /////////////////////////////////////////////////////////////////////////
// SD Card Reader / Writer, Slave #13
/*
sd_spi_wb sd_spi_wb
(.clk(wb_clk),.rst(wb_rst),
.sd_clk(sd_clk),.sd_csn(sd_csn),.sd_mosi(sd_mosi),.sd_miso(sd_miso),
.wb_cyc_i(sd_cyc),.wb_stb_i(sd_stb),.wb_we_i(sd_we),
.wb_adr_i(sd_adr[3:2]),.wb_dat_i(sd_dat_o[7:0]),.wb_dat_o(sd_dat_i[7:0]),
.wb_ack_o(sd_ack) );
assign sd_dat_i[31:8] = 0;
*/
// /////////////////////////////////////////////////////////////////////////
// ADC Frontend
wire [23:0] adc_i, adc_q;
@ -729,8 +730,7 @@ module u2_core
time_64bit #(.TICKS_PER_SEC(32'd100000000),.BASE(SR_TIME64)) time_64bit
(.clk(dsp_clk), .rst(dsp_rst), .set_stb(set_stb_dsp), .set_addr(set_addr_dsp), .set_data(set_data_dsp),
.pps(pps_in), .vita_time(vita_time), .vita_time_pps(vita_time_pps), .pps_int(pps_int),
.exp_time_in(exp_time_in), .exp_time_out(exp_time_out),
.debug(debug_sync));
.exp_time_in(exp_time_in), .exp_time_out(exp_time_out), .good_sync(good_sync), .debug(debug_sync));
// /////////////////////////////////////////////////////////////////////////////////////////
// Debug Pins

View File

@ -46,13 +46,13 @@ module vita_rx_control
wire [63:0] rcvtime_pre;
reg [63:0] rcvtime;
wire [28:0] numlines_pre;
wire send_imm_pre, chain_pre, reload_pre;
wire [27:0] numlines_pre;
wire send_imm_pre, chain_pre, reload_pre, stop_pre;
reg send_imm, chain, reload;
wire read_ctrl, not_empty_ctrl, write_ctrl;
reg sc_pre2;
wire [33:0] fifo_line;
reg [28:0] lines_left, lines_total;
reg [27:0] lines_left, lines_total;
reg [2:0] ibs_state;
wire now, early, late;
wire sample_fifo_in_rdy;
@ -83,7 +83,7 @@ module vita_rx_control
fifo_short #(.WIDTH(96)) commandfifo
(.clk(clk),.reset(reset),.clear(clear),
.datain({new_command,new_time}), .src_rdy_i(write_ctrl), .dst_rdy_o(),
.dataout({send_imm_pre,chain_pre,reload_pre,numlines_pre,rcvtime_pre}),
.dataout({send_imm_pre,chain_pre,reload_pre,stop_pre,numlines_pre,rcvtime_pre}),
.src_rdy_o(not_empty_ctrl), .dst_rdy_i(read_ctrl),
.occupied(command_queue_len), .space() );
@ -97,7 +97,7 @@ module vita_rx_control
localparam IBS_LATECMD = 6;
localparam IBS_ZEROLEN = 7;
wire signal_cmd_done = (lines_left == 1) & (~chain | (not_empty_ctrl & (numlines_pre==0)));
wire signal_cmd_done = (lines_left == 1) & (~chain | (not_empty_ctrl & stop_pre));
wire signal_overrun = (ibs_state == IBS_OVERRUN);
wire signal_brokenchain = (ibs_state == IBS_BROKENCHAIN);
wire signal_latecmd = (ibs_state == IBS_LATECMD);
@ -121,10 +121,19 @@ module vita_rx_control
time_compare
time_compare (.time_now(vita_time), .trigger_time(rcvtime), .now(now), .early(early), .late(late));
wire too_late = late & ~send_imm;
wire go_now = now | send_imm;
wire full = ~sample_fifo_in_rdy;
reg too_late;
always @(posedge clk)
if(reset | clear)
too_late <= 0;
else
too_late <= late & ~send_imm;
reg late_valid;
always @(posedge clk)
if(reset | clear)
begin
@ -135,6 +144,7 @@ module vita_rx_control
send_imm <= 0;
chain <= 0;
reload <= 0;
late_valid <= 0;
end
else
case(ibs_state)
@ -144,7 +154,8 @@ module vita_rx_control
lines_left <= numlines_pre;
lines_total <= numlines_pre;
rcvtime <= rcvtime_pre;
if(numlines_pre == 0)
late_valid <= 0;
if(stop_pre)
ibs_state <= IBS_ZEROLEN;
else
ibs_state <= IBS_WAITING;
@ -153,10 +164,14 @@ module vita_rx_control
reload <= reload_pre;
end
IBS_WAITING :
if(go_now)
ibs_state <= IBS_RUNNING;
else if(too_late)
ibs_state <= IBS_LATECMD;
begin
late_valid <= 1;
if(late_valid)
if(go_now)
ibs_state <= IBS_RUNNING;
else if(too_late)
ibs_state <= IBS_LATECMD;
end
IBS_RUNNING :
if(strobe)
if(full)
@ -182,7 +197,7 @@ module vita_rx_control
send_imm <= send_imm_pre;
chain <= chain_pre;
reload <= reload_pre;
if(numlines_pre == 0) // If we are told to stop here
if(stop_pre) // If we are told to stop here
ibs_state <= IBS_IDLE;
else
ibs_state <= IBS_RUNNING;