diff options
Diffstat (limited to 'usrp2/fpga/eth/demo/verilog/demo_packet_generator.v')
-rw-r--r-- | usrp2/fpga/eth/demo/verilog/demo_packet_generator.v | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/usrp2/fpga/eth/demo/verilog/demo_packet_generator.v b/usrp2/fpga/eth/demo/verilog/demo_packet_generator.v new file mode 100644 index 000000000..22ad52b4c --- /dev/null +++ b/usrp2/fpga/eth/demo/verilog/demo_packet_generator.v @@ -0,0 +1,274 @@ +module demo_packet_generator(
+ Reset_n,
+ Clk,
+
+ //--- Wishbone interface
+ STB_I,
+ CYC_I,
+ ADR_I,
+ WE_I,
+ DAT_I,
+ DAT_O,
+ ACK_O,
+
+ //--- Packet Descriptor Memory interface
+ // RdData_i is always valid exactly one clock after Addr_o changes
+ // and Rd_o is asserted
+ Rd_o,
+ Addr_o,
+ RdData_i,
+
+ //--- User (packet) interface
+ Rx_mac_ra,
+ Rx_mac_rd,
+ Rx_mac_data,
+ Rx_mac_BE,
+ Rx_mac_pa,
+ Rx_mac_sop,
+ Rx_mac_err,
+ Rx_mac_eop,
+
+ Tx_mac_wa,
+ Tx_mac_wr,
+ Tx_mac_data,
+ Tx_mac_BE,
+ Tx_mac_sop,
+ Tx_mac_eop
+);
+
+ input Reset_n;
+ input Clk;
+
+ //--- Wishbone interface
+ input STB_I;
+ input CYC_I;
+ input [1:0] ADR_I;
+ input WE_I;
+ input [15:0] DAT_I;
+ output [15:0] DAT_O;
+ output ACK_O;
+
+ //--- Packet Generator interface
+ // RdData_o is always valid exactly one clock after Addr_o changes
+ // and Rd_o is asserted
+ output Rd_o;
+ output [13:0] Addr_o;
+ input [31:0] RdData_i;
+
+ //--- User (packet) interface
+ input Rx_mac_ra;
+ output Rx_mac_rd;
+ input [31:0] Rx_mac_data;
+ input [1:0] Rx_mac_BE;
+ input Rx_mac_pa;
+ input Rx_mac_sop;
+ input Rx_mac_err;
+ input Rx_mac_eop;
+
+ input Tx_mac_wa;
+ output Tx_mac_wr;
+ output [31:0] Tx_mac_data;
+ output [1:0] Tx_mac_BE;
+ output Tx_mac_sop;
+ output Tx_mac_eop;
+
+ //-------------------------------------------------------------------------
+ // Local declarations
+ //-------------------------------------------------------------------------
+
+ reg ACK_O;
+ reg [15:0] DAT_O;
+
+ reg Rd_o;
+ reg Tx_mac_wr;
+ reg [1:0] Tx_mac_BE;
+ reg Tx_mac_sop;
+ reg Tx_mac_eop;
+
+ //--- Wishbone interface --------------------------------------------------
+
+ reg [1:0] PG_CFG;
+ wire PG_Enable = PG_CFG[0];
+
+ always @( negedge Reset_n or posedge Clk )
+ if ( ~Reset_n )
+ begin
+ ACK_O <= 0;
+ DAT_O <= 'b0;
+
+ PG_CFG <= 2'h0;
+ end
+ else
+ begin
+ ACK_O <= 0;
+ if ( CYC_I & STB_I )
+ begin
+ ACK_O <= ~ACK_O; // Generate single cycle pulse!
+ if ( WE_I )
+ begin
+ PG_CFG <= DAT_I;
+ end
+ else
+ begin
+ DAT_O[1:0] <= PG_CFG;
+ end
+ end
+ end
+
+ //--- Packet Generator FSM ------------------------------------------------
+
+ parameter PG_FSM_STATE_IDLE = 3'h0;
+ parameter PG_FSM_STATE_LD_DESC_1 = 3'h1;
+ parameter PG_FSM_STATE_LD_DESC_2 = 3'h2;
+ parameter PG_FSM_STATE_RD_HEADER = 3'h3;
+ parameter PG_FSM_STATE_PAYLOAD_SEQ_NUMBER = 3'h4;
+ parameter PG_FSM_STATE_PAYLOAD = 3'h5;
+ parameter PG_FSM_STATE_DONE = 3'h6;
+ reg [2:0] PG_FSM_State;
+
+ reg [9:0] DescHigh; // Selects currente descriptor
+ reg [3:0] DescLow; // Index into a single descriptor (16 entries)
+
+ reg PDM_CFG1_LAST;
+ reg [3:0] PDM_CFG1_REPEAT;
+ reg [3:0] PDM_CFG1_HDRLEN;
+ reg [15:0] PDM_CFG2_PAYLDLEN;
+
+ reg [31:0] Tx_mac_data_reg;
+ reg WriteHeader;
+ reg [15:0] PayloadRemaining;
+ reg [31:0] PacketSequenceNumber;
+ reg [31:0] Payload;
+
+ always @( negedge Reset_n or posedge Clk )
+ if ( ~Reset_n )
+ begin
+ PG_FSM_State <= PG_FSM_STATE_IDLE;
+
+ Rd_o <= 0;
+
+ DescHigh <= 10'b0;
+ DescLow <= 4'b0;
+
+ Tx_mac_wr <= 0;
+ Tx_mac_sop <= 0;
+ Tx_mac_eop <= 0;
+ Tx_mac_BE <= 2'b00;
+
+ Tx_mac_data_reg <= 32'b0;
+ WriteHeader <= 0;
+ PayloadRemaining <= 16'd0;
+
+ PacketSequenceNumber <= 32'd0;
+ Payload <= 32'h0;
+
+ { PDM_CFG1_HDRLEN, PDM_CFG1_REPEAT, PDM_CFG1_LAST, PDM_CFG2_PAYLDLEN } <= 'b0;
+ end
+ else
+ begin
+ casez ( PG_FSM_State )
+ PG_FSM_STATE_IDLE:
+ if ( PG_Enable )
+ begin
+ PG_FSM_State <= PG_FSM_STATE_LD_DESC_1;
+ Rd_o <= 1;
+ end
+ else
+ begin
+ DescHigh <= 10'b0;
+ DescLow <= 4'b0;
+ end
+
+ PG_FSM_STATE_LD_DESC_1:
+ begin
+ PG_FSM_State <= PG_FSM_STATE_LD_DESC_2;
+
+ DescLow <= DescLow + 1;
+ end
+
+ PG_FSM_STATE_LD_DESC_2:
+ begin
+ PG_FSM_State <= PG_FSM_STATE_RD_HEADER;
+
+ { PDM_CFG1_LAST, PDM_CFG1_REPEAT, PDM_CFG1_HDRLEN, PDM_CFG2_PAYLDLEN } <=
+ { RdData_i[31], RdData_i[23:20], RdData_i[19:16], RdData_i[15:0] };
+ end
+
+ PG_FSM_STATE_RD_HEADER:
+ begin
+ Tx_mac_wr <= 0;
+ if ( Tx_mac_wa )
+ begin
+ // Space in Tx FIFO - write next header word
+ DescLow <= DescLow + 1;
+ Tx_mac_wr <= 1;
+ Tx_mac_sop <= ( DescLow == 1 ); // Assert SOP on first header word
+ WriteHeader <= 1;
+ if ( DescLow == PDM_CFG1_HDRLEN )
+ begin
+ // The requested number of header words has been read
+ // - proceed to generate packet payload
+ PG_FSM_State <= PG_FSM_STATE_PAYLOAD_SEQ_NUMBER;
+ PayloadRemaining <= PDM_CFG2_PAYLDLEN;
+ end
+ end
+ end
+
+ PG_FSM_STATE_PAYLOAD_SEQ_NUMBER:
+ begin
+ WriteHeader <= 0;
+ Tx_mac_data_reg <= PacketSequenceNumber;
+ Tx_mac_wr <= 0;
+ Tx_mac_sop <= 0;
+ if ( Tx_mac_wa )
+ begin
+ Tx_mac_wr <= 1;
+ PG_FSM_State <= PG_FSM_STATE_PAYLOAD;
+ Payload <= 32'h01020304;
+ PayloadRemaining <= PayloadRemaining - 4;
+ end
+ end
+
+ PG_FSM_STATE_PAYLOAD:
+ begin
+ Tx_mac_data_reg <= Payload;
+ Tx_mac_wr <= 0;
+ if ( Tx_mac_wa )
+ begin
+ Tx_mac_wr <= 1;
+ Tx_mac_data_reg <= Payload;
+ Payload[31:24] <= Payload[31:24] + 8'h04;
+ Payload[23:16] <= Payload[23:16] + 8'h04;
+ Payload[15: 8] <= Payload[15: 8] + 8'h04;
+ Payload[ 7: 0] <= Payload[ 7: 0] + 8'h04;
+ PayloadRemaining <= PayloadRemaining - 4;
+ if ( PayloadRemaining <= 4 )
+ begin
+ PG_FSM_State <= PG_FSM_STATE_DONE;
+
+ Tx_mac_eop <= 1;
+ // Indicate how many bytes are valid in this last transfer
+ Tx_mac_BE <= PayloadRemaining[1:0];
+ end
+ end
+ end
+
+ PG_FSM_STATE_DONE:
+ begin
+ // TBD: Add support for REPEAT, NEXT & LAST!
+ Tx_mac_wr <= 0;
+ Tx_mac_eop <= 0;
+ end
+ endcase
+ end
+
+ //-------------------------------------------------------------------------
+
+ assign Tx_mac_data = WriteHeader ?
+ RdData_i : Tx_mac_data_reg;
+
+ assign Addr_o = { DescHigh, DescLow };
+
+ assign Rx_mac_rd = 0;
+
+endmodule
|