МАРСОХОД

Open Source Hardware Project

Модуль USB передатчика

//
//simplest low speed USB send function
//

module ls_usb_send(

    //clock should be 5Mhz
    input wire clk,
    input wire reset,
    input wire EOP,

    input wire [7:0]sbyte,  //byte for send
    input wire start_pkt,    //start sending packet on that signal
    input wire last_pkt_byte,  //mean send EOP at the end

    //usb BUS signals
    output reg sbit,
    output reg dp,
    output reg dm,
    
    output reg  bus_enable,
    output reg  show_next,    //on that signal core should send next byte for send and flag for last packet byte
    output wire six_ones,
    output reg strobe
    );

parameter SPEED_FACTOR = 19;

assign six_ones = (ones_cnt==3'h6);

reg my_eop;

always @*
begin
    sbit = (prev_sbit^(!send_reg[0])^(six_ones&send_reg[0])) | (~bus_ena);
        
    show_next = bit_count_eq7 & strobe & (!six_ones) & bus_ena;
    bus_enable = bus_ena | bus_ena_prev[2];
    my_eop = !(bus_ena ^ (bus_ena | bus_ena_prev[1]));
end

always @(posedge clk)
begin
    dm <=   sbit  & my_eop;
    dp <= (!sbit) & my_eop;
end

//generate send strobes only when bus enabled 
reg [5:0]clk_counter;

always @(posedge clk)
begin
    if(start_pkt)
    begin
        strobe <= 1'b0;
        clk_counter <= 0;
    end
    else
        { strobe , clk_counter } <= clk_counter + SPEED_FACTOR;
end

reg [2:0]bus_ena_prev;
always @(posedge clk)
begin
    if(strobe)
        bus_ena_prev <= {bus_ena_prev[1:0],bus_ena};
end

reg [2:0]ones_cnt;
always @(posedge clk)
begin
    if(strobe)
    begin
        if(sbit==prev_sbit && bus_ena)
            ones_cnt <= ones_cnt+1'b1;
        else
            ones_cnt <= 0;
    end
end

reg [7:0]send_reg;
always @(posedge clk)
begin
    if(strobe & bus_ena & (!six_ones) )
    begin
        if(bit_count_eq7)
            send_reg <= sbyte;
        else
            send_reg <= {1'b0, send_reg[7:1]};
    end
end

reg [2:0]bit_count;
wire bit_count_eq7; assign bit_count_eq7 = (bit_count==3'h7);
always @(posedge clk)
begin
    if(~bus_ena)
        bit_count <= 7;
    else
    if(strobe & (!six_ones) )
        bit_count <= bit_count + 1'b1;
end

reg prev_sbit;
always @(posedge clk)
    if(strobe)
        prev_sbit <= sbit & bus_ena;

reg bus_ena;
always @(posedge clk)
begin
    if( show_next | start_pkt )
        bus_ena <= ~last_pkt_byte;
end

endmodule

facebook  GitHub  YouTube  Twitter
Вы здесь: Начало Проекты Примеры программ Модуль USB передатчика