>100 Views
April 17, 26
スライド概要
コンパイラのコンパの部分 #2
低レイヤー好きの大学生です。 ハードウェア的に面白い計算装置を電子工作で自作するのが好きです。
きっちー (@rikeden_net) コンパイラのコンパの部分 #2
Motivation • 自作三進CPUを作った。 • (±5V, トランジスタ 2000 個ぐらい)
Motivation • 三進回路は脳内シミュレーションで 設計していたためミスが頻発 • 次世代機を作る前にシミュレーショ ンツールを作ろう!
Over v iew ➀三進リテラル、三進信号を含めた Verilog風HDL ➁1 trit を 2 bit で表現して Sy stemVerilog にトランスパイル 3't10# 6'b100001 twire, treg wire[1:0], reg[1:0] bwire, breg wire, reg tvalue ?? exp_1 : exp_0 : exp_# tvalue == 2'b10 ? exp_1 : tvalue == 2'b00 ? exp_0 : exp_#
Ex ample: 命令デコーダ module decoder ( input twire[4:0] inst, output twire d_ExeCmp, ); bwire op1s, op2s, cmps; assign op1s = (inst[4:3] == 2't01); assign op2s = (inst[4] == 1't1 | inst[4:3] == 2't00) & (inst[2:1] == 2't#0); assign d_ExeCmp = (op2s | op1s) ? 1't1 : 1't#; endmodule `include "terilog.sv" module decoder ( input wire [9:0] inst, output wire [1:0] d_ExeCmp ); wire op1s,op2s,cmps; assign op1s = (inst[9:6]) == (4'b0010); assign op2s = (((inst[9:8]) == (2'b10)) | ((inst[9:6]) == (4'b0000))) & ((inst[5:2]) == (4'b0100)); assign d_ExeCmp = ((op2s) | (op1s)) ? (2'b10) : (2'b01); endmodule
Ex ample: 加算器
module adder (
input twire[4:0] a,
input twire[4:0] b,
output twire[4:0] c,
output twire carry
);
assign {carry, c} = {1't0, a} + {1't0, b};
endmodule
`include "terilog.sv"
module adder (
input wire [9:0] a,
input wire [9:0] b,
output wire [9:0] c,
output wire [1:0] carry
);
assign {carry, c} = terilog::tadd6(
{2'b00, a}, {2'b00, b});
endmodule
Transpiler • Rust 製 • lalr pop で文法定義、パーサ生成 • 型チェック、emit を実装 (Github はさっき public にしたので まだ検索引っかからない) (他の方の同名のリポジトリが存在す ることにさっき気付いた) https://github.com/Kitchy-rikeden/Terilog
宣伝 • 技術書典オンラインマーケットにて 自作三進CPU本販売中!(~ 4/26) • 平衡三進数、三値論理、 三値論理回路の構成法 • 自作三進CPUのアーキテクチャ • etc.