在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 4079|回复: 4

[求助] 有人看过uvm_ref_flow_1.1里的uart组件么?

[复制链接]
发表于 2013-12-5 09:29:03 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
本帖最后由 oscillator_cn1 于 2013-12-5 09:30 编辑

各位:      关于uart的采样频率,我有点不大明白。sample_clk是对interface上的时钟进行计数,等于{cfg.baud_rate_div,cfg.baud_rate_gen}的时候开始采样,那我不大清楚,验证的时候该依据什么来配置这两个值。而且,不是说异步的嘛,为什么rx和tx都用同样的配置。
      我知道我这样说没有语境,因此,贴上rx_driver、transfer和interface的代码。
dirver:




  1. `ifndef UART_RX_DRIVER
  2. `define UART_RX_DRIVER

  3. class uart_rx_driver extends uvm_driver #(uart_frame) ;

  4.   // The virtual interface used to drive and view HDL signals.
  5.   virtual interface uart_if vif;

  6.   // handle to  a cfg class
  7.   uart_config cfg;

  8.   bit sample_clk;
  9.   bit [15:0] ua_brgr;
  10.   bit [7:0] ua_bdiv;
  11.   int num_of_bits_sent;
  12.   int num_frames_sent;

  13.   // Provide implementations of virtual methods such as get_type_name and create
  14.   `uvm_component_utils_begin(uart_rx_driver)
  15.     `uvm_field_object(cfg, UVM_DEFAULT | UVM_REFERENCE)
  16.     `uvm_field_int(ua_brgr, UVM_DEFAULT + UVM_NOPRINT)
  17.     `uvm_field_int(ua_bdiv, UVM_DEFAULT + UVM_NOPRINT)
  18.   `uvm_component_utils_end

  19.   // Constructor - required UVM syntax
  20.   function new(string name, uvm_component parent);
  21.     super.new(name,parent);
  22.   endfunction

  23.   // Additional class methods
  24.   extern virtual function void build_phase(uvm_phase phase);
  25.   extern virtual function void connect_phase(uvm_phase phase);
  26.   extern virtual task run_phase(uvm_phase phase);
  27.   extern virtual task reset();
  28.   extern virtual task get_and_drive();
  29.   extern virtual task gen_sample_rate(ref bit [15:0] ua_brgr, ref bit sample_clk);
  30.   extern virtual task send_rx_frame(input uart_frame frame);
  31.   extern virtual function void report_phase(uvm_phase phase);
  32.   
  33. endclass : uart_rx_driver

  34. // UVM build_phase
  35. function void uart_rx_driver::build_phase(uvm_phase phase);
  36.     super.build_phase(phase);
  37.     if(cfg == null)
  38.       if (!uvm_config_db#(uart_config)::get(this, "", "cfg", cfg))
  39.        `uvm_error("NOCONFIG", "uart_config not set for this component")
  40. endfunction : build_phase

  41. //UVM connect_phase
  42. function void uart_rx_driver::connect_phase(uvm_phase phase);
  43.   super.connect_phase(phase);
  44.   if (!uvm_config_db#(virtual uart_if)::get(this, "", "vif", vif))
  45.    `uvm_error("NOVIF",{"virtual interface must be set for: ",get_full_name(),".vif"})
  46. endfunction : connect_phase

  47. //UVM run_phase
  48. task uart_rx_driver::run_phase(uvm_phase phase);
  49.   fork
  50.     get_and_drive();
  51.     gen_sample_rate(ua_brgr, sample_clk);
  52.   join
  53. endtask : run_phase

  54. // reset
  55. task uart_rx_driver::reset();
  56.   @(negedge vif.reset);
  57.   `uvm_info(get_type_name(), "Reset Asserted", UVM_MEDIUM)
  58.    vif.rxd = 1;        //Receive Data
  59.    vif.cts_n = 0;      //Clear to Send
  60.    vif.dsr_n = 0;      //Data Set Ready
  61.    vif.ri_n = 0;       //Ring Indicator
  62.    vif.baud_clk = 0;   //Baud Clk - NOT USED
  63. endtask : reset

  64. //  get_and drive
  65. task uart_rx_driver::get_and_drive();
  66.   while (1) begin
  67.     reset();
  68.     fork
  69.       @(negedge vif.reset)
  70.         `uvm_info(get_type_name(), "Reset asserted", UVM_LOW)
  71.     begin
  72.       forever begin
  73.         @(posedge vif.clock iff (vif.reset))
  74.         seq_item_port.get_next_item(req);
  75.         send_rx_frame(req);
  76.         seq_item_port.item_done();
  77.       end
  78.     end
  79.     join_any
  80.     disable fork;
  81.     //If we are in the middle of a transfer, need to end the rx. Also,
  82.     //do any reset cleanup here. The only way we got to this point is via
  83.     //a reset.
  84.     if(req.is_active()) this.end_tr(req);
  85.   end
  86. endtask : get_and_drive

  87. task uart_rx_driver::gen_sample_rate(ref bit [15:0] ua_brgr, ref bit sample_clk);
  88.   forever begin
  89.     @(posedge vif.clock);
  90.     if (!vif.reset) begin
  91.       ua_brgr = 0;
  92.       sample_clk = 0;
  93.     end else begin
  94.       if (ua_brgr == ({cfg.baud_rate_div, cfg.baud_rate_gen})) begin
  95.         ua_brgr = 0;
  96.         sample_clk = 1;
  97.       end else begin
  98.         sample_clk = 0;
  99.         ua_brgr++;
  100.       end
  101.     end
  102.   end
  103. endtask : gen_sample_rate

  104. // -------------------
  105. // send_rx_frame
  106. // -------------------
  107. task uart_rx_driver::send_rx_frame(input uart_frame frame);
  108.   bit [7:0] payload_byte;
  109.   num_of_bits_sent = 0;

  110.   `uvm_info(get_type_name(),
  111.             $psprintf("Driver Sending RX Frame...\n%s", frame.sprint()),
  112.             UVM_HIGH)

  113.   repeat (frame.transmit_delay)
  114.     @(posedge vif.clock);
  115.   void'(this.begin_tr(frame));
  116.    
  117.   wait((!cfg.rts_en)||(!vif.cts_n));
  118.   `uvm_info(get_type_name(), "Driver - Modem RTS or CTS asserted", UVM_HIGH)

  119.   while (num_of_bits_sent <= (1 + cfg.char_len_val + cfg.parity_en + cfg.nbstop)) begin
  120.     @(posedge vif.clock);
  121.     #1;
  122.     if (sample_clk) begin
  123.       if (num_of_bits_sent == 0) begin
  124.         // Start sending rx_frame with "start bit"
  125.         vif.rxd = frame.start_bit;
  126.         `uvm_info(get_type_name(),
  127.                   $psprintf("Driver Sending Frame SOP: %b", frame.start_bit),
  128.                   UVM_HIGH)
  129.       end
  130.       if ((num_of_bits_sent > 0) && (num_of_bits_sent < (1 + cfg.char_len_val))) begin
  131.         // sending "data bits"
  132.         payload_byte = frame.payload[num_of_bits_sent-1] ;
  133.         vif.rxd = frame.payload[num_of_bits_sent-1];
  134.         `uvm_info(get_type_name(),
  135.              $psprintf("Driver Sending Frame data bit number:%0d value:'b%b",
  136.              (num_of_bits_sent-1), payload_byte), UVM_HIGH)
  137.       end
  138.       if ((num_of_bits_sent == (1 + cfg.char_len_val)) && (cfg.parity_en)) begin
  139.         // sending "parity bit" if parity is enabled
  140.         vif.rxd = frame.calc_parity(cfg.char_len_val, cfg.parity_mode);
  141.         `uvm_info(get_type_name(),
  142.              $psprintf("Driver Sending Frame Parity bit:'b%b",
  143.              frame.calc_parity(cfg.char_len_val, cfg.parity_mode)), UVM_HIGH)
  144.       end
  145.       if (num_of_bits_sent == (1 + cfg.char_len_val + cfg.parity_en)) begin
  146.         // sending "stop/error bits"
  147.         for (int i = 0; i < cfg.nbstop; i++) begin
  148.           `uvm_info(get_type_name(),
  149.                $psprintf("Driver Sending Frame Stop bit:'b%b",
  150.                frame.stop_bits[i]), UVM_HIGH)
  151.           wait (sample_clk);
  152.           if (frame.error_bits[i]) begin
  153.             vif.rxd = 0;
  154.             `uvm_info(get_type_name(),
  155.                  $psprintf("Driver intensionally corrupting Stop bit since error_bits['b%b] is 'b%b", i, frame.error_bits[i]),
  156.                  UVM_HIGH)
  157.           end else
  158.           vif.rxd = frame.stop_bits[i];
  159.           num_of_bits_sent++;
  160.           wait (!sample_clk);
  161.         end
  162.       end
  163.     num_of_bits_sent++;
  164.     wait (!sample_clk);
  165.     end
  166.   end
  167.   
  168.   num_frames_sent++;
  169.   `uvm_info(get_type_name(),
  170.        $psprintf("Frame **%0d** Sent...", num_frames_sent), UVM_MEDIUM)
  171.   wait (sample_clk);
  172.   vif.rxd = 1;

  173.   `uvm_info(get_type_name(), "Frame complete...", UVM_MEDIUM)
  174.   this.end_tr(frame);
  175.    
  176. endtask : send_rx_frame

  177. //UVM report_phase
  178. function void uart_rx_driver::report_phase(uvm_phase phase);
  179.   `uvm_info(get_type_name(),
  180.        $psprintf("UART Frames Sent:%0d", num_frames_sent),
  181.        UVM_LOW )
  182. endfunction : report_phase

  183. `endif // UART_RX_DRIVER


复制代码


transfer:




  1. `ifndef UART_FRAME_SVH
  2. `define UART_FRAME_SVH

  3. // Parity Type Control knob
  4. typedef enum bit {GOOD_PARITY, BAD_PARITY} parity_e;

  5. class uart_frame extends uvm_sequence_item;  //lab1_note1
  6.   // UART Frame
  7.   rand bit start_bit;
  8.   rand bit [7:0] payload;
  9.   bit parity;
  10.   rand bit [1:0] stop_bits;
  11.   rand bit [3:0] error_bits;

  12.   // Control Knobs
  13.   rand parity_e parity_type;
  14.   rand int transmit_delay;

  15.   // Default constraints  //lab1_note2
  16.   constraint default_txmit_delay {transmit_delay >= 0; transmit_delay < 20;}
  17.   constraint default_start_bit { start_bit == 1'b0;}
  18.   constraint default_stop_bits { stop_bits == 2'b11;}
  19.   constraint default_parity_type { parity_type==GOOD_PARITY;}
  20.   constraint default_error_bits { error_bits == 4'b0000;}

  21.   // These declarations implement the create() and get_type_name()
  22.   // and enable automation of the uart_frame's fields     //lab1_note3
  23.   `uvm_object_utils_begin(uart_frame)   
  24.     `uvm_field_int(start_bit, UVM_DEFAULT)
  25.     `uvm_field_int(payload, UVM_DEFAULT)  
  26.     `uvm_field_int(parity, UVM_DEFAULT)  
  27.     `uvm_field_int(stop_bits, UVM_DEFAULT)
  28.     `uvm_field_int(error_bits, UVM_DEFAULT)
  29.     `uvm_field_enum(parity_e,parity_type, UVM_DEFAULT + UVM_NOCOMPARE)
  30.     `uvm_field_int(transmit_delay, UVM_DEFAULT + UVM_DEC + UVM_NOCOMPARE + UVM_NOCOPY)
  31.   `uvm_object_utils_end

  32.   // Constructor - required UVM syntax  //lab1_note4
  33.   function new(string name = "uart_frame");
  34.     super.new(name);
  35.   endfunction
  36.    
  37.   // This method calculates the parity
  38.   function bit calc_parity(int unsigned num_of_data_bits=8,
  39.                            bit[1:0] ParityMode=0);
  40.     bit temp_parity;

  41.     if (num_of_data_bits == 6)
  42.       temp_parity = ^payload[5:0];  
  43.     else if (num_of_data_bits == 7)
  44.       temp_parity = ^payload[6:0];  
  45.     else
  46.       temp_parity = ^payload;  

  47.     case(ParityMode[0])
  48.       0: temp_parity = ~temp_parity;
  49.       1: temp_parity = temp_parity;
  50.     endcase
  51.     case(ParityMode[1])
  52.       0: temp_parity = temp_parity;
  53.       1: temp_parity = ~ParityMode[0];
  54.     endcase
  55.     if (parity_type == BAD_PARITY)
  56.       calc_parity = ~temp_parity;
  57.     else
  58.       calc_parity = temp_parity;
  59.   endfunction

  60.   // Parity is calculated in the post_randomize() method   //lab1_note5
  61.   function void post_randomize();
  62.    parity = calc_parity();
  63.   endfunction : post_randomize

  64. endclass

  65. `endif


复制代码

interface:




  1. interface uart_if(input clock, reset);

  2.   logic txd;    // Transmit Data
  3.   logic rxd;    // Receive Data
  4.   
  5.   logic intrpt;  // Interrupt

  6.   logic ri_n;    // ring indicator
  7.   logic cts_n;   // clear to send
  8.   logic dsr_n;   // data set ready
  9.   logic rts_n;   // request to send
  10.   logic dtr_n;   // data terminal ready
  11.   logic dcd_n;   // data carrier detect

  12.   logic baud_clk;  // Baud Rate Clock
  13.   
  14.   // Control flags
  15.   bit                has_checks = 1;
  16.   bit                has_coverage = 1;

  17. /*  FIX TO USE CONCURRENT ASSERTIONS
  18.   always @(posedge clock)
  19.   begin
  20.     // rxd must not be X or Z
  21.     assertRxdUnknown:assert property (
  22.                        disable iff(!has_checks || !reset)(!$isunknown(rxd)))
  23.                        else
  24.                          $error("ERR_UART001_Rxd_XZ\n Rxd went to X or Z");
  25.   end
  26. */

  27. endinterface : uart_if


复制代码
发表于 2013-12-5 17:56:23 | 显示全部楼层
波特率是由你要测试的目的和dut决定的
异步并不是指tx和rx之间,指的是接收端和发送端所使用的时钟是否一样
 楼主| 发表于 2013-12-6 09:31:52 | 显示全部楼层
回复 2# allangoing

谢谢!也就是说我要试不同的配置以观察波特率?另外,不光是tx与rx采用一样的sample_clk,我看monitor那边也是这样弄的,driver是发送方,monitor是接收方对吧。
发表于 2013-12-12 17:08:54 | 显示全部楼层
回复 1# oscillator_cn1


  我目前也在看这个例子,有机会交流学习一下。q:466183347
发表于 2017-7-10 15:47:53 | 显示全部楼层
回复 1# oscillator_cn1

看看
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条

小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-9-22 03:31 , Processed in 0.029170 second(s), 10 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表