AXIルータを自動生成できるよう、スクリプトを記述している。 今は、入力データに対して、どのようにアドレスデコーダを搭載して、パケットをルーティングするかというところだ。
$regions = Array[Array['START', Array['1011_1111_1100_XXXX_XXXX_XXXX_XXXX_XXXX']], Array['TEXT', Array['1000_XXXX_XXXX_XXXX_XXXX_XXXX_XXXX_XXXX']], Array['L1', Array['0111_XXXX_XXXX_XXXX_XXXX_XXXX_XXXX_XXXX']], Array['EX', Array['others']]]
とりあえず、指定されたアドレス領域ならば、その方向へルーティングするべき信号をassertするような生成コードを作った。
def gen_region_detector(fp, regions) regions.each{|region| region_name = region[0] region_addresses = region[1] address_exp = "" region_addresses.each{|region_address| if region_address == 'others' then regions.each {|not_region| address_exp = gen_and(address_exp, "~" + "is_region_" + not_region[0]) } break else start = 31 index = start bit_region_idx = 0 bit_region = "" region_address.each_char{|bit| if bit == '_' then next elsif bit == '1' or bit == '0' then index=index-1 bit_region[bit_region_idx] = bit bit_region_idx = bit_region_idx + 1 elsif index != start then address_exp = gen_or(address_exp, sprintf(gen_signal_bitwidth(region_name, start, index)) + " == " + sprintf("2'b%s", bit_region)) start=index bit_region_idx = 0 else start = start - 1 index = index - 1 end } end } fp.printf(connect_assign("is_region_" + region_name, address_exp)) } end
一つ一つアドレス情報をデコードして、ビットインデックスを作成していく。Xに到達したら、それより前のビット情報で比較コードを生成することを繰替えす。 これで、以下のようなコードが生成されるようになる。othersを使うと、それまでに作成した信号がどれもassertされないときに有効になる。
assign is_region_START = START[31:19] == 2'b101111111100; assign is_region_TEXT = TEXT[31:27] == 2'b1000; assign is_region_L1 = L1[31:27] == 2'b0111; assign is_region_EX = (((~is_region_START) & (~is_region_TEXT)) & (~is_region_L1)) & (~is_region_EX);
ちょっと体裁が不細工だが、自動生成だし、まずはしようがない。これを使って、いよいよパケットのルーティングと、次はアービトレーションをできるようにしていこう。