gateware

A collection of little open source FPGA hobby projects
git clone http://frotz.net/git/gateware.git
Log | Files | Refs | README

eth_rgmii_tx.sv (2850B)


      1 // Copyright 2020 Brian Swetland <swetland@frotz.net>
      2 // Licensed under the Apache License, Version 2.0.
      3 
      4 `default_nettype none
      5 
      6 module eth_rgmii_tx (
      7 	input wire tx_clk,
      8 
      9 	output wire pin_tx_clk,
     10 	output wire pin_tx_en,
     11 	output wire [3:0]pin_tx_data,
     12 
     13 	// strobe to request start
     14 	// data will be accepted 8-20 clocks later
     15 	// (depending on how soon after last packet finished)
     16 	input wire start,
     17 
     18 	// asserted to accept a byte	
     19 	output reg ready = 0,
     20 
     21 	// assert when a byte is ready to transmit
     22 	// once data transmission begins, deassertion will end the packet
     23 	input wire valid,
     24 
     25 	// assert to cease transmitting and ensure packet is invalid
     26 	// (do not complete FCS computation)
     27 	input wire error,
     28 
     29 	// byte to transmit
     30 	input wire [7:0]data
     31 );
     32 
     33 localparam IDLE = 3'd0;
     34 localparam PREAMBLE = 3'd1;
     35 localparam PACKET = 3'd2;
     36 localparam CRC1 = 3'd3;
     37 localparam CRC2 = 3'd4;
     38 localparam CRC3 = 3'd5;
     39 localparam CRC4 = 3'd6;
     40 localparam WAIT = 3'd7;
     41 
     42 reg [2:0]state = IDLE;
     43 reg tx_en = 0;
     44 reg tx_err = 0;
     45 reg [7:0]tx_data = 8'd0;
     46 reg [3:0]count = 4'd0;
     47 
     48 reg [2:0]next_state;
     49 reg [3:0]next_count;
     50 reg next_tx_en;
     51 reg next_tx_err;
     52 reg [7:0]next_tx_data;
     53 reg next_ready;
     54 
     55 wire [3:0]count_sub1;
     56 wire count_done;
     57 assign { count_done, count_sub1 } = { 1'b0, count } - 5'd1;
     58 
     59 reg crc_en;
     60 wire [31:0]crc;
     61 
     62 always_comb begin
     63 	next_state = state;
     64 	next_count = count;
     65 	next_tx_data = tx_data;
     66 	next_tx_en = tx_en;
     67 	next_tx_err = tx_err;
     68 	next_ready = 1'b0;
     69 
     70 	case (state)
     71 	IDLE: if (start) begin
     72 		next_state = PREAMBLE;
     73 		next_count = 4'd6;
     74 		next_tx_data = 8'h55;
     75 		next_tx_en = 1'b1;
     76 	end
     77 	PREAMBLE: if (count_done) begin
     78 		next_state = PACKET;
     79 		next_tx_data = 8'hD5;
     80 		next_ready = 1'b1;
     81 		next_count = 4'd11; // preload IPG count
     82 	end else begin
     83 		next_count = count_sub1;
     84 	end
     85 	PACKET: if (valid) begin
     86 		next_ready = 1'b1;
     87 		next_tx_data = data;
     88 	end else begin
     89 		next_state = CRC1;
     90 		next_tx_data = ~crc[7:0];
     91 	end
     92 	CRC1: begin
     93 		next_state = CRC2;
     94 		next_tx_data = ~crc[15:8];
     95 	end
     96 	CRC2: begin
     97 		next_state = CRC3;
     98 		next_tx_data = ~crc[23:16];
     99 	end
    100 	CRC3: begin
    101 		next_state = CRC4;
    102 		next_tx_data = ~crc[31:24];
    103 	end
    104 	CRC4: begin
    105 		next_state = WAIT;
    106 		next_tx_data = 8'd0;
    107 		next_tx_en = 1'b0;
    108 	end
    109 	WAIT: if (count_done) begin
    110 		next_state = IDLE;
    111 	end else begin
    112 		next_count = count_sub1;
    113 	end
    114 	default: next_state = IDLE;
    115 	endcase
    116 end
    117 
    118 always_ff @(posedge tx_clk) begin
    119 	state <= next_state;
    120 	count <= next_count;
    121 	tx_data <= next_tx_data;
    122 	tx_en <= next_tx_en;
    123 	tx_err <= next_tx_err;
    124 	ready <= next_ready;
    125 end
    126 
    127 // hardware-specific io buffers, delats, etc
    128 eth_rgmii_tx_glue glue(
    129 	.tx_clk(tx_clk),
    130 	.pin_tx_clk(pin_tx_clk),
    131 	.pin_tx_en(pin_tx_en),
    132 	.pin_tx_data(pin_tx_data),
    133 	.tx_en(tx_en),
    134 	.tx_err(tx_err),
    135 	.tx_data(tx_data)
    136 );
    137 
    138 eth_crc32_8 crc32(
    139 	.clk(tx_clk),
    140 	.en(valid & ready),
    141 	.rst(start),
    142 	.din(data),
    143 	.crc(crc)
    144 );
    145 endmodule