@@ -389,6 +389,147 @@ endmodule
389389 EXPECT_EQ (std::string_view{emitted}, kWantEmitted );
390390}
391391
392+ TEST (XlsCApiTest, VastWidthCast) {
393+ const std::string_view kWantEmitted = R"( module top(
394+ input wire [7:0] a,
395+ input wire [3:0] b,
396+ output wire [7:0] out_literal,
397+ output wire [11:0] out_param,
398+ output wire [15:0] out_expr
399+ );
400+ parameter WidthParam = 12;
401+ assign out_literal = 8'(a + 1);
402+ assign out_param = WidthParam'({a, b});
403+ assign out_expr = (WidthParam + 4)'(a ^ {b, 2'h3});
404+ endmodule
405+ )" ;
406+
407+ xls_vast_verilog_file* f =
408+ xls_vast_make_verilog_file (xls_vast_file_type_verilog);
409+ ASSERT_NE (f, nullptr );
410+ absl::Cleanup free_file ([&] { xls_vast_verilog_file_free (f); });
411+
412+ xls_vast_verilog_module* m = xls_vast_verilog_file_add_module (f, " top" );
413+ ASSERT_NE (m, nullptr );
414+
415+ xls_vast_data_type* u8 =
416+ xls_vast_verilog_file_make_bit_vector_type (f, 8 , /* is_signed=*/ false );
417+ xls_vast_data_type* u4 =
418+ xls_vast_verilog_file_make_bit_vector_type (f, 4 , /* is_signed=*/ false );
419+ xls_vast_data_type* u12 =
420+ xls_vast_verilog_file_make_bit_vector_type (f, 12 , /* is_signed=*/ false );
421+ xls_vast_data_type* u16 =
422+ xls_vast_verilog_file_make_bit_vector_type (f, 16 , /* is_signed=*/ false );
423+
424+ xls_vast_logic_ref* a_ref = xls_vast_verilog_module_add_input (m, " a" , u8 );
425+ ASSERT_NE (a_ref, nullptr );
426+ xls_vast_logic_ref* b_ref = xls_vast_verilog_module_add_input (m, " b" , u4);
427+ ASSERT_NE (b_ref, nullptr );
428+ xls_vast_logic_ref* out_literal_ref =
429+ xls_vast_verilog_module_add_output (m, " out_literal" , u8 );
430+ ASSERT_NE (out_literal_ref, nullptr );
431+ xls_vast_logic_ref* out_param_ref =
432+ xls_vast_verilog_module_add_output (m, " out_param" , u12);
433+ ASSERT_NE (out_param_ref, nullptr );
434+ xls_vast_logic_ref* out_expr_ref =
435+ xls_vast_verilog_module_add_output (m, " out_expr" , u16 );
436+ ASSERT_NE (out_expr_ref, nullptr );
437+
438+ xls_vast_literal* literal_12 =
439+ xls_vast_verilog_file_make_plain_literal (f, 12 );
440+ ASSERT_NE (literal_12, nullptr );
441+ xls_vast_parameter_ref* width_param = xls_vast_verilog_module_add_parameter (
442+ m, " WidthParam" , xls_vast_literal_as_expression (literal_12));
443+ ASSERT_NE (width_param, nullptr );
444+ xls_vast_expression* width_param_expr =
445+ xls_vast_parameter_ref_as_expression (width_param);
446+
447+ xls_vast_literal* literal_8 = xls_vast_verilog_file_make_plain_literal (f, 8 );
448+ ASSERT_NE (literal_8, nullptr );
449+ xls_vast_literal* literal_1 = xls_vast_verilog_file_make_plain_literal (f, 1 );
450+ ASSERT_NE (literal_1, nullptr );
451+ xls_vast_expression* a_expr = xls_vast_logic_ref_as_expression (a_ref);
452+ ASSERT_NE (a_expr, nullptr );
453+ xls_vast_expression* a_plus_one = xls_vast_verilog_file_make_binary (
454+ f, a_expr, xls_vast_literal_as_expression (literal_1),
455+ xls_vast_operator_kind_add);
456+ ASSERT_NE (a_plus_one, nullptr );
457+
458+ xls_vast_expression* width_cast_literal =
459+ xls_vast_verilog_file_make_width_cast (
460+ f, xls_vast_literal_as_expression (literal_8), a_plus_one);
461+ ASSERT_NE (width_cast_literal, nullptr );
462+ xls_vast_continuous_assignment* assign_literal =
463+ xls_vast_verilog_file_make_continuous_assignment (
464+ f, xls_vast_logic_ref_as_expression (out_literal_ref),
465+ width_cast_literal);
466+ ASSERT_NE (assign_literal, nullptr );
467+ xls_vast_verilog_module_add_member_continuous_assignment (m, assign_literal);
468+
469+ std::vector<xls_vast_expression*> param_concat_args = {
470+ xls_vast_logic_ref_as_expression (a_ref),
471+ xls_vast_logic_ref_as_expression (b_ref)};
472+ xls_vast_concat* param_concat = xls_vast_verilog_file_make_concat (
473+ f, param_concat_args.data (), param_concat_args.size ());
474+ ASSERT_NE (param_concat, nullptr );
475+ xls_vast_expression* width_cast_param = xls_vast_verilog_file_make_width_cast (
476+ f, width_param_expr, xls_vast_concat_as_expression (param_concat));
477+ ASSERT_NE (width_cast_param, nullptr );
478+ xls_vast_continuous_assignment* assign_param =
479+ xls_vast_verilog_file_make_continuous_assignment (
480+ f, xls_vast_logic_ref_as_expression (out_param_ref), width_cast_param);
481+ ASSERT_NE (assign_param, nullptr );
482+ xls_vast_verilog_module_add_member_continuous_assignment (m, assign_param);
483+
484+ xls_vast_literal* literal_4 = xls_vast_verilog_file_make_plain_literal (f, 4 );
485+ ASSERT_NE (literal_4, nullptr );
486+ xls_vast_expression* complex_width = xls_vast_verilog_file_make_binary (
487+ f, width_param_expr, xls_vast_literal_as_expression (literal_4),
488+ xls_vast_operator_kind_add);
489+ ASSERT_NE (complex_width, nullptr );
490+
491+ struct xls_bits * bits = nullptr ;
492+ char * error_out = nullptr ;
493+ ASSERT_TRUE (
494+ xls_bits_make_ubits (/* bit_count=*/ 2 , /* value=*/ 3 , &error_out, &bits));
495+ ASSERT_EQ (error_out, nullptr );
496+ absl::Cleanup free_bits ([&] { xls_bits_free (bits); });
497+
498+ xls_vast_literal* literal_2h3 = nullptr ;
499+ ASSERT_TRUE (xls_vast_verilog_file_make_literal (
500+ f, bits, xls_format_preference_hex, /* emit_bit_count=*/ true , &error_out,
501+ &literal_2h3));
502+ ASSERT_EQ (error_out, nullptr );
503+ ASSERT_NE (literal_2h3, nullptr );
504+
505+ std::vector<xls_vast_expression*> tail_concat_args = {
506+ xls_vast_logic_ref_as_expression (b_ref),
507+ xls_vast_literal_as_expression (literal_2h3)};
508+ xls_vast_concat* tail_concat = xls_vast_verilog_file_make_concat (
509+ f, tail_concat_args.data (), tail_concat_args.size ());
510+ ASSERT_NE (tail_concat, nullptr );
511+
512+ xls_vast_expression* complex_value = xls_vast_verilog_file_make_binary (
513+ f, a_expr, xls_vast_concat_as_expression (tail_concat),
514+ xls_vast_operator_kind_bitwise_xor);
515+ ASSERT_NE (complex_value, nullptr );
516+
517+ xls_vast_expression* width_cast_complex =
518+ xls_vast_verilog_file_make_width_cast (f, complex_width, complex_value);
519+ ASSERT_NE (width_cast_complex, nullptr );
520+ xls_vast_continuous_assignment* assign_complex =
521+ xls_vast_verilog_file_make_continuous_assignment (
522+ f, xls_vast_logic_ref_as_expression (out_expr_ref),
523+ width_cast_complex);
524+ ASSERT_NE (assign_complex, nullptr );
525+ xls_vast_verilog_module_add_member_continuous_assignment (m, assign_complex);
526+
527+ char * emitted = xls_vast_verilog_file_emit (f);
528+ ASSERT_NE (emitted, nullptr );
529+ absl::Cleanup free_emitted ([&] { xls_c_str_free (emitted); });
530+ EXPECT_EQ (std::string_view{emitted}, kWantEmitted );
531+ }
532+
392533TEST (XlsCApiTest, VastUnsizedLiteralsParameters) {
393534 const std::string_view kWantEmitted = R"( module top;
394535 parameter P0 = '0;
0 commit comments