目的:
入出力ポートには2次元配列を使用できない為、2次元配列を1次元配列にアサインする。
記述例:
内部信号
reg [P_BW-1:0] r_rise_pos[0:6] ;
を 1次元の配列
wire [P_BW*7-1:0] w_rise_pos ;
に アサイン する場合の記述例を以下に示す。
例1 :
assign w_rise_pos = {r_rise_pos[6], r_rise_pos[5],r_rise_pos[4],r_rise_pos[3],
r_rise_pos[2], r_rise_pos[1],r_rise_pos[0] } ;
例2 :
generate
for (i=0; i<7; i=i+1)
begin : asin_1d
assign w_rise_pos[(i+1)*P_BW-1:i*P_BW] = r_rise_pos[i] ;
end
endgenerate
回路例:

この回路例は、レジスタブロック(pgen_reg)とパルス生成ブロック(pgen_plsgen)で構成。
7組の 立ち上げタイミング(r_rise_pos)と立ち下げタイミング(r_fall_pos)レジスタを持ち、スタートビット(r_cntstart) に '1' をライトする事で、設定したタイミングで ON/OFF する7つのパルスを出力する。
立ち上げ/たち下げタイミングを 2次元配列とし、ブロック間 を1次元配列として接続している。
RTL (Verilog)
レジスタブロック : 2次元配列→1次元配列 のアサインに 上述の 例1 と 例2 を使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | // ----------------------------------------------------- // 2d-array Sample module // // Module Name : pgen_reg // Version : 0.00 // ----------------------------------------------------- module pgen_reg #( // Module name : test parameter P_BW = 8 // parameter list ) ( // clr, // port list clk, adr, we, data, rd_data, cntstart, cntmax, rise_pos, fall_pos ) ; // ====== port declaration ================ input clr ; input clk ; input [3:0] adr ; input we ; input [P_BW-1:0] data ; output [P_BW-1:0] rd_data ; output cntstart ; output [P_BW-1:0] cntmax ; output reg [7*P_BW-1:0] rise_pos ; output reg [7*P_BW-1:0] fall_pos ; // ====== parameter declaration =========== parameter DLY = 1 ; // ====== internal signal declaration ===== wire [15:0] sel ; wire [15:0] reg_wen ; wire [7*P_BW-1:0] w_rise_pos ; wire [7*P_BW-1:0] w_fall_pos ; reg r_cntstart ; reg [P_BW-1:0] r_cntmax ; reg [P_BW-1:0] r_rise_pos[0:6] ; reg [P_BW-1:0] r_fall_pos[0:6] ; // variable for generate ---------- genvar i ; // ====== logical description ============= // address decode ------------------------- assign sel = 16'd1 << adr ; // write enable --------------------------- assign reg_wen = sel & {16{we}} ; // register ------------------------------- // cntstart reg ----------------------- always @(posedge clk or posedge clr) if (clr) r_cntstart <= #DLY 1'b0 ; else if (reg_wen[0]) r_cntstart <= #DLY data[0] ; // cntmax reg ------------------------- always @(posedge clk or posedge clr) if (clr) r_cntmax <= #DLY {P_BW{1'b0}} ; else if (reg_wen[1]) r_cntmax <= #DLY data ; // rise_pos, fall_pos reg ------------- generate for (i=0; i<7; i=i+1) begin : pos_reg always @(posedge clk or posedge clr) if (clr) r_rise_pos[i] <= #DLY {P_BW{1'b0}} ; else if (reg_wen[i*2+2]) r_rise_pos[i] <= #DLY data ; always @(posedge clk or posedge clr) if (clr) begin r_fall_pos[i] <= #DLY {P_BW{1'b0}} ; end else if (reg_wen[i*2+3]) r_fall_pos[i] <= #DLY data ; end endgenerate // read data select ----------------------- assign rd_data = (sel[0]) ? {{(P_BW-1){1'b0}},r_cntstart} : (sel[1]) ? r_cntmax : (sel[2]) ? r_rise_pos[0] : (sel[3]) ? r_fall_pos[0] : (sel[4]) ? r_rise_pos[1] : (sel[5]) ? r_fall_pos[1] : (sel[6]) ? r_rise_pos[2] : (sel[7]) ? r_fall_pos[2] : (sel[8]) ? r_rise_pos[3] : (sel[9]) ? r_fall_pos[3] : (sel[10]) ? r_rise_pos[4] : (sel[11]) ? r_fall_pos[4] : (sel[12]) ? r_rise_pos[5] : (sel[13]) ? r_fall_pos[5] : (sel[14]) ? r_rise_pos[6] : (sel[15]) ? r_fall_pos[6] : {P_BW{1'b1}} ; // 2d_array -> 1d_array -------------------- // EX.1 ------------ assign w_rise_pos = { r_rise_pos[6], r_rise_pos[5], r_rise_pos[4], r_rise_pos[3], r_rise_pos[2], r_rise_pos[1], r_rise_pos[0] } ; // EX.2 ------------ generate for (i=0; i<7; i=i+1) begin : asin_1d assign w_fall_pos[(i+1)*P_BW-1:i*P_BW] = r_fall_pos[i] ; end endgenerate // output signal --------------------------- assign cntstart = r_cntstart ; assign cntmax = r_cntmax ; always @(posedge clk or posedge clr) if (clr) rise_pos <= #DLY {(7*P_BW){1'b0}} ; else rise_pos <= #DLY w_rise_pos ; always @(posedge clk or posedge clr) if (clr) fall_pos <= #DLY {(7*P_BW){1'b0}} ; else fall_pos <= #DLY w_fall_pos ; endmodule |
パルス生成ブロック : 1次元配列→2次元配列 のアサインに 上述の 例2 と同様の記述を使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | // ----------------------------------------------------- // 2d-array Sample module // // Module Name : pgen_plsgen // Version : 0.00 // ----------------------------------------------------- module pgen_plsgen #( // Module name : test_plsgen parameter P_BW = 8 // parameter list ) ( // clr, // port list clk, cntstart, cntmax, rise_pos, fall_pos, pls_0, pls_1, pls_2, pls_3, pls_4, pls_5, pls_6 ) ; // ====== port declaration ================ input clr ; input clk ; input cntstart ; input [P_BW-1:0] cntmax ; input [7*P_BW-1:0] rise_pos ; input [7*P_BW-1:0] fall_pos ; output pls_0 ; output pls_1 ; output pls_2 ; output pls_3 ; output pls_4 ; output pls_5 ; output pls_6 ; // ====== parameter declaration =========== parameter DLY = 1 ; // ====== internal signal declaration ===== wire w_start_pls ; wire [P_BW-1:0] w_rise_pos[0:6] ; wire [P_BW-1:0] w_fall_pos[0:6] ; wire w_pls[0:6] ; wire w_valid ; reg r_start_dl ; reg [P_BW-1:0] r_count ; reg r_pls[0:6] ; // variable for generate ---------- genvar i ; // ====== logical description ============= // input array -> 2d array assign --------- generate for (i=0; i<7; i=i+1) begin : asin_2d assign w_rise_pos[i] = rise_pos[(i+1)*P_BW-1:i*P_BW] ; assign w_fall_pos[i] = fall_pos[(i+1)*P_BW-1:i*P_BW] ; end endgenerate // generate start pulse ------------------- always @(posedge clk or posedge clr) if (clr) r_start_dl <= #DLY 1'b0 ; else r_start_dl <= #DLY cntstart ; assign w_start_pls = cntstart & ~r_start_dl ; // pulse counter ------------------------- always @(posedge clk or posedge clr) if (clr) r_count <= #DLY {P_BW{1'b0}}; else if (w_start_pls) r_count <= #DLY {{(P_BW-1){1'b0}},1'b1} ; else if ((r_count > 0) && (r_count < cntmax) ) r_count <= #DLY r_count + 1 ; else if (r_count == cntmax) r_count <= #DLY {P_BW{1'b0}} ; assign r_valid = r_count != 0 ; // pulse generate ------------------------- generate for (i=0; i<7; i=i+1) begin : pos_reg assign w_pls[i] = (w_rise_pos[i] <= r_count) && (r_count < w_fall_pos[i]) && r_valid ; always @(posedge clk or posedge clr) if (clr) r_pls[i] <= #DLY {P_BW{1'b0}} ; else r_pls[i] <= #DLY w_pls[i] ; end endgenerate // output signal --------------------------- assign pls_0 = r_pls[0] ; assign pls_1 = r_pls[1] ; assign pls_2 = r_pls[2] ; assign pls_3 = r_pls[3] ; assign pls_4 = r_pls[4] ; assign pls_5 = r_pls[5] ; assign pls_6 = r_pls[6] ; endmodule |
トップブロック : レジスタブロックとパルス生成ブロックの上位ブロック
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | // ----------------------------------------------------- // 2d-array Sample module // // Module Name : pgen // Version : 0.00 // ----------------------------------------------------- module pgen( clr, // port list clk, adr, we, data, rd_data, pls_0, pls_1, pls_2, pls_3, pls_4, pls_5, pls_6 ) ; // ====== port declaration ================ input clr ; input clk ; input [3:0] adr ; input we ; input [ 7:0] data ; output [ 7:0] rd_data ; output pls_0 ; output pls_1 ; output pls_2 ; output pls_3 ; output pls_4 ; output pls_5 ; output pls_6 ; // ====== internal signal declaration ===== wire cntstart ; wire [ 7:0] cntmax ; wire [7*8 -1:0] rise_pos ; wire [7*8 -1:0] fall_pos ; // ====== logical description ============= pgen_reg #( .P_BW (8) )i_test_reg( .clr ( clr ), .clk ( clk ), .adr ( adr ), .we ( we ), .data ( data ), .rd_data ( rd_data ), .cntstart ( cntstart ), .cntmax ( cntmax ), .rise_pos ( rise_pos ), .fall_pos ( fall_pos ) ) ; pgen_plsgen #( .P_BW (8) )i_test_plsgen( .clr ( clr ), .clk ( clk ), .cntstart ( cntstart ), .cntmax ( cntmax ), .rise_pos ( rise_pos ), .fall_pos ( fall_pos ), .pls_0 ( pls_0 ), .pls_1 ( pls_1 ), .pls_2 ( pls_2 ), .pls_3 ( pls_3 ), .pls_4 ( pls_4 ), .pls_5 ( pls_5 ), .pls_6 ( pls_6 ) ) ; endmodule |
シミュレーション用のテストベンチ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | // ---------------------------------------------------------- // test bench // // for pgen.v // ---------------------------------------------------------- `timescale 1ns / 1ps module testbench ; // testbench logic ------------------- logic clr; logic clk; logic [ 3:0] adr ; logic we ; logic [ 7:0] data ; logic [ 7:0] rd_data ; logic pls_0 ; logic pls_1 ; logic pls_2 ; logic pls_3 ; logic pls_4 ; logic pls_5 ; logic pls_6 ; // parameter ------------------------- parameter MAX_SIM_TIME = 20000 ; // target module --------------------- pgen i_pgen ( .clr ( clr ), .clk ( clk ), .adr ( adr ), .we ( we ), .data ( data ), .rd_data ( rd_data ), .pls_0 ( pls_0 ), .pls_1 ( pls_1 ), .pls_2 ( pls_2 ), .pls_3 ( pls_3 ), .pls_4 ( pls_4 ), .pls_5 ( pls_5 ), .pls_6 ( pls_6 ) ) ; // clock, reset generate ------------- initial begin clk = 0 ; clr = 1 ; #10 clr = 0 ; forever begin #10 clk = ~clk ; end end // scenario -------------------------- initial begin $dumpfile("wave.vcd"); $dumpvars(0,testbench) ; adr = 4'h0 ; we = 1'b0 ; data = 8'h0 ; #MAX_SIM_TIME $display(" SIM TIME OUT !!") ; $finish ; end // include test patteern ------------ initial begin $display (" ") ; #200 @(posedge clk) #1 adr = 4'h2 ; // rise_pos 0 data = 8'h10 ; we = 1'b1 ; @(posedge clk) #1 we = 1'b0 ; @(posedge clk) #1 @(posedge clk) #1 adr = 4'h3 ; // fall_pos 0 data = 8'h14 ; we = 1'b1 ; @(posedge clk) #1 we = 1'b0 ; @(posedge clk) #1 adr = 4'h4 ; // rise_pos 1 data = 8'h20 ; we = 1'b1 ; @(posedge clk) #1 we = 1'b0 ; @(posedge clk) #1 @(posedge clk) #1 adr = 4'h5 ; // fall_pos 1 data = 8'h28 ; we = 1'b1 ; @(posedge clk) #1 we = 1'b0 ; @(posedge clk) #1 adr = 4'h6 ; // rise_pos 2 data = 8'h30 ; we = 1'b1 ; @(posedge clk) #1 we = 1'b0 ; @(posedge clk) #1 @(posedge clk) #1 adr = 4'h7 ; // fall_pos 2 data = 8'h3f ; we = 1'b1 ; @(posedge clk) #1 we = 1'b0 ; @(posedge clk) #1 adr = 4'h8 ; // rise_pos 3 data = 8'h12 ; we = 1'b1 ; @(posedge clk) #1 we = 1'b0 ; @(posedge clk) #1 @(posedge clk) #1 adr = 4'h9 ; // fall_pos 3 data = 8'h38 ; we = 1'b1 ; @(posedge clk) #1 we = 1'b0 ; @(posedge clk) #1 adr = 4'ha ; // rise_pos 4 data = 8'h3e ; we = 1'b1 ; @(posedge clk) #1 we = 1'b0 ; @(posedge clk) #1 @(posedge clk) #1 adr = 4'hb ; // fall_pos 4 data = 8'h3f ; we = 1'b1 ; @(posedge clk) #1 we = 1'b0 ; @(posedge clk) #1 adr = 4'hc ; // rise_pos 5 data = 8'h0f ; we = 1'b1 ; @(posedge clk) #1 we = 1'b0 ; @(posedge clk) #1 @(posedge clk) #1 adr = 4'hd ; // fall_pos 5 data = 8'h10 ; we = 1'b1 ; @(posedge clk) #1 we = 1'b0 ; @(posedge clk) #1 adr = 4'he ; // rise_pos 6 data = 8'h20 ; we = 1'b1 ; @(posedge clk) #1 we = 1'b0 ; @(posedge clk) #1 @(posedge clk) #1 adr = 4'hf ; // fall_pos 7 data = 8'h21 ; we = 1'b1 ; @(posedge clk) #1 we = 1'b0 ; @(posedge clk) #1 adr = 4'h1 ; // count max data = 8'h50 ; we = 1'b1 ; @(posedge clk) #1 we = 1'b0 ; @(posedge clk) #1 @(posedge clk) #1 adr = 4'h0 ; // count start on data = 8'h01 ; we = 1'b1 ; @(posedge clk) #1 we = 1'b0 ; @(posedge clk) #1 @(posedge clk) #1 adr = 4'h0 ; // count start off data = 8'h00 ; we = 1'b1 ; @(posedge clk) #1 we = 1'b0 ; repeat(100) @(posedge clk) ; $display ("test_END"); $finish ; end // include assertion bind list ------- //`include "bind.list" //`include "bind_sva.sv" //`include "sva_1.sv" endmodule |
シミュレーション結果を以下に示す。
コマンドラインからの VCD出力では 2次元配列の信号が表示されなかった為、vivado GUI でのシミュレーション波形を表示。pls0 のみ レジスタブロックとパルス生成ブロックの2次元配列を表示。(他は パルス生成ブロックのみ)
0 件のコメント:
コメントを投稿