1 module demo_packet_generator(
\r
5 //--- Wishbone interface
\r
14 //--- Packet Descriptor Memory interface
\r
15 // RdData_i is always valid exactly one clock after Addr_o changes
\r
16 // and Rd_o is asserted
\r
21 //--- User (packet) interface
\r
42 //--- Wishbone interface
\r
48 output [15:0] DAT_O;
\r
51 //--- Packet Generator interface
\r
52 // RdData_o is always valid exactly one clock after Addr_o changes
\r
53 // and Rd_o is asserted
\r
55 output [13:0] Addr_o;
\r
56 input [31:0] RdData_i;
\r
58 //--- User (packet) interface
\r
61 input [31:0] Rx_mac_data;
\r
62 input [1:0] Rx_mac_BE;
\r
70 output [31:0] Tx_mac_data;
\r
71 output [1:0] Tx_mac_BE;
\r
75 //-------------------------------------------------------------------------
\r
76 // Local declarations
\r
77 //-------------------------------------------------------------------------
\r
84 reg [1:0] Tx_mac_BE;
\r
88 //--- Wishbone interface --------------------------------------------------
\r
91 wire PG_Enable = PG_CFG[0];
\r
93 always @( negedge Reset_n or posedge Clk )
\r
104 if ( CYC_I & STB_I )
\r
106 ACK_O <= ~ACK_O; // Generate single cycle pulse!
\r
113 DAT_O[1:0] <= PG_CFG;
\r
118 //--- Packet Generator FSM ------------------------------------------------
\r
120 parameter PG_FSM_STATE_IDLE = 3'h0;
\r
121 parameter PG_FSM_STATE_LD_DESC_1 = 3'h1;
\r
122 parameter PG_FSM_STATE_LD_DESC_2 = 3'h2;
\r
123 parameter PG_FSM_STATE_RD_HEADER = 3'h3;
\r
124 parameter PG_FSM_STATE_PAYLOAD_SEQ_NUMBER = 3'h4;
\r
125 parameter PG_FSM_STATE_PAYLOAD = 3'h5;
\r
126 parameter PG_FSM_STATE_DONE = 3'h6;
\r
127 reg [2:0] PG_FSM_State;
\r
129 reg [9:0] DescHigh; // Selects currente descriptor
\r
130 reg [3:0] DescLow; // Index into a single descriptor (16 entries)
\r
133 reg [3:0] PDM_CFG1_REPEAT;
\r
134 reg [3:0] PDM_CFG1_HDRLEN;
\r
135 reg [15:0] PDM_CFG2_PAYLDLEN;
\r
137 reg [31:0] Tx_mac_data_reg;
\r
139 reg [15:0] PayloadRemaining;
\r
140 reg [31:0] PacketSequenceNumber;
\r
141 reg [31:0] Payload;
\r
143 always @( negedge Reset_n or posedge Clk )
\r
146 PG_FSM_State <= PG_FSM_STATE_IDLE;
\r
156 Tx_mac_BE <= 2'b00;
\r
158 Tx_mac_data_reg <= 32'b0;
\r
160 PayloadRemaining <= 16'd0;
\r
162 PacketSequenceNumber <= 32'd0;
\r
165 { PDM_CFG1_HDRLEN, PDM_CFG1_REPEAT, PDM_CFG1_LAST, PDM_CFG2_PAYLDLEN } <= 'b0;
\r
169 casez ( PG_FSM_State )
\r
173 PG_FSM_State <= PG_FSM_STATE_LD_DESC_1;
\r
182 PG_FSM_STATE_LD_DESC_1:
\r
184 PG_FSM_State <= PG_FSM_STATE_LD_DESC_2;
\r
186 DescLow <= DescLow + 1;
\r
189 PG_FSM_STATE_LD_DESC_2:
\r
191 PG_FSM_State <= PG_FSM_STATE_RD_HEADER;
\r
193 { PDM_CFG1_LAST, PDM_CFG1_REPEAT, PDM_CFG1_HDRLEN, PDM_CFG2_PAYLDLEN } <=
\r
194 { RdData_i[31], RdData_i[23:20], RdData_i[19:16], RdData_i[15:0] };
\r
197 PG_FSM_STATE_RD_HEADER:
\r
202 // Space in Tx FIFO - write next header word
\r
203 DescLow <= DescLow + 1;
\r
205 Tx_mac_sop <= ( DescLow == 1 ); // Assert SOP on first header word
\r
207 if ( DescLow == PDM_CFG1_HDRLEN )
\r
209 // The requested number of header words has been read
\r
210 // - proceed to generate packet payload
\r
211 PG_FSM_State <= PG_FSM_STATE_PAYLOAD_SEQ_NUMBER;
\r
212 PayloadRemaining <= PDM_CFG2_PAYLDLEN;
\r
217 PG_FSM_STATE_PAYLOAD_SEQ_NUMBER:
\r
220 Tx_mac_data_reg <= PacketSequenceNumber;
\r
226 PG_FSM_State <= PG_FSM_STATE_PAYLOAD;
\r
227 Payload <= 32'h01020304;
\r
228 PayloadRemaining <= PayloadRemaining - 4;
\r
232 PG_FSM_STATE_PAYLOAD:
\r
234 Tx_mac_data_reg <= Payload;
\r
239 Tx_mac_data_reg <= Payload;
\r
240 Payload[31:24] <= Payload[31:24] + 8'h04;
\r
241 Payload[23:16] <= Payload[23:16] + 8'h04;
\r
242 Payload[15: 8] <= Payload[15: 8] + 8'h04;
\r
243 Payload[ 7: 0] <= Payload[ 7: 0] + 8'h04;
\r
244 PayloadRemaining <= PayloadRemaining - 4;
\r
245 if ( PayloadRemaining <= 4 )
\r
247 PG_FSM_State <= PG_FSM_STATE_DONE;
\r
250 // Indicate how many bytes are valid in this last transfer
\r
251 Tx_mac_BE <= PayloadRemaining[1:0];
\r
258 // TBD: Add support for REPEAT, NEXT & LAST!
\r
265 //-------------------------------------------------------------------------
\r
267 assign Tx_mac_data = WriteHeader ?
\r
268 RdData_i : Tx_mac_data_reg;
\r
270 assign Addr_o = { DescHigh, DescLow };
\r
272 assign Rx_mac_rd = 0;
\r