221 lines
6.9 KiB
Verilog
221 lines
6.9 KiB
Verilog
module pingxelflut #(
|
|
parameter MAC_ADDRESS = 48'h02_00_00_00_00_00,
|
|
|
|
parameter SCREEN_WIDTH = 346
|
|
) (
|
|
input rx_clk,
|
|
input [3:0] rxd,
|
|
input rx_dv,
|
|
input rx_er,
|
|
|
|
output reg bus_clk,
|
|
output reg [15:0] bus_data,
|
|
output reg [23:0] bus_addr,
|
|
output reg [1:0] bus_sel
|
|
);
|
|
localparam PREAMBLE = 7'b0000000;
|
|
localparam DEST_0 = 7'b0000001;
|
|
localparam DEST_1 = 7'b0000010;
|
|
localparam DEST_2 = 7'b0000011;
|
|
localparam DEST_3 = 7'b0000100;
|
|
localparam DEST_4 = 7'b0000101;
|
|
localparam DEST_5 = 7'b0000110;
|
|
localparam DEST_6 = 7'b0000111;
|
|
localparam DEST_7 = 7'b0001000;
|
|
localparam DEST_8 = 7'b0001001;
|
|
localparam DEST_9 = 7'b0001010;
|
|
localparam DEST_A = 7'b0001011;
|
|
localparam DEST_B = 7'b0001100;
|
|
localparam SRC_0 = 7'b0001101;
|
|
localparam SRC_1 = 7'b0001110;
|
|
localparam SRC_2 = 7'b0001111;
|
|
localparam SRC_3 = 7'b0010000;
|
|
localparam SRC_4 = 7'b0010001;
|
|
localparam SRC_5 = 7'b0010010;
|
|
localparam SRC_6 = 7'b0010011;
|
|
localparam SRC_7 = 7'b0010100;
|
|
localparam SRC_8 = 7'b0010101;
|
|
localparam SRC_9 = 7'b0010110;
|
|
localparam SRC_A = 7'b0010111;
|
|
localparam SRC_B = 7'b0011000;
|
|
localparam ETHER_TYPE_0 = 7'b0011001;
|
|
localparam ETHER_TYPE_1 = 7'b0011010;
|
|
localparam ETHER_TYPE_2 = 7'b0011011;
|
|
localparam ETHER_TYPE_3 = 7'b0011100;
|
|
|
|
localparam TRAFFIC_CLASS_0 = 7'b0100000;
|
|
localparam VERSION = 7'b0100001;
|
|
localparam FLOW_LABEL_0 = 7'b0100010;
|
|
localparam TRAFFIC_CLASS_1 = 7'b0100011;
|
|
localparam FLOW_LABEL_1 = 7'b0100100;
|
|
localparam FLOW_LABEL_2 = 7'b0100101;
|
|
localparam FLOW_LABEL_3 = 7'b0100110;
|
|
localparam FLOW_LABEL_4 = 7'b0100111;
|
|
localparam PAYLOAD_LENGTH_0 = 7'b0101000;
|
|
localparam PAYLOAD_LENGTH_1 = 7'b0101001;
|
|
localparam PAYLOAD_LENGTH_2 = 7'b0101010;
|
|
localparam PAYLOAD_LENGTH_3 = 7'b0101011;
|
|
localparam NEXT_HEADER_0 = 7'b0101100;
|
|
localparam NEXT_HEADER_1 = 7'b0101101;
|
|
localparam HOP_LIMIT_0 = 7'b0101110;
|
|
localparam HOP_LIMIT_1 = 7'b0101111;
|
|
localparam SRC_ADDR_0 = 7'b0110000;
|
|
localparam DEST_PREFIX_0 = 7'b1010000;
|
|
localparam X_0 = 7'b1100000;
|
|
localparam X_1 = 7'b1100001;
|
|
localparam X_2 = 7'b1100010;
|
|
localparam X_3 = 7'b1100011;
|
|
localparam Y_0 = 7'b1100100;
|
|
localparam Y_1 = 7'b1100101;
|
|
localparam Y_2 = 7'b1100110;
|
|
localparam Y_3 = 7'b1100111;
|
|
localparam RED_LOW = 7'b1101000;
|
|
localparam RED_HIGH = 7'b1101001;
|
|
localparam GREEN_LOW = 7'b1101010;
|
|
localparam GREEN_HIGH = 7'b1101011;
|
|
localparam BLUE_LOW = 7'b1101100;
|
|
localparam BLUE_HIGH = 7'b1101101;
|
|
localparam PADDING_LOW = 7'b1101110;
|
|
localparam PADDING_HIGH = 7'b1101111;
|
|
|
|
localparam IGNORE = 7'b1111111;
|
|
|
|
localparam ETHER_TYPE_IPV6 = 16'h86dd;
|
|
|
|
reg [6:0] state;
|
|
reg broadcast;
|
|
reg [23:0] pixel_addr;
|
|
reg [16:0] pixel_data;
|
|
|
|
wire maybe_broadcast;
|
|
|
|
assign maybe_broadcast = broadcast && rxd == 4'hf;
|
|
|
|
wire [23:0] base_addr;
|
|
|
|
assign base_addr = pixel_addr * 3 >> 1;
|
|
|
|
initial begin
|
|
bus_clk <= 0;
|
|
bus_data <= 16'b0;
|
|
bus_addr <= 24'b0;
|
|
bus_sel <= 2'b0;
|
|
|
|
state <= PREAMBLE;
|
|
broadcast <= 0;
|
|
pixel_addr <= 24'b0;
|
|
pixel_data <= 16'b0;
|
|
end
|
|
|
|
always @(posedge rx_clk) begin
|
|
if (rx_dv && ~rx_er) begin
|
|
if (state >= DEST_0 && state < ETHER_TYPE_3 || state >= TRAFFIC_CLASS_0 && state < PADDING_HIGH) state <= state + 1;
|
|
else if (state == ETHER_TYPE_3) state <= TRAFFIC_CLASS_0;
|
|
else if (state == PADDING_HIGH) state <= IGNORE;
|
|
|
|
broadcast <= maybe_broadcast;
|
|
|
|
case (state)
|
|
PREAMBLE: begin
|
|
if (rxd == 4'hd) begin
|
|
state <= DEST_0;
|
|
broadcast <= 1;
|
|
end
|
|
end
|
|
DEST_0: if (rxd != MAC_ADDRESS[43:40] && ~maybe_broadcast) state <= IGNORE;
|
|
DEST_1: if (rxd != MAC_ADDRESS[47:44] && ~maybe_broadcast) state <= IGNORE;
|
|
DEST_2: if (rxd != MAC_ADDRESS[35:32] && ~maybe_broadcast) state <= IGNORE;
|
|
DEST_3: if (rxd != MAC_ADDRESS[39:36] && ~maybe_broadcast) state <= IGNORE;
|
|
DEST_4: if (rxd != MAC_ADDRESS[27:24] && ~maybe_broadcast) state <= IGNORE;
|
|
DEST_5: if (rxd != MAC_ADDRESS[31:28] && ~maybe_broadcast) state <= IGNORE;
|
|
DEST_6: if (rxd != MAC_ADDRESS[19:16] && ~maybe_broadcast) state <= IGNORE;
|
|
DEST_7: if (rxd != MAC_ADDRESS[23:20] && ~maybe_broadcast) state <= IGNORE;
|
|
DEST_8: if (rxd != MAC_ADDRESS[11: 8] && ~maybe_broadcast) state <= IGNORE;
|
|
DEST_9: if (rxd != MAC_ADDRESS[15:12] && ~maybe_broadcast) state <= IGNORE;
|
|
DEST_A: if (rxd != MAC_ADDRESS[ 3: 0] && ~maybe_broadcast) state <= IGNORE;
|
|
DEST_B: if (rxd != MAC_ADDRESS[ 7: 4] && ~maybe_broadcast) state <= IGNORE;
|
|
ETHER_TYPE_0: if (rxd != ETHER_TYPE_IPV6[11: 8]) state <= IGNORE;
|
|
ETHER_TYPE_1: if (rxd != ETHER_TYPE_IPV6[15:12]) state <= IGNORE;
|
|
ETHER_TYPE_2: if (rxd != ETHER_TYPE_IPV6[ 3: 0]) state <= IGNORE;
|
|
ETHER_TYPE_3: if (rxd != ETHER_TYPE_IPV6[ 7: 4]) state <= IGNORE;
|
|
VERSION: if (rxd != 4'b0110) state <= IGNORE;
|
|
X_0: pixel_addr[11:8] <= rxd;
|
|
X_2: pixel_addr[ 3:0] <= rxd;
|
|
X_3: pixel_addr[ 7:4] <= rxd;
|
|
Y_2: pixel_addr <= pixel_addr + rxd * SCREEN_WIDTH;
|
|
Y_3: pixel_addr <= pixel_addr + {rxd, 4'b0} * SCREEN_WIDTH;
|
|
RED_LOW: begin
|
|
if (pixel_addr[0]) pixel_data[11:8] <= rxd;
|
|
else pixel_data[ 3:0] <= rxd;
|
|
end
|
|
RED_HIGH: begin
|
|
if (pixel_addr[0]) pixel_data[15:12] <= rxd;
|
|
else pixel_data[ 7: 4] <= rxd;
|
|
end
|
|
GREEN_LOW: begin
|
|
if (pixel_addr[0]) begin
|
|
pixel_data[ 3:0] <= rxd;
|
|
end else begin
|
|
bus_data <= pixel_data;
|
|
bus_addr <= base_addr + 1;
|
|
bus_sel <= 2'b01;
|
|
|
|
pixel_data[11:8] <= rxd;
|
|
end
|
|
end
|
|
GREEN_HIGH: begin
|
|
if (pixel_addr[0]) begin
|
|
pixel_data[ 7: 4] <= rxd;
|
|
end else begin
|
|
bus_clk <= 1;
|
|
|
|
pixel_data[15:12] <= rxd;
|
|
end
|
|
end
|
|
BLUE_LOW: begin
|
|
if (pixel_addr[0]) begin
|
|
bus_data <= pixel_data;
|
|
bus_addr <= base_addr + 1;
|
|
bus_sel <= 2'b11;
|
|
|
|
pixel_data[11:8] <= rxd;
|
|
end else begin
|
|
bus_clk <= 0;
|
|
|
|
pixel_data[ 3:0] <= rxd;
|
|
end
|
|
end
|
|
BLUE_HIGH: begin
|
|
if (pixel_addr[0]) begin
|
|
bus_clk <= 1;
|
|
|
|
pixel_data[15:12] <= rxd;
|
|
end else begin
|
|
pixel_data[ 7: 4] <= rxd;
|
|
end
|
|
end
|
|
PADDING_LOW: begin
|
|
bus_data <= pixel_data;
|
|
|
|
if (pixel_addr[0]) begin
|
|
bus_clk <= 0;
|
|
bus_addr <= base_addr;
|
|
bus_sel <= 2'b10;
|
|
end else begin
|
|
bus_addr <= base_addr;
|
|
bus_sel <= 2'b11;
|
|
end
|
|
end
|
|
PADDING_HIGH: bus_clk <= 1;
|
|
IGNORE: bus_clk <= 0;
|
|
endcase
|
|
end else begin
|
|
bus_clk <= 0;
|
|
|
|
state <= PREAMBLE;
|
|
pixel_addr <= 24'b0;
|
|
pixel_data <= 16'b0;
|
|
end
|
|
end
|
|
endmodule
|