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

Subversion Repositories uart2bus_testbench

[/] [uart2bus_testbench/] [trunk/] [tb/] [interfaces/] [uart_interface.sv] - Rev 2

Go to most recent revision | Compare with Previous | Blame | View Log

//-----------------------------------------------------------------------------
//
//                             UART2BUS VERIFICATION
//
//-----------------------------------------------------------------------------
// CREATOR    : HANY SALAH
// PROJECT    : UART2BUS UVM TEST BENCH
// UNIT       : BUS FUNCTIONAL MODEL
//-----------------------------------------------------------------------------
// TITLE      : UART Interface 
// DESCRIPTION: This 
//-----------------------------------------------------------------------------
// LOG DETAILS
//-------------
// VERSION      NAME        DATE        DESCRIPTION
//    1       HANY SALAH    25122015    FILE CREATION
//    2       HANY SALAH    07012016    ADD USER ROUTINE, TEXT MODE ROUTINES.
//    3       HANY SALAH    21012016    REPLACE PUSH BYTE WITH PUSH FIELD
//-----------------------------------------------------------------------------
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR
// OPENCORES MEMBERS ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE 
// CREATOR'S PERMISSION
//-----------------------------------------------------------------------------
`include "defin_lib.svh"
interface uart_interface (input bit clock,        // Global Clock Signal
                          input bit reset);       // Global Asynchronous Reset Signal

//-----------------------------------------------
//
//                BFM Parameter
//
//-----------------------------------------------

  int                 act_edge;     // 2: negative edge   1: positive edge
  int                 start_bit;    // 2: LSB first       1: MSB first 
  int                 num_stop_bits;// 2: two stop bits   1: one stop bits
  int                 num_bits;     // 7: seven bits data 8: eight bits data
  int                 data_rep;     // 2: binarry         1: ASCII
  int                 parity;  // 3: parity odd      2: parity even        1: parity off
  time                response_time;


//-----------------------------------------------
//
//              UART Signals
//
//-----------------------------------------------

  logic               ser_in;         // Serial Data Input
  logic               ser_out;        // Serial Data Ouptut
  wire                serial_out;

//-----------------------------------------------
//
//              USER Variables Declarations
//
//-----------------------------------------------

  event start_trans;

  assign serial_out = 1'bz;
  assign serial_out = ser_out;

//-----------------------------------------------
//
//   USER Routines
//
//-----------------------------------------------

  // Through This routine, the uart bfm is initialize its configuration parameters
  // BFM should know through which edge it will either capture or force the data.
  // Also should know whether the sent or received data will start with most sign-
  // ificant bit or least significant bit.
  function void set_configuration ( int _edge,
                                    int first_bit,
                                    int _numstopbits,
                                    int _numbits,
                                    int _datarep,
                                    int _paritymode,
                                    time _resp);
    act_edge        = _edge;
    start_bit       = first_bit;
    num_stop_bits   = _numstopbits;
    num_bits        = _numbits;
    data_rep        = _datarep;
    parity          = _paritymode;
    response_time   = _resp;
  endfunction: set_configuration


  // Through the following routine, the uart bfm make an event that some transact-
  // -ion would be forced on UART signals
  function void set_event ();
    -> start_trans ;
  endfunction:set_event 


  function void force_sout(bit x);
    case (x)
      1'b1:
        begin
        //ser_out = `one;
        ser_out = 1'b1;
        end
      1'b0:
        begin
        //ser_out = `zero;
        ser_out = 1'b0;
        end
    endcase
  endfunction:force_sout

  // Through this routine, the uart bfm push bit on the serial ouptut port ser_out
  // based on the configured active edge field, UART will push bit on data. BFM
  // will assign testbench error in case of un-configured active edge.
  task push_bit_serout (input bit data);
    case (act_edge)
      `_negedge:
        begin
        @(negedge clock)
          begin
          force_sout(data);
          end
        end
      `_posedge:
        begin
        @(posedge clock)
          begin
          force_sout(data);
          end
        end
      default:
        begin
        $error("undefined active edge");
        end
    endcase
  endtask:push_bit_serout

  // Through this routine, the uart bfm push bit on the serial input port ser_in
  // based on the configured active edge field, UART will push bit on data. BFM
  // will assign testbench error in case of un-configured active edge.
  /*task push_bit_serin (input bit data);
    case (act_edge)
      `_negedge:
        begin
        @(negedge clock)
          begin
          ser_in = data;
          end
        end
      `_posedge:
        begin
        @(posedge clock)
          begin
          ser_in = data;
          end
        end
      default:
        begin
        $error("undefined active edge");
        end
    endcase
  endtask:push_bit_serin*/

  // The following task will catch single bit from serial output port ser_out based
  // on the configured active edge field, UART will capture data bit. BFM will
  // assign testbench error in case of un-configured active edge.
  task catch_bit_serout (output bit data);
    case (act_edge)
      `_negedge:
        begin
        @(negedge clock)
          begin
          #(`buad_clk_period/4) data = ser_out;
          end
        end
      `_posedge:
        begin
        @(posedge clock)
          begin
          #(`buad_clk_period/4) data = ser_out;
          end
        end
      default:
        begin
        $error("undefined active edge");
        end
    endcase
  endtask:catch_bit_serout

  // The following task will catch single bit from serial input port ser_in based
  // on the configured active edge field, UART will capture data bit. BFM will
  // assign testbench error in case of un-configured active edge.
  task catch_bit_serin (output bit data);
    case (act_edge)
      `_negedge:
        begin
        @(negedge clock)
          begin
          #(`buad_clk_period/4) data = ser_in;
          end
        end
      `_posedge:
        begin
        @(posedge clock)
          begin
          #(`buad_clk_period/4)data = ser_in;
          end
        end
      default:
        begin
        $error("undefined active edge");
        end
    endcase
  endtask:catch_bit_serin

  // Through the following task, UART BFM will force data byte on serial output
  // port based on the configured start_bit field. BFM will assign testbench err-
  // or in case of un-configured start_bit field.
  task push_field_serout (input byte data);
    // start bit
    push_bit_serout(1'b0);

    // data fields
    case (start_bit)
      `lsb_first:
        begin
        for (int index=0;index<8;index++)
          begin
          push_bit_serout(data[index]);
          end
        end
      `msb_first:
        begin
        for (int index=7;index>=0;index--)
          begin
          push_bit_serout(data[index]);
          end
        end
      default:
        begin
        $error("Undefined serial mode");
        end
    endcase

    // Stop bit(s)
    repeat (num_stop_bits)
      begin
      push_bit_serout(1'b1);
      end

  endtask:push_field_serout

  // Through the following task, UART BFM will force data byte on serial output
  // port based on the configured start_bit field. BFM will assign testbench err-
  // or in case of un-configured start_bit field.
  /*task push_byte_serin (input byte data);
    case (start_bit)
      `lsb_first:
        begin
        for (int index=0;index<8;index++)
          begin
          push_bit_serin(data[index]);
          end
        end
      `msb_first:
        begin
        for (int index=7;index>=0;index--)
          begin
          push_bit_serin(data[index]);
          end
        end
      default:
        begin
        $error("Undefined serial mode");
        end
    endcase
  endtask:push_byte_serin*/


  // Through the following task, UART BFM will catpure data byte from serial out-
  // put port based on the configured start_bit field. BFM will assign testbench
  // error in case of un-configured start_bit field.
  task catch_field_serout (output byte data);
    bit end_bit;

    // wait start bit
    wait(ser_out == 1'b0);
    case(start_bit)
      `lsb_first:
        begin
        for (int index=0;index<8;index++)
          begin
          catch_bit_serout(data[index]);
          end
        end
      `msb_first:
        begin
        for (int index=7;index>=0;index--)
          begin
          catch_bit_serout(data[index]);
          end
        end
      default:
        begin
        $error("Undefined serial mode");
        end
    endcase
    catch_bit_serout(end_bit);
    if(end_bit != 1'b1)
      begin
      $error("at time =%0t ,, the first end bit = %0b",$time,end_bit);
      $stop;
      end
    if (num_stop_bits == 2)
      begin
      catch_bit_serout(end_bit);
      if(end_bit != 1'b1)
        begin
        $error("at time =%0t ,, the first end bit = %0b",$time,end_bit);
        $stop;
        end
      end
  endtask:catch_field_serout

  // Through the following task, UART BFM will catpure data byte from serial out-
  // put port based on the configured start_bit field. BFM will assign testbench
  // error in case of un-configured start_bit field.
  task catch_field_serin (output byte data);
    bit end_bit;
    
    // wait start bit

    wait (ser_in == 1'b0);
    #(`buad_clk_period/2);
    case(start_bit)
      `lsb_first:
        begin
        for (int index=0;index<8;index++)
          begin
          catch_bit_serin(data[index]);
          end
        end
      `msb_first:
        begin
        for (int index=7;index>=0;index--)
          begin
          catch_bit_serin(data[index]);
          end
        end
      default:
        begin
        $error("Undefined serial mode");
        end
    endcase
    catch_bit_serin(end_bit);
    if(end_bit != 1'b1)
      begin
      $error("at time =%0t ,, the first end bit = %0b",$time,end_bit);
      $stop;
      end
    if (num_stop_bits == 2)
      begin
      catch_bit_serin(end_bit);
      if(end_bit != 1'b1)
        begin
        $error("at time =%0t ,, the first end bit = %0b",$time,end_bit);
        $stop;
        end
      end
  endtask:catch_field_serin


  // Through the following function, the byte is reversed in the manner that the
  // byte is merrored
  function byte reverse_byte (byte data);
    byte tmp;
    for (int index=0;index<8;index++)
      begin
      tmp[index] = data[7-index];
      end
    return tmp;
  endfunction:reverse_byte

//-----------------------------------------------
//
//   UART Routines
//
//-----------------------------------------------

  // Through the following method, UART BFM will initialize write request in UART
  // text mode. This task is accomplished with known of either the request chara-
  // cter is capital or small, and also the used white space type is either single
  // space or tab, and finally the end of line mechanism.
  task write_text_mode(input int alph,
                       input int scp_type1,
                       input byte space_wrong1,
                       input int scp_type2,
                       input byte space_wrong2,
                       input int eol,
                       input byte eol_wrong,
                       input bit [`size-1:0] address,
                       input byte data);
    // Write procedures
      // First Field
      if (alph == `small_let)
        begin
        push_field_serout(`w);
        end
      else if (alph == `capital_let)
        begin
        push_field_serout(`W);
        end
      else
        $error("Testbench error .. No capitar or small letter is choosed");

      // Second Field
      if (scp_type1 == `single_space)
        begin
        push_field_serout(`space);
        end
      else if (scp_type1 == `tab_space)
        begin
        push_field_serout(`tab);
        end
      else if (scp_type1 == `space_wrong)
        begin
        push_field_serout(space_wrong1);
        end
      else
        $error("Testbench error .. No single space or multiple space is choosed");

      // third field
      case (data_rep)
        `binary_rep:
          begin
          push_field_serout(data);
          end
        `ascii_rep:
          begin
          push_field_serout(bin_asci_conv(data[7:4]));
          push_field_serout(bin_asci_conv(data[3:0]));      
          end
        default:$error("undefined data representation");
      endcase

      // forth field
      if (scp_type2 == `single_space)
        begin
        push_field_serout(`space);
        end
      else if (scp_type2 == `tab_space)
        begin
        push_field_serout(`tab);
        end
      else if (scp_type2 == `space_wrong)
        begin
        push_field_serout(space_wrong2);
        end
      else
        $error("Testbench error .. No single or multiple space is choosed");
      // fivth field
      case (data_rep)
        `binary_rep:
          begin
          push_field_serout(address[15:08]);
          push_field_serout(address[07:00]);
          end
        `ascii_rep:
          begin
          push_field_serout(bin_asci_conv(address[15:12]));
          push_field_serout(bin_asci_conv(address[11:08]));
          push_field_serout(bin_asci_conv(address[07:04]));
          push_field_serout(bin_asci_conv(address[03:00]));      
          end
        default:$error("undefined data representation");
      endcase

      // sixth Field
      if (eol == `cr_eol)
        begin
        push_field_serout(`CR);
        end
      else if (eol == `lf_eol)
        begin
        push_field_serout(`LF);
        end
      else if (eol == `eol_wrong)
        begin
        push_field_serout(eol_wrong);
        end
      else
        $error("Testbench error .. either CR or LF isn't choosed as eol");
  endtask:write_text_mode

  // Through the following method, UART BFM will initialize read request in UART
  // text mode and receive the response as defined in UART specification standard
  // This task is accomplished with known of either the request character is cap-
  // ital or small, and also the used white space type is either single space or 
  // tab, and finally the end of line mechanism. This methed includes two main se-
  // ctions; the first one includes the four successive fields of defined read re-
  // quest. And the another one includes the response.
  task read_text_mode (input int alph,
                       input int scp_type,
                       input byte space_wrong,
                       input int eol,
                       input byte eol_wrong,
                       input bit [`size-1:0] address);
    byte data;
    byte temp;
    byte char1,char2;
    bit miss;
    time prope1;
    // Read Request
      // First Field
      if (alph == `small_let)
        begin
        push_field_serout(`r);
        end
      else if (alph == `capital_let)
        begin
        push_field_serout(`R);
        end
      else
        $error("Testbench error .. No capitar or small letter is choosed");
      // Second Field
      if (scp_type == `single_space)
        begin
        push_field_serout(`space);
        end
      else if (scp_type == `tab_space)
        begin
        push_field_serout(`tab);
        end
      else if (scp_type == `space_wrong)
        begin
        push_field_serout(space_wrong);
        end
      else
        $error("Testbench error .. No single or multiple white space is choosed");

      // Third Field
      case (data_rep)
        `binary_rep:
          begin
          push_field_serout(address[15:08]);
          push_field_serout(address[07:00]);
          end
        `ascii_rep:
          begin
          push_field_serout(bin_asci_conv(address[15:12]));
          push_field_serout(bin_asci_conv(address[11:08]));
          push_field_serout(bin_asci_conv(address[07:04]));
          push_field_serout(bin_asci_conv(address[03:00]));
          end
        default:$error("undefined data representation");
      endcase

      // Forth Field
      if (eol == `cr_eol)
        begin
        push_field_serout(`CR);
        end
      else if (eol == `lf_eol)
        begin
        push_field_serout(`LF);
        end
      else if (eol == `eol_wrong)
        begin
        push_field_serout(eol_wrong);
        end
      else
        $error("Testbench error .. No CR or LF is choosed");

      miss = 1'b0;       
      prope1 = $time;
      fork
        begin: miss_response_thread
        while (($time-prope1)<response_time)
          begin
          #1;
          end
        disable capture_response_thread;
        miss = 1'b1;
        end

        begin: capture_response_thread
        wait(ser_in == 1'b0);
        disable miss_response_thread;
        end
      join
      // Capture Response
      if (miss == 1'b0)
        begin
        case (data_rep)
          `binary_rep:
            begin
            catch_field_serin(data);
            end
          `ascii_rep:
            begin
            catch_field_serin(temp);
            data[7:4] = asci_bin_conv(temp);
            catch_field_serin(temp);
            data[3:0] = asci_bin_conv(temp);
            end
          default:
            begin
            $error("Undefined data representation");
            $stop;
            end
        endcase      
        catch_field_serin(char1);
        catch_field_serin(char2);
        if (char1 != `CR || char2 != `LF)
          begin
          $error("EOL is refuesed");
          end
        end
  endtask:read_text_mode

  // Write bytes of data in command mode
  task automatic write_binary_mode (input int reqack,
                                    input int reqinc,
                                    input int unsigned data_length,
                                    input bit [`size-1:0] address,
                                    ref byte data []);
    byte tmp;
    int unsigned index;

    // first byte : binary prefix
    push_field_serout(`bin_prfx);

    // second byte : command
    tmp[5:4] = 2'b10;
    if(reqinc==`_yes)
      begin
      tmp[1] = 1'b0;
      end
    else if (reqinc == `_no)
      begin
      tmp[1] = 1'b1;
      end
    else
      begin
      $error("undefined increment request");
      end

    if(reqack==`_yes)
      begin
      tmp[0] = 1'b1;
      end
    else if (reqack == `_no)
      begin
      tmp[0] = 1'b0;
      end
    else
      begin
      $error("undefined acknowledge request");
      end
    push_field_serout(tmp);

    // Third byte : higher byte of address
    push_field_serout(address[15:08]);

    // Forth byte : Lower byte of address
    push_field_serout(address[07:00]);

    // Fifth byte : data length
    push_field_serout(data_length);

    index = 0;
    while(index<data_length)
      begin
      push_field_serout(data[index]);
      index++;
      end

    if (reqack == `_yes)
      begin
      catch_field_serin(tmp);
      if (tmp != `ACK)
        begin
        $error("The captured acknowledge isn't as unified character");
        end
      end

  endtask:write_binary_mode

  // Read bytes of data in command mode
  task automatic read_binary_mode  (input int reqack,
                                    input int reqinc,
                                    input int unsigned data_length,
                                    input bit [`size-1:0] address,
                                    ref byte data []);
    byte tmp;
    int unsigned index;

    // first byte : binary prefix
    push_field_serout(`bin_prfx);

    // second byte : command
    tmp[5:4] = 2'b01;
    if(reqinc==`_yes)
      begin
      tmp[1] = 1'b0;
      end
    else if (reqinc == `_no)
      begin
      tmp[1] = 1'b1;
      end
    else
      begin
      $error("undefined increment request");
      end

    if(reqack==`_yes)
      begin
      tmp[0] = 1'b1;
      end
    else if (reqack == `_no)
      begin
      tmp[0] = 1'b0;
      end
    else
      begin
      $error("undefined acknowledge request");
      end
    push_field_serout(tmp);

    // Third byte : higher byte of address
    push_field_serout(address[15:08]);

    // Forth byte : Lower byte of address
    push_field_serout(address[07:00]);

    // Fifth byte : data length
    push_field_serout(data_length);

    index = 0;
    while(index<data_length)
      begin
      catch_field_serin(data[index]);
      index++;
      end

    if (reqack == `_yes)
      begin
      catch_field_serin(tmp);
      if (tmp != `ACK)
        begin
        $error("The captured acknowledge isn't as unified character");
        end
      end
  endtask:read_binary_mode

  // No Operation Command
  task nop_command (input int reqack,
                    input int reqinc);
    byte tmp;
    int unsigned index;
    // first byte : prefix
    push_field_serout(`bin_prfx);

    // second byte :  command
    tmp[5:4] = 2'b00;
    if(reqinc==`_yes)
      begin
      tmp[1] = 1'b0;
      end
    else if (reqinc == `_no)
      begin
      tmp[1] = 1'b1;
      end
    else
      begin
      $error("undefined increment request");
      end

    if(reqack==`_yes)
      begin
      tmp[0] = 1'b1;
      end
    else if (reqack == `_no)
      begin
      tmp[0] = 1'b0;
      end
    else
      begin
      $error("undefined acknowledge request");
      end
    push_field_serout(tmp);

    if(reqack==`_yes)
      begin
      catch_field_serin(tmp);
      if(tmp!=`ACK)
        begin
        $error("Undefined acknowledge character");
        end
      end
  endtask:nop_command

  task automatic wrong_command (input int reqack,
                                input int reqinc,
                                input byte wrong_prefix, 
                                input int unsigned data_length,
                                input bit [`size-1:0] address,
                                ref byte data []);
    byte tmp;
    int index;
    time prope1;

    push_field_serout(wrong_prefix);
    tmp[5:4] = 2'b01;
    if(reqinc==`_yes)
      begin
      tmp[1] = 1'b0;
      end
    else if (reqinc == `_no)
      begin
      tmp[1] = 1'b1;
      end
    else
      begin
      $error("undefined increment request");
      end

    if(reqack==`_yes)
      begin
      tmp[0] = 1'b1;
      end
    else if (reqack == `_no)
      begin
      tmp[0] = 1'b0;
      end
    else
      begin
      $error("undefined acknowledge request");
      end
    push_field_serout(tmp);

    // Third byte : higher byte of address
    push_field_serout(address[15:08]);

    // Forth byte : Lower byte of address
    push_field_serout(address[07:00]);

    // Fifth byte : data length
    push_field_serout(data_length);

    fork : response_thread
      begin
      index = 0;

      while(index<data_length)
        begin
        catch_field_serin(data[index]);
        index++;
        end

      if (reqack == `_yes)
        begin
        catch_field_serin(tmp);
        if (tmp != `ACK)
          begin
          $error("The captured acknowledge isn't as unified character");
          end
        end
      end

      begin
      prope1=$time;
      while (($time-prope1)< response_time)
        begin
        #1;
        end
      disable response_thread;
      end
    join

  endtask:wrong_command


  // Wait idle time
  task wait_idle_time (time idle);
    force_sout(1'b1);
    #idle;
  endtask: wait_idle_time

//-----------------------------------------------
//
//    MONITOR ROUTINES
//
//-----------------------------------------------
  
  // This routine is used to wait for transaction start
  task wait_event();
    wait (start_trans);
  endtask:wait_event

  task capture_text_read_command (output int _spacetype,
                                  output int space_wrong,
                                  output int _eoltype,
                                  output int eol_wrong,
                                  output bit [`size-1:0] address,
                                  output byte data);
    byte read_byte;
    catch_field_serout(read_byte);
    case (read_byte)
      `space:
        begin
        _spacetype  = `single_space;
        end
      `tab:
        begin
        _spacetype  = `tab_space;
        end
      default:
        begin
        _spacetype  = `space_wrong;
        space_wrong = read_byte;
        end
    endcase

    case(data_rep)
      `binary_rep:
        begin
        catch_field_serout(read_byte);
        address[15:08] = read_byte;
        catch_field_serout(read_byte);
        address[07:00] = read_byte;
        end
      `ascii_rep:
        begin
        catch_field_serout(read_byte);
        address[15:12] = asci_bin_conv(read_byte);
        catch_field_serout(read_byte);
        address[11:08] = asci_bin_conv(read_byte);
        catch_field_serout(read_byte);
        address[07:04] = asci_bin_conv(read_byte);
        catch_field_serout(read_byte);
        address[03:00] = asci_bin_conv(read_byte);
        end
      default:
        begin
        $error("undefined data representation");
        $stop;
        end
    endcase

    catch_field_serout(read_byte);
    case(read_byte)
      `CR:
        begin
        _eoltype    = `cr_eol;
        end
      `LF:
        begin
        _eoltype    = `lf_eol;
        end
      default:
        begin
        _eoltype    = `eol_wrong;
        eol_wrong   = read_byte;
        end
    endcase

    case(data_rep)
      `binary_rep:
        begin
        catch_field_serin(read_byte);
        data = read_byte;
        end
      `ascii_rep:
        begin
        catch_field_serin(read_byte);
        data[7:4] = bin_asci_conv(read_byte);
        catch_field_serin(read_byte);
        data[3:0] = bin_asci_conv(read_byte);
        end
      default:
        begin
        $error("undefined data representation");
        $stop;
        end
    endcase

    catch_field_serin(read_byte);
    if (read_byte == `CR)
      begin
      catch_field_serin(read_byte);
      if (read_byte != `LF)
        begin
        $error("the catpured byte isn't LF");
        end
      end
    else if (read_byte == `LF)
      begin
      $error("The captured byte is LF instead of CR");
      end
    else
      begin
      $error("Fatal Error : final character in read request isn't CR and LF");
      end
  endtask:capture_text_read_command


  task capture_text_write_command ( output int _spacetype1,
                                    output int space_wrong1,
                                    output int _spacetype2,
                                    output int space_wrong2,
                                    output int _eoltype,
                                    output int eol_wrong,
                                    output bit [`size-1:0] address,
                                    output byte data);

    byte read_byte;
    catch_field_serout(read_byte);
    case (read_byte)
      `space:
        begin
        _spacetype1  = `single_space;
        end
      `tab:
        begin
        _spacetype1  = `tab_space;
        end
      default:
        begin
        _spacetype1  = `space_wrong;
        space_wrong1 = read_byte;
        end
    endcase

    case(data_rep)
      `binary_rep:
        begin
        catch_field_serout(read_byte);
        data = read_byte;
        end
      `ascii_rep:
        begin
        catch_field_serout(read_byte);
        data[7:4] = asci_bin_conv(read_byte);
        catch_field_serout(read_byte);
        data[3:0] = asci_bin_conv(read_byte);
        end
      default:
        begin
        $error("undefined data representation");
        $stop;
        end
    endcase

    catch_field_serout(read_byte);
    case (read_byte)
      `space:
        begin
        _spacetype2  = `single_space;
        end
      `tab:
        begin
        _spacetype2  = `tab_space;
        end
      default:
        begin
        _spacetype2  = `space_wrong;
        space_wrong2 = read_byte;
        end
    endcase

    case(data_rep)
      `binary_rep:
        begin
        catch_field_serout(read_byte);
        address[15:08] = read_byte;
        catch_field_serout(read_byte);
        address[07:00] = read_byte;
        end
      `ascii_rep:
        begin
        catch_field_serout(read_byte);
        address[15:12] = asci_bin_conv(read_byte);
        catch_field_serout(read_byte);
        address[11:08] = asci_bin_conv(read_byte);
        catch_field_serout(read_byte);
        address[07:04] = asci_bin_conv(read_byte);
        catch_field_serout(read_byte);
        address[03:00] = asci_bin_conv(read_byte);
        end
      default:
        begin
        $error("Undefined data representation");
        $stop;
        end
    endcase

    catch_field_serout(read_byte);
    case(read_byte)
      `CR:
        begin
        _eoltype    = `cr_eol;
        end
      `LF:
        begin
        _eoltype    = `lf_eol;
        end
      default:
        begin
        _eoltype    = `eol_wrong;
        eol_wrong   = read_byte;
        end
    endcase
  endtask: capture_text_write_command

  task automatic capture_binary_command (output int _command,
                                         output int _reqack,
                                         output int _reqinc,
                                         output bit [15:0] address,
                                         output int data_length,
                                         ref byte data [ ],
                                         output byte acknowledge);
    byte read_byte;
    int index;
    byte que [$];
    // first byte
    catch_field_serout(read_byte);
    case(read_byte[5:4])
      `nop_ctrl:
        begin
        _command = `nop_comm;
        end
      `read_ctrl:
        begin
        _command = `read_comm;
        end
      `write_ctrl:
        begin
        _command = `write_comm;
        end
      default:
        begin
        $error("undefined 2-bits command");
        end
    endcase
    if (read_byte[1])
      begin
      _reqinc = `_no;
      end
    else
      begin
      _reqinc = `_yes;
      end
    if (read_byte[0])
      begin
      _reqack = `_yes;
      end
    else
      begin
      _reqack = `_no;
      end

    catch_field_serout(read_byte);
    address[15:08] = read_byte;

    catch_field_serout(read_byte);
    address[07:00] = read_byte;

    catch_field_serout(read_byte);
    if (read_byte == 8'h00)
      begin
      data_length = 256;
      end
    else
      begin
      data_length = read_byte;
      end

    que.delete();
    case (_command)
      `read_comm:
        begin
        index=0;
        while(index < data_length)
          begin
          catch_field_serin(read_byte);
          que.push_back(read_byte);
          index++;
          end
        end
      `write_comm:
        begin
        index=0;
        while(index < data_length)
          begin
          catch_field_serout(read_byte);
          que.push_back(read_byte);
          index++;
          end
        end
      default:
        begin
        $error("Undefined Command");
        end
    endcase

    data = new [que.size];
    data = que;
    catch_field_serin(acknowledge);
  endtask:capture_binary_command

  // General Capture Command Routine
  task automatic capture_command (output int command_type,
                                  output int _command,
                                  output int _chartype,
                                  output int _spacetype1,
                                  output int space_wrong1,
                                  output int _spacetype2,
                                  output int space_wrong2,
                                  output int _eoltype,
                                  output int eol_wrong,
                                  output bit [`size-1:0] address,
                                  ref byte data [],
                                  output byte acknowledge,
                                  output int unsigned data_length,
                                  output int _reqack,
                                  output int _reqinc);

    byte read_byte;
    catch_field_serout(read_byte);
    case (read_byte)
      `w:
        begin
        command_type  = `text_mode;
        _command      = `write_comm;
        _chartype     = `small_let;
        data = new [1];
        capture_text_write_command(_spacetype1,
                                   space_wrong1,
                                   _spacetype2,
                                   space_wrong2,
                                   _eoltype,
                                   eol_wrong,
                                   address,
                                   data[0]);
        end
      `W:
        begin
        command_type  = `text_mode;
        _command      = `write_comm;
        _chartype     = `capital_let;
        data = new[1];
        capture_text_write_command(_spacetype1,
                                   space_wrong1,
                                   _spacetype2,
                                   space_wrong2,
                                   _eoltype,
                                   eol_wrong,
                                   address,
                                   data[0]);
        end
      `r:
        begin
        command_type  = `text_mode;
        _command      = `read_comm;
        _chartype     = `small_let;
        data = new[1];
        capture_text_read_command(_spacetype1,
                                  space_wrong1,
                                  _eoltype,
                                  eol_wrong,
                                  address,
                                  data[0]);
        end
      `R:
        begin
        command_type  = `text_mode;
        _command      = `read_comm;
        _chartype     = `capital_let;
        data = new [1];
        capture_text_read_command(_spacetype1,
                                  space_wrong1,
                                  _eoltype,
                                  eol_wrong,
                                  address,
                                  data[0]);
        end
      `bin_prfx:
        begin
        command_type  = `binary_mode;
        capture_binary_command(_command,
                               _reqack,
                               _reqinc,
                               address,
                               data_length,
                               data,
                               acknowledge);
        end
      default:
        begin
        command_type  = `wrong_mode;
        _command      = `wrong_comm;
        end
    endcase
  endtask:capture_command
endinterface:uart_interface

Go to most recent revision | 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.