2020年4月19日日曜日

verilog : 多ビット信号の配列 (二次元配列)

目的:

多ビット信号の配列(二次元配列)を使用する。

宣言:

レジスタ(メモリ)
reg  [7:0] r_data[0:127]    // 8bit幅 128 個のレジスタ宣言

信号(Wire)
wire [7:0] w_data[0:127]    // 8bit幅 128 組の ワイヤ宣言

Verilog では ポートに二次元配列は使用できない。

代入:

wire       sig_1b ;
wire [7:0] sig_8b ;
assign w_data[14] = sig ;        // 8bit 幅の信号を 15番目の 8bit信号 に代入
assign sig_1b = w_data[127][7] ; // 1bit 幅の信号に 127番目の bit7(MSB)を代入

例:

回路図

 ( 各BIT_WIDTH 幅の FF の MSB を 束ねて dt_msb 信号として出力 )

verilog (モジュール)
FF は generate 文を使用して for - next で 記述。
ポートは二次元配列で記述できない為、内部で宣言した wire に 1つづつ assign 。
二次元配列から一次元配列へのアサインは「多ビット信号の配列(二次元配列)と入出力ポート 」を参照。
// -----------------------------------------------------
//   Sample module
//
//   Module Name : test_md1
//   Version     : 0.00
// -----------------------------------------------------
 
module test_md1 #(                      // Module name : test
  parameter BIT_WIDTH = 4 ,             // parameter list
  parameter DATA_NUM  = 8               // parameter list
) (                                     //
  clr,                                  // port list
  clk,
  enable,
  set,
  data_1,
  data_2,
  data_3,
  data_4,
  data_5,
  data_6,
  data_7,
  data_8,
  out_dt1,
  out_dt2,
  out_dt3,
  out_dt4,
  out_dt5,
  out_dt6,
  out_dt7,
  out_dt8,
  dt_msb
) ;
 
// port declaration ----------------
input                  clr ;
input                  clk ;
input                  enable ;
input                  set ;
input  [BIT_WIDTH-1:0] data_1 ;
input  [BIT_WIDTH-1:0] data_2 ;
input  [BIT_WIDTH-1:0] data_3 ;
input  [BIT_WIDTH-1:0] data_4 ;
input  [BIT_WIDTH-1:0] data_5 ;
input  [BIT_WIDTH-1:0] data_6 ;
input  [BIT_WIDTH-1:0] data_7 ;
input  [BIT_WIDTH-1:0] data_8 ;
output [BIT_WIDTH-1:0] out_dt1 ;
output [BIT_WIDTH-1:0] out_dt2 ;
output [BIT_WIDTH-1:0] out_dt3 ;
output [BIT_WIDTH-1:0] out_dt4 ;
output [BIT_WIDTH-1:0] out_dt5 ;
output [BIT_WIDTH-1:0] out_dt6 ;
output [BIT_WIDTH-1:0] out_dt7 ;
output [BIT_WIDTH-1:0] out_dt8 ;
output [DATA_NUM-1:0]  dt_msb ;
 
// parameter declaration -----------
parameter DLY = 1 ;
 
// internal signal declaration -----
wire                 set_enable ;

wire [BIT_WIDTH-1:0] in_data[1:DATA_NUM] ;
reg  [BIT_WIDTH-1:0] lt_data[1:DATA_NUM] ;
 
// logical description -------------
assign set_enable = enable & set ;

assign in_data[1] = data_1 ;
assign in_data[2] = data_2 ;
assign in_data[3] = data_3 ;
assign in_data[4] = data_4 ;
assign in_data[5] = data_5 ;
assign in_data[6] = data_6 ;
assign in_data[7] = data_7 ;
assign in_data[8] = data_8 ;

generate
  genvar i ;
  for (i=1; i<DATA_NUM+1; i=i+1) 
    begin : dtlatch
      always @(posedge clk or posedge clr)
        if (clr) 
          lt_data[i]  <= #DLY  {BIT_WIDTH{1'b0}} ;
        else if (set_enable)
            lt_data[i]  <= #DLY  in_data[i] ;

      assign dt_msb[i-1] = lt_data[i][BIT_WIDTH-1] ;
    end

endgenerate
 
assign out_dt1 = lt_data[1] ;
assign out_dt2 = lt_data[2] ;
assign out_dt3 = lt_data[3] ;
assign out_dt4 = lt_data[4] ;
assign out_dt5 = lt_data[5] ;
assign out_dt6 = lt_data[6] ;
assign out_dt7 = lt_data[7] ;
assign out_dt8 = lt_data[8] ;
 
endmodule

verilog (上位階層)
//   Sample test
//
//   Module Name : test
//   Version     : 0.00
// -----------------------------------------------------
 
module test(
  clr,                                  // port list
  clk,
  enable,
  set,
  data_1,
  data_2,
  data_3,
  data_4,
  data_5,
  data_6,
  data_7,
  data_8,
  out_dt1,
  out_dt2,
  out_dt3,
  out_dt4,
  out_dt5,
  out_dt6,
  out_dt7,
  out_dt8,
  dt_msb
) ;
 
// port declaration ----------------
input        clr ;
input        clk ;
input        enable ;
input        set ;
input  [7:0] data_1 ;
input  [7:0] data_2 ;
input  [7:0] data_3 ;
input  [7:0] data_4 ;
input  [7:0] data_5 ;
input  [7:0] data_6 ;
input  [7:0] data_7 ;
input  [7:0] data_8 ;
output [7:0] out_dt1 ;
output [7:0] out_dt2 ;
output [7:0] out_dt3 ;
output [7:0] out_dt4 ;
output [7:0] out_dt5 ;
output [7:0] out_dt6 ;
output [7:0] out_dt7 ;
output [7:0] out_dt8 ;
output [7:0]  dt_msb ;
 
test_md1 #(
  .BIT_WIDTH (8) 
)i_test(
  .clr      (clr),
  .clk      (clk),
  .enable   (enable),
  .set      (set),
  .data_1   (data_1),
  .data_2   (data_2),
  .data_3   (data_3),
  .data_4   (data_4),
  .data_5   (data_5),
  .data_6   (data_6),
  .data_7   (data_7),
  .data_8   (data_8),
  .out_dt1  (out_dt1),
  .out_dt2  (out_dt2),
  .out_dt3  (out_dt3),
  .out_dt4  (out_dt4),
  .out_dt5  (out_dt5),
  .out_dt6  (out_dt6),
  .out_dt7  (out_dt7),
  .out_dt8  (out_dt8),
  .dt_msb   (dt_msb)
) ;

endmodule


verilog (テストベンチ, 呼び出し側)
// ----------------------------------------------------------
//   test bench
//
//     for test.v
// ----------------------------------------------------------

`timescale 1ns / 1ps

module testbench ;

// testbench logic -------------------
reg   clr;
reg   clk;
reg   [7:0] in_data_1 ;
reg   [7:0] in_data_2 ;
reg   [7:0] in_data_3 ;
reg   [7:0] in_data_4 ;
reg   [7:0] in_data_5 ;
reg   [7:0] in_data_6 ;
reg   [7:0] in_data_7 ;
reg   [7:0] in_data_8 ;
reg   enable ;
reg   set ;
wire  [7:0] out_data_1 ;
wire  [7:0] out_data_2 ;
wire  [7:0] out_data_3 ;
wire  [7:0] out_data_4 ;
wire  [7:0] out_data_5 ;
wire  [7:0] out_data_6 ;
wire  [7:0] out_data_7 ;
wire  [7:0] out_data_8 ;

wire  [7:0] data_msb ;

test  i_test(
  .clr      (clr),
  .clk      (clk),
  .enable   (enable),
  .set      (set),
  .data_1   (in_data_1),
  .data_2   (in_data_2),
  .data_3   (in_data_3),
  .data_4   (in_data_4),
  .data_5   (in_data_5),
  .data_6   (in_data_6),
  .data_7   (in_data_7),
  .data_8   (in_data_8),
  .out_dt1  (out_data_1),
  .out_dt2  (out_data_2),
  .out_dt3  (out_data_3),
  .out_dt4  (out_data_4),
  .out_dt5  (out_data_5),
  .out_dt6  (out_data_6),
  .out_dt7  (out_data_7),
  .out_dt8  (out_data_8),
  .dt_msb   (data_msb)
) ;

initial begin
  clk = 0 ;
  clr = 1 ;
  #10 clr = 0 ;
  forever begin
    #10 clk = ~clk ;
  end
end

// scenario --------------------------
initial begin
  $dumpfile("tb.vcd");
  $dumpvars(0,testbench) ;

  enable    = 1'b0 ;
  set       = 1'b0 ;
  in_data_1 = 8'd0 ;
  in_data_2 = 8'd0 ;
  in_data_3 = 8'd0 ;
  in_data_4 = 8'd0 ;
  in_data_5 = 8'd0 ;
  in_data_6 = 8'd0 ;
  in_data_7 = 8'd0 ;
  in_data_8 = 8'd0 ;

  #200 enable    = 1'b1 ;
       in_data_1 = 8'h01 ;
       in_data_2 = 8'h92 ;
       in_data_3 = 8'h23 ;
       in_data_4 = 8'hb4 ;
       in_data_5 = 8'hc5 ;
       in_data_6 = 8'h56 ;
       in_data_7 = 8'he7 ;
       in_data_8 = 8'h78 ;
  #101 set       = 1'b1 ;
  #20  set       = 1'b0 ; 
  #100 enable    = 1'b0 ;
       in_data_1 = 8'hff ;
       in_data_2 = 8'hff ;
       in_data_3 = 8'hff ;
       in_data_4 = 8'hff ;
       in_data_5 = 8'hff ;
       in_data_6 = 8'hff ;
       in_data_7 = 8'hff ;
       in_data_8 = 8'hff ;
  #101 set       = 1'b1 ;
  #20  set       = 1'b0 ; 
  #200 ;
  $finish;
  end

endmodule

シミュレーション結果


0 件のコメント:

コメントを投稿