SystemVerilog课程笔记(三)

1. DUT——router功能概述

1.1管脚图

以router(路由器)为例

1.2输入输出信号

左边是输入:16位的din(数据输入)、16位的frame_n(数据帧有效,低电平有效)、16位的valid_n(有效信号,低电平有效)、reset_n(低电平复位)和clock(时钟)
右边是输出:16位的dout(数据输出)、16位的dout(数据输出)、16位的frameo_n(数据帧输出有效)、16位的valido_n(输出有效信号,低电平有效)

1.3模块功能

16个输入的通道,选一个通道作为输入通道,同样的,16个输出的通道,也是选一个通道作为输出通道,数据是一bit一bit地传输。
例如,选择din[7]为数据的输入通道,所以frame_n[7]和valid_n[7]就是控制信号;选择dout[3]为数据的输出通道,所以frameo_n[3]和valido_n[3]就是控制信号。因此数据会从7号输入通道输入,然后从3号通道输出,路由器的功能就是这么简单。

1.4输入信号协议

din信号
1.din[i]中的i表示从哪路输入,din中的第一段4bit的数据表示输出地址(低位开始),从哪路输出
2.地址传输完毕后拉高进入隔离段
3.隔离段结束后开始传输数据(低位开始)
frame_n信号
1.下降沿指示packet的第一位数据
2.上升沿指示packet的最后一位数据
valid_n信号
1.其在din的地址输入时间段可为任意值x
2.在隔离段pad拉高
3.其拉低时表示数据有效,因此在payload段若其拉高,则din数据无效
4.数据输入完毕后拉高

1.5输出信号协议

输出信号时序图如上,比较简单,当valido_n和frameo_n均为低时数据有效,除了packet最后一位输出数据时frameo_n为高 。

1.6复位信号协议

以上为其复位协议时序图,有以下几点需要注意:
1.复位时,reset_n为低电平,frame_n和valid_n为高电平
2.有效复位至少保持1个clk
3.复位后至少等待15个时钟周期后才可以发送数据

2. 实验代码

2.1 router代码

DUT:router代码如下:

// control pins:
// input: reset_n - active low reset
// input: clock   - master clock input

// input port pins:
// input: frame_n - must be active during whole input packet
// input: valid_n - valid data input
// input: di    - the data input
// output: busy_n - tells input that connection is busy

// output port pins:
// output: do   - the data output
// output: valido_n - tells output device that "do" contain valid data
// output: frameo_n - active during the whole output packet
// frame format:
//
// Frame start must look like this:
//
// frame_n: |  1 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0  | ...
// di:    |  X | A0 | A1 | A2 | A3 |  1 |  X |  X |  X | D0  | ...
// valid_n: |  X |  X |  X |  X |  X |  X |  1 |  1 |  1 | 0/1 | ...
//
// note1: frame_n must deasserted at least one cycle between packets.
// note2: address data does not have to wait for busy_n = 1.
// note3: di must wait for busy_n = 1.
// note4: a di is taken by the chip if:  busy_n == 1 && valid_n == 0
// note5: frame_n must be deasserted with the last data bit in the frame.
// note6: once connection is successfully made, busy_n is guaranteed to
//    stay inactive until to the end of the current frame.
module router
  (
    reset_n,
    clock,
    frame_n,
    valid_n,
    din,
    dout,
    busy_n,
    valido_n,
    frameo_n
  );

  input reset_n, clock;

  input [15:0] din, frame_n, valid_n;

  output [15:0] dout, valido_n, busy_n, frameo_n;

  wire reset;
  wire [15:0] arb0, arb1, arb2, arb3, arb4, arb5, arb6, arb7;
  wire [15:0] di;
  wire [15:0] arb8, arb9, arb10, arb11, arb12, arb13, arb14, arb15;
  wire [15:0] arb_head, okstep;

  tri0 [15:0] doint;
  tri1 [15:0] valdoint_n, frameoint_n;

  reg [15:0] dout, valido_n, frameo_n;
  reg [3:0] arb_head_num;

  assign di = din;

  assign reset = ~reset_n;
  assign arb_head = 1 << arb_head_num;

  rtslice rts0(reset,clock,frame_n[0],valid_n[0],di[0],
    arb0,arb1,arb_head[0],okstep[0],
    doint,busy_n[0],valdoint_n,frameoint_n);
  rtslice rts1(reset,clock,frame_n[1],valid_n[1],di[1],
    arb1,arb2,arb_head[1],okstep[1],
    doint,busy_n[1],valdoint_n,frameoint_n);
  rtslice rts2(reset,clock,frame_n[2],valid_n[2],di[2],
    arb2,arb3,arb_head[2],okstep[2],
    doint,busy_n[2],valdoint_n,frameoint_n);
  rtslice rts3(reset,clock,frame_n[3],valid_n[3],di[3],
    arb3,arb4,arb_head[3],okstep[3],
    doint,busy_n[3],valdoint_n,frameoint_n);
  rtslice rts4(reset,clock,frame_n[4],valid_n[4],di[4],
    arb4,arb5,arb_head[4],okstep[4],
    doint,busy_n[4],valdoint_n,frameoint_n);
  rtslice rts5(reset,clock,frame_n[5],valid_n[5],di[5],
    arb5,arb6,arb_head[5],okstep[5],
    doint,busy_n[5],valdoint_n,frameoint_n);
  rtslice rts6(reset,clock,frame_n[6],valid_n[6],di[6],
    arb6,arb7,arb_head[6],okstep[6],
    doint,busy_n[6],valdoint_n,frameoint_n);
  rtslice rts7(reset,clock,frame_n[7],valid_n[7],di[7],
    arb7,arb8,arb_head[7],okstep[7],
    doint,busy_n[7],valdoint_n,frameoint_n);
  rtslice rts8(reset,clock,frame_n[8],valid_n[8],di[8],
    arb8,arb9,arb_head[8],okstep[8],
    doint,busy_n[8],valdoint_n,frameoint_n);
  rtslice rts9(reset,clock,frame_n[9],valid_n[9],di[9],
    arb9,arb10,arb_head[9],okstep[9],
    doint,busy_n[9],valdoint_n,frameoint_n);
  rtslice rts10(reset,clock,frame_n[10],valid_n[10],di[10],
    arb10,arb11,arb_head[10],okstep[10],
    doint,busy_n[10],valdoint_n,frameoint_n);
  rtslice rts11(reset,clock,frame_n[11],valid_n[11],di[11],
    arb11,arb12,arb_head[11],okstep[11],
    doint,busy_n[11],valdoint_n,frameoint_n);
  rtslice rts12(reset,clock,frame_n[12],valid_n[12],di[12],
    arb12,arb13,arb_head[12],okstep[12],
    doint,busy_n[12],valdoint_n,frameoint_n);
  rtslice rts13(reset,clock,frame_n[13],valid_n[13],di[13],
    arb13,arb14,arb_head[13],okstep[13],
    doint,busy_n[13],valdoint_n,frameoint_n);
  rtslice rts14(reset,clock,frame_n[14],valid_n[14],di[14],
    arb14,arb15,arb_head[14],okstep[14],
    doint,busy_n[14],valdoint_n,frameoint_n);
//rtslicef rts15(reset,clock,frame_n[15],valid_n[15],di[15],
//  arb15,arb0,arb_head[15],okstep[15],
//  doint,busy_n[15],valdoint_n,frameoint_n);
  rtslice rts15(reset,clock,frame_n[15],valid_n[15],di[15],
    arb15,arb0,arb_head[15],okstep[15],
    doint,busy_n[15],valdoint_n,frameoint_n);

  always @(posedge reset) begin
    arb_head_num <= 4'b0;
  end

  always @(posedge clock) begin
    dout <= doint;
    valido_n <= valdoint_n;
    frameo_n <= frameoint_n;
    if (reset == 1'b0) begin
      if (okstep[arb_head_num] == 1'b1)
        arb_head_num <= arb_head_num + 1;
    end
  end

endmodule //router

module rtslice
  (
    reset,
    clock,
    frame_n,
    valid_n,
    din,
    iarbin,
    arbout,
    arbhead,
    okstep,
    dout,
    busy_n,
    valido_n,
    frameo_n
  );

  input reset,clock,frame_n,valid_n,din, arbhead;
  output busy_n,okstep;
  input [15:0] iarbin;
  output [15:0] arbout,dout,valido_n;
  inout [15:0] frameo_n;

  reg [4:0] addrsf, addrsel;
  reg [5:0] addrfsr;
  reg din1, busy_n, frame1_n, frame2_n, vald1_n, arbena;

  wire [15:0] dout;
  wire [15:0] arbin;
  wire busy1_n;
  wire [4:0] addrsel_g;

  reg [3:0] i;

  assign arbin = (arbhead == 1'b1) ? 16'hffff : iarbin;
  assign addrsel_g = (arbena == 1'b1) ? addrsel : 5'h0;

//  always @ ( posedge clock)
//  begin
  assign dout[0] =
    (addrsel_g == 5'h10 && arbin[0] == 1'b1) ? din1 : 1'bZ;
//  end
  assign dout[1] =
    (addrsel_g == 5'h11 && arbin[1] == 1'b1) ? din1 : 1'bZ;
  assign dout[2] =
    (addrsel_g == 5'h12 && arbin[2] == 1'b1) ? din1 : 1'bZ;
  assign dout[3] =
    (addrsel_g == 5'h13 && arbin[3] == 1'b1) ? din1 : 1'bZ;
  assign dout[4] =
    (addrsel_g == 5'h14 && arbin[4] == 1'b1) ? din1 : 1'bZ;
  assign dout[5] =
    (addrsel_g == 5'h15 && arbin[5] == 1'b1) ? din1 : 1'bZ;
  assign dout[6] =
    (addrsel_g == 5'h16 && arbin[6] == 1'b1) ? din1 : 1'bZ;
  assign dout[7] =
    (addrsel_g == 5'h17 && arbin[7] == 1'b1) ? din1 : 1'bZ;
  assign dout[8] =
    (addrsel_g == 5'h18 && arbin[8] == 1'b1) ? din1 : 1'bZ;
  assign dout[9] =
    (addrsel_g == 5'h19 && arbin[9] == 1'b1) ? din1 : 1'bZ;
  assign dout[10] =
    (addrsel_g == 5'h1a && arbin[10] == 1'b1) ? din1 : 1'bZ;
  assign dout[11] =
    (addrsel_g == 5'h1b && arbin[11] == 1'b1) ? din1 : 1'bZ;
  assign dout[12] =
    (addrsel_g == 5'h1c && arbin[12] == 1'b1) ? din1 : 1'bZ;
  assign dout[13] =
    (addrsel_g == 5'h1d && arbin[13] == 1'b1) ? din1 : 1'bZ;
  assign dout[14] =
    (addrsel_g == 5'h1e && arbin[14] == 1'b1) ? din1 : 1'bZ;
  assign dout[15] =
    (addrsel_g == 5'h1f && arbin[15] == 1'b1) ? din1 : 1'bZ;

  assign frameo_n[0] =
    (addrsel_g == 5'h10 && arbin[0] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[1] =
    (addrsel_g == 5'h11 && arbin[1] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[2] =
    (addrsel_g == 5'h12 && arbin[2] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[3] =
    (addrsel_g == 5'h13 && arbin[3] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[4] =
    (addrsel_g == 5'h14 && arbin[4] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[5] =
    (addrsel_g == 5'h15 && arbin[5] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[6] =
    (addrsel_g == 5'h16 && arbin[6] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[7] =
    (addrsel_g == 5'h17 && arbin[7] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[8] =
    (addrsel_g == 5'h18 && arbin[8] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[9] =
    (addrsel_g == 5'h19 && arbin[9] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[10] =
    (addrsel_g == 5'h1a && arbin[10] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[11] =
    (addrsel_g == 5'h1b && arbin[11] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[12] =
    (addrsel_g == 5'h1c && arbin[12] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[13] =
    (addrsel_g == 5'h1d && arbin[13] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[14] =
    (addrsel_g == 5'h1e && arbin[14] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[15] =
    (addrsel_g == 5'h1f && arbin[15] == 1'b1) ? frame1_n : 1'bZ;

  assign valido_n[0] =
    (addrsel_g == 5'h10 && arbin[0] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[1] =
    (addrsel_g == 5'h11 && arbin[1] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[2] =
    (addrsel_g == 5'h12 && arbin[2] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[3] =
    (addrsel_g == 5'h13 && arbin[3] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[4] =
    (addrsel_g == 5'h14 && arbin[4] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[5] =
    (addrsel_g == 5'h15 && arbin[5] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[6] =
    (addrsel_g == 5'h16 && arbin[6] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[7] =
    (addrsel_g == 5'h17 && arbin[7] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[8] =
    (addrsel_g == 5'h18 && arbin[8] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[9] =
    (addrsel_g == 5'h19 && arbin[9] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[10] =
    (addrsel_g == 5'h1a && arbin[10] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[11] =
    (addrsel_g == 5'h1b && arbin[11] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[12] =
    (addrsel_g == 5'h1c && arbin[12] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[13] =
    (addrsel_g == 5'h1d && arbin[13] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[14] =
    (addrsel_g == 5'h1e && arbin[14] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[15] =
    (addrsel_g == 5'h1f && arbin[15] == 1'b1) ? vald1_n : 1'bZ;

  assign arbout[0] =
    (addrsel_g != 5'h10 && arbin[0] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[1] =
    (addrsel_g != 5'h11 && arbin[1] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[2] =
    (addrsel_g != 5'h12 && arbin[2] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[3] =
    (addrsel_g != 5'h13 && arbin[3] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[4] =
    (addrsel_g != 5'h14 && arbin[4] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[5] =
    (addrsel_g != 5'h15 && arbin[5] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[6] =
    (addrsel_g != 5'h16 && arbin[6] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[7] =
    (addrsel_g != 5'h17 && arbin[7] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[8] =
    (addrsel_g != 5'h18 && arbin[8] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[9] =
    (addrsel_g != 5'h19 && arbin[9] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[10] =
    (addrsel_g != 5'h1a && arbin[10] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[11] =
    (addrsel_g != 5'h1b && arbin[11] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[12] =
    (addrsel_g != 5'h1c && arbin[12] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[13] =
    (addrsel_g != 5'h1d && arbin[13] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[14] =
    (addrsel_g != 5'h1e && arbin[14] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[15] =
    (addrsel_g != 5'h1f && arbin[15] == 1'b1) ? 1'b1 : 1'b0;

  assign busy1_n = (arbout != arbin) ? 1'b1 : ~addrsel[4];
  assign okstep = (arbout == arbin) ? 1'b1 : 1'b0;

  always @(posedge reset) begin
    if (reset == 1'b1) begin
      addrsel <= 5'b0;
      addrfsr <= 6'b0;
      arbena <= 1'b0;
    end
  end

  always @(posedge clock) begin
    frame1_n <= frame_n;
    frame2_n <= frame1_n;
    busy_n <= busy1_n;
    din1 <= din;
    vald1_n <= valid_n | ~busy_n ;

    if (reset == 1'b0) begin
      if (frame2_n != frame1_n && frame1_n == 1'b1) begin // frame is now inactive
        addrsel <= 5'b0; // clear the address register
        addrfsr <= 6'b0; // clear the address flag reg.
        arbena <= 1'b0;
      end
      else begin
        if (addrsel[4] == 1'b1 && frameo_n[addrsel[3:0]] == 1'b1)
          arbena <= 1'b1;
      end

      if (frame1_n != frame_n && frame_n == 1'b0)
        addrfsr <= 6'b11_1111;

      if (addrfsr[5:4] == 2'b10)
        addrsel <= {addrsf[0],addrsf[1],addrsf[2],addrsf[3],addrsf[4]};
      if (addrfsr[4] == 1'b1) addrsf <= (addrsf << 1) | { 4'b0, din1 };
      if (addrfsr[5] == 1'b1) addrfsr <= addrfsr << 1;
    end
  end

endmodule //rtslice

module rtslicef
  (
    reset,
    clock,
    frame_n,
    valid_n,
    din,
    iarbin,
    arbout,
    arbhead,
    okstep,
    dout,
    busy_n,
    valido_n,
    frameo_n
  );

  input reset,clock,frame_n,valid_n,din, arbhead;
  output busy_n,okstep;
  input [15:0] iarbin;
  output [15:0] arbout,dout,valido_n;
  inout [15:0] frameo_n;

  reg [4:0] addrsf, addrsel;
  reg [5:0] addrfsr;
  reg din1, busy_n, frame1_n, frame2_n, vald1_n, arbena;

  wire [15:0] dout;
  wire [15:0] arbin;
  wire busy1_n;
  wire [4:0] addrsel_g;

  assign arbin = (arbhead == 1'b1) ? 16'hffff : iarbin;
  assign addrsel_g = (arbena == 1'b1) ? addrsel : 5'h0;

  assign dout[0] =
    (addrsel_g == 5'h10 && arbin[0] == 1'b1) ? din1 : 1'bZ;
  assign dout[1] =
    (addrsel_g == 5'h11 && arbin[1] == 1'b1) ? din1 : 1'bZ;
  assign dout[2] =
    (addrsel_g == 5'h12 && arbin[2] == 1'b1) ? din1 : 1'bZ;
  assign dout[3] =
    (addrsel_g == 5'h13 && arbin[3] == 1'b1) ? din1 : 1'bZ;
  assign dout[4] =
    (addrsel_g == 5'h14 && arbin[4] == 1'b1) ? din1 : 1'bZ;
  assign dout[5] =
    (addrsel_g == 5'h15 && arbin[5] == 1'b1) ? din1 : 1'bZ;
  assign dout[6] =
    (addrsel_g == 5'h16 && arbin[6] == 1'b1) ? din1 : 1'bZ;
  assign dout[7] =
    (addrsel_g == 5'h17 && arbin[7] == 1'b1) ? din1 : 1'bZ;
  // stuck at x
  assign dout[8] =
//  (addrsel_g == 5'h18 && arbin[8] == 1'b1) ? din1 : 1'bZ;
    (addrsel_g == 5'h18 && arbin[8] == 1'b1) ? 1'bx : 1'bZ;
  assign dout[9] =
    (addrsel_g == 5'h19 && arbin[9] == 1'b1) ? din1 : 1'bZ;
  assign dout[10] =
    (addrsel_g == 5'h1a && arbin[10] == 1'b1) ? din1 : 1'bZ;
  assign dout[11] =
    (addrsel_g == 5'h1b && arbin[11] == 1'b1) ? din1 : 1'bZ;
  assign dout[12] =
    (addrsel_g == 5'h1c && arbin[12] == 1'b1) ? din1 : 1'bZ;
  assign dout[13] =
    (addrsel_g == 5'h1d && arbin[13] == 1'b1) ? din1 : 1'bZ;
  assign dout[14] =
    (addrsel_g == 5'h1e && arbin[14] == 1'b1) ? din1 : 1'bZ;
  assign dout[15] =
    (addrsel_g == 5'h1f && arbin[15] == 1'b1) ? din1 : 1'bZ;

  assign frameo_n[0] =
    (addrsel_g == 5'h10 && arbin[0] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[1] =
    (addrsel_g == 5'h11 && arbin[1] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[2] =
    (addrsel_g == 5'h12 && arbin[2] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[3] =
    (addrsel_g == 5'h13 && arbin[3] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[4] =
    (addrsel_g == 5'h14 && arbin[4] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[5] =
    (addrsel_g == 5'h15 && arbin[5] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[6] =
    (addrsel_g == 5'h16 && arbin[6] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[7] =
    (addrsel_g == 5'h17 && arbin[7] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[8] =
    (addrsel_g == 5'h18 && arbin[8] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[9] =
    (addrsel_g == 5'h19 && arbin[9] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[10] =
    (addrsel_g == 5'h1a && arbin[10] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[11] =
    (addrsel_g == 5'h1b && arbin[11] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[12] =
    (addrsel_g == 5'h1c && arbin[12] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[13] =
    (addrsel_g == 5'h1d && arbin[13] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[14] =
    (addrsel_g == 5'h1e && arbin[14] == 1'b1) ? frame1_n : 1'bZ;
  assign frameo_n[15] =
    (addrsel_g == 5'h1f && arbin[15] == 1'b1) ? frame1_n : 1'bZ;

  assign valido_n[0] =
    (addrsel_g == 5'h10 && arbin[0] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[1] =
    (addrsel_g == 5'h11 && arbin[1] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[2] =
    (addrsel_g == 5'h12 && arbin[2] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[3] =
    (addrsel_g == 5'h13 && arbin[3] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[4] =
    (addrsel_g == 5'h14 && arbin[4] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[5] =
    (addrsel_g == 5'h15 && arbin[5] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[6] =
    (addrsel_g == 5'h16 && arbin[6] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[7] =
    (addrsel_g == 5'h17 && arbin[7] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[8] =
    (addrsel_g == 5'h18 && arbin[8] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[9] =
    (addrsel_g == 5'h19 && arbin[9] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[10] =
    (addrsel_g == 5'h1a && arbin[10] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[11] =
    (addrsel_g == 5'h1b && arbin[11] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[12] =
    (addrsel_g == 5'h1c && arbin[12] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[13] =
    (addrsel_g == 5'h1d && arbin[13] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[14] =
    (addrsel_g == 5'h1e && arbin[14] == 1'b1) ? vald1_n : 1'bZ;
  assign valido_n[15] =
    (addrsel_g == 5'h1f && arbin[15] == 1'b1) ? vald1_n : 1'bZ;

  assign arbout[0] =
    (addrsel_g != 5'h10 && arbin[0] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[1] =
    (addrsel_g != 5'h11 && arbin[1] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[2] =
    (addrsel_g != 5'h12 && arbin[2] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[3] =
    (addrsel_g != 5'h13 && arbin[3] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[4] =
    (addrsel_g != 5'h14 && arbin[4] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[5] =
    (addrsel_g != 5'h15 && arbin[5] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[6] =
    (addrsel_g != 5'h16 && arbin[6] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[7] =
    (addrsel_g != 5'h17 && arbin[7] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[8] =
    (addrsel_g != 5'h18 && arbin[8] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[9] =
    (addrsel_g != 5'h19 && arbin[9] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[10] =
    (addrsel_g != 5'h1a && arbin[10] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[11] =
    (addrsel_g != 5'h1b && arbin[11] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[12] =
    (addrsel_g != 5'h1c && arbin[12] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[13] =
    (addrsel_g != 5'h1d && arbin[13] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[14] =
    (addrsel_g != 5'h1e && arbin[14] == 1'b1) ? 1'b1 : 1'b0;
  assign arbout[15] =
    (addrsel_g != 5'h1f && arbin[15] == 1'b1) ? 1'b1 : 1'b0;

  assign busy1_n = (arbout != arbin) ? 1'b1 : ~addrsel[4];
  assign okstep = (arbout == arbin) ? 1'b1 : 1'b0;

  always @(posedge reset) begin
    if (reset == 1'b1) begin
      addrsel <= 5'b0;
      addrfsr <= 6'b0;
      arbena <= 1'b0;
    end
  end

  always @(posedge clock) begin
    frame1_n <= frame_n;
    frame2_n <= frame1_n;
    busy_n <= busy1_n;
    din1 <= din;
    vald1_n <= valid_n | ~busy_n ;

    if (reset == 1'b0) begin
      if (frame1_n != frame_n && frame_n == 1'b0)
        addrfsr <= 6'b11_1111;

      if (frame2_n != frame1_n && frame1_n == 1'b1) begin // frame is now inactive
        addrsel <= 5'b0; // clear the address register
        addrfsr <= 6'b0; // clear the address flag reg.
        arbena <= 1'b0;
      end
      else begin
        if (addrsel[4] == 1'b1 && frameo_n[addrsel[3:0]] == 1'b1)
          arbena <= 1'b1;
      end

      if (addrfsr[5:4] == 2'b10)
        addrsel <= {addrsf[0],addrsf[1],addrsf[2],addrsf[3],addrsf[4]};
      if (addrfsr[4] == 1'b1) addrsf <= (addrsf << 1) | { 4'b0, din1 };
      if (addrfsr[5] == 1'b1) addrfsr <= addrfsr << 1;
    end
  end

endmodule //rtslicef

2.2 tb代码

//********************************** stimulator **********************************//
module rt_stimulator(
  input clock
  ,input reset_n
  ,output logic [15:0] din
  ,output logic [15:0] frame_n
  ,output logic [15:0] valid_n
  ,input [15:0] dout
  ,input [15:0] valido_n
  ,input [15:0] busy_n
  ,input [15:0] frameo_n
);
//for debug purpose from waveform   //定义检测状态的变量
  typedef enum {DRV_RESET,DRV_IDLE,DRV_ADDR,DRV_PAD,DRV_DATA} drv_state_t;
  drv_state_t dbg_state;  
  byte unsigned dbg_din_chnl0_data; 

initial begin : drive_reset_proc //reset阶段,复位时,reset_n为低电平,frame_n和valid_n为高电平
  @(negedge reset_n);
  dbg_state <= DRV_RESET;
  din <= 0;
  frame_n <= 1;
  valid_n <= 1;
end

// drive chaannel 0 - chanel 15 (din[15:0])定义数据输出地址及数据
bit [3:0] addr;
byte unsigned data[];

initial begin : drive_chnl0_proc
  @(negedge reset_n);
  repeat(10) @(posedge clock);//延迟10个时钟周期
  addr = 3;     //从第3位输出
  data = '{8'h33,8'h77}; 
    // drive address phase 输入地址位阶段
for(int i=0;i<4;i++)begin  //4 clock
  @(posedge clock);
  dbg_state <=DRV_ADDR;  
  din[0] <= addr[i];
  valid_n[0] <= $urandom_range(0,1); //valid_n在din的地址输入时间段可为任意值x
  frame_n[0] <= 1'b0;   //frame_n需要为低
end
    // drive pad phase //隔离阶段
  for (int i=0;i<5;i++)begin  //5 clock
    @(posedge clock);
    dbg_state <=DRV_PAD;
    din[0] <= 1'b1;
    valid_n[0] <= 1'b1; //valid_n需为高电平
    frame_n[0] <= 1'b0; //frame_n需为低电平
  end
    // drive data phase 传输数据阶段
  foreach(data[id])begin
    for(int i=0;i<8;i++)begin
     @(posedge clock);
      dbg_state <=DRV_DATA;
      dbg_din_chnl0_data <= data[id];
      din[0] <= data[id][i];
      valid_n[0] <=1'b0;
      frame_n <= (id == data.size()-1 && i == 7) ? 1'b1 : 1'b0;//packet最后一位输出数据时frameo_n为高
    end
  end
// drive idle phase 闲置(没有数据传输)阶段
  @(posedge clock);
  dbg_state <=DRV_IDLE;
  dbg_din_chnl0_data <= 0;
  din[0] <= 1'b0;
  valid_n[0] <= 1'b1;
  frame_n <= 1'b1;
end
endmodule

//********************************** tb **********************************//
module lab3tb;

bit clk,rstn;
logic [15:0] din, frame_n, valid_n;
logic [15:0] dout, valido_n, busy_n, frameo_n;

// 产生时钟,周期为10ns
initial 
    forever #5ns clk <= !clk;

// 产生复位信号
  initial begin
    #2ns rstn <= 1;
    #10ns rstn <= 0;
    #10ns rstn <= 1;
  end

//例化router为DUT
router dut(           
  .reset_n(rstn),
  .clock(clk),
  .*  //其余端口名称均相同
);

//例化stimulator
rt_stimulator stim(
  .reset_n(rstn),
  .clock(clk),
  .*
);
endmodule 

3. 仿真结果

另,关于vim编辑器

4. 初步TestBench平台概览

来自广东
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇