2014年6月7日 星期六

Parallel to Serial (位元數可以變更)

Reference:
“Digital VLSI Design with Verilog”, John Williams, Springer, 2008.
Page 78 – 80.
1、Verilog Code
SerClock:a Serial Clock input;
ParValid: indicate when data on the parallel bus are stable and valid;
SerValidFlag: Clock out the data high-order bit (MSB) first, one bit per serial clock, setting a SerValidFlag when the first bit is on the serial bus and clearing it after the last bit is on the serial bus.
Done: use it to hold the state of the serialization.


`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: SEU.IC
// Engineer: Ray
//
// Create Date:    15:27:50 04/03/2011
// Design Name:
// Module Name:    par_to_ser_2
//////////////////////////////////////////////////////////////////////////////////
module ParToSerial #(parameter BusHi = 12)
                    (output SerOut, SerValidFlag
                    , input SerClock, ParValid
                    , input[BusHi:0] BusIn
                    );
  //
  // A clever way to declare the width of ix to agree with
  // the parameterized width of BusHi would be to calculate
  // the log using the C-like conditional expression operator.
  //
  // Note:  A localparam is the same as a parameter,
  // which would be OK here.   A localparam can not be
  // overridden; it gets a definite value, not just a default.
  //
  localparam ixHi = (BusHi <  2**2)?  1
                  : (BusHi <  2**3)?  2
                  : (BusHi <  2**4)?  3
                  : (BusHi <  2**5)?  4
                  : (BusHi <  2**6)?  5
                  : (BusHi <  2**7)?  6
                  : (BusHi <  2**8)?  7
                  : (BusHi <  2**9)?  8
                  : (BusHi < 2**10)?  9
                  : (BusHi < 2**11)? 10
                  : 'bx;
  // Might as well stop at 10:  That will handle
  // BusIn up to 2**11 = 2048 bits wide.
  //
  reg[ixHi:0] ix;
  //
  reg SerValid, Done, SerBit;
  reg SerValidFlag;

  assign SerOut       = SerBit;
  always @ (posedge SerClock)
    SerValidFlag <= SerValid;

  always@(posedge SerClock)
    begin
    // Reset everything unless ParValid:
    if (ParValid==1'b1)
          if (SerValid==1'b1)
               begin
               SerBit <= BusIn[ix]; // Current serial bit.
               if (ix==0)
                    begin
                    SerValid <= 1'b0;
                    Done     <= 1'b1;
                    end
               else ix <= ix - 1;
               end // SerValid was asserted.
          else // No start yet:
               begin
               if (Done==1'b0)
                 begin
                 SerValid <= 1'b1; // Flag start on next SerClock.
                 ix       <= BusHi ;
                 // Ready to start on next SerClock.
                 end
               SerBit <= 1'b0; // Serial bit default.
               end
      else // ParValid not 1; reset everything:
           begin
           SerValid <= 1'b0;
           Done     <= 1'b0;
           SerBit   <= 1'b0; // Serial bit default.
           end // if ParValid else
    end // always
  //
endmodule // ParToSerial


testbench for the verilog code,


`timescale 1ns / 1ps
////////////////////////////////////////////////////////////////////////////////
// Company: SEU.IC
// Engineer:Ray
//
// Create Date:   15:47:35 04/03/2011
// Design Name:   ParToSerial
// Module Name:   E:/ray_study_verilog/parallel_to_serial/tb_par_to_sel_2_2.v
// Project Name:  parallel_to_serial
////////////////////////////////////////////////////////////////////////////////
module tb_par_to_sel;
    // Inputs
    reg SerClock;
    reg ParValid;
    reg [12:0] BusIn;
    // Outputs
    wire SerOut;
    wire SerValidFlag;
    // Instantiate the Unit Under Test (UUT)
    ParToSerial uut (
        .SerOut(SerOut),
        .SerValidFlag(SerValidFlag),
        .SerClock(SerClock),
        .ParValid(ParValid),
        .BusIn(BusIn)
    );
  
  always@(SerClock) // 100 MHz
     #5 SerClock <= ~SerClock;
  //
  always@(BusIn) // 1 MHz
    begin
    #500 BusIn <= BusIn   +16'h010f;
    end
  //
  always@(BusIn)
    begin
    #14 ParValid = 1'b1;
    #460 ParValid = 1'b0;
    end
  //
  initial
    begin
    #0    SerClock = 1'b0;
    #0    ParValid = 1'b0;
    #21   BusIn    = 16'hf000;
    #5000 $finish;
    end    
endmodule



Simulation Waves:

1、parallel data width is 13

2、parallel data width is 16

沒有留言:

張貼留言

Messaging API作為替代方案

  LINE超好用功能要沒了!LINE Notify明年3月底終止服務,有什麼替代方案? LINE Notify將於2025年3月31日結束服務,官方建議改用Messaging API作為替代方案。 //CHANNEL_ACCESS_TOKEN = 'Messaging ...