OpenCores
URL https://opencores.org/ocsvn/usb_ft232h_avalon-mm_interface/usb_ft232h_avalon-mm_interface/trunk

Subversion Repositories usb_ft232h_avalon-mm_interface

[/] [usb_ft232h_avalon-mm_interface/] [trunk/] [hw/] [usb_fifos_avalon_mm_interface.sv] - Rev 6

Compare with Previous | Blame | View Log

module usb_fifos_avalon_mm_interface(
  reset_i,
  clk_i,
  
  // Avalon-MM
  address_i,
  read_i,
  readdata_o,
  readdatavalid_o,
  write_i,
  writedata_i,
  waitrequest_o,
  
  // RX FIFO
  rxf_rdclk_o,
  rxf_rdempty_i,
  rxf_rdfull_i,
  rxf_rdreq_o,
  rxf_rddata_i,
  rxf_rdusedw_i,
  
  // TX FIFO
  txf_wrclk_o,
  txf_wrfull_i,
  txf_wrreq_o,
  txf_wrdata_o,
  txf_wrusedw_i
);


parameter RX_FIFO_WIDTHU  = 9;
parameter TX_FIFO_WIDTHU  = 9;
parameter CMD_LATENCY     = 1;
parameter READ_LATENCY    = 1;
parameter WRITE_LATENCY   = 1;


localparam WRDATA_ADDR    = 3'd0;
localparam RDDATA_ADDR    = 3'd1;
localparam TXSTATUSL_ADDR = 3'd2;
localparam TXSTATUSH_ADDR = 3'd3;
localparam RXSTATUSL_ADDR = 3'd4;
localparam RXSTATUSH_ADDR = 3'd5;



input  logic                      reset_i;
input  logic                      clk_i;
  // Avalon-MM
input  logic [2:0]                address_i;
input  logic                      read_i;
output logic [7:0]                readdata_o;
output logic                      readdatavalid_o;
input  logic                      write_i;
input  logic [7:0]                writedata_i;
output logic                      waitrequest_o;
  // RX FIFO
output logic                      rxf_rdclk_o;
input  logic                      rxf_rdempty_i;
input  logic                      rxf_rdfull_i;
output logic                      rxf_rdreq_o;
input  logic [7:0]                rxf_rddata_i;
input  logic [RX_FIFO_WIDTHU-1:0] rxf_rdusedw_i;
  // TX FIFO
output logic                      txf_wrclk_o;
input  logic                      txf_wrfull_i;
output logic                      txf_wrreq_o;
output logic [7:0]                txf_wrdata_o;
input  logic [TX_FIFO_WIDTHU-1:0] txf_wrusedw_i;




logic [15:0]  txstatus;
logic [15:0]  rxstatus;


logic         read_ready;
logic         read_waitrequest;

logic         read_pipe;
logic [2:0]   address_pipe;

logic [7:0]   read_data;
logic         read_datavalid;

logic         rxf_rdreq_reg;

logic [5:0]   address_decode;
logic [5:0]   address_decode_pipe;

logic         ad_en;
logic         ad_clken;
logic         ad_en_reg;
logic [3:0]   ad_status;

logic         ad_rdata;
logic         ad_rxsl;
logic         ad_rxsh;
logic         ad_txsl;
logic         ad_txsh;




assign rxf_rdclk_o = clk_i;


// READ
assign read_ready = ~rxf_rdempty_i;
assign read_waitrequest = ad_rdata & ~read_ready;

assign ad_en = read_pipe | read_waitrequest;
assign ad_clken = (ad_en | ad_en_reg) & ~read_waitrequest;

assign ad_rdata  = address_decode_pipe[1];
assign ad_rxsl  = ad_status[2];
assign ad_rxsh  = ad_status[3];
assign ad_txsl  = ad_status[0];
assign ad_txsh  = ad_status[1];




pipeline cmd_pipe_inst (
  .clk_i   (clk_i),
  .reset_i (reset_i),
  // data source side
  .valid_i (1'b1),
  .data_i  (read_i),
  .ready_o (),
  // data destination side
  .ready_i (~read_waitrequest),
  .valid_o (),
  .data_o  (read_pipe)
  );
  defparam
    cmd_pipe_inst.LATENCY = CMD_LATENCY,
    cmd_pipe_inst.DATA_WIDTH = 1;


pipeline addr_pipe_inst (
  .clk_i   (clk_i),
  .reset_i (reset_i),
  // data source side
  .valid_i (1'b1),
  .data_i  (address_i),
  .ready_o (),
  // data destination side
  .ready_i (~read_waitrequest),
  .valid_o (),
  .data_o  (address_pipe)
  );
  defparam
    addr_pipe_inst.LATENCY = CMD_LATENCY,
    addr_pipe_inst.DATA_WIDTH = 3;


pipeline read_pipe_inst (
  .clk_i   (clk_i),
  .reset_i (reset_i),
  // data source side
  .valid_i (read_datavalid),
  .data_i  (read_data),
  .ready_o (),
  // data destination side
  .ready_i (1'b1),
  .valid_o (readdatavalid_o),
  .data_o  (readdata_o)
  );
  defparam
    read_pipe_inst.LATENCY = READ_LATENCY;
    
    
lpm_decode LPM_DECODE_component (
  .clock (clk_i),
  .data (address_pipe),
  .eq (address_decode),
  .aclr (),
  .clken (ad_clken),
  .enable (ad_en)
  );
  defparam
    LPM_DECODE_component.lpm_decodes = 6,
    LPM_DECODE_component.lpm_pipeline = 1,
    LPM_DECODE_component.lpm_type = "LPM_DECODE",
    LPM_DECODE_component.lpm_width = 3;




always_ff @(posedge clk_i)
begin
  txstatus[15]                  <= ~txf_wrfull_i; //can write
  txstatus[14:TX_FIFO_WIDTHU+1] <= 0;
  txstatus[TX_FIFO_WIDTHU]      <= txf_wrfull_i;
  txstatus[TX_FIFO_WIDTHU-1:0]  <= ( txf_wrfull_i ? {TX_FIFO_WIDTHU{1'b0}} : txf_wrusedw_i );

  rxstatus[15]                  <= ~rxf_rdempty_i; //can read
  rxstatus[14:RX_FIFO_WIDTHU+1] <= 0;
  rxstatus[RX_FIFO_WIDTHU]      <= rxf_rdfull_i;
  rxstatus[RX_FIFO_WIDTHU-1:0]  <= ( rxf_rdempty_i ? {RX_FIFO_WIDTHU{1'b0}} : rxf_rdusedw_i );
end



/* READ */
always_ff @(posedge clk_i)
begin
  if (~read_waitrequest)
    address_decode_pipe <= address_decode;
  
  ad_en_reg <= ad_en;
  
  ad_status <= address_decode_pipe[5:2];
end


always_ff @(posedge clk_i)
begin
  if (rxf_rdreq_reg)
    begin
      read_data <= rxf_rddata_i;
      read_datavalid <= 1;
    end
  else if (ad_rxsl)
    begin
      read_data <= rxstatus[7:0];
      read_datavalid <= 1;
    end
  else if (ad_rxsh)
    begin
      read_data <= rxstatus[15:8];
      read_datavalid <= 1;
    end
  else if (ad_txsl)
    begin
      read_data <= txstatus[7:0];
      read_datavalid <= 1;
    end
  else if (ad_txsh)
    begin
      read_data <= txstatus[15:8];
      read_datavalid <= 1;
    end
  else
    begin
      read_data <= 0;
      read_datavalid <= 0;
    end
end


always_ff @(negedge rxf_rdclk_o or posedge reset_i)
begin
  if (reset_i)
    begin
      rxf_rdreq_o <= 1'b0;
    end
  else
    begin
      if (ad_rdata & ~rxf_rdempty_i)
        rxf_rdreq_o <= 1'b1;
      else
        rxf_rdreq_o <= 1'b0;
    end
end


always_ff @(posedge clk_i)
begin
  rxf_rdreq_reg <= rxf_rdreq_o;
end
/*==========================================*/




/*          ----=== WRITE ===----           */

logic         write_reg;
logic         write_data_request;
logic         write_ready;
logic [7:0]   write_data;
logic         write_datavalid;
logic         write_waitrequest;

logic         txf_wrfull_reg;

logic [2:0]   write_data_addr = WRDATA_ADDR;



assign txf_wrclk_o = ~clk_i;

assign write_ready = ~txf_wrfull_reg;
assign write_datavalid = write_reg & write_data_request & write_ready;
assign write_waitrequest = ~write_ready;



lpm_compare LPM_COMPARE_component (
  .clken (1'b1),
  .clock (clk_i),
  .dataa (address_i),
  .datab (write_data_addr),
  .aeb (write_data_request),
  .aclr (reset_i),
  .agb (),
  .ageb (),
  .alb (),
  .aleb (),
  .aneb ());
  defparam
    LPM_COMPARE_component.lpm_hint = "ONE_INPUT_IS_CONSTANT=YES",
    LPM_COMPARE_component.lpm_pipeline = 1,
    LPM_COMPARE_component.lpm_representation = "UNSIGNED",
    LPM_COMPARE_component.lpm_type = "LPM_COMPARE",
    LPM_COMPARE_component.lpm_width = 3;


pipeline write_pipe_inst (
  .clk_i   (clk_i),
  .reset_i (reset_i),
  // data source side
  .valid_i (write_datavalid),
  .data_i  (write_data),
  .ready_o (),
  // data destination side
  .ready_i (write_ready),
  .valid_o (txf_wrreq_o),
  .data_o  (txf_wrdata_o)
  );
  defparam
    write_pipe_inst.LATENCY = WRITE_LATENCY;




always_ff @(posedge clk_i)
begin
  txf_wrfull_reg <= txf_wrfull_i;
end


always_ff @(posedge clk_i or posedge reset_i)
begin
  if (reset_i)
    begin
      write_data <= '0;
      write_reg <= 1'b0;
    end
  else
    begin
      if (write_i & write_ready)
        write_data <= writedata_i;
        
      if (~write_waitrequest)
        write_reg <= write_i;
    end
end
/*==========================================*/



assign waitrequest_o = (read_waitrequest & read_i) | (write_i & write_waitrequest);


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.