目的:
除算器の構成、RTLについて記す。仕様:
本除算器は、- 演算は 16bit ÷ 16bit の符号なし整数 の 除算で、出力は 商と剰余 各16bit
- 複数クロックを使用して演算を行う。
- 開始パルスで演算を開始し、演算終了で終了信号を出力する。
除算方法:
除算は、回復法により行う。除算の方法を下図に示す。
除算の手順は、
- 被除数の上位に除数のbit数分の 0 拡張を、除数に 1bit の 0拡張を行う。
- 被除数の上位bit から 除数 を減算する。
- 減算できる場合 (ボローが発生しない場合) は、減算した結果で被除数の上位bit を置き換えて 1bit 左シフトし、減算できない場合(ボローが発生した場合) は 被除数の上位 bit の置き換えは行わずに 1bit 左シフトを行う。
- また、商(初期値 0) を 1bit 左シフトし、最下位bit を ボローの反転値 とする。
- 2~5 を 被除数のbit数(拡張前) 分繰り返して商を得る。
- また、繰り返し終了後の被除数の拡張部分の値が 剰余となる。
被除数 3bit の為、3回繰り返して 商と剰余を得る。
右側に対応する 2進数での 割り算 の筆算 を示している。
ブロック図:
除算器のブロック図を以下に示す。
動作は、上述の除算方法の通り。RTL:
上述のブロック図 の RTL を以下に示す。// ---------------------------------------------------------------------------- // Divider // // Module Name : divid // Version : 0.00 // ---------------------------------------------------------------------------- module divid ( // Module name : divid CLR, // port list CLK, a, b, start, division, remainder, complete ) ; // port declaration ---------------- input CLR ; input CLK ; input [15:0] a ; input [15:0] b ; input start ; output reg [15:0] division ; output reg [15:0] remainder ; output reg complete ; // parameter declaration ----------- parameter P_DLY = 1 ; // internal signal declaration ----- wire op_cnt_en ; wire borrow ; wire [17:0] sub ; wire div_en ; reg [4:0] op_cnt ; reg [32:0] div_ref ; reg [15:0] div_val ; // logical description ------------- assign op_cnt_en = (op_cnt < 6'd16) ; always @(posedge CLK or posedge CLR) if (CLR) op_cnt <= #P_DLY 5'd31 ; else if (start) op_cnt <= #P_DLY 5'd0 ; else if (op_cnt_en) op_cnt <= #P_DLY op_cnt + 5'd1 ; always @(posedge CLK or posedge CLR) if (CLR) div_ref <= #P_DLY 32'd0 ; else if (start) div_ref <= #P_DLY {16'b0,a} ; else if (~borrow & div_en) div_ref <= #P_DLY {sub[15:0],div_ref[14:0],1'b0} ; else if (div_en) div_ref <= #P_DLY div_ref << 1 ; assign sub = {1'b0,div_ref[31:15]} - {2'b0,b} ; assign borrow = sub[17] ; assign div_en = (op_cnt <= 5'd15) ; always @(posedge CLK or posedge CLR) if (CLR) div_val <= #P_DLY 16'd0 ; else if (start) div_val <= #P_DLY 16'd0 ; else if (div_en) div_val <= #P_DLY {div_val[14:0],~borrow} ; always @(posedge CLK or posedge CLR) if (CLR) complete <= #P_DLY 1'b0 ; else complete <= #P_DLY (op_cnt == 5'd16) ; always @(posedge CLK or posedge CLR) if (CLR) division <= #P_DLY 16'd0 ; else division <= #P_DLY div_val ; always @(posedge CLK or posedge CLR) if (CLR) remainder <= #P_DLY 16'd0 ; else remainder <= #P_DLY div_ref[31:16] ; endmodule
0 件のコメント:
コメントを投稿