![見出し画像](https://assets.st-note.com/production/uploads/images/167847386/rectangle_large_type_2_ab8932e0fd0ce93c8f554630046b2b29.png?width=1200)
Photo by
take_kuroki
GoogleXLSでprocを使ってみる
背景
昨日の練習結果。fn hogehogeは使いこなせるようになってきたので、次はXLSのproc(状態回路)を練習してみよう。
練習
xlsのgithubからのサンプル
まずは練習。
fmac.x
import float32;
type F32 = float32::F32;
proc Fmac {
input_a_consumer: chan<F32> in;
input_b_consumer: chan<F32> in;
output_producer: chan<F32> out;
init {
float32::zero(false)
}
config(input_a_consumer: chan<F32> in, input_b_consumer: chan<F32> in,
output_producer: chan<F32> out) {
(input_a_consumer, input_b_consumer, output_producer)
}
next(state: F32) {
let tok = join();
let (tok_a, input_a) = recv(tok, input_a_consumer);
let (tok_b, input_b) = recv(tok, input_b_consumer);
let result = float32::fma(input_a, input_b, state);
let tok = join(tok_a, tok_b);
let tok = send(tok, output_producer, result);
result
}
}
Float32:a + Float:b = Float:out
と計算するのが内容です。
Makefile
# Variables
TOP = Fmac
INPUT_FILE = fmac.x
IR_FILE = $(TOP).ir
OPT_IR_FILE = $(TOP)_opt.ir
OUTPUT_DIR = /home/haruhiko/xls/bazel-bin
OUTPUT_FILE = fmac.v
# Tools
INTERPRETER = $(OUTPUT_DIR)/xls/dslx/interpreter_main
IR_CONVERTER = $(OUTPUT_DIR)/xls/dslx/ir_convert/ir_converter_main
OPT_MAIN = $(OUTPUT_DIR)/xls/tools/opt_main
CODEGEN_MAIN = $(OUTPUT_DIR)/xls/tools/codegen_main
# Default target
all: codegen
# Targets with dependencies
ir_convert: interpret
$(IR_CONVERTER) --top=$(TOP) $(INPUT_FILE) > $(IR_FILE)
optimize: ir_convert
$(OPT_MAIN) $(IR_FILE) > $(OPT_IR_FILE)
codegen: optimize
$(CODEGEN_MAIN) \
--pipeline_stages=1 \
--generator=pipeline \
--delay_model=unit \
--use_system_verilog=false \
--reset=... \
$(OPT_IR_FILE) > $(OUTPUT_FILE)
interpret:
$(INTERPRETER) $(INPUT_FILE)
# Clean intermediate files
clean:
rm -f $(IR_FILE) $(OPT_IR_FILE) $(OUTPUT_FILE)
結果
haruhiko@haruhiko-Default-string:~/Program/GoogleXLS_test-main$ make
/home/haruhiko/xls/bazel-bin/xls/dslx/interpreter_main fmac.x
[===============] 0 test(s) ran; 0 failed; 0 skipped.
/home/haruhiko/xls/bazel-bin/xls/dslx/ir_convert/ir_converter_main --top=Fmac fmac.x > Fmac.ir
/home/haruhiko/xls/bazel-bin/xls/tools/opt_main Fmac.ir > Fmac_opt.ir
/home/haruhiko/xls/bazel-bin/xls/tools/codegen_main \
--pipeline_stages=1 \
--generator=pipeline \
--delay_model=unit \
--use_system_verilog=false \
--reset=... \
Fmac_opt.ir > fmac.v
Verilogコード
module __fmac__Fmac_0_next(
input wire clk,
input wire ___,
input wire [31:0] fmac__input_a_consumer,
input wire fmac__input_a_consumer_vld,
input wire [31:0] fmac__input_b_consumer,
input wire fmac__input_b_consumer_vld,
input wire fmac__output_producer_rdy,
output wire [31:0] fmac__output_producer,
output wire fmac__output_producer_vld,
output wire fmac__input_a_consumer_rdy,
output wire fmac__input_b_consumer_rdy
);
// lint_off MULTIPLY
function automatic [47:0] umul48b_24b_x_24b (input reg [23:0] lhs, input reg [23:0] rhs);
begin
umul48b_24b_x_24b = lhs * rhs;
end
endfunction
// lint_on MULTIPLY
function automatic priority_sel_1b_2way (input reg [1:0] sel, input reg case0, input reg case1, input reg default_value);
begin
casez (sel)
2'b?1: begin
priority_sel_1b_2way = case0;
end
2'b10: begin
priority_sel_1b_2way = case1;
end
2'b00: begin
priority_sel_1b_2way = default_value;
end
default: begin
// Propagate X
priority_sel_1b_2way = 1'dx;
end
endcase
end
endfunction
wire [31:0] __fmac__input_a_consumer_reg_init = {1'h0, 8'h00, 23'h00_0000};
wire [31:0] __fmac__input_b_consumer_reg_init = {1'h0, 8'h00, 23'h00_0000};
wire [31:0] __fmac__output_producer_reg_init = {1'h0, 8'h00, 23'h00_0000};
reg [7:0] ____state_1;
reg [22:0] ____state_2;
reg ____state_0;
reg [31:0] __fmac__input_a_consumer_reg;
reg __fmac__input_a_consumer_valid_reg;
reg [31:0] __fmac__input_b_consumer_reg;
reg __fmac__input_b_consumer_valid_reg;
reg [31:0] __fmac__output_producer_reg;
reg __fmac__output_producer_valid_reg;
wire [7:0] input_a_bexp__4;
wire [7:0] input_b_bexp__4;
wire eq_2233;
wire eq_2234;
wire [22:0] input_a_fraction__1;
wire [22:0] input_b_fraction__1;
wire [23:0] input_a_fraction__6;
wire [23:0] input_b_fraction__6;
wire [47:0] fraction;
wire __stateancel__7;
wire __stateancel__8;
wire __stateancel__6;
wire [8:0] add_2257;
wire [8:0] add_2258;
wire [9:0] input_bexp__6;
wire [9:0] input_bexp__11;
wire [9:0] input_bexp__12;
wire [9:0] input_bexp__13;
wire [7:0] max_exp;
wire [7:0] max_exp__1;
wire is_subnormal;
wire eq_2271;
wire eq_2272;
wire eq_2273;
wire eq_2274;
wire has_0_arg;
wire has_inf_arg;
wire __stateancel__3;
wire [8:0] result_exp__3;
wire is_result_nan__1;
wire [47:0] fraction__1;
wire [8:0] sub_exp;
wire [8:0] high_exp;
wire __stateancel__1;
wire [8:0] result_exp__4;
wire [8:0] concat_2309;
wire [47:0] result_fraction__5;
wire ugt_2315;
wire [47:0] result_fraction__7;
wire [47:0] nan_fraction;
wire [23:0] wide_c__3;
wire [8:0] add_2321;
wire [8:0] greater_exp;
wire [47:0] result_fraction__8;
wire [8:0] add_2325;
wire [72:0] wide_c__2;
wire [8:0] sub_2327;
wire [72:0] wide_ab;
wire [8:0] sub_2329;
wire [8:0] rshift_c;
wire [72:0] dropped_c;
wire [72:0] dropped_ab;
wire [23:0] dropped_c__2;
wire input_a_sign__2;
wire input_b_sign__2;
wire [8:0] rshift_ab;
wire result_sign__3;
wire [72:0] shifted_ab;
wire [72:0] sticky_ab;
wire [72:0] shifted_c;
wire [72:0] sticky_c;
wire result_sign__4;
wire __stateancel__9;
wire __stateancel__10;
wire greater_sign;
wire [73:0] shifted_ab__1_squeezed;
wire [73:0] shifted_c__1_squeezed;
wire [73:0] shifted_ab__2_squeezed;
wire [73:0] shifted_c__2_squeezed;
wire [74:0] shifted_ab__2;
wire [74:0] shifted_c__2;
wire [74:0] sum_fraction;
wire [73:0] input_abs_fraction__1;
wire [73:0] reverse_2375;
wire [74:0] one_hot_2376;
wire [6:0] encode_2377;
wire __stateancel__4;
wire __statearry_bit__1;
wire [8:0] high_exp__2;
wire [8:0] add_2388;
wire [72:0] __statearry_fraction__3;
wire [2:0] concat_2396;
wire [72:0] __statearry_fraction__2;
wire [72:0] __stateancel_fraction__1;
wire [72:0] shifted_fraction;
wire [48:0] normal_chunk;
wire [48:0] half_of_extra;
wire [1:0] half_way_chunk;
wire __stateancel__11;
wire [24:0] concat_2409;
wire do_round_up;
wire [24:0] add_2412;
wire [24:0] rounded_fraction__1;
wire __stateancel__2;
wire rounding_carry;
wire [9:0] add_2420;
wire fraction_is_zero;
wire [9:0] add_2424;
wire [9:0] input_bexp__3;
wire [9:0] input_bexp__4;
wire [8:0] high_exp__1;
wire [7:0] max_exp__2;
wire eq_2438;
wire eq_2439;
wire eq_2440;
wire eq_2441;
wire and_2446;
wire [8:0] input_bexp__5;
wire has_pos_inf;
wire has_neg_inf;
wire fmac__output_producer_valid_inv;
wire is_operand_inf;
wire and_reduce_2456;
wire is_result_nan;
wire p0_all_active_inputs_valid;
wire fmac__output_producer_valid_load_en;
wire or_2461;
wire or_2476;
wire fmac__output_producer_load_en;
wire __stateancel__5;
wire p0_stage_done;
wire and_2486;
wire and_2487;
wire result_sign;
wire [22:0] result_fraction;
wire [3:0] one_hot_2567;
wire fmac__input_a_consumer_valid_inv;
wire fmac__input_b_consumer_valid_inv;
wire result_sign__1;
wire [7:0] max_exp__3;
wire [22:0] result_fraction__3;
wire [1:0] concat_2513;
wire [7:0] max_exp__4;
wire [2:0] concat_2521;
wire fmac__input_a_consumer_valid_load_en;
wire fmac__input_b_consumer_valid_load_en;
wire result_sign__2;
wire [7:0] result_exp__2;
wire [22:0] result_fraction__4;
wire [7:0] one_hot_sel_2514;
wire [22:0] one_hot_sel_2522;
wire and_2533;
wire fmac__input_a_consumer_load_en;
wire fmac__input_b_consumer_load_en;
wire [31:0] result;
assign input_a_bexp__4 = __fmac__input_a_consumer_reg[30:23];
assign input_b_bexp__4 = __fmac__input_b_consumer_reg[30:23];
assign eq_2233 = input_a_bexp__4 == 8'h00;
assign eq_2234 = input_b_bexp__4 == 8'h00;
assign input_a_fraction__1 = __fmac__input_a_consumer_reg[22:0];
assign input_b_fraction__1 = __fmac__input_b_consumer_reg[22:0];
assign input_a_fraction__6 = {1'h1, input_a_fraction__1} & {24{~eq_2233}};
assign input_b_fraction__6 = {1'h1, input_b_fraction__1} & {24{~eq_2234}};
assign fraction = umul48b_24b_x_24b(input_a_fraction__6, input_b_fraction__6);
assign __stateancel__7 = 1'h0;
assign __stateancel__8 = 1'h0;
assign __stateancel__6 = 1'h0;
assign add_2257 = {__stateancel__7, input_a_bexp__4} + {__stateancel__8, input_b_bexp__4};
assign add_2258 = {8'h00, fraction[47]} + 9'h181;
assign input_bexp__6 = {__stateancel__6, add_2257};
assign input_bexp__11 = {{1{add_2258[8]}}, add_2258};
assign input_bexp__12 = input_bexp__6 + input_bexp__11;
assign input_bexp__13 = input_bexp__12 & {10{~(eq_2233 | eq_2234)}};
assign max_exp = 8'hff;
assign max_exp__1 = 8'hff;
assign is_subnormal = $signed(input_bexp__13) <= $signed(10'h000);
assign eq_2271 = input_a_bexp__4 == max_exp;
assign eq_2272 = input_a_fraction__1 == 23'h00_0000;
assign eq_2273 = input_b_bexp__4 == max_exp__1;
assign eq_2274 = input_b_fraction__1 == 23'h00_0000;
assign has_0_arg = eq_2233 | eq_2234;
assign has_inf_arg = eq_2271 & eq_2272 | eq_2273 & eq_2274;
assign __stateancel__3 = 1'h0;
assign result_exp__3 = input_bexp__13[8:0] & {9{~is_subnormal}};
assign is_result_nan__1 = ~(~eq_2271 | eq_2272) | ~(~eq_2273 | eq_2274) | has_0_arg & has_inf_arg;
assign fraction__1 = fraction[47] ? fraction : {fraction[46:0], __stateancel__3};
assign sub_exp = input_bexp__13[9] ? -input_bexp__13[8:0] : input_bexp__13[8:0];
assign high_exp = 9'h1ff;
assign __stateancel__1 = 1'h0;
assign result_exp__4 = is_result_nan__1 | has_inf_arg ? high_exp : result_exp__3;
assign concat_2309 = {__stateancel__1, ____state_1};
assign result_fraction__5 = is_subnormal ? (sub_exp >= 9'h030 ? 48'h0000_0000_0000 : fraction__1 >> sub_exp) : fraction__1;
assign ugt_2315 = result_exp__4 > concat_2309;
assign result_fraction__7 = result_fraction__5 & {48{~(has_inf_arg | (&result_exp__3))}};
assign nan_fraction = 48'h0000_0000_0001;
assign wide_c__3 = {1'h1, ____state_2} & {24{____state_1 != 8'h00}};
assign add_2321 = concat_2309 + 9'h049;
assign greater_exp = ugt_2315 ? result_exp__4 : concat_2309;
assign result_fraction__8 = is_result_nan__1 ? nan_fraction : result_fraction__7;
assign add_2325 = result_exp__4 + 9'h049;
assign wide_c__2 = {wide_c__3, 49'h0_0000_0000_0000};
assign sub_2327 = add_2321 - greater_exp;
assign wide_ab = {result_fraction__8, 25'h000_0000};
assign sub_2329 = add_2325 - greater_exp;
assign rshift_c = greater_exp - concat_2309;
assign dropped_c = sub_2327 >= 9'h049 ? 73'h000_0000_0000_0000_0000 : wide_c__2 << sub_2327;
assign dropped_ab = sub_2329 >= 9'h049 ? 73'h000_0000_0000_0000_0000 : wide_ab << sub_2329;
assign dropped_c__2 = rshift_c > 9'h048 ? wide_c__3 : dropped_c[72:49];
assign input_a_sign__2 = __fmac__input_a_consumer_reg[31:31];
assign input_b_sign__2 = __fmac__input_b_consumer_reg[31:31];
assign rshift_ab = greater_exp - result_exp__4;
assign result_sign__3 = input_a_sign__2 ^ input_b_sign__2;
assign shifted_ab = rshift_ab >= 9'h049 ? 73'h000_0000_0000_0000_0000 : wide_ab >> rshift_ab;
assign sticky_ab = {72'h00_0000_0000_0000_0000, dropped_ab[72:25] != 48'h0000_0000_0000};
assign shifted_c = rshift_c >= 9'h049 ? 73'h000_0000_0000_0000_0000 : wide_c__2 >> rshift_c;
assign sticky_c = {72'h00_0000_0000_0000_0000, dropped_c__2 != 24'h00_0000};
assign result_sign__4 = ~is_result_nan__1 & result_sign__3;
assign __stateancel__9 = 1'h0;
assign __stateancel__10 = 1'h0;
assign greater_sign = ugt_2315 ? result_sign__4 : ____state_0;
assign shifted_ab__1_squeezed = {__stateancel__9, shifted_ab | sticky_ab};
assign shifted_c__1_squeezed = {__stateancel__10, shifted_c | sticky_c};
assign shifted_ab__2_squeezed = result_sign__4 ^ greater_sign ? -shifted_ab__1_squeezed : shifted_ab__1_squeezed;
assign shifted_c__2_squeezed = ____state_0 ^ greater_sign ? -shifted_c__1_squeezed : shifted_c__1_squeezed;
assign shifted_ab__2 = {{1{shifted_ab__2_squeezed[73]}}, shifted_ab__2_squeezed};
assign shifted_c__2 = {{1{shifted_c__2_squeezed[73]}}, shifted_c__2_squeezed};
assign sum_fraction = shifted_ab__2 + shifted_c__2;
assign input_abs_fraction__1 = sum_fraction[74] ? -sum_fraction[73:0] : sum_fraction[73:0];
assign reverse_2375 = {input_abs_fraction__1[0], input_abs_fraction__1[1], input_abs_fraction__1[2], input_abs_fraction__1[3], input_abs_fraction__1[4], input_abs_fraction__1[5], input_abs_fraction__1[6], input_abs_fraction__1[7], input_abs_fraction__1[8], input_abs_fraction__1[9], input_abs_fraction__1[10], input_abs_fraction__1[11], input_abs_fraction__1[12], input_abs_fraction__1[13], input_abs_fraction__1[14], input_abs_fraction__1[15], input_abs_fraction__1[16], input_abs_fraction__1[17], input_abs_fraction__1[18], input_abs_fraction__1[19], input_abs_fraction__1[20], input_abs_fraction__1[21], input_abs_fraction__1[22], input_abs_fraction__1[23], input_abs_fraction__1[24], input_abs_fraction__1[25], input_abs_fraction__1[26], input_abs_fraction__1[27], input_abs_fraction__1[28], input_abs_fraction__1[29], input_abs_fraction__1[30], input_abs_fraction__1[31], input_abs_fraction__1[32], input_abs_fraction__1[33], input_abs_fraction__1[34], input_abs_fraction__1[35], input_abs_fraction__1[36], input_abs_fraction__1[37], input_abs_fraction__1[38], input_abs_fraction__1[39], input_abs_fraction__1[40], input_abs_fraction__1[41], input_abs_fraction__1[42], input_abs_fraction__1[43], input_abs_fraction__1[44], input_abs_fraction__1[45], input_abs_fraction__1[46], input_abs_fraction__1[47], input_abs_fraction__1[48], input_abs_fraction__1[49], input_abs_fraction__1[50], input_abs_fraction__1[51], input_abs_fraction__1[52], input_abs_fraction__1[53], input_abs_fraction__1[54], input_abs_fraction__1[55], input_abs_fraction__1[56], input_abs_fraction__1[57], input_abs_fraction__1[58], input_abs_fraction__1[59], input_abs_fraction__1[60], input_abs_fraction__1[61], input_abs_fraction__1[62], input_abs_fraction__1[63], input_abs_fraction__1[64], input_abs_fraction__1[65], input_abs_fraction__1[66], input_abs_fraction__1[67], input_abs_fraction__1[68], input_abs_fraction__1[69], input_abs_fraction__1[70], input_abs_fraction__1[71], input_abs_fraction__1[72], input_abs_fraction__1[73]};
assign one_hot_2376 = {reverse_2375[73:0] == 74'h000_0000_0000_0000_0000, reverse_2375[73] && reverse_2375[72:0] == 73'h000_0000_0000_0000_0000, reverse_2375[72] && reverse_2375[71:0] == 72'h00_0000_0000_0000_0000, reverse_2375[71] && reverse_2375[70:0] == 71'h00_0000_0000_0000_0000, reverse_2375[70] && reverse_2375[69:0] == 70'h00_0000_0000_0000_0000, reverse_2375[69] && reverse_2375[68:0] == 69'h00_0000_0000_0000_0000, reverse_2375[68] && reverse_2375[67:0] == 68'h0_0000_0000_0000_0000, reverse_2375[67] && reverse_2375[66:0] == 67'h0_0000_0000_0000_0000, reverse_2375[66] && reverse_2375[65:0] == 66'h0_0000_0000_0000_0000, reverse_2375[65] && reverse_2375[64:0] == 65'h0_0000_0000_0000_0000, reverse_2375[64] && reverse_2375[63:0] == 64'h0000_0000_0000_0000, reverse_2375[63] && reverse_2375[62:0] == 63'h0000_0000_0000_0000, reverse_2375[62] && reverse_2375[61:0] == 62'h0000_0000_0000_0000, reverse_2375[61] && reverse_2375[60:0] == 61'h0000_0000_0000_0000, reverse_2375[60] && reverse_2375[59:0] == 60'h000_0000_0000_0000, reverse_2375[59] && reverse_2375[58:0] == 59'h000_0000_0000_0000, reverse_2375[58] && reverse_2375[57:0] == 58'h000_0000_0000_0000, reverse_2375[57] && reverse_2375[56:0] == 57'h000_0000_0000_0000, reverse_2375[56] && reverse_2375[55:0] == 56'h00_0000_0000_0000, reverse_2375[55] && reverse_2375[54:0] == 55'h00_0000_0000_0000, reverse_2375[54] && reverse_2375[53:0] == 54'h00_0000_0000_0000, reverse_2375[53] && reverse_2375[52:0] == 53'h00_0000_0000_0000, reverse_2375[52] && reverse_2375[51:0] == 52'h0_0000_0000_0000, reverse_2375[51] && reverse_2375[50:0] == 51'h0_0000_0000_0000, reverse_2375[50] && reverse_2375[49:0] == 50'h0_0000_0000_0000, reverse_2375[49] && reverse_2375[48:0] == 49'h0_0000_0000_0000, reverse_2375[48] && reverse_2375[47:0] == 48'h0000_0000_0000, reverse_2375[47] && reverse_2375[46:0] == 47'h0000_0000_0000, reverse_2375[46] && reverse_2375[45:0] == 46'h0000_0000_0000, reverse_2375[45] && reverse_2375[44:0] == 45'h0000_0000_0000, reverse_2375[44] && reverse_2375[43:0] == 44'h000_0000_0000, reverse_2375[43] && reverse_2375[42:0] == 43'h000_0000_0000, reverse_2375[42] && reverse_2375[41:0] == 42'h000_0000_0000, reverse_2375[41] && reverse_2375[40:0] == 41'h000_0000_0000, reverse_2375[40] && reverse_2375[39:0] == 40'h00_0000_0000, reverse_2375[39] && reverse_2375[38:0] == 39'h00_0000_0000, reverse_2375[38] && reverse_2375[37:0] == 38'h00_0000_0000, reverse_2375[37] && reverse_2375[36:0] == 37'h00_0000_0000, reverse_2375[36] && reverse_2375[35:0] == 36'h0_0000_0000, reverse_2375[35] && reverse_2375[34:0] == 35'h0_0000_0000, reverse_2375[34] && reverse_2375[33:0] == 34'h0_0000_0000, reverse_2375[33] && reverse_2375[32:0] == 33'h0_0000_0000, reverse_2375[32] && reverse_2375[31:0] == 32'h0000_0000, reverse_2375[31] && reverse_2375[30:0] == 31'h0000_0000, reverse_2375[30] && reverse_2375[29:0] == 30'h0000_0000, reverse_2375[29] && reverse_2375[28:0] == 29'h0000_0000, reverse_2375[28] && reverse_2375[27:0] == 28'h000_0000, reverse_2375[27] && reverse_2375[26:0] == 27'h000_0000, reverse_2375[26] && reverse_2375[25:0] == 26'h000_0000, reverse_2375[25] && reverse_2375[24:0] == 25'h000_0000, reverse_2375[24] && reverse_2375[23:0] == 24'h00_0000, reverse_2375[23] && reverse_2375[22:0] == 23'h00_0000, reverse_2375[22] && reverse_2375[21:0] == 22'h00_0000, reverse_2375[21] && reverse_2375[20:0] == 21'h00_0000, reverse_2375[20] && reverse_2375[19:0] == 20'h0_0000, reverse_2375[19] && reverse_2375[18:0] == 19'h0_0000, reverse_2375[18] && reverse_2375[17:0] == 18'h0_0000, reverse_2375[17] && reverse_2375[16:0] == 17'h0_0000, reverse_2375[16] && reverse_2375[15:0] == 16'h0000, reverse_2375[15] && reverse_2375[14:0] == 15'h0000, reverse_2375[14] && reverse_2375[13:0] == 14'h0000, reverse_2375[13] && reverse_2375[12:0] == 13'h0000, reverse_2375[12] && reverse_2375[11:0] == 12'h000, reverse_2375[11] && reverse_2375[10:0] == 11'h000, reverse_2375[10] && reverse_2375[9:0] == 10'h000, reverse_2375[9] && reverse_2375[8:0] == 9'h000, reverse_2375[8] && reverse_2375[7:0] == 8'h00, reverse_2375[7] && reverse_2375[6:0] == 7'h00, reverse_2375[6] && reverse_2375[5:0] == 6'h00, reverse_2375[5] && reverse_2375[4:0] == 5'h00, reverse_2375[4] && reverse_2375[3:0] == 4'h0, reverse_2375[3] && reverse_2375[2:0] == 3'h0, reverse_2375[2] && reverse_2375[1:0] == 2'h0, reverse_2375[1] && !reverse_2375[0], reverse_2375[0]};
assign encode_2377 = {one_hot_2376[64] | one_hot_2376[65] | one_hot_2376[66] | one_hot_2376[67] | one_hot_2376[68] | one_hot_2376[69] | one_hot_2376[70] | one_hot_2376[71] | one_hot_2376[72] | one_hot_2376[73] | one_hot_2376[74], one_hot_2376[32] | one_hot_2376[33] | one_hot_2376[34] | one_hot_2376[35] | one_hot_2376[36] | one_hot_2376[37] | one_hot_2376[38] | one_hot_2376[39] | one_hot_2376[40] | one_hot_2376[41] | one_hot_2376[42] | one_hot_2376[43] | one_hot_2376[44] | one_hot_2376[45] | one_hot_2376[46] | one_hot_2376[47] | one_hot_2376[48] | one_hot_2376[49] | one_hot_2376[50] | one_hot_2376[51] | one_hot_2376[52] | one_hot_2376[53] | one_hot_2376[54] | one_hot_2376[55] | one_hot_2376[56] | one_hot_2376[57] | one_hot_2376[58] | one_hot_2376[59] | one_hot_2376[60] | one_hot_2376[61] | one_hot_2376[62] | one_hot_2376[63], one_hot_2376[16] | one_hot_2376[17] | one_hot_2376[18] | one_hot_2376[19] | one_hot_2376[20] | one_hot_2376[21] | one_hot_2376[22] | one_hot_2376[23] | one_hot_2376[24] | one_hot_2376[25] | one_hot_2376[26] | one_hot_2376[27] | one_hot_2376[28] | one_hot_2376[29] | one_hot_2376[30] | one_hot_2376[31] | one_hot_2376[48] | one_hot_2376[49] | one_hot_2376[50] | one_hot_2376[51] | one_hot_2376[52] | one_hot_2376[53] | one_hot_2376[54] | one_hot_2376[55] | one_hot_2376[56] | one_hot_2376[57] | one_hot_2376[58] | one_hot_2376[59] | one_hot_2376[60] | one_hot_2376[61] | one_hot_2376[62] | one_hot_2376[63], one_hot_2376[8] | one_hot_2376[9] | one_hot_2376[10] | one_hot_2376[11] | one_hot_2376[12] | one_hot_2376[13] | one_hot_2376[14] | one_hot_2376[15] | one_hot_2376[24] | one_hot_2376[25] | one_hot_2376[26] | one_hot_2376[27] | one_hot_2376[28] | one_hot_2376[29] | one_hot_2376[30] | one_hot_2376[31] | one_hot_2376[40] | one_hot_2376[41] | one_hot_2376[42] | one_hot_2376[43] | one_hot_2376[44] | one_hot_2376[45] | one_hot_2376[46] | one_hot_2376[47] | one_hot_2376[56] | one_hot_2376[57] | one_hot_2376[58] | one_hot_2376[59] | one_hot_2376[60] | one_hot_2376[61] | one_hot_2376[62] | one_hot_2376[63] | one_hot_2376[72] | one_hot_2376[73] | one_hot_2376[74], one_hot_2376[4] | one_hot_2376[5] | one_hot_2376[6] | one_hot_2376[7] | one_hot_2376[12] | one_hot_2376[13] | one_hot_2376[14] | one_hot_2376[15] | one_hot_2376[20] | one_hot_2376[21] | one_hot_2376[22] | one_hot_2376[23] | one_hot_2376[28] | one_hot_2376[29] | one_hot_2376[30] | one_hot_2376[31] | one_hot_2376[36] | one_hot_2376[37] | one_hot_2376[38] | one_hot_2376[39] | one_hot_2376[44] | one_hot_2376[45] | one_hot_2376[46] | one_hot_2376[47] | one_hot_2376[52] | one_hot_2376[53] | one_hot_2376[54] | one_hot_2376[55] | one_hot_2376[60] | one_hot_2376[61] | one_hot_2376[62] | one_hot_2376[63] | one_hot_2376[68] | one_hot_2376[69] | one_hot_2376[70] | one_hot_2376[71], one_hot_2376[2] | one_hot_2376[3] | one_hot_2376[6] | one_hot_2376[7] | one_hot_2376[10] | one_hot_2376[11] | one_hot_2376[14] | one_hot_2376[15] | one_hot_2376[18] | one_hot_2376[19] | one_hot_2376[22] | one_hot_2376[23] | one_hot_2376[26] | one_hot_2376[27] | one_hot_2376[30] | one_hot_2376[31] | one_hot_2376[34] | one_hot_2376[35] | one_hot_2376[38] | one_hot_2376[39] | one_hot_2376[42] | one_hot_2376[43] | one_hot_2376[46] | one_hot_2376[47] | one_hot_2376[50] | one_hot_2376[51] | one_hot_2376[54] | one_hot_2376[55] | one_hot_2376[58] | one_hot_2376[59] | one_hot_2376[62] | one_hot_2376[63] | one_hot_2376[66] | one_hot_2376[67] | one_hot_2376[70] | one_hot_2376[71] | one_hot_2376[74], one_hot_2376[1] | one_hot_2376[3] | one_hot_2376[5] | one_hot_2376[7] | one_hot_2376[9] | one_hot_2376[11] | one_hot_2376[13] | one_hot_2376[15] | one_hot_2376[17] | one_hot_2376[19] | one_hot_2376[21] | one_hot_2376[23] | one_hot_2376[25] | one_hot_2376[27] | one_hot_2376[29] | one_hot_2376[31] | one_hot_2376[33] | one_hot_2376[35] | one_hot_2376[37] | one_hot_2376[39] | one_hot_2376[41] | one_hot_2376[43] | one_hot_2376[45] | one_hot_2376[47] | one_hot_2376[49] | one_hot_2376[51] | one_hot_2376[53] | one_hot_2376[55] | one_hot_2376[57] | one_hot_2376[59] | one_hot_2376[61] | one_hot_2376[63] | one_hot_2376[65] | one_hot_2376[67] | one_hot_2376[69] | one_hot_2376[71] | one_hot_2376[73]};
assign __stateancel__4 = |encode_2377[6:1];
assign __statearry_bit__1 = input_abs_fraction__1[73];
assign high_exp__2 = 9'h1ff;
assign add_2388 = {2'h0, encode_2377} + high_exp__2;
assign __statearry_fraction__3 = input_abs_fraction__1[73:1];
assign concat_2396 = {~(__statearry_bit__1 | __stateancel__4), ~(__statearry_bit__1 | ~__stateancel__4), ~(~__statearry_bit__1 | __stateancel__4)};
assign __statearry_fraction__2 = __statearry_fraction__3 | {72'h00_0000_0000_0000_0000, input_abs_fraction__1[0]};
assign __stateancel_fraction__1 = {{65{add_2388[8]}}, add_2388} >= 74'h000_0000_0000_0000_0049 ? 73'h000_0000_0000_0000_0000 : input_abs_fraction__1[72:0] << {{65{add_2388[8]}}, add_2388};
assign shifted_fraction = __statearry_fraction__2 & {73{concat_2396[0]}} | __stateancel_fraction__1 & {73{concat_2396[1]}} | input_abs_fraction__1[72:0] & {73{concat_2396[2]}};
assign normal_chunk = shifted_fraction[48:0];
assign half_of_extra = 49'h1_0000_0000_0000;
assign half_way_chunk = shifted_fraction[49:48];
assign __stateancel__11 = 1'h0;
assign concat_2409 = {__stateancel__11, shifted_fraction[72:49]};
assign do_round_up = normal_chunk > half_of_extra | half_way_chunk == 2'h3;
assign add_2412 = concat_2409 + 25'h000_0001;
assign rounded_fraction__1 = do_round_up ? add_2412 : concat_2409;
assign __stateancel__2 = 1'h0;
assign rounding_carry = rounded_fraction__1[24];
assign add_2420 = {__stateancel__2, greater_exp} + {9'h000, rounding_carry};
assign fraction_is_zero = sum_fraction == 75'h000_0000_0000_0000_0000;
assign add_2424 = add_2420 + 10'h001;
assign input_bexp__3 = add_2424 - {3'h0, encode_2377};
assign input_bexp__4 = input_bexp__3 & {10{~fraction_is_zero}};
assign high_exp__1 = 9'h1ff;
assign max_exp__2 = 8'hff;
assign eq_2438 = result_exp__4 == high_exp__1;
assign eq_2439 = result_fraction__8 == 48'h0000_0000_0000;
assign eq_2440 = ____state_1 == max_exp__2;
assign eq_2441 = ____state_2 == 23'h00_0000;
assign and_2446 = eq_2438 & eq_2439;
assign input_bexp__5 = input_bexp__4[8:0] & {9{~input_bexp__4[9]}};
assign has_pos_inf = ~(~(eq_2438 & eq_2439) | result_sign__4) | ~(~eq_2440 | ~eq_2441 | ____state_0);
assign has_neg_inf = and_2446 & result_sign__4 | eq_2440 & eq_2441 & ____state_0;
assign fmac__output_producer_valid_inv = ~__fmac__output_producer_valid_reg;
assign is_operand_inf = and_2446 | eq_2440 & eq_2441;
assign and_reduce_2456 = &input_bexp__5[7:0];
assign is_result_nan = ~(~eq_2438 | eq_2439) | ~(~eq_2440 | eq_2441) | has_pos_inf & has_neg_inf;
assign p0_all_active_inputs_valid = __fmac__input_a_consumer_valid_reg & __fmac__input_b_consumer_valid_reg;
assign fmac__output_producer_valid_load_en = fmac__output_producer_rdy | fmac__output_producer_valid_inv;
assign or_2461 = is_operand_inf | input_bexp__5[8] | and_reduce_2456 | input_bexp__5 == 9'h000;
assign or_2476 = is_result_nan | is_operand_inf | input_bexp__5[8] | and_reduce_2456;
assign fmac__output_producer_load_en = p0_all_active_inputs_valid & fmac__output_producer_valid_load_en;
assign __stateancel__5 = 1'h0;
assign p0_stage_done = p0_all_active_inputs_valid & fmac__output_producer_load_en;
assign and_2486 = ~is_result_nan & ~or_2461;
assign and_2487 = ~is_result_nan & or_2461;
assign result_sign = priority_sel_1b_2way({sum_fraction[74], fraction_is_zero}, __stateancel__5, ~greater_sign, greater_sign);
assign result_fraction = rounded_fraction__1[22:0];
assign one_hot_2567 = {concat_2396[2:0] == 3'h0, concat_2396[2] && concat_2396[1:0] == 2'h0, concat_2396[1] && !concat_2396[0], concat_2396[0]};
assign fmac__input_a_consumer_valid_inv = ~__fmac__input_a_consumer_valid_reg;
assign fmac__input_b_consumer_valid_inv = ~__fmac__input_b_consumer_valid_reg;
assign result_sign__1 = is_operand_inf ? ~has_pos_inf : result_sign;
assign max_exp__3 = 8'hff;
assign result_fraction__3 = result_fraction & {23{~or_2461}};
assign concat_2513 = {~or_2476 & p0_stage_done, or_2476 & p0_stage_done};
assign max_exp__4 = 8'hff;
assign concat_2521 = {is_result_nan & p0_stage_done, and_2486 & p0_stage_done, and_2487 & p0_stage_done};
assign fmac__input_a_consumer_valid_load_en = p0_stage_done | fmac__input_a_consumer_valid_inv;
assign fmac__input_b_consumer_valid_load_en = p0_stage_done | fmac__input_b_consumer_valid_inv;
assign result_sign__2 = ~is_result_nan & result_sign__1;
assign result_exp__2 = or_2476 ? max_exp__3 : input_bexp__5[7:0];
assign result_fraction__4 = is_result_nan ? 23'h08_0000 : result_fraction__3;
assign one_hot_sel_2514 = max_exp__4 & {8{concat_2513[0]}} | input_bexp__5[7:0] & {8{concat_2513[1]}};
assign one_hot_sel_2522 = 23'h00_0000 & {23{concat_2521[0]}} | result_fraction & {23{concat_2521[1]}} | 23'h08_0000 & {23{concat_2521[2]}};
assign and_2533 = (is_result_nan | and_2486 | and_2487) & p0_stage_done;
assign fmac__input_a_consumer_load_en = fmac__input_a_consumer_vld & fmac__input_a_consumer_valid_load_en;
assign fmac__input_b_consumer_load_en = fmac__input_b_consumer_vld & fmac__input_b_consumer_valid_load_en;
assign result = {result_sign__2, result_exp__2, result_fraction__4};
always @ (posedge clk) begin
if (___) begin
____state_1 <= 8'h00;
____state_2 <= 23'h00_0000;
____state_0 <= 1'h0;
__fmac__input_a_consumer_reg <= __fmac__input_a_consumer_reg_init;
__fmac__input_a_consumer_valid_reg <= 1'h0;
__fmac__input_b_consumer_reg <= __fmac__input_b_consumer_reg_init;
__fmac__input_b_consumer_valid_reg <= 1'h0;
__fmac__output_producer_reg <= __fmac__output_producer_reg_init;
__fmac__output_producer_valid_reg <= 1'h0;
end else begin
____state_1 <= p0_stage_done ? one_hot_sel_2514 : ____state_1;
____state_2 <= and_2533 ? one_hot_sel_2522 : ____state_2;
____state_0 <= p0_stage_done ? result_sign__2 : ____state_0;
__fmac__input_a_consumer_reg <= fmac__input_a_consumer_load_en ? fmac__input_a_consumer : __fmac__input_a_consumer_reg;
__fmac__input_a_consumer_valid_reg <= fmac__input_a_consumer_valid_load_en ? fmac__input_a_consumer_vld : __fmac__input_a_consumer_valid_reg;
__fmac__input_b_consumer_reg <= fmac__input_b_consumer_load_en ? fmac__input_b_consumer : __fmac__input_b_consumer_reg;
__fmac__input_b_consumer_valid_reg <= fmac__input_b_consumer_valid_load_en ? fmac__input_b_consumer_vld : __fmac__input_b_consumer_valid_reg;
__fmac__output_producer_reg <= fmac__output_producer_load_en ? result : __fmac__output_producer_reg;
__fmac__output_producer_valid_reg <= fmac__output_producer_valid_load_en ? p0_all_active_inputs_valid : __fmac__output_producer_valid_reg;
end
end
assign fmac__output_producer = __fmac__output_producer_reg;
assign fmac__output_producer_vld = __fmac__output_producer_valid_reg;
assign fmac__input_a_consumer_rdy = fmac__input_a_consumer_load_en;
assign fmac__input_b_consumer_rdy = fmac__input_b_consumer_load_en;
endmodule
fnとproc両方を使った場合は
コード
fn double_val(x: u32) -> u32 {
// A pure function that returns 2*x
x + x
}
proc pass_data {
// Input channel for reading 32-bit data
input_r: chan<u32> in;
// Output channel for sending 32-bit data
output_w: chan<u32> out;
config(input_r: chan<u32> in, output_w: chan<u32> out) {
// Bind the channels to this proc
(input_r, output_w)
}
init {
// This proc is stateless, so the initial state is empty
()
}
next(state: ()) {
// Receive a 32-bit value from the input channel
let (tok, data) = recv(join(), input_r);
// Call the pure function to double the received value
let doubled_data = double_val(data);
// Send the doubled value to the output channel
send(tok, output_w, doubled_data);
}
}
生成されるVerilogコードは
module __pass_data__pass_data_0_next(
input wire clk,
input wire ___,
input wire [31:0] pass_data__input_r,
input wire pass_data__input_r_vld,
input wire pass_data__output_w_rdy,
output wire [31:0] pass_data__output_w,
output wire pass_data__output_w_vld,
output wire pass_data__input_r_rdy
);
reg [31:0] __pass_data__input_r_reg;
reg __pass_data__input_r_valid_reg;
reg [31:0] __pass_data__output_w_reg;
reg __pass_data__output_w_valid_reg;
wire pass_data__output_w_valid_inv;
wire pass_data__output_w_valid_load_en;
wire pass_data__output_w_load_en;
wire p0_stage_done;
wire pass_data__input_r_valid_inv;
wire pass_data__input_r_valid_load_en;
wire pass_data__input_r_load_en;
wire [31:0] doubled_data;
assign pass_data__output_w_valid_inv = ~__pass_data__output_w_valid_reg;
assign pass_data__output_w_valid_load_en = pass_data__output_w_rdy | pass_data__output_w_valid_inv;
assign pass_data__output_w_load_en = __pass_data__input_r_valid_reg & pass_data__output_w_valid_load_en;
assign p0_stage_done = __pass_data__input_r_valid_reg & pass_data__output_w_load_en;
assign pass_data__input_r_valid_inv = ~__pass_data__input_r_valid_reg;
assign pass_data__input_r_valid_load_en = p0_stage_done | pass_data__input_r_valid_inv;
assign pass_data__input_r_load_en = pass_data__input_r_vld & pass_data__input_r_valid_load_en;
assign doubled_data = __pass_data__input_r_reg + __pass_data__input_r_reg;
always @ (posedge clk) begin
if (___) begin
__pass_data__input_r_reg <= 32'h0000_0000;
__pass_data__input_r_valid_reg <= 1'h0;
__pass_data__output_w_reg <= 32'h0000_0000;
__pass_data__output_w_valid_reg <= 1'h0;
end else begin
__pass_data__input_r_reg <= pass_data__input_r_load_en ? pass_data__input_r : __pass_data__input_r_reg;
__pass_data__input_r_valid_reg <= pass_data__input_r_valid_load_en ? pass_data__input_r_vld : __pass_data__input_r_valid_reg;
__pass_data__output_w_reg <= pass_data__output_w_load_en ? doubled_data : __pass_data__output_w_reg;
__pass_data__output_w_valid_reg <= pass_data__output_w_valid_load_en ? __pass_data__input_r_valid_reg : __pass_data__output_w_valid_reg;
end
end
assign pass_data__output_w = __pass_data__output_w_reg;
assign pass_data__output_w_vld = __pass_data__output_w_valid_reg;
assign pass_data__input_r_rdy = pass_data__input_r_load_en;
endmodule
_vldと_ready信号は不要なのですが・・
所感
GoolgeXLS(設計ソフト)使いこなせるようになりました!
昨日のCRC32のコードもprocを使って追記しましょう。
(今日は終わり)