⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mac_rd.v

📁 DM9000A读寄存器模块, verilog HDL
💻 V
字号:
/*------------------------------------------------------------------------------
        Project:        SH_IPv6( SmartHone_based_on_IPv6 )
        Module:         MAC_rd
        Author:         machenghai machenghai@gmail.com
        Organization:   Shandong University
        Date:           2009-2-22
        Platform:       Quartus 8.0
        Simulator:      Modelsim 6.4 SE
        Synthesizer:    Synplify Premier 9.0.2
        Target:         Altera DE2 (Cyclone II EP2C35F672C6)
        Description:    Read data from MAC
--------------------------------------------------------------------------------
        Revision Number:
        Version:        
        Date:           
        Modifier:       
        Description:    
------------------------------------------------------------------------------*/

module MAC_rd (
    // inputs
    input               clk,
    input               rst_n,
    input               MAC_rd_start,
    input       [ 7:0]  MAC_rd_index,
    input       [15:0]  MAC_data_in,
    // outputs
    output reg          MAC_rd_done,             // something wrong with it
    output reg  [15:0]  MAC_data_rd,
    output reg  [15:0]  MAC_rd_data_out,
    
    output reg          MAC_rd_cmd,
    output reg          MAC_rd_rd_n,
    output reg          MAC_rd_wr_n
    
    `ifdef DEBUG
    ,
    output reg [2:0] current_state
    `endif
);

`ifndef DEBUG
reg [2:0] current_state;
`endif
reg [2:0] next_state;
reg delay_start;                // start the delay module
reg [2:0] delay_cycles;         // cycles will be delayed

wire delay_done;                // indicates delay ends

parameter IDLE  = 3'd0;
parameter INDEX = 3'd1;
parameter WRITE = 3'd2;
parameter DATA  = 3'd3;
parameter READ  = 3'd4;
parameter DONE  = 3'd5;

always @( posedge clk ) begin
    if ( ~rst_n )
        current_state <= IDLE;
    else
        current_state <= next_state;
end

always @( * ) begin
    if ( ~rst_n )
        next_state = IDLE;
    else begin
        case ( current_state )
            IDLE: begin
                if ( MAC_rd_start )
                    next_state = INDEX;
                else
                    next_state = IDLE;
            end
            INDEX:  next_state = WRITE;
/*
            INDEX:  
                if ( delay_done )
                    next_state = WRITE;
                else
                    next_state = INDEX;
*/
            WRITE: begin
                if ( delay_done )
                    next_state = DATA;
                else
                    next_state = WRITE;
            end
            DATA:   next_state = READ;
/*
            DATA: 
                if ( delay_done )
                    next_state = READ;
                else
                    next_state = DATA;
*/
            READ: begin
                if ( delay_done )
                    next_state = DONE;
                else
                    next_state = READ;
            end
            DONE:   next_state = IDLE;
            default next_state = IDLE;
        endcase
    end
end

delay delay(
    // inputs
    .clk                ( clk ),// 50MHz
    .rst_n              ( rst_n ),
    .delay_start        ( delay_start ),
    .delay_cycles       ( delay_cycles ),// 20ns-2048ns
    // oututs
    .delay_done         ( delay_done )
);

always @( posedge clk ) begin
    if ( ~rst_n )
        {delay_start, delay_cycles} <= {1'b0, 3'd0};
    else begin
        case ( next_state )
            WRITE: {delay_start, delay_cycles} <= {1'b1, 3'd4}; // 2  maybe 1 cycle will be supported
            READ:  {delay_start, delay_cycles} <= {1'b1, 3'd6};// 4
            default{delay_start, delay_cycles} <= {1'b0, 3'd0};
        endcase
    end
end
/*
always @( posedge clk ) begin
    if ( ~rst_n )
        {MAC_rd_data_out, MAC_rd_done, MAC_data_rd} <= {16'd0, 1'b0, 16'd0};
    else begin
        case ( next_state )
            IDLE: // MAC_data_rd keeps the value last time
                {MAC_rd_data_out, MAC_rd_done} <= {16'd0, 1'b0};
            INDEX:
                {MAC_rd_data_out, MAC_rd_done, MAC_data_rd} <= {{8'd0, MAC_rd_index}, 1'b0, 16'd0};
            WRITE:
                {MAC_rd_done, MAC_data_rd} <= {1'b0, 16'd0}; // MAC_rd_data_out keeps its values
       //     DATA:
        //        {MAC_rd_data_out, MAC_rd_done, MAC_data_rd} <= {16'd0, 1'b0, 16'd0};
            READ:
                {MAC_rd_data_out, MAC_rd_done, MAC_data_rd} <= {16'd0, 1'b0, MAC_data_in};
            DONE:// MAC_data_rd keeps the value last time
                {MAC_rd_data_out, MAC_rd_done} <= {16'd0, 1'b1};
            default: 
                 {MAC_rd_data_out, MAC_rd_done, MAC_data_rd} <= {16'd0, 1'b0, 16'd0};
        endcase
    end
end
*/

always @( posedge clk ) begin
    if ( ~rst_n )
        MAC_data_rd <= 16'd0;
    else if ( next_state == READ )
        MAC_data_rd <= MAC_data_in;
end

always @( posedge clk ) begin
    if ( ~rst_n )
        MAC_rd_data_out <= 16'd0;
    else if ( next_state == INDEX )
        MAC_rd_data_out <= {8'd0, MAC_rd_index};
end

always @( posedge clk ) begin
    if ( ~rst_n )
        MAC_rd_done <= 1'b0;
    else if ( next_state == DONE )
        MAC_rd_done <= 1'b1;
    else
        MAC_rd_done <= 1'b0;
end

/*
 * MAC_rd_cmd, MAC_rd_rd_n, MAC_rd_wr_n
 */
always @( posedge clk ) begin
    if ( ~rst_n )
        {MAC_rd_cmd, MAC_rd_rd_n, MAC_rd_wr_n} <= 3'b111;
    else begin
        case ( next_state )
            INDEX: {MAC_rd_cmd, MAC_rd_rd_n, MAC_rd_wr_n} <= 3'b010;
          // WRITE: {MAC_rd_cmd, MAC_rd_rd_n, MAC_rd_wr_n} <= 3'b011; //NOTICE
            DATA:  {MAC_rd_cmd, MAC_rd_rd_n, MAC_rd_wr_n} <= 3'b101;
            default{MAC_rd_cmd, MAC_rd_rd_n, MAC_rd_wr_n} <= 3'b111;
        endcase
    end
end

endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -