OpenCores
URL https://opencores.org/ocsvn/aoocs/aoocs/trunk

Subversion Repositories aoocs

[/] [aoocs/] [trunk/] [tests/] [ethernet_test/] [ethernet.v] - Rev 2

Compare with Previous | Blame | View Log

/*
Send UDP packet:
ethernet
    dest mac(6), src mac(6), type(2 = 0x0800 IPv4)
ip
    version,header([1] = 0x45), tos([1] = 0x00), length([2] = 4*5 + 4*2 + len = 992 = 0x03E0)
    id([2] = 0x0000), flags,offset([2] = 0x40, 0x00)
    ttl([1] = 0x0F), protocol([1] = 0x11), header checksum([2] = 0)
    source ip([4])
    dest ip([4])
udp
    source port([2]), dest port([2])
    length([2] = 8 + len = 972 = 0x03CC), checksum([2] = 0)
data
    (len = line num(1) + line(214*36/8 = 963) = 964)
 
--full ethernet packet len = 992 + 14 = 1006 = 0x03EE
 
DM9000A control to send:
    set IMR(FFh = 0x80)
 
    set checksum reg (31h = 0x05)
 
    set early transmit (30h = 0x83) ? threshold 75%
 
    power-up PHY (1Fh = 0x00)
 
    dummy MWCDM ?
 
    DO
 
        packet I
        set MWCMD(F8h = 16-bit data) 
 
        wait for packet II
        read TX(02h bit 0 == 0)
 
        set TXPLL(FCh = low byte)
        set TXPLH(FDh = high byte)
 
        write TX(02h 0x01)
 
        packet II
        set MWCMD(F8h = 16-bit data) 
 
        wait for packet I
        read TX(02h bit 0 == 0)
 
        set TXPLL(FCh = low byte)
        set TXPLH(FDh = high byte)
 
        write TX(02h 0x01)
 
    LOOP
 
*/
 
module ethernet(
    input clk_50,
    input reset_ext_n,
 
    output enet_clk_25,
    output enet_reset_n,
    output enet_cs_n,
 
    input enet_irq,
 
    output reg enet_ior_n,
    output reg enet_iow_n,
    output reg enet_cmd,
 
    inout [15:0] enet_data,
 
    input key,
    output [7:0] leds
);
 
assign leds = state_counter[7:0];
 
/***********************************************************************************************************************
 * System PLL
 **********************************************************************************************************************/
 
wire [5:0]  pll_clocks;
assign      enet_clk_25 = pll_clocks[0];
wire        clk_30 = pll_clocks[1];
wire        pll_locked;
 
altpll pll_inst(
    .inclk  ( {1'b0, clk_50} ),
    .clk    (pll_clocks),
    .locked (pll_locked)
);
defparam
    pll_inst.clk0_divide_by             = 2,
    pll_inst.clk0_duty_cycle            = 50,
    pll_inst.clk0_multiply_by           = 1,
    pll_inst.clk0_phase_shift           = "0",
    pll_inst.clk1_divide_by             = 5,
    pll_inst.clk1_duty_cycle            = 50,
    pll_inst.clk1_multiply_by           = 3,
    pll_inst.clk1_phase_shift           = "0",
    pll_inst.compensate_clock           = "CLK0",
    pll_inst.gate_lock_counter          = 1048575,
    pll_inst.gate_lock_signal           = "YES",
    pll_inst.inclk0_input_frequency     = 20000,
    pll_inst.intended_device_family     = "Cyclone II",
    pll_inst.invalid_lock_multiplier    = 5,
    pll_inst.lpm_hint                   = "CBX_MODULE_PREFIX=pll30",
    pll_inst.lpm_type                   = "altpll",
    pll_inst.operation_mode             = "NORMAL",
    pll_inst.valid_lock_multiplier      = 1;
 
wire reset_n            = pll_locked & reset_ext_n;
 
/***********************************************************************************************************************
 *
 **********************************************************************************************************************/
assign enet_reset_n = reset_n;
assign enet_cs_n    = 1'b0;
 
reg tx_active;
 
reg enet_data_oe;
reg [15:0] enet_data_out;
assign enet_data = (enet_data_oe == 1'b1)? enet_data_out : 16'bZ;
 
//************
reg [5:0] ram_addr;
wire [15:0] ram_q;
 
altsyncram ethernet_ram_inst(
    .clock0(clk_30),
    .address_a(ram_addr),
    .q_a(ram_q)
);
defparam
    ethernet_ram_inst.operation_mode = "ROM",
    ethernet_ram_inst.width_a = 16,
    ethernet_ram_inst.widthad_a = 6,
    ethernet_ram_inst.init_file = "ethernet.mif";
 
//************
 
 
reg [15:0] state_counter;
always @(posedge clk_30 or negedge reset_n) begin
    if(reset_n == 1'b0) begin
        state_counter   <= 16'd0;
        tx_active       <= 1'b0;
 
        enet_iow_n      <= 1'b1;
        enet_ior_n      <= 1'b1;
        enet_cmd        <= 1'b0;        // low: INDEX, high: DATA
        enet_data_oe    <= 1'b0;
        enet_data_out   <= 16'd0;
 
        ram_addr        <= 6'd0;
    end
    else if(state_counter == 16'd50000) begin
        //if(key == 1'b0) begin
            enet_iow_n <= 1'b0;
            enet_cmd <= 1'b0;
            enet_data_oe <= 1'b1;
            enet_data_out <= { 8'd0, 8'hFF }; // set IMR(FFh = 0x80)
 
            state_counter <= state_counter + 16'd1;
        //end
    end
    else if(state_counter == 16'd50002) begin
        enet_iow_n <= 1'b0;
        enet_cmd <= 1'b1;
        enet_data_out <= { 8'd0, 8'h80 }; 
 
        state_counter <= state_counter + 16'd1;
    end
    else if(state_counter == 16'd50005) begin
        enet_iow_n <= 1'b0;
        enet_cmd <= 1'b0;
        enet_data_out <= { 8'd0, 8'h1F }; // power-up PHY (1Fh = 0x00)
 
        state_counter <= state_counter + 16'd1;
    end
    else if(state_counter == 16'd50007) begin
        enet_iow_n <= 1'b0;
        enet_cmd <= 1'b1;
        enet_data_out <= { 8'd0, 8'h00 }; 
 
        state_counter <= state_counter + 16'd1;
    end
 
    else if(state_counter == 16'd50010) begin
        enet_iow_n <= 1'b0;
        enet_cmd <= 1'b0;
        enet_data_out <= { 8'd0, 8'h31 }; // set checksum reg (31h = 0x05)
 
        state_counter <= state_counter + 16'd1;
    end
    else if(state_counter == 16'd50012) begin
        enet_iow_n <= 1'b0;
        enet_cmd <= 1'b1;
        enet_data_out <= { 8'd0, 8'h05 }; 
 
        state_counter <= state_counter + 16'd1;
    end
 
 
    else if(state_counter == 16'd50018) begin
        enet_iow_n <= 1'b0;
        enet_cmd <= 1'b0;
        enet_data_out <= { 8'd0, 8'hF8 }; // set MWCMD(F8h = 16-bit data) 
 
        ram_addr <= 6'd0;
        state_counter <= state_counter + 16'd1;
    end
    else if(state_counter >= 16'd50020 && state_counter <= 16'd50060 && state_counter[0] == 1'b0) begin
        enet_iow_n <= 1'b0;
        enet_cmd <= 1'b1;
        enet_data_out <= ram_q;
 
        ram_addr <= ram_addr + 6'd1;
        state_counter <= state_counter + 16'd1;
    end
 
    else if(state_counter >= 16'd50062 && state_counter <= 16'd51024 && state_counter[0] == 1'b0) begin
        enet_iow_n <= 1'b0;
        enet_cmd <= 1'b1;
        enet_data_out <= { 16'hAAAA }; 
 
        if(state_counter == 16'd51024)  state_counter <= 16'd60016 - 16'd1;
        else                            state_counter <= state_counter + 16'd1;
    end
 
 
    else if(state_counter == 16'd60016) begin
        enet_iow_n <= 1'b0;
        enet_cmd <= 1'b0;
        enet_data_oe <= 1'b1;
        enet_data_out <= { 8'd0, 8'h02 }; // read TX(02h bit 0 == 0)
 
        state_counter <= state_counter + 16'd1;
    end
    else if(state_counter == 16'd60018) begin
        enet_ior_n <= 1'b0;
        enet_cmd <= 1'b1;
        enet_data_oe <= 1'b0;
 
        state_counter <= state_counter + 16'd1;
    end
    else if(state_counter == 16'd60020) begin
        enet_ior_n <= 1'b1;
        tx_active <= enet_data[0];
 
        state_counter <= state_counter + 16'd1;
    end
    else if(state_counter == 16'd60022) begin
        if(tx_active == 1'b0)   state_counter <= 16'd60118;
        else                    state_counter <= 16'd60016;
    end
 
    else if(state_counter == 16'd60118) begin
        enet_iow_n <= 1'b0;
        enet_cmd <= 1'b0;
        enet_data_oe <= 1'b1;
        enet_data_out <= { 8'd0, 8'hFC }; // set TXPLL(FCh = low byte)
 
        state_counter <= state_counter + 16'd1;
    end
    else if(state_counter == 16'd60120) begin
        enet_iow_n <= 1'b0;
        enet_cmd <= 1'b1;
        enet_data_out <= { 8'h00, 8'hEE }; 
 
        state_counter <= state_counter + 16'd1;
    end
 
    else if(state_counter == 16'd60123) begin
        enet_iow_n <= 1'b0;
        enet_cmd <= 1'b0;
        enet_data_out <= { 8'd0, 8'hFD }; // set TXPLH(FDh = high byte)
 
        state_counter <= state_counter + 16'd1;
    end
    else if(state_counter == 16'd60125) begin
        enet_iow_n <= 1'b0;
        enet_cmd <= 1'b1;
        enet_data_out <= { 8'h00, 8'h03 }; 
 
        state_counter <= state_counter + 16'd1;
    end
 
    else if(state_counter == 16'd60128) begin
        enet_iow_n <= 1'b0;
        enet_cmd <= 1'b0;
        enet_data_out <= { 8'd0, 8'h02 }; // write TX(02h = 0x01)
 
        state_counter <= state_counter + 16'd1;
    end
    else if(state_counter == 16'd60130) begin
        enet_iow_n <= 1'b0;
        enet_cmd <= 1'b1;
        enet_data_out <= { 8'h00, 8'h01 }; 
 
        state_counter <= state_counter + 16'd1;
    end
 
    else if(state_counter == 16'd60132) begin
         state_counter <= 16'd50018;
    end
 
    else if(state_counter <= 16'd60132) begin
        enet_iow_n <= 1'b1;
        enet_ior_n <= 1'b1;
        state_counter <= state_counter + 16'd1;
    end
 
end
 
endmodule
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.