HierarchyFilesModulesSignalsTasksFunctionsHelp
//-----------------------------------------------------------------------------
// customised example Cortex-M0 controller UART with file logging
// A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license.
//
// Contributors
//
// David Flynn (d.w.flynn@soton.ac.uk)
//
// Copyright © 2022, SoC Labs (www.soclabs.org)
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Abstract : FT1248 1-bit data off-chip interface (emulate FT232H device)
// and allows cmsdk_uart_capture testbench models to log ADP ip, op streams
//-----------------------------------------------------------------------------


[Up: tb_cmsdk_mcu u_ft1248_adpio]
module cmsdk_ft1248x1_adpioIndex
  #(parameter ADPFILENAME = "adp.cmd",
    parameter VERBOSE = 0)
  (
  input  wire  ft_clk_i,         // SCLK
  input  wire  ft_ssn_i,         // SS_N
  output wire  ft_miso_o,        // MISO
  inout  wire  ft_miosio_io,     // MIOSIO tristate output when enabled

  output wire       FTDI_CLK2UART_o, // Clock (baud rate)
  output wire       FTDI_OP2UART_o, // Received data to UART capture
  output wire       FTDI_IP2UART_o  // Transmitted data to UART capture
  );


 //----------------------------------------------
 //-- File I/O
 //----------------------------------------------


   integer        fdcmd;       // channel descriptor for cmd file input
   integer        ch;
`define EOF -1

   reg       ft_rxreq;
   wire      ft_rxack;
   reg [7:0] ft_adpbyte;
   
   initial
     begin
       ft_rxreq <= 0;
       $timeformat(-9, 0, " ns", 14);
       fdcmd= $fopen(ADPFILENAME,"r");
       if (fdcmd == 0)
          $write("** FT1248x1 : no command file **\n");
       else begin
         ch =  $fgetc(fdcmd);
         while (ch != `EOF) begin
           ft_adpbyte <= (ch & 8'hff);
           ft_rxreq <= 1'b1;
           while (ft_ssn_i == 1'b0)
             @(posedge ft_ssn_i);
           @(posedge ft_rxack);
           ft_rxreq <=0;
           @(negedge ft_rxack);
           ch =  $fgetc(fdcmd);
         end
       end
       $fclose(fdcmd);
       ft_rxreq <= 0;
     end
     

//----------------------------------------------
//-- State Machine
//----------------------------------------------

wire ft_miosio_i;
wire ft_miosio_o;
wire ft_miosio_z;

// tri-state pad control for MIOSIO
assign ft_miosio_io = (ft_miosio_z) ? 1'bz : ft_miosio_o;
// add notinal delay on inout to ensure last "half-bit" on FT1248TXD is sampled before tri-stated
assign #1 ft_miosio_i  = ft_miosio_io;

reg [4:0] ft_state; // 17-state for bit-serial
wire [5:0] ft_nextstate = ft_state + 5'b00001;

always @(posedge ft_clk_i or posedge ft_ssn_i)
  if (ft_ssn_i)
    ft_state <= 5'b11111;
  else // loop if multi-data
//    ft_state <= (ft_state == 5'b01111) ? 5'b01000 : ft_nextstate;
    ft_state <= ft_nextstate;

// 16: bus turnaround (or bit[5])
// 0 for CMD3
// 3 for CMD2
// 5 for CMD1
// 6 for CMD0
// 7 for cmd turnaround
// 8 for data bit0
// 9 for data bit1
// 10 for data bit2
// 11 for data bit3
// 12 for data bit4
// 13 for data bit5
// 14 for data bit6
// 15 for data bit7

// ft_miso_o reflects RXE when deselected
assign ft_miso_o = (ft_ssn_i) ? !ft_rxreq : (ft_state == 5'b00111);

// capture CMD on falling edge of clock (mid-data)
// - valid sample ready after 7th edge (ready RX or TX data phase functionality)
reg [7:0] ft_cmd;
always @(negedge ft_clk_i or posedge ft_ssn_i)
  if (ft_ssn_i)
    ft_cmd <= 8'b00000001;
  else // shift in data
    ft_cmd <= (!ft_state[3] & !ft_nextstate[3]) ? {ft_cmd[6:0],ft_miosio_i} : ft_cmd;

wire ft_cmd_valid = ft_cmd[7];
wire ft_cmd_rxd =  ft_cmd[7] & !ft_cmd[6] & !ft_cmd[3] & !ft_cmd[1] &  ft_cmd[0];
wire ft_cmd_txd =  ft_cmd[7] & !ft_cmd[6] & !ft_cmd[3] & !ft_cmd[1] & !ft_cmd[0];

// tristate enable for miosio (deselected status or serialized data for read command)
wire ft_miosio_e = ft_ssn_i | (ft_cmd_rxd & !ft_state[4] & ft_state[3]);
assign ft_miosio_z = !ft_miosio_e;

// serial data formatted with start bit for UART capture (on rising uart-clock)
assign   FTDI_CLK2UART_o = !ft_clk_i;
// suitable for CMSDK UART capture IO
// inject a start bit low else mark high
assign FTDI_OP2UART_o = (ft_cmd_txd & (ft_state[4:3]) == 2'b01) ? ft_miosio_i : !(ft_cmd_txd & (ft_state == 5'b00111)); 
assign FTDI_IP2UART_o = (ft_cmd_rxd & (ft_state[4:3]) == 2'b01) ? ft_miosio_io : !(ft_cmd_rxd & (ft_state == 5'b00111));

// capture RXD on falling edge of clock
reg [8:0] ft_rxd;
always @(negedge ft_clk_i or posedge ft_ssn_i)
  if (ft_ssn_i)
    ft_rxd <= 9'b111111111;
  else if (ft_cmd_txd & !(ft_miosio_i & (&ft_rxd[8:0])))  //only on valid start-bit
    ft_rxd <= {ft_miosio_i, ft_rxd[8:1]};

// shift TXD on rising edge of clock
reg [8:0] ft_txd;
always @(posedge ft_clk_i or posedge ft_ssn_i)
  if (ft_ssn_i)
    ft_txd <= {1'b1,ft_adpbyte};
  else if (ft_rxreq & ft_cmd_rxd & (ft_state[4:3] == 2'b01))  //valid TX shift
    ft_txd <= {1'b0,ft_txd[8:1]};

assign ft_rxack = (ft_cmd_rxd & (ft_state==5'b01111));
  
// ft_miso_o reflects TXF when deselected (never full for simulation output)
assign ft_miosio_o =  (ft_ssn_i) ? 1'b0 : ft_txd[0];

endmodule

HierarchyFilesModulesSignalsTasksFunctionsHelp

This page: Created:Wed Feb 22 13:33:07 2023
From: ../verilog/cmsdk_ft1248x1_adpio.v

Verilog converted to html by v2html 7.30.1.3 (written by Costas Calamvokis).Help