aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2013-01-05 11:13:26 +0100
committerClifford Wolf <clifford@clifford.at>2013-01-05 11:13:26 +0100
commit7764d0ba1dcf064ae487ee985c43083a0909e7f4 (patch)
tree18c05b8729df381af71b707748ce1d605e0df764 /tests
downloadyosys-7764d0ba1dcf064ae487ee985c43083a0909e7f4.tar.gz
yosys-7764d0ba1dcf064ae487ee985c43083a0909e7f4.tar.bz2
yosys-7764d0ba1dcf064ae487ee985c43083a0909e7f4.zip
initial import
Diffstat (limited to 'tests')
-rw-r--r--tests/asicworld/README1
-rw-r--r--tests/asicworld/code_hdl_models_GrayCounter.v33
-rw-r--r--tests/asicworld/code_hdl_models_arbiter.v123
-rw-r--r--tests/asicworld/code_hdl_models_arbiter_tb.v62
-rw-r--r--tests/asicworld/code_hdl_models_cam.v60
-rw-r--r--tests/asicworld/code_hdl_models_clk_div.v27
-rw-r--r--tests/asicworld/code_hdl_models_clk_div_45.v54
-rw-r--r--tests/asicworld/code_hdl_models_d_ff_gates.v29
-rw-r--r--tests/asicworld/code_hdl_models_d_latch_gates.v15
-rw-r--r--tests/asicworld/code_hdl_models_decoder_2to4_gates.v14
-rw-r--r--tests/asicworld/code_hdl_models_decoder_using_assign.v20
-rw-r--r--tests/asicworld/code_hdl_models_decoder_using_case.v43
-rw-r--r--tests/asicworld/code_hdl_models_dff_async_reset.v30
-rw-r--r--tests/asicworld/code_hdl_models_dff_sync_reset.v30
-rw-r--r--tests/asicworld/code_hdl_models_dlatch_reset.v30
-rw-r--r--tests/asicworld/code_hdl_models_encoder_4to2_gates.v8
-rw-r--r--tests/asicworld/code_hdl_models_encoder_using_case.v42
-rw-r--r--tests/asicworld/code_hdl_models_encoder_using_if.v58
-rw-r--r--tests/asicworld/code_hdl_models_full_adder_gates.v18
-rw-r--r--tests/asicworld/code_hdl_models_full_subtracter_gates.v20
-rw-r--r--tests/asicworld/code_hdl_models_gray_counter.v33
-rw-r--r--tests/asicworld/code_hdl_models_half_adder_gates.v14
-rw-r--r--tests/asicworld/code_hdl_models_lfsr.v35
-rw-r--r--tests/asicworld/code_hdl_models_lfsr_updown.v35
-rw-r--r--tests/asicworld/code_hdl_models_misc1.v22
-rw-r--r--tests/asicworld/code_hdl_models_mux21_switch.v22
-rw-r--r--tests/asicworld/code_hdl_models_mux_2to1_gates.v18
-rw-r--r--tests/asicworld/code_hdl_models_mux_using_assign.v22
-rw-r--r--tests/asicworld/code_hdl_models_mux_using_case.v28
-rw-r--r--tests/asicworld/code_hdl_models_mux_using_if.v29
-rw-r--r--tests/asicworld/code_hdl_models_nand_switch.v14
-rw-r--r--tests/asicworld/code_hdl_models_one_hot_cnt.v31
-rw-r--r--tests/asicworld/code_hdl_models_parallel_crc.v53
-rw-r--r--tests/asicworld/code_hdl_models_parity_using_assign.v21
-rw-r--r--tests/asicworld/code_hdl_models_parity_using_bitwise.v16
-rw-r--r--tests/asicworld/code_hdl_models_parity_using_function.v29
-rw-r--r--tests/asicworld/code_hdl_models_pri_encoder_using_assign.v36
-rw-r--r--tests/asicworld/code_hdl_models_ram_sp_ar_sw.v58
-rw-r--r--tests/asicworld/code_hdl_models_ram_sp_sr_sw.v62
-rw-r--r--tests/asicworld/code_hdl_models_rom_using_case.v42
-rw-r--r--tests/asicworld/code_hdl_models_serial_crc.v54
-rw-r--r--tests/asicworld/code_hdl_models_t_gate_switch.v11
-rw-r--r--tests/asicworld/code_hdl_models_tff_async_reset.v27
-rw-r--r--tests/asicworld/code_hdl_models_tff_sync_reset.v27
-rw-r--r--tests/asicworld/code_hdl_models_uart.v154
-rw-r--r--tests/asicworld/code_hdl_models_up_counter.v29
-rw-r--r--tests/asicworld/code_hdl_models_up_counter_load.v32
-rw-r--r--tests/asicworld/code_hdl_models_up_down_counter.v29
-rw-r--r--tests/asicworld/code_specman_switch_fabric.v82
-rw-r--r--tests/asicworld/code_tidbits_asyn_reset.v18
-rw-r--r--tests/asicworld/code_tidbits_blocking.v17
-rw-r--r--tests/asicworld/code_tidbits_fsm_using_always.v91
-rw-r--r--tests/asicworld/code_tidbits_fsm_using_function.v94
-rw-r--r--tests/asicworld/code_tidbits_fsm_using_single_always.v63
-rw-r--r--tests/asicworld/code_tidbits_nonblocking.v17
-rw-r--r--tests/asicworld/code_tidbits_reg_combo_example.v13
-rw-r--r--tests/asicworld/code_tidbits_reg_seq_example.v15
-rw-r--r--tests/asicworld/code_tidbits_syn_reset.v19
-rw-r--r--tests/asicworld/code_tidbits_wire_example.v9
-rw-r--r--tests/asicworld/code_verilog_tutorial_addbit.v24
-rw-r--r--tests/asicworld/code_verilog_tutorial_always_example.v11
-rw-r--r--tests/asicworld/code_verilog_tutorial_bus_con.v8
-rw-r--r--tests/asicworld/code_verilog_tutorial_comment.v25
-rw-r--r--tests/asicworld/code_verilog_tutorial_counter.v19
-rw-r--r--tests/asicworld/code_verilog_tutorial_counter_tb.v113
-rw-r--r--tests/asicworld/code_verilog_tutorial_d_ff.v14
-rw-r--r--tests/asicworld/code_verilog_tutorial_decoder.v14
-rw-r--r--tests/asicworld/code_verilog_tutorial_decoder_always.v20
-rw-r--r--tests/asicworld/code_verilog_tutorial_escape_id.v14
-rw-r--r--tests/asicworld/code_verilog_tutorial_explicit.v35
-rw-r--r--tests/asicworld/code_verilog_tutorial_first_counter.v47
-rw-r--r--tests/asicworld/code_verilog_tutorial_first_counter_tb.v36
-rw-r--r--tests/asicworld/code_verilog_tutorial_flip_flop.v15
-rw-r--r--tests/asicworld/code_verilog_tutorial_fsm_full.v114
-rw-r--r--tests/asicworld/code_verilog_tutorial_fsm_full_tb.v48
-rw-r--r--tests/asicworld/code_verilog_tutorial_good_code.v18
-rw-r--r--tests/asicworld/code_verilog_tutorial_if_else.v13
-rw-r--r--tests/asicworld/code_verilog_tutorial_multiply.v8
-rw-r--r--tests/asicworld/code_verilog_tutorial_mux_21.v9
-rw-r--r--tests/asicworld/code_verilog_tutorial_n_out_primitive.v13
-rw-r--r--tests/asicworld/code_verilog_tutorial_parallel_if.v21
-rw-r--r--tests/asicworld/code_verilog_tutorial_parity.v41
-rw-r--r--tests/asicworld/code_verilog_tutorial_simple_function.v10
-rw-r--r--tests/asicworld/code_verilog_tutorial_simple_if.v11
-rw-r--r--tests/asicworld/code_verilog_tutorial_task_global.v12
-rw-r--r--tests/asicworld/code_verilog_tutorial_tri_buf.v9
-rw-r--r--tests/asicworld/code_verilog_tutorial_v2k_reg.v24
-rw-r--r--tests/asicworld/code_verilog_tutorial_which_clock.v12
-rwxr-xr-xtests/asicworld/run-test.sh3
-rw-r--r--tests/hana/README14
-rw-r--r--tests/hana/hana_vlib.v1139
-rwxr-xr-xtests/hana/run-test.sh3
-rw-r--r--tests/hana/test_intermout_always_comb_1_test.v13
-rw-r--r--tests/hana/test_intermout_always_comb_3_test.v10
-rw-r--r--tests/hana/test_intermout_always_comb_4_test.v9
-rw-r--r--tests/hana/test_intermout_always_comb_5_test.v11
-rw-r--r--tests/hana/test_intermout_always_ff_3_test.v15
-rw-r--r--tests/hana/test_intermout_always_ff_4_test.v11
-rw-r--r--tests/hana/test_intermout_always_ff_5_test.v13
-rw-r--r--tests/hana/test_intermout_always_ff_6_test.v7
-rw-r--r--tests/hana/test_intermout_always_ff_8_test.v11
-rw-r--r--tests/hana/test_intermout_always_ff_9_test.v14
-rw-r--r--tests/hana/test_intermout_always_latch_1_test.v9
-rw-r--r--tests/hana/test_intermout_bufrm_1_test.v4
-rw-r--r--tests/hana/test_intermout_bufrm_2_test.v7
-rw-r--r--tests/hana/test_intermout_bufrm_6_test.v22
-rw-r--r--tests/hana/test_intermout_bufrm_7_test.v33
-rw-r--r--tests/hana/test_intermout_exprs_add_test.v10
-rw-r--r--tests/hana/test_intermout_exprs_binlogic_test.v13
-rw-r--r--tests/hana/test_intermout_exprs_bitwiseneg_test.v5
-rw-r--r--tests/hana/test_intermout_exprs_buffer_test.v9
-rw-r--r--tests/hana/test_intermout_exprs_condexpr_mux_test.v11
-rw-r--r--tests/hana/test_intermout_exprs_condexpr_tribuf_test.v9
-rw-r--r--tests/hana/test_intermout_exprs_const_test.v7
-rw-r--r--tests/hana/test_intermout_exprs_constshift_test.v12
-rw-r--r--tests/hana/test_intermout_exprs_div_test.v10
-rw-r--r--tests/hana/test_intermout_exprs_logicneg_test.v7
-rw-r--r--tests/hana/test_intermout_exprs_mod_test.v10
-rw-r--r--tests/hana/test_intermout_exprs_mul_test.v10
-rw-r--r--tests/hana/test_intermout_exprs_redand_test.v5
-rw-r--r--tests/hana/test_intermout_exprs_redop_test.v16
-rw-r--r--tests/hana/test_intermout_exprs_sub_test.v10
-rw-r--r--tests/hana/test_intermout_exprs_unaryminus_test.v5
-rw-r--r--tests/hana/test_intermout_exprs_unaryplus_test.v4
-rw-r--r--tests/hana/test_intermout_exprs_varshift_test.v10
-rw-r--r--tests/hana/test_parse2synthtrans_behavopt_1_test.v22
-rw-r--r--tests/hana/test_parse2synthtrans_case_1_test.v26
-rw-r--r--tests/hana/test_parse2synthtrans_contassign_1_test.v7
-rw-r--r--tests/hana/test_parse2synthtrans_module_basic0_test.v2
-rw-r--r--tests/hana/test_parse2synthtrans_operators_1_test.v11
-rw-r--r--tests/hana/test_parse2synthtrans_param_1_test.v7
-rw-r--r--tests/hana/test_parse2synthtrans_port_scalar_1_test.v6
-rw-r--r--tests/hana/test_parse2synthtrans_port_vector_1_test.v9
-rw-r--r--tests/hana/test_parse2synthtrans_v2k_comb_logic_sens_list_test.v9
-rw-r--r--tests/hana/test_parser_constructs_module_basic1_test.v2
-rw-r--r--tests/hana/test_parser_constructs_param_basic0_test.v10
-rw-r--r--tests/hana/test_parser_constructs_port_basic0_test.v8
-rw-r--r--tests/hana/test_parser_directives_define_simpledef_test.v9
-rw-r--r--tests/hana/test_parser_misc_operators_test.v29
-rw-r--r--tests/hana/test_parser_v2k_comb_port_data_type_test.v6
-rw-r--r--tests/hana/test_parser_v2k_comma_sep_sens_list_test.v9
-rw-r--r--tests/hana/test_simulation_always_15_test.v5
-rw-r--r--tests/hana/test_simulation_always_17_test.v13
-rw-r--r--tests/hana/test_simulation_always_18_test.v10
-rw-r--r--tests/hana/test_simulation_always_19_test.v11
-rw-r--r--tests/hana/test_simulation_always_1_test.v5
-rw-r--r--tests/hana/test_simulation_always_20_test.v15
-rw-r--r--tests/hana/test_simulation_always_21_test.v11
-rw-r--r--tests/hana/test_simulation_always_22_test.v7
-rw-r--r--tests/hana/test_simulation_always_23_test.v14
-rw-r--r--tests/hana/test_simulation_always_27_test.v13
-rw-r--r--tests/hana/test_simulation_always_29_test.v9
-rw-r--r--tests/hana/test_simulation_always_31_tt.v50
-rw-r--r--tests/hana/test_simulation_and_1_test.v3
-rw-r--r--tests/hana/test_simulation_and_2_test.v3
-rw-r--r--tests/hana/test_simulation_and_3_test.v3
-rw-r--r--tests/hana/test_simulation_and_4_test.v3
-rw-r--r--tests/hana/test_simulation_and_5_test.v3
-rw-r--r--tests/hana/test_simulation_and_6_test.v3
-rw-r--r--tests/hana/test_simulation_and_7_test.v3
-rw-r--r--tests/hana/test_simulation_buffer_1_test.v3
-rw-r--r--tests/hana/test_simulation_buffer_2_test.v4
-rw-r--r--tests/hana/test_simulation_buffer_3_test.v4
-rw-r--r--tests/hana/test_simulation_decoder_2_test.v14
-rw-r--r--tests/hana/test_simulation_decoder_3_test.v14
-rw-r--r--tests/hana/test_simulation_decoder_4_test.v14
-rw-r--r--tests/hana/test_simulation_decoder_5_test.v17
-rw-r--r--tests/hana/test_simulation_decoder_6_test.v27
-rw-r--r--tests/hana/test_simulation_decoder_7_test.v43
-rw-r--r--tests/hana/test_simulation_decoder_8_test.v76
-rw-r--r--tests/hana/test_simulation_inc_16_test.v5
-rw-r--r--tests/hana/test_simulation_inc_1_test.v5
-rw-r--r--tests/hana/test_simulation_inc_2_test.v5
-rw-r--r--tests/hana/test_simulation_inc_32_test.v5
-rw-r--r--tests/hana/test_simulation_inc_4_test.v5
-rw-r--r--tests/hana/test_simulation_inc_8_test.v5
-rw-r--r--tests/hana/test_simulation_mod_1_xx.v13
-rw-r--r--tests/hana/test_simulation_mux_16_test.v22
-rw-r--r--tests/hana/test_simulation_mux_2_test.v8
-rw-r--r--tests/hana/test_simulation_mux_32_test.v39
-rw-r--r--tests/hana/test_simulation_mux_4_test.v10
-rw-r--r--tests/hana/test_simulation_mux_64_test.v71
-rw-r--r--tests/hana/test_simulation_mux_8_test.v14
-rw-r--r--tests/hana/test_simulation_nand_1_test.v3
-rw-r--r--tests/hana/test_simulation_nand_3_test.v3
-rw-r--r--tests/hana/test_simulation_nand_4_test.v3
-rw-r--r--tests/hana/test_simulation_nand_5_test.v3
-rw-r--r--tests/hana/test_simulation_nand_6_test.v3
-rw-r--r--tests/hana/test_simulation_nor_1_test.v3
-rw-r--r--tests/hana/test_simulation_nor_2_test.v3
-rw-r--r--tests/hana/test_simulation_nor_3_test.v3
-rw-r--r--tests/hana/test_simulation_nor_4_test.v3
-rw-r--r--tests/hana/test_simulation_opt_constprop_contassign_1_test.v3
-rw-r--r--tests/hana/test_simulation_or_1_test.v3
-rw-r--r--tests/hana/test_simulation_or_2_test.v3
-rw-r--r--tests/hana/test_simulation_or_3_test.v3
-rw-r--r--tests/hana/test_simulation_or_4_test.v3
-rw-r--r--tests/hana/test_simulation_or_5_test.v3
-rw-r--r--tests/hana/test_simulation_or_6_test.v3
-rw-r--r--tests/hana/test_simulation_seq_ff_1_test.v4
-rw-r--r--tests/hana/test_simulation_seq_ff_2_test.v4
-rw-r--r--tests/hana/test_simulation_shifter_left_16_test.v4
-rw-r--r--tests/hana/test_simulation_shifter_left_32_test.v4
-rw-r--r--tests/hana/test_simulation_shifter_left_4_test.v4
-rw-r--r--tests/hana/test_simulation_shifter_left_64_test.v4
-rw-r--r--tests/hana/test_simulation_shifter_left_8_test.v4
-rw-r--r--tests/hana/test_simulation_shifter_right_16_test.v4
-rw-r--r--tests/hana/test_simulation_shifter_right_32_test.v4
-rw-r--r--tests/hana/test_simulation_shifter_right_4_test.v4
-rw-r--r--tests/hana/test_simulation_shifter_right_64_test.v4
-rw-r--r--tests/hana/test_simulation_shifter_right_8_test.v4
-rw-r--r--tests/hana/test_simulation_sop_basic_10_test.v8
-rw-r--r--tests/hana/test_simulation_sop_basic_11_test.v10
-rw-r--r--tests/hana/test_simulation_sop_basic_12_test.v14
-rw-r--r--tests/hana/test_simulation_sop_basic_18_test.v5
-rw-r--r--tests/hana/test_simulation_sop_basic_3_test.v3
-rw-r--r--tests/hana/test_simulation_sop_basic_7_test.v3
-rw-r--r--tests/hana/test_simulation_sop_basic_8_test.v3
-rw-r--r--tests/hana/test_simulation_sop_basic_9_test.v3
-rw-r--r--tests/hana/test_simulation_techmap_and_19_tech.v7
-rw-r--r--tests/hana/test_simulation_techmap_and_5_tech.v3
-rw-r--r--tests/hana/test_simulation_techmap_buf_test.v3
-rw-r--r--tests/hana/test_simulation_techmap_inv_test.v3
-rw-r--r--tests/hana/test_simulation_techmap_mux_0_test.v8
-rw-r--r--tests/hana/test_simulation_techmap_mux_128_test.v134
-rw-r--r--tests/hana/test_simulation_techmap_mux_8_test.v14
-rw-r--r--tests/hana/test_simulation_techmap_nand_19_tech.v11
-rw-r--r--tests/hana/test_simulation_techmap_nand_2_tech.v11
-rw-r--r--tests/hana/test_simulation_techmap_nand_5_tech.v11
-rw-r--r--tests/hana/test_simulation_techmap_nor_19_tech.v11
-rw-r--r--tests/hana/test_simulation_techmap_nor_2_tech.v11
-rw-r--r--tests/hana/test_simulation_techmap_nor_5_tech.v11
-rw-r--r--tests/hana/test_simulation_techmap_or_19_tech.v7
-rw-r--r--tests/hana/test_simulation_techmap_or_5_tech.v3
-rw-r--r--tests/hana/test_simulation_techmap_xnor_2_tech.v6
-rw-r--r--tests/hana/test_simulation_techmap_xnor_5_tech.v6
-rw-r--r--tests/hana/test_simulation_techmap_xor_19_tech.v3
-rw-r--r--tests/hana/test_simulation_techmap_xor_2_tech.v6
-rw-r--r--tests/hana/test_simulation_techmap_xor_5_tech.v6
-rw-r--r--tests/hana/test_simulation_tribuf_2_test.v3
-rw-r--r--tests/hana/test_simulation_xnor_1_test.v3
-rw-r--r--tests/hana/test_simulation_xnor_2_test.v3
-rw-r--r--tests/hana/test_simulation_xnor_3_test.v3
-rw-r--r--tests/hana/test_simulation_xnor_4_test.v3
-rw-r--r--tests/hana/test_simulation_xor_1_test.v3
-rw-r--r--tests/hana/test_simulation_xor_2_test.v3
-rw-r--r--tests/hana/test_simulation_xor_3_test.v3
-rw-r--r--tests/hana/test_simulation_xor_4_test.v3
-rw-r--r--tests/i2c_bench/i2c_master_bit_ctrl.v576
-rw-r--r--tests/i2c_bench/i2c_master_byte_ctrl.v344
-rw-r--r--tests/i2c_bench/i2c_master_defines.v59
-rw-r--r--tests/i2c_bench/i2c_master_top.v301
-rw-r--r--tests/i2c_bench/i2c_slave_model.v361
-rwxr-xr-xtests/i2c_bench/run-test.sh50
-rw-r--r--tests/i2c_bench/spi_slave_model.v125
-rw-r--r--tests/i2c_bench/timescale.v2
-rw-r--r--tests/i2c_bench/tst_bench_top.v468
-rw-r--r--tests/i2c_bench/wb_master_model.v205
-rw-r--r--tests/iwls2005/README7
-rw-r--r--tests/iwls2005/aes_core/aes_cipher_top.v256
-rw-r--r--tests/iwls2005/aes_core/aes_inv_cipher_top.v327
-rw-r--r--tests/iwls2005/aes_core/aes_inv_sbox.v328
-rw-r--r--tests/iwls2005/aes_core/aes_key_expand_128.v87
-rw-r--r--tests/iwls2005/aes_core/aes_rcon.v96
-rw-r--r--tests/iwls2005/aes_core/aes_sbox.v329
-rw-r--r--tests/iwls2005/aes_core/timescale.v1
-rw-r--r--tests/iwls2005/fpu/except.v153
-rw-r--r--tests/iwls2005/fpu/fpu.v560
-rw-r--r--tests/iwls2005/fpu/post_norm.v676
-rw-r--r--tests/iwls2005/fpu/pre_norm.v270
-rw-r--r--tests/iwls2005/fpu/pre_norm_fmul.v150
-rw-r--r--tests/iwls2005/fpu/primitives.v103
-rw-r--r--tests/iwls2005/i2c/i2c_master_bit_ctrl.v535
-rw-r--r--tests/iwls2005/i2c/i2c_master_byte_ctrl.v344
-rw-r--r--tests/iwls2005/i2c/i2c_master_defines.v64
-rw-r--r--tests/iwls2005/i2c/i2c_master_top.v301
-rw-r--r--tests/iwls2005/i2c/timescale.v2
-rwxr-xr-xtests/iwls2005/run-fm.sh42
-rwxr-xr-xtests/iwls2005/run-synth.sh45
-rw-r--r--tests/iwls2005/run-synth.ys11
-rw-r--r--tests/iwls2005/sasc/sasc_brg.v160
-rw-r--r--tests/iwls2005/sasc/sasc_fifo4.v135
-rw-r--r--tests/iwls2005/sasc/sasc_top.v301
-rw-r--r--tests/iwls2005/sasc/timescale.v1
-rw-r--r--tests/iwls2005/simple_spi/fifo4.v134
-rw-r--r--tests/iwls2005/simple_spi/simple_spi_top.v329
-rw-r--r--tests/iwls2005/spi/spi_clgen.v108
-rw-r--r--tests/iwls2005/spi/spi_defines.v159
-rw-r--r--tests/iwls2005/spi/spi_shift.v238
-rw-r--r--tests/iwls2005/spi/spi_top.v287
-rw-r--r--tests/iwls2005/spi/timescale.v2
-rw-r--r--tests/iwls2005/ss_pcm/pcm_slv_top.v222
-rw-r--r--tests/iwls2005/ss_pcm/timescale.v1
-rw-r--r--tests/iwls2005/systemcaes/aes.v358
-rw-r--r--tests/iwls2005/systemcaes/byte_mixcolum.v92
-rw-r--r--tests/iwls2005/systemcaes/keysched.v248
-rw-r--r--tests/iwls2005/systemcaes/mixcolum.v188
-rw-r--r--tests/iwls2005/systemcaes/sbox.v392
-rw-r--r--tests/iwls2005/systemcaes/subbytes.v259
-rw-r--r--tests/iwls2005/systemcaes/timescale.v1
-rw-r--r--tests/iwls2005/systemcaes/word_mixcolum.v124
-rw-r--r--tests/iwls2005/usb_phy/timescale.v1
-rw-r--r--tests/iwls2005/usb_phy/usb_phy.v184
-rw-r--r--tests/iwls2005/usb_phy/usb_rx_phy.v452
-rw-r--r--tests/iwls2005/usb_phy/usb_tx_phy.v465
-rw-r--r--tests/no-icarus/README2
-rw-r--r--tests/no-icarus/autowire.v25
-rw-r--r--tests/no-icarus/var_range.v45
-rw-r--r--tests/openmsp430/rtl/omsp_alu.v258
-rw-r--r--tests/openmsp430/rtl/omsp_and_gate.v89
-rw-r--r--tests/openmsp430/rtl/omsp_clock_gate.v86
-rw-r--r--tests/openmsp430/rtl/omsp_clock_module.v1058
-rw-r--r--tests/openmsp430/rtl/omsp_clock_mux.v192
-rw-r--r--tests/openmsp430/rtl/omsp_dbg.v827
-rw-r--r--tests/openmsp430/rtl/omsp_dbg_hwbrk.v282
-rw-r--r--tests/openmsp430/rtl/omsp_dbg_uart.v298
-rw-r--r--tests/openmsp430/rtl/omsp_execution_unit.v420
-rw-r--r--tests/openmsp430/rtl/omsp_frontend.v966
-rw-r--r--tests/openmsp430/rtl/omsp_mem_backbone.v275
-rw-r--r--tests/openmsp430/rtl/omsp_multiplier.v420
-rw-r--r--tests/openmsp430/rtl/omsp_register_file.v618
-rw-r--r--tests/openmsp430/rtl/omsp_scan_mux.v75
-rw-r--r--tests/openmsp430/rtl/omsp_sfr.v353
-rw-r--r--tests/openmsp430/rtl/omsp_sync_cell.v80
-rw-r--r--tests/openmsp430/rtl/omsp_sync_reset.v78
-rw-r--r--tests/openmsp430/rtl/omsp_wakeup_cell.v108
-rw-r--r--tests/openmsp430/rtl/omsp_watchdog.v556
-rw-r--r--tests/openmsp430/rtl/openMSP430.v584
-rw-r--r--tests/openmsp430/rtl/openMSP430_defines.v843
-rw-r--r--tests/openmsp430/rtl/openMSP430_undefines.v732
-rw-r--r--tests/openmsp430/run-fm.do37
-rw-r--r--tests/openmsp430/run-fm.sh5
-rw-r--r--tests/openmsp430/run-synth.sh3
-rw-r--r--tests/openmsp430/run-synth.ys11
-rw-r--r--tests/openmsp430/sim_mul.v29
-rw-r--r--tests/or1200/config.patch46
-rw-r--r--tests/or1200/run-checkout.sh4
-rw-r--r--tests/or1200/run-fm-mods.sh24
-rw-r--r--tests/or1200/run-fm.do53
-rw-r--r--tests/or1200/run-fm.sh5
-rw-r--r--tests/or1200/run-synth.sh2
-rw-r--r--tests/or1200/run-synth.ys11
-rw-r--r--tests/or1200/run-vg.sh4
-rw-r--r--tests/simple/aes_kexp128.v24
-rw-r--r--tests/simple/dff_different_styles.v52
-rw-r--r--tests/simple/fiedler-cooley.v33
-rw-r--r--tests/simple/fsm.v69
-rw-r--r--tests/simple/generate.v67
-rw-r--r--tests/simple/i2c_master_tests.v62
-rw-r--r--tests/simple/loops.v79
-rw-r--r--tests/simple/mem2reg.v17
-rw-r--r--tests/simple/memory.v19
-rw-r--r--tests/simple/muxtree.v50
-rw-r--r--tests/simple/omsp_dbg_uart.v34
-rw-r--r--tests/simple/operators.v97
-rw-r--r--tests/simple/paramods.v37
-rw-r--r--tests/simple/process.v65
-rwxr-xr-xtests/simple/run-test.sh3
-rw-r--r--tests/simple/subbytes.v82
-rw-r--r--tests/simple/task_func.v35
-rw-r--r--tests/simple/usb_phy_tetsts.v36
-rw-r--r--tests/simple/values.v44
-rwxr-xr-xtests/tools/autotest.sh164
-rw-r--r--tests/tools/cmp_tbdata.c67
-rwxr-xr-xtests/tools/profiler.pl55
-rwxr-xr-xtests/tools/rtlview.sh63
-rwxr-xr-xtests/tools/vcdcd.pl201
367 files changed, 28611 insertions, 0 deletions
diff --git a/tests/asicworld/README b/tests/asicworld/README
new file mode 100644
index 000000000..0e96edb7b
--- /dev/null
+++ b/tests/asicworld/README
@@ -0,0 +1 @@
+Borrowed verilog examples from http://www.asic-world.com/.
diff --git a/tests/asicworld/code_hdl_models_GrayCounter.v b/tests/asicworld/code_hdl_models_GrayCounter.v
new file mode 100644
index 000000000..23f0da04b
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_GrayCounter.v
@@ -0,0 +1,33 @@
+//==========================================
+// Function : Code Gray counter.
+// Coder : Alex Claros F.
+// Date : 15/May/2005.
+//=======================================
+
+module GrayCounter
+ #(parameter COUNTER_WIDTH = 4)
+
+ (output reg [COUNTER_WIDTH-1:0] GrayCount_out, //'Gray' code count output.
+
+ input wire Enable_in, //Count enable.
+ input wire Clear_in, //Count reset.
+
+ input wire Clk);
+
+ /////////Internal connections & variables///////
+ reg [COUNTER_WIDTH-1:0] BinaryCount;
+
+ /////////Code///////////////////////
+
+ always @ (posedge Clk)
+ if (Clear_in) begin
+ BinaryCount <= {COUNTER_WIDTH{1'b 0}} + 1; //Gray count begins @ '1' with
+ GrayCount_out <= {COUNTER_WIDTH{1'b 0}}; // first 'Enable_in'.
+ end
+ else if (Enable_in) begin
+ BinaryCount <= BinaryCount + 1;
+ GrayCount_out <= {BinaryCount[COUNTER_WIDTH-1],
+ BinaryCount[COUNTER_WIDTH-2:0] ^ BinaryCount[COUNTER_WIDTH-1:1]};
+ end
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_arbiter.v b/tests/asicworld/code_hdl_models_arbiter.v
new file mode 100644
index 000000000..978e1987b
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_arbiter.v
@@ -0,0 +1,123 @@
+//----------------------------------------------------
+// A four level, round-robin arbiter. This was
+// orginally coded by WD Peterson in VHDL.
+//----------------------------------------------------
+module arbiter (
+ clk,
+ rst,
+ req3,
+ req2,
+ req1,
+ req0,
+ gnt3,
+ gnt2,
+ gnt1,
+ gnt0
+);
+// --------------Port Declaration-----------------------
+input clk;
+input rst;
+input req3;
+input req2;
+input req1;
+input req0;
+output gnt3;
+output gnt2;
+output gnt1;
+output gnt0;
+
+//--------------Internal Registers----------------------
+wire [1:0] gnt ;
+wire comreq ;
+wire beg ;
+wire [1:0] lgnt ;
+wire lcomreq ;
+reg lgnt0 ;
+reg lgnt1 ;
+reg lgnt2 ;
+reg lgnt3 ;
+reg lasmask ;
+reg lmask0 ;
+reg lmask1 ;
+reg ledge ;
+
+//--------------Code Starts Here-----------------------
+always @ (posedge clk)
+if (rst) begin
+ lgnt0 <= 0;
+ lgnt1 <= 0;
+ lgnt2 <= 0;
+ lgnt3 <= 0;
+end else begin
+ lgnt0 <=(~lcomreq & ~lmask1 & ~lmask0 & ~req3 & ~req2 & ~req1 & req0)
+ | (~lcomreq & ~lmask1 & lmask0 & ~req3 & ~req2 & req0)
+ | (~lcomreq & lmask1 & ~lmask0 & ~req3 & req0)
+ | (~lcomreq & lmask1 & lmask0 & req0 )
+ | ( lcomreq & lgnt0 );
+ lgnt1 <=(~lcomreq & ~lmask1 & ~lmask0 & req1)
+ | (~lcomreq & ~lmask1 & lmask0 & ~req3 & ~req2 & req1 & ~req0)
+ | (~lcomreq & lmask1 & ~lmask0 & ~req3 & req1 & ~req0)
+ | (~lcomreq & lmask1 & lmask0 & req1 & ~req0)
+ | ( lcomreq & lgnt1);
+ lgnt2 <=(~lcomreq & ~lmask1 & ~lmask0 & req2 & ~req1)
+ | (~lcomreq & ~lmask1 & lmask0 & req2)
+ | (~lcomreq & lmask1 & ~lmask0 & ~req3 & req2 & ~req1 & ~req0)
+ | (~lcomreq & lmask1 & lmask0 & req2 & ~req1 & ~req0)
+ | ( lcomreq & lgnt2);
+ lgnt3 <=(~lcomreq & ~lmask1 & ~lmask0 & req3 & ~req2 & ~req1)
+ | (~lcomreq & ~lmask1 & lmask0 & req3 & ~req2)
+ | (~lcomreq & lmask1 & ~lmask0 & req3)
+ | (~lcomreq & lmask1 & lmask0 & req3 & ~req2 & ~req1 & ~req0)
+ | ( lcomreq & lgnt3);
+end
+
+//----------------------------------------------------
+// lasmask state machine.
+//----------------------------------------------------
+assign beg = (req3 | req2 | req1 | req0) & ~lcomreq;
+always @ (posedge clk)
+begin
+ lasmask <= (beg & ~ledge & ~lasmask);
+ ledge <= (beg & ~ledge & lasmask)
+ | (beg & ledge & ~lasmask);
+end
+
+//----------------------------------------------------
+// comreq logic.
+//----------------------------------------------------
+assign lcomreq = ( req3 & lgnt3 )
+ | ( req2 & lgnt2 )
+ | ( req1 & lgnt1 )
+ | ( req0 & lgnt0 );
+
+//----------------------------------------------------
+// Encoder logic.
+//----------------------------------------------------
+assign lgnt = {(lgnt3 | lgnt2),(lgnt3 | lgnt1)};
+
+//----------------------------------------------------
+// lmask register.
+//----------------------------------------------------
+always @ (posedge clk )
+if( rst ) begin
+ lmask1 <= 0;
+ lmask0 <= 0;
+end else if(lasmask) begin
+ lmask1 <= lgnt[1];
+ lmask0 <= lgnt[0];
+end else begin
+ lmask1 <= lmask1;
+ lmask0 <= lmask0;
+end
+
+assign comreq = lcomreq;
+assign gnt = lgnt;
+//----------------------------------------------------
+// Drive the outputs
+//----------------------------------------------------
+assign gnt3 = lgnt3;
+assign gnt2 = lgnt2;
+assign gnt1 = lgnt1;
+assign gnt0 = lgnt0;
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_arbiter_tb.v b/tests/asicworld/code_hdl_models_arbiter_tb.v
new file mode 100644
index 000000000..5e7bf46b9
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_arbiter_tb.v
@@ -0,0 +1,62 @@
+module testbench ();
+
+reg clk;
+reg rst;
+reg req3;
+reg req2;
+reg req1;
+reg req0;
+wire gnt3;
+wire gnt2;
+wire gnt1;
+wire gnt0;
+
+// Clock generator
+always #1 clk = ~clk;
+
+initial begin
+ $dumpfile ("arbiter.vcd");
+ $dumpvars();
+ clk = 0;
+ rst = 1;
+ req0 = 0;
+ req1 = 0;
+ req2 = 0;
+ req3 = 0;
+ #10 rst = 0;
+ repeat (1) @ (posedge clk);
+ req0 <= 1;
+ repeat (1) @ (posedge clk);
+ req0 <= 0;
+ repeat (1) @ (posedge clk);
+ req0 <= 1;
+ req1 <= 1;
+ repeat (1) @ (posedge clk);
+ req2 <= 1;
+ req1 <= 0;
+ repeat (1) @ (posedge clk);
+ req3 <= 1;
+ req2 <= 0;
+ repeat (1) @ (posedge clk);
+ req3 <= 0;
+ repeat (1) @ (posedge clk);
+ req0 <= 0;
+ repeat (1) @ (posedge clk);
+ #10 $finish;
+end
+
+// Connect the DUT
+arbiter U (
+ clk,
+ rst,
+ req3,
+ req2,
+ req1,
+ req0,
+ gnt3,
+ gnt2,
+ gnt1,
+ gnt0
+);
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_cam.v b/tests/asicworld/code_hdl_models_cam.v
new file mode 100644
index 000000000..0cebc07cc
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_cam.v
@@ -0,0 +1,60 @@
+//-----------------------------------------------------
+// Design Name : cam
+// File Name : cam.v
+// Function : CAM
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module cam (
+clk , // Cam clock
+cam_enable , // Cam enable
+cam_data_in , // Cam data to match
+cam_hit_out , // Cam match has happened
+cam_addr_out // Cam output address
+);
+
+parameter ADDR_WIDTH = 8;
+parameter DEPTH = 1 << ADDR_WIDTH;
+//------------Input Ports--------------
+input clk;
+input cam_enable;
+input [DEPTH-1:0] cam_data_in;
+//----------Output Ports--------------
+output cam_hit_out;
+output [ADDR_WIDTH-1:0] cam_addr_out;
+//------------Internal Variables--------
+reg [ADDR_WIDTH-1:0] cam_addr_out;
+reg cam_hit_out;
+reg [ADDR_WIDTH-1:0] cam_addr_combo;
+reg cam_hit_combo;
+reg found_match;
+integer i;
+//-------------Code Starts Here-------
+always @(cam_data_in) begin
+ cam_addr_combo = {ADDR_WIDTH{1'b0}};
+ found_match = 1'b0;
+ cam_hit_combo = 1'b0;
+ for (i=0; i<DEPTH; i=i+1) begin
+ if (cam_data_in[i] && !found_match) begin
+ found_match = 1'b1;
+ cam_hit_combo = 1'b1;
+ cam_addr_combo = i;
+ end else begin
+ found_match = found_match;
+ cam_hit_combo = cam_hit_combo;
+ cam_addr_combo = cam_addr_combo;
+ end
+ end
+end
+
+// Register the outputs
+always @(posedge clk) begin
+ if (cam_enable) begin
+ cam_hit_out <= cam_hit_combo;
+ cam_addr_out <= cam_addr_combo;
+ end else begin
+ cam_hit_out <= 1'b0;
+ cam_addr_out <= {ADDR_WIDTH{1'b0}};
+ end
+end
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_clk_div.v b/tests/asicworld/code_hdl_models_clk_div.v
new file mode 100644
index 000000000..c48ab0dd0
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_clk_div.v
@@ -0,0 +1,27 @@
+//-----------------------------------------------------
+// Design Name : clk_div
+// File Name : clk_div.v
+// Function : Divide by two counter
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+
+module clk_div (clk_in, enable,reset, clk_out);
+ // --------------Port Declaration-----------------------
+ input clk_in ;
+ input reset ;
+ input enable ;
+ output clk_out ;
+ //--------------Port data type declaration-------------
+ wire clk_in ;
+ wire enable ;
+//--------------Internal Registers----------------------
+reg clk_out ;
+//--------------Code Starts Here-----------------------
+always @ (posedge clk_in)
+if (reset) begin
+ clk_out <= 1'b0;
+end else if (enable) begin
+ clk_out <= !clk_out ;
+end
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_clk_div_45.v b/tests/asicworld/code_hdl_models_clk_div_45.v
new file mode 100644
index 000000000..d9d289673
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_clk_div_45.v
@@ -0,0 +1,54 @@
+//-----------------------------------------------------
+// Design Name : clk_div_45
+// File Name : clk_div_45.v
+// Function : Divide by 4.5
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module clk_div_45 (
+clk_in, // Input Clock
+enable, // Enable is sync with falling edge of clk_in
+clk_out // Output Clock
+);
+
+// --------------Port Declaration-----------------------
+input clk_in ;
+input enable ;
+output clk_out ;
+
+//--------------Port data type declaration-------------
+wire clk_in ;
+wire enable ;
+wire clk_out ;
+
+//--------------Internal Registers----------------------
+reg [3:0] counter1 ;
+reg [3:0] counter2 ;
+reg toggle1 ;
+reg toggle2 ;
+
+//--------------Code Starts Here-----------------------
+always @ (posedge clk_in)
+if (enable == 1'b0) begin
+ counter1 <= 4'b0;
+ toggle1 <= 0;
+end else if ((counter1 == 3 && toggle2) || (~toggle1 && counter1 == 4)) begin
+ counter1 <= 4'b0;
+ toggle1 <= ~toggle1;
+end else begin
+ counter1 <= counter1 + 1;
+end
+
+always @ (negedge clk_in)
+if (enable == 1'b0) begin
+ counter2 <= 4'b0;
+ toggle2 <= 0;
+end else if ((counter2 == 3 && ~toggle2) || (toggle2 && counter2 == 4)) begin
+ counter2 <= 4'b0;
+ toggle2 <= ~toggle2;
+end else begin
+ counter2 <= counter2 + 1;
+end
+
+assign clk_out = (counter1 <3 && counter2 < 3) & enable;
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_d_ff_gates.v b/tests/asicworld/code_hdl_models_d_ff_gates.v
new file mode 100644
index 000000000..8706f154c
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_d_ff_gates.v
@@ -0,0 +1,29 @@
+module d_ff_gates(d,clk,q,q_bar);
+input d,clk;
+output q, q_bar;
+
+wire n1,n2,n3,q_bar_n;
+wire cn,dn,n4,n5,n6;
+
+// First Latch
+not (n1,d);
+
+nand (n2,d,clk);
+nand (n3,n1,clk);
+
+nand (dn,q_bar_n,n2);
+nand (q_bar_n,dn,n3);
+
+// Second Latch
+not (cn,clk);
+
+not (n4,dn);
+
+nand (n5,dn,cn);
+nand (n6,n4,cn);
+
+nand (q,q_bar,n5);
+nand (q_bar,q,n6);
+
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_d_latch_gates.v b/tests/asicworld/code_hdl_models_d_latch_gates.v
new file mode 100644
index 000000000..3f5f6b2bb
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_d_latch_gates.v
@@ -0,0 +1,15 @@
+module d_latch_gates(d,clk,q,q_bar);
+input d,clk;
+output q, q_bar;
+
+wire n1,n2,n3;
+
+not (n1,d);
+
+nand (n2,d,clk);
+nand (n3,n1,clk);
+
+nand (q,q_bar,n2);
+nand (q_bar,q,n3);
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_decoder_2to4_gates.v b/tests/asicworld/code_hdl_models_decoder_2to4_gates.v
new file mode 100644
index 000000000..810003a85
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_decoder_2to4_gates.v
@@ -0,0 +1,14 @@
+module decoder_2to4_gates (x,y,f0,f1,f2,f3);
+input x,y;
+output f0,f1,f2,f3;
+
+wire n1,n2;
+
+not i1 (n1,x);
+not i2 (n2,y);
+and a1 (f0,n1,n2);
+and a2 (f1,n1,y);
+and a3 (f2,x,n2);
+and a4 (f3,x,y);
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_decoder_using_assign.v b/tests/asicworld/code_hdl_models_decoder_using_assign.v
new file mode 100644
index 000000000..ec0dc95b2
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_decoder_using_assign.v
@@ -0,0 +1,20 @@
+//-----------------------------------------------------
+// Design Name : decoder_using_assign
+// File Name : decoder_using_assign.v
+// Function : decoder using assign
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module decoder_using_assign (
+binary_in , // 4 bit binary input
+decoder_out , // 16-bit out
+enable // Enable for the decoder
+);
+input [3:0] binary_in ;
+input enable ;
+output [15:0] decoder_out ;
+
+wire [15:0] decoder_out ;
+
+assign decoder_out = (enable) ? (1 << binary_in) : 16'b0 ;
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_decoder_using_case.v b/tests/asicworld/code_hdl_models_decoder_using_case.v
new file mode 100644
index 000000000..ad42acdf0
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_decoder_using_case.v
@@ -0,0 +1,43 @@
+//-----------------------------------------------------
+// Design Name : decoder_using_case
+// File Name : decoder_using_case.v
+// Function : decoder using case
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module decoder_using_case (
+binary_in , // 4 bit binary input
+decoder_out , // 16-bit out
+enable // Enable for the decoder
+);
+input [3:0] binary_in ;
+input enable ;
+output [15:0] decoder_out ;
+
+reg [15:0] decoder_out ;
+
+always @ (enable or binary_in)
+begin
+ decoder_out = 0;
+ if (enable) begin
+ case (binary_in)
+ 4'h0 : decoder_out = 16'h0001;
+ 4'h1 : decoder_out = 16'h0002;
+ 4'h2 : decoder_out = 16'h0004;
+ 4'h3 : decoder_out = 16'h0008;
+ 4'h4 : decoder_out = 16'h0010;
+ 4'h5 : decoder_out = 16'h0020;
+ 4'h6 : decoder_out = 16'h0040;
+ 4'h7 : decoder_out = 16'h0080;
+ 4'h8 : decoder_out = 16'h0100;
+ 4'h9 : decoder_out = 16'h0200;
+ 4'hA : decoder_out = 16'h0400;
+ 4'hB : decoder_out = 16'h0800;
+ 4'hC : decoder_out = 16'h1000;
+ 4'hD : decoder_out = 16'h2000;
+ 4'hE : decoder_out = 16'h4000;
+ 4'hF : decoder_out = 16'h8000;
+ endcase
+ end
+end
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_dff_async_reset.v b/tests/asicworld/code_hdl_models_dff_async_reset.v
new file mode 100644
index 000000000..a156082f4
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_dff_async_reset.v
@@ -0,0 +1,30 @@
+//-----------------------------------------------------
+// Design Name : dff_async_reset
+// File Name : dff_async_reset.v
+// Function : D flip-flop async reset
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module dff_async_reset (
+data , // Data Input
+clk , // Clock Input
+reset , // Reset input
+q // Q output
+);
+//-----------Input Ports---------------
+input data, clk, reset ;
+
+//-----------Output Ports---------------
+output q;
+
+//------------Internal Variables--------
+reg q;
+
+//-------------Code Starts Here---------
+always @ ( posedge clk or negedge reset)
+if (~reset) begin
+ q <= 1'b0;
+end else begin
+ q <= data;
+end
+
+endmodule //End Of Module dff_async_reset
diff --git a/tests/asicworld/code_hdl_models_dff_sync_reset.v b/tests/asicworld/code_hdl_models_dff_sync_reset.v
new file mode 100644
index 000000000..7ef404548
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_dff_sync_reset.v
@@ -0,0 +1,30 @@
+//-----------------------------------------------------
+// Design Name : dff_sync_reset
+// File Name : dff_sync_reset.v
+// Function : D flip-flop sync reset
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module dff_sync_reset (
+data , // Data Input
+clk , // Clock Input
+reset , // Reset input
+q // Q output
+);
+//-----------Input Ports---------------
+input data, clk, reset ;
+
+//-----------Output Ports---------------
+output q;
+
+//------------Internal Variables--------
+reg q;
+
+//-------------Code Starts Here---------
+always @ ( posedge clk)
+if (~reset) begin
+ q <= 1'b0;
+end else begin
+ q <= data;
+end
+
+endmodule //End Of Module dff_sync_reset
diff --git a/tests/asicworld/code_hdl_models_dlatch_reset.v b/tests/asicworld/code_hdl_models_dlatch_reset.v
new file mode 100644
index 000000000..2cfc6fbd8
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_dlatch_reset.v
@@ -0,0 +1,30 @@
+//-----------------------------------------------------
+// Design Name : dlatch_reset
+// File Name : dlatch_reset.v
+// Function : DLATCH async reset
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module dlatch_reset (
+data , // Data Input
+en , // LatchInput
+reset , // Reset input
+q // Q output
+);
+//-----------Input Ports---------------
+input data, en, reset ;
+
+//-----------Output Ports---------------
+output q;
+
+//------------Internal Variables--------
+reg q;
+
+//-------------Code Starts Here---------
+always @ ( en or reset or data)
+if (~reset) begin
+ q <= 1'b0;
+end else if (en) begin
+ q <= data;
+end
+
+endmodule //End Of Module dlatch_reset
diff --git a/tests/asicworld/code_hdl_models_encoder_4to2_gates.v b/tests/asicworld/code_hdl_models_encoder_4to2_gates.v
new file mode 100644
index 000000000..0bfdc28ad
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_encoder_4to2_gates.v
@@ -0,0 +1,8 @@
+module encoder_4to2_gates (i0,i1,i2,i3,y);
+input i0,i1,i2,i3;
+output [1:0] y;
+
+or o1 (y[0],i1,i3);
+or o2 (y[1],i2,i3);
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_encoder_using_case.v b/tests/asicworld/code_hdl_models_encoder_using_case.v
new file mode 100644
index 000000000..32e1b720f
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_encoder_using_case.v
@@ -0,0 +1,42 @@
+//-----------------------------------------------------
+// Design Name : encoder_using_case
+// File Name : encoder_using_case.v
+// Function : Encoder using Case
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module encoder_using_case(
+binary_out , // 4 bit binary Output
+encoder_in , // 16-bit Input
+enable // Enable for the encoder
+);
+output [3:0] binary_out ;
+input enable ;
+input [15:0] encoder_in ;
+
+reg [3:0] binary_out ;
+
+always @ (enable or encoder_in)
+begin
+ binary_out = 0;
+ if (enable) begin
+ case (encoder_in)
+ 16'h0002 : binary_out = 1;
+ 16'h0004 : binary_out = 2;
+ 16'h0008 : binary_out = 3;
+ 16'h0010 : binary_out = 4;
+ 16'h0020 : binary_out = 5;
+ 16'h0040 : binary_out = 6;
+ 16'h0080 : binary_out = 7;
+ 16'h0100 : binary_out = 8;
+ 16'h0200 : binary_out = 9;
+ 16'h0400 : binary_out = 10;
+ 16'h0800 : binary_out = 11;
+ 16'h1000 : binary_out = 12;
+ 16'h2000 : binary_out = 13;
+ 16'h4000 : binary_out = 14;
+ 16'h8000 : binary_out = 15;
+ endcase
+ end
+end
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_encoder_using_if.v b/tests/asicworld/code_hdl_models_encoder_using_if.v
new file mode 100644
index 000000000..2c97ddba6
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_encoder_using_if.v
@@ -0,0 +1,58 @@
+//-----------------------------------------------------
+// Design Name : encoder_using_if
+// File Name : encoder_using_if.v
+// Function : Encoder using If
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module encoder_using_if(
+binary_out , // 4 bit binary output
+encoder_in , // 16-bit input
+enable // Enable for the encoder
+);
+//-----------Output Ports---------------
+output [3:0] binary_out ;
+//-----------Input Ports---------------
+input enable ;
+input [15:0] encoder_in ;
+//------------Internal Variables--------
+reg [3:0] binary_out ;
+//-------------Code Start-----------------
+always @ (enable or encoder_in)
+ begin
+ binary_out = 0;
+ if (enable) begin
+ if (encoder_in == 16'h0002) begin
+ binary_out = 1;
+ end if (encoder_in == 16'h0004) begin
+ binary_out = 2;
+ end if (encoder_in == 16'h0008) begin
+ binary_out = 3;
+ end if (encoder_in == 16'h0010) begin
+ binary_out = 4;
+ end if (encoder_in == 16'h0020) begin
+ binary_out = 5;
+ end if (encoder_in == 16'h0040) begin
+ binary_out = 6;
+ end if (encoder_in == 16'h0080) begin
+ binary_out = 7;
+ end if (encoder_in == 16'h0100) begin
+ binary_out = 8;
+ end if (encoder_in == 16'h0200) begin
+ binary_out = 9;
+ end if (encoder_in == 16'h0400) begin
+ binary_out = 10;
+ end if (encoder_in == 16'h0800) begin
+ binary_out = 11;
+ end if (encoder_in == 16'h1000) begin
+ binary_out = 12;
+ end if (encoder_in == 16'h2000) begin
+ binary_out = 13;
+ end if (encoder_in == 16'h4000) begin
+ binary_out = 14;
+ end if (encoder_in == 16'h8000) begin
+ binary_out = 15;
+ end
+ end
+end
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_full_adder_gates.v b/tests/asicworld/code_hdl_models_full_adder_gates.v
new file mode 100644
index 000000000..1ddc4c567
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_full_adder_gates.v
@@ -0,0 +1,18 @@
+//-----------------------------------------------------
+// Design Name : full_adder_gates
+// File Name : full_adder_gates.v
+// Function : Full Adder Using Gates
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module full_adder_gates(x,y,z,sum,carry);
+input x,y,z;
+output sum,carry;
+wire and1,and2,and3,sum1;
+
+and U_and1 (and1,x,y),
+ U_and2 (and2,x,z),
+ U_and3 (and3,y,z);
+or U_or (carry,and1,and2,and3);
+xor U_sum (sum,x,y,z);
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_full_subtracter_gates.v b/tests/asicworld/code_hdl_models_full_subtracter_gates.v
new file mode 100644
index 000000000..c24588ece
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_full_subtracter_gates.v
@@ -0,0 +1,20 @@
+//-----------------------------------------------------
+// Design Name : full_subtracter_gates
+// File Name : full_subtracter_gates.v
+// Function : Full Subtracter Using Gates
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module full_subtracter_gates(x,y,z,difference,borrow);
+input x,y,z;
+output difference,borrow;
+
+wire inv_x,borrow1,borrow2,borrow3;
+
+not (inv_x,x);
+and U_borrow1 (borrow1,inv_x,y),
+ U_borrow2 (borrow2,inv_x,z),
+ U_borrow3 (borrow3,y,z);
+
+xor U_diff (difference,borrow1,borrow2,borrows);
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_gray_counter.v b/tests/asicworld/code_hdl_models_gray_counter.v
new file mode 100644
index 000000000..bc1e740ab
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_gray_counter.v
@@ -0,0 +1,33 @@
+//-----------------------------------------------------
+// Design Name : gray_counter
+// File Name : gray_counter.v
+// Function : 8 bit gray counterS
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module gray_counter (
+ out , // counter out
+ enable , // enable for counter
+ clk , // clock
+ rst // active hight reset
+ );
+
+ //------------Input Ports--------------
+ input clk, rst, enable;
+ //----------Output Ports----------------
+ output [ 7:0] out;
+ //------------Internal Variables--------
+ wire [7:0] out;
+ reg [7:0] count;
+ //-------------Code Starts Here---------
+ always @ (posedge clk)
+ if (rst)
+ count <= 0;
+ else if (enable)
+ count <= count + 1;
+
+ assign out = { count[7], (count[7] ^ count[6]),(count[6] ^
+ count[5]),(count[5] ^ count[4]), (count[4] ^
+ count[3]),(count[3] ^ count[2]), (count[2] ^
+ count[1]),(count[1] ^ count[0]) };
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_half_adder_gates.v b/tests/asicworld/code_hdl_models_half_adder_gates.v
new file mode 100644
index 000000000..6acf243fd
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_half_adder_gates.v
@@ -0,0 +1,14 @@
+//-----------------------------------------------------
+// Design Name : half_adder_gates
+// File Name : half_adder_gates.v
+// Function : CCITT Serial CRC
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module half_adder_gates(x,y,sum,carry);
+input x,y;
+output sum,carry;
+
+and U_carry (carry,x,y);
+xor U_sum (sum,x,y);
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_lfsr.v b/tests/asicworld/code_hdl_models_lfsr.v
new file mode 100644
index 000000000..639780832
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_lfsr.v
@@ -0,0 +1,35 @@
+//-----------------------------------------------------
+// Design Name : lfsr
+// File Name : lfsr.v
+// Function : Linear feedback shift register
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module lfsr (
+out , // Output of the counter
+enable , // Enable for counter
+clk , // clock input
+reset // reset input
+);
+
+//----------Output Ports--------------
+output [7:0] out;
+//------------Input Ports--------------
+input enable, clk, reset;
+//------------Internal Variables--------
+reg [7:0] out;
+wire linear_feedback;
+
+//-------------Code Starts Here-------
+assign linear_feedback = !(out[7] ^ out[3]);
+
+always @(posedge clk)
+if (reset) begin // active high reset
+ out <= 8'b0 ;
+end else if (enable) begin
+ out <= {out[6],out[5],
+ out[4],out[3],
+ out[2],out[1],
+ out[0], linear_feedback};
+end
+
+endmodule // End Of Module counter
diff --git a/tests/asicworld/code_hdl_models_lfsr_updown.v b/tests/asicworld/code_hdl_models_lfsr_updown.v
new file mode 100644
index 000000000..0bd29b835
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_lfsr_updown.v
@@ -0,0 +1,35 @@
+`define WIDTH 8
+module lfsr_updown (
+clk , // Clock input
+reset , // Reset input
+enable , // Enable input
+up_down , // Up Down input
+count , // Count output
+overflow // Overflow output
+);
+
+ input clk;
+ input reset;
+ input enable;
+ input up_down;
+
+ output [`WIDTH-1 : 0] count;
+ output overflow;
+
+ reg [`WIDTH-1 : 0] count;
+
+ assign overflow = (up_down) ? (count == {{`WIDTH-1{1'b0}}, 1'b1}) :
+ (count == {1'b1, {`WIDTH-1{1'b0}}}) ;
+
+ always @(posedge clk)
+ if (reset)
+ count <= {`WIDTH{1'b0}};
+ else if (enable) begin
+ if (up_down) begin
+ count <= {~(^(count & `WIDTH'b01100011)),count[`WIDTH-1:1]};
+ end else begin
+ count <= {count[`WIDTH-2:0],~(^(count & `WIDTH'b10110001))};
+ end
+ end
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_misc1.v b/tests/asicworld/code_hdl_models_misc1.v
new file mode 100644
index 000000000..e3d9d5d64
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_misc1.v
@@ -0,0 +1,22 @@
+module misc1 (a,b,c,d,y);
+input a, b,c,d;
+output y;
+
+wire net1,net2,net3;
+
+supply1 vdd;
+supply0 vss;
+
+// y = !((a+b+c).d)
+
+pmos p1 (vdd,net1,a);
+pmos p2 (net1,net2,b);
+pmos p3 (net2,y,c);
+pmos p4 (vdd,y,d);
+
+nmos n1 (vss,net3,a);
+nmos n2 (vss,net3,b);
+nmos n3 (vss,net3,c);
+nmos n4 (net3,y,d);
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_mux21_switch.v b/tests/asicworld/code_hdl_models_mux21_switch.v
new file mode 100644
index 000000000..519c07fc5
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_mux21_switch.v
@@ -0,0 +1,22 @@
+//-----------------------------------------------------
+// Design Name : mux21_switch
+// File Name : mux21_switch.v
+// Function : 2:1 Mux using Switch Primitives
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module mux21_switch (out, ctrl, in1, in2);
+
+ output out;
+ input ctrl, in1, in2;
+ wire w;
+
+ supply1 power;
+ supply0 ground;
+
+ pmos N1 (w, power, ctrl);
+ nmos N2 (w, ground, ctrl);
+
+ cmos C1 (out, in1, w, ctrl);
+ cmos C2 (out, in2, ctrl, w);
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_mux_2to1_gates.v b/tests/asicworld/code_hdl_models_mux_2to1_gates.v
new file mode 100644
index 000000000..fc762159d
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_mux_2to1_gates.v
@@ -0,0 +1,18 @@
+//-----------------------------------------------------
+// Design Name : mux_2to1_gates
+// File Name : mux_2to1_gates.v
+// Function : 2:1 Mux using Gate Primitives
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module mux_2to1_gates(a,b,sel,y);
+input a,b,sel;
+output y;
+
+wire sel,a_sel,b_sel;
+
+not U_inv (inv_sel,sel);
+and U_anda (asel,a,inv_sel),
+ U_andb (bsel,b,sel);
+or U_or (y,asel,bsel);
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_mux_using_assign.v b/tests/asicworld/code_hdl_models_mux_using_assign.v
new file mode 100644
index 000000000..4284f10ca
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_mux_using_assign.v
@@ -0,0 +1,22 @@
+//-----------------------------------------------------
+// Design Name : mux_using_assign
+// File Name : mux_using_assign.v
+// Function : 2:1 Mux using Assign
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module mux_using_assign(
+din_0 , // Mux first input
+din_1 , // Mux Second input
+sel , // Select input
+mux_out // Mux output
+);
+//-----------Input Ports---------------
+input din_0, din_1, sel ;
+//-----------Output Ports---------------
+output mux_out;
+//------------Internal Variables--------
+wire mux_out;
+//-------------Code Start-----------------
+assign mux_out = (sel) ? din_1 : din_0;
+
+endmodule //End Of Module mux
diff --git a/tests/asicworld/code_hdl_models_mux_using_case.v b/tests/asicworld/code_hdl_models_mux_using_case.v
new file mode 100644
index 000000000..123da4483
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_mux_using_case.v
@@ -0,0 +1,28 @@
+//-----------------------------------------------------
+// Design Name : mux_using_case
+// File Name : mux_using_case.v
+// Function : 2:1 Mux using Case
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module mux_using_case(
+din_0 , // Mux first input
+din_1 , // Mux Second input
+sel , // Select input
+mux_out // Mux output
+);
+//-----------Input Ports---------------
+input din_0, din_1, sel ;
+//-----------Output Ports---------------
+output mux_out;
+//------------Internal Variables--------
+reg mux_out;
+//-------------Code Starts Here---------
+always @ (sel or din_0 or din_1)
+begin : MUX
+ case(sel )
+ 1'b0 : mux_out = din_0;
+ 1'b1 : mux_out = din_1;
+ endcase
+end
+
+endmodule //End Of Module mux
diff --git a/tests/asicworld/code_hdl_models_mux_using_if.v b/tests/asicworld/code_hdl_models_mux_using_if.v
new file mode 100644
index 000000000..4d42e2089
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_mux_using_if.v
@@ -0,0 +1,29 @@
+//-----------------------------------------------------
+// Design Name : mux_using_if
+// File Name : mux_using_if.v
+// Function : 2:1 Mux using If
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module mux_using_if(
+din_0 , // Mux first input
+din_1 , // Mux Second input
+sel , // Select input
+mux_out // Mux output
+);
+//-----------Input Ports---------------
+input din_0, din_1, sel ;
+//-----------Output Ports---------------
+output mux_out;
+//------------Internal Variables--------
+reg mux_out;
+//-------------Code Starts Here---------
+always @ (sel or din_0 or din_1)
+begin : MUX
+ if (sel == 1'b0) begin
+ mux_out = din_0;
+ end else begin
+ mux_out = din_1 ;
+ end
+end
+
+endmodule //End Of Module mux
diff --git a/tests/asicworld/code_hdl_models_nand_switch.v b/tests/asicworld/code_hdl_models_nand_switch.v
new file mode 100644
index 000000000..1ccdd3a7c
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_nand_switch.v
@@ -0,0 +1,14 @@
+module nand_switch(a,b,out);
+input a,b;
+output out;
+
+supply0 vss;
+supply1 vdd;
+wire net1;
+
+pmos p1 (vdd,out,a);
+pmos p2 (vdd,out,b);
+nmos n1 (vss,net1,a);
+nmos n2 (net1,out,b);
+
+endmodule \ No newline at end of file
diff --git a/tests/asicworld/code_hdl_models_one_hot_cnt.v b/tests/asicworld/code_hdl_models_one_hot_cnt.v
new file mode 100644
index 000000000..f6b84c6e5
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_one_hot_cnt.v
@@ -0,0 +1,31 @@
+//-----------------------------------------------------
+// Design Name : one_hot_cnt
+// File Name : one_hot_cnt.v
+// Function : 8 bit one hot counter
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module one_hot_cnt (
+out , // Output of the counter
+enable , // enable for counter
+clk , // clock input
+reset // reset input
+);
+//----------Output Ports--------------
+output [7:0] out;
+
+//------------Input Ports--------------
+input enable, clk, reset;
+
+//------------Internal Variables--------
+reg [7:0] out;
+
+//-------------Code Starts Here-------
+always @ (posedge clk)
+if (reset) begin
+ out <= 8'b0000_0001 ;
+end else if (enable) begin
+ out <= {out[6],out[5],out[4],out[3],
+ out[2],out[1],out[0],out[7]};
+end
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_parallel_crc.v b/tests/asicworld/code_hdl_models_parallel_crc.v
new file mode 100644
index 000000000..d8d0bf1c6
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_parallel_crc.v
@@ -0,0 +1,53 @@
+//-----------------------------------------------------
+// Design Name : parallel_crc_ccitt
+// File Name : parallel_crc.v
+// Function : CCITT Parallel CRC
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module parallel_crc_ccitt (
+clk ,
+reset ,
+enable ,
+init ,
+data_in ,
+crc_out
+);
+//-----------Input Ports---------------
+input clk ;
+input reset ;
+input enable ;
+input init ;
+input [7:0] data_in ;
+//-----------Output Ports---------------
+output [15:0] crc_out;
+//------------Internal Variables--------
+reg [15:0] crc_reg;
+wire [15:0] next_crc;
+//-------------Code Start-----------------
+assign crc_out = crc_reg;
+// CRC Control logic
+always @ (posedge clk)
+if (reset) begin
+ crc_reg <= 16'hFFFF;
+end else if (enable) begin
+ if (init) begin
+ crc_reg <= 16'hFFFF;
+ end else begin
+ crc_reg <= next_crc;
+ end
+end
+// Parallel CRC calculation
+assign next_crc[0] = data_in[7] ^ data_in[0] ^ crc_reg[4] ^ crc_reg[11];
+assign next_crc[1] = data_in[1] ^ crc_reg[5];
+assign next_crc[2] = data_in[2] ^ crc_reg[6];
+assign next_crc[3] = data_in[3] ^ crc_reg[7];
+assign next_crc[4] = data_in[4] ^ crc_reg[8];
+assign next_crc[5] = data_in[7] ^ data_in[5] ^ data_in[0] ^ crc_reg[4] ^ crc_reg[9] ^ crc_reg[11];
+assign next_crc[6] = data_in[6] ^ data_in[1] ^ crc_reg[5] ^ crc_reg[10];
+assign next_crc[7] = data_in[7] ^ data_in[2] ^ crc_reg[6] ^ crc_reg[11];
+assign next_crc[8] = data_in[3] ^ crc_reg[0] ^ crc_reg[7];
+assign next_crc[9] = data_in[4] ^ crc_reg[1] ^ crc_reg[8];
+assign next_crc[10] = data_in[5] ^ crc_reg[2] ^ crc_reg[9];
+assign next_crc[11] = data_in[6] ^ crc_reg[3] ^ crc_reg[10];
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_parity_using_assign.v b/tests/asicworld/code_hdl_models_parity_using_assign.v
new file mode 100644
index 000000000..b0282e8d7
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_parity_using_assign.v
@@ -0,0 +1,21 @@
+//-----------------------------------------------------
+// Design Name : parity_using_assign
+// File Name : parity_using_assign.v
+// Function : Parity using assign
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module parity_using_assign (
+data_in , // 8 bit data in
+parity_out // 1 bit parity out
+);
+output parity_out ;
+input [7:0] data_in ;
+
+wire parity_out ;
+
+assign parity_out = (data_in[0] ^ data_in[1]) ^
+ (data_in[2] ^ data_in[3]) ^
+ (data_in[4] ^ data_in[5]) ^
+ (data_in[6] ^ data_in[7]);
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_parity_using_bitwise.v b/tests/asicworld/code_hdl_models_parity_using_bitwise.v
new file mode 100644
index 000000000..0046fb143
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_parity_using_bitwise.v
@@ -0,0 +1,16 @@
+//-----------------------------------------------------
+// Design Name : parity_using_bitwise
+// File Name : parity_using_bitwise.v
+// Function : Parity using bitwise xor
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module parity_using_bitwise (
+data_in , // 8 bit data in
+parity_out // 1 bit parity out
+);
+output parity_out ;
+input [7:0] data_in ;
+
+assign parity_out = ^data_in;
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_parity_using_function.v b/tests/asicworld/code_hdl_models_parity_using_function.v
new file mode 100644
index 000000000..0d07aaebe
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_parity_using_function.v
@@ -0,0 +1,29 @@
+//-----------------------------------------------------
+// Design Name : parity_using_function
+// File Name : parity_using_function.v
+// Function : Parity using function
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module parity_using_function (
+data_in , // 8 bit data in
+parity_out // 1 bit parity out
+);
+output parity_out ;
+input [7:0] data_in ;
+
+wire parity_out ;
+
+function parity;
+ input [31:0] data;
+ begin
+ parity = (data_in[0] ^ data_in[1]) ^
+ (data_in[2] ^ data_in[3]) ^
+ (data_in[4] ^ data_in[5]) ^
+ (data_in[6] ^ data_in[7]);
+ end
+endfunction
+
+
+assign parity_out = parity(data_in);
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_pri_encoder_using_assign.v b/tests/asicworld/code_hdl_models_pri_encoder_using_assign.v
new file mode 100644
index 000000000..c1ce960c4
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_pri_encoder_using_assign.v
@@ -0,0 +1,36 @@
+//-----------------------------------------------------
+// Design Name : pri_encoder_using_assign
+// File Name : pri_encoder_using_assign.v
+// Function : Pri Encoder using assign
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module pri_encoder_using_assign (
+binary_out , // 4 bit binary output
+encoder_in , // 16-bit input
+enable // Enable for the encoder
+);
+
+output [3:0] binary_out ;
+input enable ;
+input [15:0] encoder_in ;
+
+wire [3:0] binary_out ;
+
+assign binary_out = (!enable) ? 0 : (
+ (encoder_in == 16'bxxxx_xxxx_xxxx_xxx1) ? 0 :
+ (encoder_in == 16'bxxxx_xxxx_xxxx_xx10) ? 1 :
+ (encoder_in == 16'bxxxx_xxxx_xxxx_x100) ? 2 :
+ (encoder_in == 16'bxxxx_xxxx_xxxx_1000) ? 3 :
+ (encoder_in == 16'bxxxx_xxxx_xxx1_0000) ? 4 :
+ (encoder_in == 16'bxxxx_xxxx_xx10_0000) ? 5 :
+ (encoder_in == 16'bxxxx_xxxx_x100_0000) ? 6 :
+ (encoder_in == 16'bxxxx_xxxx_1000_0000) ? 7 :
+ (encoder_in == 16'bxxxx_xxx1_0000_0000) ? 8 :
+ (encoder_in == 16'bxxxx_xx10_0000_0000) ? 9 :
+ (encoder_in == 16'bxxxx_x100_0000_0000) ? 10 :
+ (encoder_in == 16'bxxxx_1000_0000_0000) ? 11 :
+ (encoder_in == 16'bxxx1_0000_0000_0000) ? 12 :
+ (encoder_in == 16'bxx10_0000_0000_0000) ? 13 :
+ (encoder_in == 16'bx100_0000_0000_0000) ? 14 : 15);
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_ram_sp_ar_sw.v b/tests/asicworld/code_hdl_models_ram_sp_ar_sw.v
new file mode 100644
index 000000000..d3338f749
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_ram_sp_ar_sw.v
@@ -0,0 +1,58 @@
+//-----------------------------------------------------
+// Design Name : ram_sp_ar_sw
+// File Name : ram_sp_ar_sw.v
+// Function : Asynchronous read write RAM
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module ram_sp_ar_sw (
+clk , // Clock Input
+address , // Address Input
+data , // Data bi-directional
+cs , // Chip Select
+we , // Write Enable/Read Enable
+oe // Output Enable
+);
+
+parameter DATA_WIDTH = 8 ;
+parameter ADDR_WIDTH = 8 ;
+parameter RAM_DEPTH = 1 << ADDR_WIDTH;
+
+//--------------Input Ports-----------------------
+input clk ;
+input [ADDR_WIDTH-1:0] address ;
+input cs ;
+input we ;
+input oe ;
+
+//--------------Inout Ports-----------------------
+inout [DATA_WIDTH-1:0] data ;
+
+//--------------Internal variables----------------
+reg [DATA_WIDTH-1:0] data_out ;
+reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
+
+//--------------Code Starts Here------------------
+
+// Tri-State Buffer control
+// output : When we = 0, oe = 1, cs = 1
+assign data = (cs && oe && !we) ? data_out : 8'bz;
+
+// Memory Write Block
+// Write Operation : When we = 1, cs = 1
+always @ (posedge clk)
+begin : MEM_WRITE
+ if ( cs && we ) begin
+ mem[address] = data;
+ end
+end
+
+// Memory Read Block
+// Read Operation : When we = 0, oe = 1, cs = 1
+always @ (address or cs or we or oe)
+begin : MEM_READ
+ if (cs && !we && oe) begin
+ data_out = mem[address];
+ end
+end
+
+endmodule // End of Module ram_sp_ar_sw
diff --git a/tests/asicworld/code_hdl_models_ram_sp_sr_sw.v b/tests/asicworld/code_hdl_models_ram_sp_sr_sw.v
new file mode 100644
index 000000000..c7fd9554d
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_ram_sp_sr_sw.v
@@ -0,0 +1,62 @@
+//-----------------------------------------------------
+// Design Name : ram_sp_sr_sw
+// File Name : ram_sp_sr_sw.v
+// Function : Synchronous read write RAM
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module ram_sp_sr_sw (
+clk , // Clock Input
+address , // Address Input
+data , // Data bi-directional
+cs , // Chip Select
+we , // Write Enable/Read Enable
+oe // Output Enable
+);
+
+parameter DATA_WIDTH = 8 ;
+parameter ADDR_WIDTH = 8 ;
+parameter RAM_DEPTH = 1 << ADDR_WIDTH;
+
+//--------------Input Ports-----------------------
+input clk ;
+input [ADDR_WIDTH-1:0] address ;
+input cs ;
+input we ;
+input oe ;
+
+//--------------Inout Ports-----------------------
+inout [DATA_WIDTH-1:0] data ;
+
+//--------------Internal variables----------------
+reg [DATA_WIDTH-1:0] data_out ;
+reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
+reg oe_r;
+
+//--------------Code Starts Here------------------
+
+// Tri-State Buffer control
+// output : When we = 0, oe = 1, cs = 1
+assign data = (cs && oe && !we) ? data_out : 8'bz;
+
+// Memory Write Block
+// Write Operation : When we = 1, cs = 1
+always @ (posedge clk)
+begin : MEM_WRITE
+ if ( cs && we ) begin
+ mem[address] = data;
+ end
+end
+
+// Memory Read Block
+// Read Operation : When we = 0, oe = 1, cs = 1
+always @ (posedge clk)
+begin : MEM_READ
+ if (cs && !we && oe) begin
+ data_out = mem[address];
+ oe_r = 1;
+ end else begin
+ oe_r = 0;
+ end
+end
+
+endmodule // End of Module ram_sp_sr_sw
diff --git a/tests/asicworld/code_hdl_models_rom_using_case.v b/tests/asicworld/code_hdl_models_rom_using_case.v
new file mode 100644
index 000000000..6b700993b
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_rom_using_case.v
@@ -0,0 +1,42 @@
+//-----------------------------------------------------
+// Design Name : rom_using_case
+// File Name : rom_using_case.v
+// Function : ROM using case
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module rom_using_case (
+address , // Address input
+data , // Data output
+read_en , // Read Enable
+ce // Chip Enable
+);
+input [3:0] address;
+output [7:0] data;
+input read_en;
+input ce;
+
+reg [7:0] data ;
+
+always @ (ce or read_en or address)
+begin
+ case (address)
+ 0 : data = 10;
+ 1 : data = 55;
+ 2 : data = 244;
+ 3 : data = 0;
+ 4 : data = 1;
+ 5 : data = 8'hff;
+ 6 : data = 8'h11;
+ 7 : data = 8'h1;
+ 8 : data = 8'h10;
+ 9 : data = 8'h0;
+ 10 : data = 8'h10;
+ 11 : data = 8'h15;
+ 12 : data = 8'h60;
+ 13 : data = 8'h90;
+ 14 : data = 8'h70;
+ 15 : data = 8'h90;
+ endcase
+end
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_serial_crc.v b/tests/asicworld/code_hdl_models_serial_crc.v
new file mode 100644
index 000000000..a4a63a26f
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_serial_crc.v
@@ -0,0 +1,54 @@
+//-----------------------------------------------------
+// Design Name : serial_crc_ccitt
+// File Name : serial_crc.v
+// Function : CCITT Serial CRC
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module serial_crc_ccitt (
+clk ,
+reset ,
+enable ,
+init ,
+data_in ,
+crc_out
+);
+//-----------Input Ports---------------
+input clk ;
+input reset ;
+input enable ;
+input init ;
+input data_in ;
+//-----------Output Ports---------------
+output [15:0] crc_out;
+//------------Internal Variables--------
+reg [15:0] lfsr;
+//-------------Code Start-----------------
+assign crc_out = lfsr;
+// Logic to CRC Calculation
+always @ (posedge clk)
+if (reset) begin
+ lfsr <= 16'hFFFF;
+end else if (enable) begin
+ if (init) begin
+ lfsr <= 16'hFFFF;
+ end else begin
+ lfsr[0] <= data_in ^ lfsr[15];
+ lfsr[1] <= lfsr[0];
+ lfsr[2] <= lfsr[1];
+ lfsr[3] <= lfsr[2];
+ lfsr[4] <= lfsr[3];
+ lfsr[5] <= lfsr[4] ^ data_in ^ lfsr[15];
+ lfsr[6] <= lfsr[5];
+ lfsr[7] <= lfsr[6];
+ lfsr[8] <= lfsr[7];
+ lfsr[9] <= lfsr[8];
+ lfsr[10] <= lfsr[9];
+ lfsr[11] <= lfsr[10];
+ lfsr[12] <= lfsr[11] ^ data_in ^ lfsr[15];
+ lfsr[13] <= lfsr[12];
+ lfsr[14] <= lfsr[13];
+ lfsr[15] <= lfsr[14];
+ end
+end
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_t_gate_switch.v b/tests/asicworld/code_hdl_models_t_gate_switch.v
new file mode 100644
index 000000000..1bff66af8
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_t_gate_switch.v
@@ -0,0 +1,11 @@
+module t_gate_switch (L,R,nC,C);
+ inout L;
+ inout R;
+ input nC;
+ input C;
+
+ //Syntax: keyword unique_name (drain. source, gate);
+ pmos p1 (L,R,nC);
+ nmos p2 (L,R,C);
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_tff_async_reset.v b/tests/asicworld/code_hdl_models_tff_async_reset.v
new file mode 100644
index 000000000..4c5a1fa9c
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_tff_async_reset.v
@@ -0,0 +1,27 @@
+//-----------------------------------------------------
+// Design Name : tff_async_reset
+// File Name : tff_async_reset.v
+// Function : T flip-flop async reset
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module tff_async_reset (
+data , // Data Input
+clk , // Clock Input
+reset , // Reset input
+q // Q output
+);
+//-----------Input Ports---------------
+input data, clk, reset ;
+//-----------Output Ports---------------
+output q;
+//------------Internal Variables--------
+reg q;
+//-------------Code Starts Here---------
+always @ ( posedge clk or negedge reset)
+if (~reset) begin
+ q <= 1'b0;
+end else if (data) begin
+ q <= !q;
+end
+
+endmodule //End Of Module tff_async_reset
diff --git a/tests/asicworld/code_hdl_models_tff_sync_reset.v b/tests/asicworld/code_hdl_models_tff_sync_reset.v
new file mode 100644
index 000000000..a962d53d8
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_tff_sync_reset.v
@@ -0,0 +1,27 @@
+//-----------------------------------------------------
+// Design Name : tff_sync_reset
+// File Name : tff_sync_reset.v
+// Function : T flip-flop sync reset
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module tff_sync_reset (
+data , // Data Input
+clk , // Clock Input
+reset , // Reset input
+q // Q output
+);
+//-----------Input Ports---------------
+input data, clk, reset ;
+//-----------Output Ports---------------
+output q;
+//------------Internal Variables--------
+reg q;
+//-------------Code Starts Here---------
+always @ ( posedge clk)
+if (~reset) begin
+ q <= 1'b0;
+end else if (data) begin
+ q <= !q;
+end
+
+endmodule //End Of Module tff_async_reset
diff --git a/tests/asicworld/code_hdl_models_uart.v b/tests/asicworld/code_hdl_models_uart.v
new file mode 100644
index 000000000..40205250a
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_uart.v
@@ -0,0 +1,154 @@
+//-----------------------------------------------------
+// Design Name : uart
+// File Name : uart.v
+// Function : Simple UART
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module uart (
+reset ,
+txclk ,
+ld_tx_data ,
+tx_data ,
+tx_enable ,
+tx_out ,
+tx_empty ,
+rxclk ,
+uld_rx_data ,
+rx_data ,
+rx_enable ,
+rx_in ,
+rx_empty
+);
+// Port declarations
+input reset ;
+input txclk ;
+input ld_tx_data ;
+input [7:0] tx_data ;
+input tx_enable ;
+output tx_out ;
+output tx_empty ;
+input rxclk ;
+input uld_rx_data ;
+output [7:0] rx_data ;
+input rx_enable ;
+input rx_in ;
+output rx_empty ;
+
+// Internal Variables
+reg [7:0] tx_reg ;
+reg tx_empty ;
+reg tx_over_run ;
+reg [3:0] tx_cnt ;
+reg tx_out ;
+reg [7:0] rx_reg ;
+reg [7:0] rx_data ;
+reg [3:0] rx_sample_cnt ;
+reg [3:0] rx_cnt ;
+reg rx_frame_err ;
+reg rx_over_run ;
+reg rx_empty ;
+reg rx_d1 ;
+reg rx_d2 ;
+reg rx_busy ;
+
+// UART RX Logic
+always @ (posedge rxclk or posedge reset)
+if (reset) begin
+ rx_reg <= 0;
+ rx_data <= 0;
+ rx_sample_cnt <= 0;
+ rx_cnt <= 0;
+ rx_frame_err <= 0;
+ rx_over_run <= 0;
+ rx_empty <= 1;
+ rx_d1 <= 1;
+ rx_d2 <= 1;
+ rx_busy <= 0;
+end else begin
+ // Synchronize the asynch signal
+ rx_d1 <= rx_in;
+ rx_d2 <= rx_d1;
+ // Uload the rx data
+ if (uld_rx_data) begin
+ rx_data <= rx_reg;
+ rx_empty <= 1;
+ end
+ // Receive data only when rx is enabled
+ if (rx_enable) begin
+ // Check if just received start of frame
+ if (!rx_busy && !rx_d2) begin
+ rx_busy <= 1;
+ rx_sample_cnt <= 1;
+ rx_cnt <= 0;
+ end
+ // Start of frame detected, Proceed with rest of data
+ if (rx_busy) begin
+ rx_sample_cnt <= rx_sample_cnt + 1;
+ // Logic to sample at middle of data
+ if (rx_sample_cnt == 7) begin
+ if ((rx_d2 == 1) && (rx_cnt == 0)) begin
+ rx_busy <= 0;
+ end else begin
+ rx_cnt <= rx_cnt + 1;
+ // Start storing the rx data
+ if (rx_cnt > 0 && rx_cnt < 9) begin
+ rx_reg[rx_cnt - 1] <= rx_d2;
+ end
+ if (rx_cnt == 9) begin
+ rx_busy <= 0;
+ // Check if End of frame received correctly
+ if (rx_d2 == 0) begin
+ rx_frame_err <= 1;
+ end else begin
+ rx_empty <= 0;
+ rx_frame_err <= 0;
+ // Check if last rx data was not unloaded,
+ rx_over_run <= (rx_empty) ? 0 : 1;
+ end
+ end
+ end
+ end
+ end
+ end
+ if (!rx_enable) begin
+ rx_busy <= 0;
+ end
+end
+
+// UART TX Logic
+always @ (posedge txclk or posedge reset)
+if (reset) begin
+ tx_reg <= 0;
+ tx_empty <= 1;
+ tx_over_run <= 0;
+ tx_out <= 1;
+ tx_cnt <= 0;
+end else begin
+ if (ld_tx_data) begin
+ if (!tx_empty) begin
+ tx_over_run <= 0;
+ end else begin
+ tx_reg <= tx_data;
+ tx_empty <= 0;
+ end
+ end
+ if (tx_enable && !tx_empty) begin
+ tx_cnt <= tx_cnt + 1;
+ if (tx_cnt == 0) begin
+ tx_out <= 0;
+ end
+ if (tx_cnt > 0 && tx_cnt < 9) begin
+ tx_out <= tx_reg[tx_cnt -1];
+ end
+ if (tx_cnt == 9) begin
+ tx_out <= 1;
+ tx_cnt <= 0;
+ tx_empty <= 1;
+ end
+ end
+ if (!tx_enable) begin
+ tx_cnt <= 0;
+ end
+end
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_up_counter.v b/tests/asicworld/code_hdl_models_up_counter.v
new file mode 100644
index 000000000..ffe670994
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_up_counter.v
@@ -0,0 +1,29 @@
+//-----------------------------------------------------
+// Design Name : up_counter
+// File Name : up_counter.v
+// Function : Up counter
+// Coder  : Deepak
+//-----------------------------------------------------
+module up_counter (
+out , // Output of the counter
+enable , // enable for counter
+clk , // clock Input
+reset // reset Input
+);
+//----------Output Ports--------------
+ output [7:0] out;
+//------------Input Ports--------------
+ input enable, clk, reset;
+//------------Internal Variables--------
+ reg [7:0] out;
+//-------------Code Starts Here-------
+always @(posedge clk)
+if (reset) begin
+ out <= 8'b0 ;
+end else if (enable) begin
+ out <= out + 1;
+end
+
+
+endmodule
+
diff --git a/tests/asicworld/code_hdl_models_up_counter_load.v b/tests/asicworld/code_hdl_models_up_counter_load.v
new file mode 100644
index 000000000..92ad895aa
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_up_counter_load.v
@@ -0,0 +1,32 @@
+//-----------------------------------------------------
+// Design Name : up_counter_load
+// File Name : up_counter_load.v
+// Function : Up counter with load
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module up_counter_load (
+out , // Output of the counter
+data , // Parallel load for the counter
+load , // Parallel load enable
+enable , // Enable counting
+clk , // clock input
+reset // reset input
+);
+//----------Output Ports--------------
+output [7:0] out;
+//------------Input Ports--------------
+input [7:0] data;
+input load, enable, clk, reset;
+//------------Internal Variables--------
+reg [7:0] out;
+//-------------Code Starts Here-------
+always @(posedge clk)
+if (reset) begin
+ out <= 8'b0 ;
+end else if (load) begin
+ out <= data;
+end else if (enable) begin
+ out <= out + 1;
+end
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_up_down_counter.v b/tests/asicworld/code_hdl_models_up_down_counter.v
new file mode 100644
index 000000000..fff2982af
--- /dev/null
+++ b/tests/asicworld/code_hdl_models_up_down_counter.v
@@ -0,0 +1,29 @@
+//-----------------------------------------------------
+// Design Name : up_down_counter
+// File Name : up_down_counter.v
+// Function : Up down counter
+// Coder : Deepak Kumar Tala
+//-----------------------------------------------------
+module up_down_counter (
+out , // Output of the counter
+up_down , // up_down control for counter
+clk , // clock input
+reset // reset input
+);
+//----------Output Ports--------------
+output [7:0] out;
+//------------Input Ports--------------
+input up_down, clk, reset;
+//------------Internal Variables--------
+reg [7:0] out;
+//-------------Code Starts Here-------
+always @(posedge clk)
+if (reset) begin // active high reset
+ out <= 8'b0 ;
+end else if (up_down) begin
+ out <= out + 1;
+end else begin
+ out <= out - 1;
+end
+
+endmodule
diff --git a/tests/asicworld/code_specman_switch_fabric.v b/tests/asicworld/code_specman_switch_fabric.v
new file mode 100644
index 000000000..1ac7ee701
--- /dev/null
+++ b/tests/asicworld/code_specman_switch_fabric.v
@@ -0,0 +1,82 @@
+module switch_fabric(
+ clk, reset, data_in0, data_in1, data_in2,
+ data_in3, data_in4, data_in5, data_in_valid0,
+ data_in_valid1, data_in_valid2, data_in_valid3,
+ data_in_valid4, data_in_valid5, data_out0,
+ data_out1, data_out2, data_out3, data_out4,
+ data_out5, data_out_ack0, data_out_ack1,
+ data_out_ack2, data_out_ack3, data_out_ack4,
+ data_out_ack5
+);
+
+input clk, reset;
+input [7:0] data_in0, data_in1, data_in2, data_in3;
+input [7:0] data_in4, data_in5;
+input data_in_valid0, data_in_valid1, data_in_valid2;
+input [7:0] data_in_valid3, data_in_valid4, data_in_valid5;
+output [7:0] data_out0, data_out1, data_out2, data_out3;
+output [7:0] data_out4, data_out5;
+output data_out_ack0, data_out_ack1, data_out_ack2;
+output [7:0] data_out_ack3, data_out_ack4, data_out_ack5;
+
+(* gentb_clock *)
+wire clk;
+
+switch port_0 ( .clk(clk), .reset(reset), .data_in(data_in0),
+ .data_in_valid(data_in_valid0), .data_out(data_out0),
+ .data_out_ack(data_out_ack0));
+
+switch port_1 ( .clk(clk), .reset(reset), .data_in(data_in1),
+ .data_in_valid(data_in_valid1), .data_out(data_out1),
+ .data_out_ack(data_out_ack1));
+
+switch port_2 ( .clk(clk), .reset(reset), .data_in(data_in2),
+ .data_in_valid(data_in_valid2), .data_out(data_out2), .
+ data_out_ack(data_out_ack2));
+
+switch port_3 ( .clk(clk), .reset(reset), .data_in(data_in3),
+ .data_in_valid(data_in_valid3), .data_out(data_out3),
+ .data_out_ack(data_out_ack3));
+
+switch port_4 ( .clk(clk), .reset(reset), .data_in(data_in4),
+ .data_in_valid(data_in_valid4), .data_out(data_out4),
+ .data_out_ack(data_out_ack4));
+
+switch port_5 ( .clk(clk), .reset(reset), .data_in(data_in5),
+ .data_in_valid(data_in_valid5), .data_out(data_out5),
+ .data_out_ack(data_out_ack5));
+
+endmodule
+
+module switch (
+ clk,
+ reset,
+ data_in,
+ data_in_valid,
+ data_out,
+ data_out_ack
+);
+
+input clk;
+input reset;
+input [7:0] data_in;
+input data_in_valid;
+output [7:0] data_out;
+output data_out_ack;
+
+reg [7:0] data_out;
+reg data_out_ack;
+
+always @ (posedge clk)
+if (reset) begin
+ data_out <= 0;
+ data_out_ack <= 0;
+end else if (data_in_valid) begin
+ data_out <= data_in;
+ data_out_ack <= 1;
+end else begin
+ data_out <= 0;
+ data_out_ack <= 0;
+end
+
+endmodule
diff --git a/tests/asicworld/code_tidbits_asyn_reset.v b/tests/asicworld/code_tidbits_asyn_reset.v
new file mode 100644
index 000000000..58e47c567
--- /dev/null
+++ b/tests/asicworld/code_tidbits_asyn_reset.v
@@ -0,0 +1,18 @@
+module asyn_reset(clk,reset,a,c);
+ input clk;
+ input reset;
+ input a;
+ output c;
+
+ wire clk;
+ wire reset;
+ wire a;
+ reg c;
+
+always @ (posedge clk or posedge reset)
+ if ( reset == 1'b1) begin
+ c <= 0;
+ end else begin
+ c <= a;
+ end
+endmodule
diff --git a/tests/asicworld/code_tidbits_blocking.v b/tests/asicworld/code_tidbits_blocking.v
new file mode 100644
index 000000000..e13b72cc7
--- /dev/null
+++ b/tests/asicworld/code_tidbits_blocking.v
@@ -0,0 +1,17 @@
+module blocking (clk,a,c);
+input clk;
+input a;
+output c;
+
+wire clk;
+wire a;
+reg c;
+reg b;
+
+always @ (posedge clk )
+begin
+ b = a;
+ c = b;
+end
+
+endmodule
diff --git a/tests/asicworld/code_tidbits_fsm_using_always.v b/tests/asicworld/code_tidbits_fsm_using_always.v
new file mode 100644
index 000000000..8a8775b95
--- /dev/null
+++ b/tests/asicworld/code_tidbits_fsm_using_always.v
@@ -0,0 +1,91 @@
+//-----------------------------------------------------
+// This is FSM demo program using always block
+// Design Name : fsm_using_always
+// File Name : fsm_using_always.v
+//-----------------------------------------------------
+module fsm_using_always (
+clock , // clock
+reset , // Active high, syn reset
+req_0 , // Request 0
+req_1 , // Request 1
+gnt_0 , // Grant 0
+gnt_1
+);
+//-------------Input Ports-----------------------------
+input clock,reset,req_0,req_1;
+ //-------------Output Ports----------------------------
+output gnt_0,gnt_1;
+//-------------Input ports Data Type-------------------
+wire clock,reset,req_0,req_1;
+//-------------Output Ports Data Type------------------
+reg gnt_0,gnt_1;
+//-------------Internal Constants--------------------------
+parameter SIZE = 3 ;
+parameter IDLE = 3'b001,GNT0 = 3'b010,GNT1 = 3'b100 ;
+//-------------Internal Variables---------------------------
+reg [SIZE-1:0] state ;// Seq part of the FSM
+reg [SIZE-1:0] next_state ;// combo part of FSM
+//----------Code startes Here------------------------
+always @ (state or req_0 or req_1)
+begin : FSM_COMBO
+ next_state = 3'b000;
+ case(state)
+ IDLE : if (req_0 == 1'b1) begin
+ next_state = GNT0;
+ end else if (req_1 == 1'b1) begin
+ next_state= GNT1;
+ end else begin
+ next_state = IDLE;
+ end
+ GNT0 : if (req_0 == 1'b1) begin
+ next_state = GNT0;
+ end else begin
+ next_state = IDLE;
+ end
+ GNT1 : if (req_1 == 1'b1) begin
+ next_state = GNT1;
+ end else begin
+ next_state = IDLE;
+ end
+ default : next_state = IDLE;
+ endcase
+end
+//----------Seq Logic-----------------------------
+always @ (posedge clock)
+begin : FSM_SEQ
+ if (reset == 1'b1) begin
+ state <= #1 IDLE;
+ end else begin
+ state <= #1 next_state;
+ end
+end
+//----------Output Logic-----------------------------
+always @ (posedge clock)
+begin : OUTPUT_LOGIC
+if (reset == 1'b1) begin
+ gnt_0 <= #1 1'b0;
+ gnt_1 <= #1 1'b0;
+end
+else begin
+ case(state)
+ IDLE : begin
+ gnt_0 <= #1 1'b0;
+ gnt_1 <= #1 1'b0;
+ end
+ GNT0 : begin
+ gnt_0 <= #1 1'b1;
+ gnt_1 <= #1 1'b0;
+ end
+ GNT1 : begin
+ gnt_0 <= #1 1'b0;
+ gnt_1 <= #1 1'b1;
+ end
+ default : begin
+ gnt_0 <= #1 1'b0;
+ gnt_1 <= #1 1'b0;
+ end
+ endcase
+end
+end // End Of Block OUTPUT_LOGIC
+
+endmodule // End of Module arbiter
diff --git a/tests/asicworld/code_tidbits_fsm_using_function.v b/tests/asicworld/code_tidbits_fsm_using_function.v
new file mode 100644
index 000000000..404498a01
--- /dev/null
+++ b/tests/asicworld/code_tidbits_fsm_using_function.v
@@ -0,0 +1,94 @@
+//-----------------------------------------------------
+// This is FSM demo program using function
+// Design Name : fsm_using_function
+// File Name : fsm_using_function.v
+//-----------------------------------------------------
+module fsm_using_function (
+clock , // clock
+reset , // Active high, syn reset
+req_0 , // Request 0
+req_1 , // Request 1
+gnt_0 , // Grant 0
+gnt_1
+);
+//-------------Input Ports-----------------------------
+input clock,reset,req_0,req_1;
+ //-------------Output Ports----------------------------
+output gnt_0,gnt_1;
+//-------------Input ports Data Type-------------------
+wire clock,reset,req_0,req_1;
+//-------------Output Ports Data Type------------------
+reg gnt_0,gnt_1;
+//-------------Internal Constants--------------------------
+parameter SIZE = 3 ;
+parameter IDLE = 3'b001,GNT0 = 3'b010,GNT1 = 3'b100 ;
+//-------------Internal Variables---------------------------
+reg [SIZE-1:0] state ;// Seq part of the FSM
+wire [SIZE-1:0] next_state ;// combo part of FSM
+//----------Code startes Here------------------------
+assign next_state = fsm_function(state, req_0, req_1);
+//----------Function for Combo Logic-----------------
+function [SIZE-1:0] fsm_function;
+ input [SIZE-1:0] state ;
+ input req_0 ;
+ input req_1 ;
+ case(state)
+ IDLE : if (req_0 == 1'b1) begin
+ fsm_function = GNT0;
+ end else if (req_1 == 1'b1) begin
+ fsm_function= GNT1;
+ end else begin
+ fsm_function = IDLE;
+ end
+ GNT0 : if (req_0 == 1'b1) begin
+ fsm_function = GNT0;
+ end else begin
+ fsm_function = IDLE;
+ end
+ GNT1 : if (req_1 == 1'b1) begin
+ fsm_function = GNT1;
+ end else begin
+ fsm_function = IDLE;
+ end
+ default : fsm_function = IDLE;
+ endcase
+endfunction
+//----------Seq Logic-----------------------------
+always @ (posedge clock)
+begin : FSM_SEQ
+ if (reset == 1'b1) begin
+ state <= #1 IDLE;
+ end else begin
+ state <= #1 next_state;
+ end
+end
+//----------Output Logic-----------------------------
+always @ (posedge clock)
+begin : OUTPUT_LOGIC
+if (reset == 1'b1) begin
+ gnt_0 <= #1 1'b0;
+ gnt_1 <= #1 1'b0;
+end
+else begin
+ case(state)
+ IDLE : begin
+ gnt_0 <= #1 1'b0;
+ gnt_1 <= #1 1'b0;
+ end
+ GNT0 : begin
+ gnt_0 <= #1 1'b1;
+ gnt_1 <= #1 1'b0;
+ end
+ GNT1 : begin
+ gnt_0 <= #1 1'b0;
+ gnt_1 <= #1 1'b1;
+ end
+ default : begin
+ gnt_0 <= #1 1'b0;
+ gnt_1 <= #1 1'b0;
+ end
+ endcase
+end
+end // End Of Block OUTPUT_LOGIC
+
+endmodule // End of Module arbiter
diff --git a/tests/asicworld/code_tidbits_fsm_using_single_always.v b/tests/asicworld/code_tidbits_fsm_using_single_always.v
new file mode 100644
index 000000000..67cc08841
--- /dev/null
+++ b/tests/asicworld/code_tidbits_fsm_using_single_always.v
@@ -0,0 +1,63 @@
+//====================================================
+// This is FSM demo program using single always
+// for both seq and combo logic
+// Design Name : fsm_using_single_always
+// File Name : fsm_using_single_always.v
+//=====================================================
+module fsm_using_single_always (
+clock , // clock
+reset , // Active high, syn reset
+req_0 , // Request 0
+req_1 , // Request 1
+gnt_0 , // Grant 0
+gnt_1
+);
+//=============Input Ports=============================
+input clock,reset,req_0,req_1;
+ //=============Output Ports===========================
+output gnt_0,gnt_1;
+//=============Input ports Data Type===================
+wire clock,reset,req_0,req_1;
+//=============Output Ports Data Type==================
+reg gnt_0,gnt_1;
+//=============Internal Constants======================
+parameter SIZE = 3 ;
+parameter IDLE = 3'b001,GNT0 = 3'b010,GNT1 = 3'b100 ;
+//=============Internal Variables======================
+reg [SIZE-1:0] state ;// Seq part of the FSM
+reg [SIZE-1:0] next_state ;// combo part of FSM
+//==========Code startes Here==========================
+always @ (posedge clock)
+begin : FSM
+if (reset == 1'b1) begin
+ state <= #1 IDLE;
+ gnt_0 <= 0;
+ gnt_1 <= 0;
+end else
+ case(state)
+ IDLE : if (req_0 == 1'b1) begin
+ state <= #1 GNT0;
+ gnt_0 <= 1;
+ end else if (req_1 == 1'b1) begin
+ gnt_1 <= 1;
+ state <= #1 GNT1;
+ end else begin
+ state <= #1 IDLE;
+ end
+ GNT0 : if (req_0 == 1'b1) begin
+ state <= #1 GNT0;
+ end else begin
+ gnt_0 <= 0;
+ state <= #1 IDLE;
+ end
+ GNT1 : if (req_1 == 1'b1) begin
+ state <= #1 GNT1;
+ end else begin
+ gnt_1 <= 0;
+ state <= #1 IDLE;
+ end
+ default : state <= #1 IDLE;
+endcase
+end
+
+endmodule // End of Module arbiter
diff --git a/tests/asicworld/code_tidbits_nonblocking.v b/tests/asicworld/code_tidbits_nonblocking.v
new file mode 100644
index 000000000..4a0d365e0
--- /dev/null
+++ b/tests/asicworld/code_tidbits_nonblocking.v
@@ -0,0 +1,17 @@
+module nonblocking (clk,a,c);
+input clk;
+input a;
+output c;
+
+wire clk;
+wire a;
+reg c;
+reg b;
+
+always @ (posedge clk )
+begin
+ b <= a;
+ c <= b;
+end
+
+endmodule
diff --git a/tests/asicworld/code_tidbits_reg_combo_example.v b/tests/asicworld/code_tidbits_reg_combo_example.v
new file mode 100644
index 000000000..9689788c4
--- /dev/null
+++ b/tests/asicworld/code_tidbits_reg_combo_example.v
@@ -0,0 +1,13 @@
+module reg_combo_example( a, b, y);
+input a, b;
+output y;
+
+reg y;
+wire a, b;
+
+always @ ( a or b)
+begin
+ y = a & b;
+end
+
+endmodule
diff --git a/tests/asicworld/code_tidbits_reg_seq_example.v b/tests/asicworld/code_tidbits_reg_seq_example.v
new file mode 100644
index 000000000..458c87927
--- /dev/null
+++ b/tests/asicworld/code_tidbits_reg_seq_example.v
@@ -0,0 +1,15 @@
+module reg_seq_example( clk, reset, d, q);
+input clk, reset, d;
+output q;
+
+reg q;
+wire clk, reset, d;
+
+always @ (posedge clk or posedge reset)
+if (reset) begin
+ q <= 1'b0;
+end else begin
+ q <= d;
+end
+
+endmodule
diff --git a/tests/asicworld/code_tidbits_syn_reset.v b/tests/asicworld/code_tidbits_syn_reset.v
new file mode 100644
index 000000000..994771b16
--- /dev/null
+++ b/tests/asicworld/code_tidbits_syn_reset.v
@@ -0,0 +1,19 @@
+module syn_reset (clk,reset,a,c);
+ input clk;
+ input reset;
+ input a;
+ output c;
+
+ wire clk;
+ wire reset;
+ wire a;
+ reg c;
+
+always @ (posedge clk )
+ if ( reset == 1'b1) begin
+ c <= 0;
+ end else begin
+ c <= a;
+ end
+
+endmodule
diff --git a/tests/asicworld/code_tidbits_wire_example.v b/tests/asicworld/code_tidbits_wire_example.v
new file mode 100644
index 000000000..577a535d1
--- /dev/null
+++ b/tests/asicworld/code_tidbits_wire_example.v
@@ -0,0 +1,9 @@
+module wire_example( a, b, y);
+ input a, b;
+ output y;
+
+ wire a, b, y;
+
+ assign y = a & b;
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_addbit.v b/tests/asicworld/code_verilog_tutorial_addbit.v
new file mode 100644
index 000000000..22063b052
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_addbit.v
@@ -0,0 +1,24 @@
+module addbit (
+a , // first input
+b , // Second input
+ci , // Carry input
+sum , // sum output
+co // carry output
+);
+//Input declaration
+input a;
+input b;
+input ci;
+//Ouput declaration
+output sum;
+output co;
+//Port Data types
+wire a;
+wire b;
+wire ci;
+wire sum;
+wire co;
+//Code starts here
+assign {co,sum} = a + b + ci;
+
+endmodule // End of Module addbit
diff --git a/tests/asicworld/code_verilog_tutorial_always_example.v b/tests/asicworld/code_verilog_tutorial_always_example.v
new file mode 100644
index 000000000..8b0fc2067
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_always_example.v
@@ -0,0 +1,11 @@
+module always_example();
+reg clk,reset,enable,q_in,data;
+
+always @ (posedge clk)
+if (reset) begin
+ data <= 0;
+end else if (enable) begin
+ data <= q_in;
+end
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_bus_con.v b/tests/asicworld/code_verilog_tutorial_bus_con.v
new file mode 100644
index 000000000..b100c8136
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_bus_con.v
@@ -0,0 +1,8 @@
+module bus_con (a,b, y);
+ input [3:0] a, b;
+ output [7:0] y;
+ wire [7:0] y;
+
+ assign y = {a,b};
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_comment.v b/tests/asicworld/code_verilog_tutorial_comment.v
new file mode 100644
index 000000000..1cc0eb424
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_comment.v
@@ -0,0 +1,25 @@
+/* This is a
+ Multi line comment
+ example */
+module addbit (
+a,
+b,
+ci,
+sum,
+co);
+
+// Input Ports Single line comment
+input a;
+input b;
+input ci;
+// Output ports
+output sum;
+output co;
+// Data Types
+wire a;
+wire b;
+wire ci;
+wire sum;
+wire co;
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_counter.v b/tests/asicworld/code_verilog_tutorial_counter.v
new file mode 100644
index 000000000..534519745
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_counter.v
@@ -0,0 +1,19 @@
+//-----------------------------------------------------
+// Design Name : counter
+// File Name : counter.v
+// Function : 4 bit up counter
+// Coder : Deepak
+//-----------------------------------------------------
+module counter (clk, reset, enable, count);
+input clk, reset, enable;
+output [3:0] count;
+reg [3:0] count;
+
+always @ (posedge clk)
+if (reset == 1'b1) begin
+ count <= 0;
+end else if ( enable == 1'b1) begin
+ count <= count + 1;
+end
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_counter_tb.v b/tests/asicworld/code_verilog_tutorial_counter_tb.v
new file mode 100644
index 000000000..104779381
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_counter_tb.v
@@ -0,0 +1,113 @@
+///////////////////////////////////////////////////////////////////////////
+// MODULE : counter_tb //
+// TOP MODULE : -- //
+// //
+// PURPOSE : 4-bit up counter test bench //
+// //
+// DESIGNER : Deepak Kumar Tala //
+// //
+// Revision History //
+// //
+// DEVELOPMENT HISTORY : //
+// Rev0.0 : Jan 03, 2003 //
+// Initial Revision //
+// //
+///////////////////////////////////////////////////////////////////////////
+module testbench;
+
+reg clk, reset, enable;
+wire [3:0] count;
+reg dut_error;
+
+counter U0 (
+.clk (clk),
+.reset (reset),
+.enable (enable),
+.count (count)
+);
+
+event reset_enable;
+event terminate_sim;
+
+initial
+begin
+ $display ("###################################################");
+ clk = 0;
+ reset = 0;
+ enable = 0;
+ dut_error = 0;
+end
+
+always
+ #5 clk = !clk;
+
+initial
+begin
+ $dumpfile ("counter.vcd");
+ $dumpvars;
+end
+
+
+initial
+@ (terminate_sim) begin
+ $display ("Terminating simulation");
+ if (dut_error == 0) begin
+ $display ("Simulation Result : PASSED");
+ end
+ else begin
+ $display ("Simulation Result : FAILED");
+ end
+ $display ("###################################################");
+ #1 $finish;
+end
+
+
+
+event reset_done;
+
+initial
+forever begin
+ @ (reset_enable);
+ @ (negedge clk)
+ $display ("Applying reset");
+ reset = 1;
+ @ (negedge clk)
+ reset = 0;
+ $display ("Came out of Reset");
+ -> reset_done;
+end
+
+initial begin
+ #10 -> reset_enable;
+ @ (reset_done);
+ @ (negedge clk);
+ enable = 1;
+ repeat (5)
+ begin
+ @ (negedge clk);
+ end
+ enable = 0;
+ #5 -> terminate_sim;
+end
+
+
+reg [3:0] count_compare;
+
+always @ (posedge clk)
+if (reset == 1'b1)
+ count_compare <= 0;
+else if ( enable == 1'b1)
+ count_compare <= count_compare + 1;
+
+
+
+always @ (negedge clk)
+if (count_compare != count) begin
+ $display ("DUT ERROR AT TIME%d",$time);
+ $display ("Expected value %d, Got Value %d", count_compare, count);
+ dut_error = 1;
+ #5 -> terminate_sim;
+end
+
+endmodule
+
diff --git a/tests/asicworld/code_verilog_tutorial_d_ff.v b/tests/asicworld/code_verilog_tutorial_d_ff.v
new file mode 100644
index 000000000..7a4083605
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_d_ff.v
@@ -0,0 +1,14 @@
+// D flip-flop Code
+module d_ff ( d, clk, q, q_bar);
+input d ,clk;
+output q, q_bar;
+wire d ,clk;
+reg q, q_bar;
+
+always @ (posedge clk)
+begin
+ q <= d;
+ q_bar <= !d;
+end
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_decoder.v b/tests/asicworld/code_verilog_tutorial_decoder.v
new file mode 100644
index 000000000..5efdbd7e7
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_decoder.v
@@ -0,0 +1,14 @@
+module decoder (in,out);
+input [2:0] in;
+output [7:0] out;
+wire [7:0] out;
+assign out = (in == 3'b000 ) ? 8'b0000_0001 :
+(in == 3'b001 ) ? 8'b0000_0010 :
+(in == 3'b010 ) ? 8'b0000_0100 :
+(in == 3'b011 ) ? 8'b0000_1000 :
+(in == 3'b100 ) ? 8'b0001_0000 :
+(in == 3'b101 ) ? 8'b0010_0000 :
+(in == 3'b110 ) ? 8'b0100_0000 :
+(in == 3'b111 ) ? 8'b1000_0000 : 8'h00;
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_decoder_always.v b/tests/asicworld/code_verilog_tutorial_decoder_always.v
new file mode 100644
index 000000000..4418ec700
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_decoder_always.v
@@ -0,0 +1,20 @@
+module decoder_always (in,out);
+input [2:0] in;
+output [7:0] out;
+reg [7:0] out;
+
+always @ (in)
+begin
+ out = 0;
+ case (in)
+ 3'b001 : out = 8'b0000_0001;
+ 3'b010 : out = 8'b0000_0010;
+ 3'b011 : out = 8'b0000_0100;
+ 3'b100 : out = 8'b0000_1000;
+ 3'b101 : out = 8'b0001_0000;
+ 3'b110 : out = 8'b0100_0000;
+ 3'b111 : out = 8'b1000_0000;
+ endcase
+end
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_escape_id.v b/tests/asicworld/code_verilog_tutorial_escape_id.v
new file mode 100644
index 000000000..6c33da174
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_escape_id.v
@@ -0,0 +1,14 @@
+// There must be white space after the
+// string which uses escape character
+module \1dff (
+q, // Q output
+\q~ , // Q_out output
+d, // D input
+cl$k, // CLOCK input
+\reset* // Reset input
+);
+
+input d, cl$k, \reset* ;
+output q, \q~ ;
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_explicit.v b/tests/asicworld/code_verilog_tutorial_explicit.v
new file mode 100644
index 000000000..88427ff08
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_explicit.v
@@ -0,0 +1,35 @@
+module explicit();
+reg clk,d,rst,pre;
+wire q;
+
+// Here q_bar is not connected
+// We can connect ports in any order
+dff u0 (
+.q (q),
+.d (d),
+.clk (clk),
+.q_bar (),
+.rst (rst),
+.pre (pre)
+);
+
+endmodule
+
+// D fli-flop
+module dff (q, q_bar, clk, d, rst, pre);
+input clk, d, rst, pre;
+output q, q_bar;
+reg q;
+
+assign q_bar = ~q;
+
+always @ (posedge clk)
+if (rst == 1'b1) begin
+ q <= 0;
+end else if (pre == 1'b1) begin
+ q <= 1;
+end else begin
+ q <= d;
+end
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_first_counter.v b/tests/asicworld/code_verilog_tutorial_first_counter.v
new file mode 100644
index 000000000..d35d4aacc
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_first_counter.v
@@ -0,0 +1,47 @@
+//-----------------------------------------------------
+// This is my second Verilog Design
+// Design Name : first_counter
+// File Name : first_counter.v
+// Function : This is a 4 bit up-counter with
+// Synchronous active high reset and
+// with active high enable signal
+//-----------------------------------------------------
+module first_counter (
+clock , // Clock input of the design
+reset , // active high, synchronous Reset input
+enable , // Active high enable signal for counter
+counter_out // 4 bit vector output of the counter
+); // End of port list
+//-------------Input Ports-----------------------------
+input clock ;
+input reset ;
+input enable ;
+//-------------Output Ports----------------------------
+output [3:0] counter_out ;
+//-------------Input ports Data Type-------------------
+// By rule all the input ports should be wires
+wire clock ;
+wire reset ;
+wire enable ;
+//-------------Output Ports Data Type------------------
+// Output port can be a storage element (reg) or a wire
+reg [3:0] counter_out ;
+
+//------------Code Starts Here-------------------------
+// Since this counter is a positive edge trigged one,
+// We trigger the below block with respect to positive
+// edge of the clock.
+always @ (posedge clock)
+begin : COUNTER // Block Name
+ // At every rising edge of clock we check if reset is active
+ // If active, we load the counter output with 4'b0000
+ if (reset == 1'b1) begin
+ counter_out <= 4'b0000;
+ end
+ // If enable is active, then we increment the counter
+ else if (enable == 1'b1) begin
+ counter_out <= counter_out + 1;
+ end
+end // End of Block COUNTER
+
+endmodule // End of Module counter
diff --git a/tests/asicworld/code_verilog_tutorial_first_counter_tb.v b/tests/asicworld/code_verilog_tutorial_first_counter_tb.v
new file mode 100644
index 000000000..f065732be
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_first_counter_tb.v
@@ -0,0 +1,36 @@
+module testbench();
+// Declare inputs as regs and outputs as wires
+reg clock, reset, enable;
+wire [3:0] counter_out;
+
+// Initialize all variables
+initial begin
+ $display ("time\t clk reset enable counter");
+ $monitor ("%g\t %b %b %b %b",
+ $time, clock, reset, enable, counter_out);
+ clock = 1; // initial value of clock
+ reset = 0; // initial value of reset
+ enable = 0; // initial value of enable
+ #5 reset = 1; // Assert the reset
+ #10 reset = 0; // De-assert the reset
+ #10 enable = 1; // Assert enable
+ #100 enable = 0; // De-assert enable
+ #5 $finish; // Terminate simulation
+end
+
+// Clock generator
+initial begin
+ #1;
+ forever
+ #5 clock = ~clock; // Toggle clock every 5 ticks
+end
+
+// Connect DUT to test bench
+first_counter U_counter (
+clock,
+reset,
+enable,
+counter_out
+);
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_flip_flop.v b/tests/asicworld/code_verilog_tutorial_flip_flop.v
new file mode 100644
index 000000000..ed2e88c2e
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_flip_flop.v
@@ -0,0 +1,15 @@
+module flif_flop (clk,reset, q, d);
+input clk, reset, d;
+output q;
+reg q;
+
+always @ (posedge clk )
+begin
+ if (reset == 1) begin
+ q <= 0;
+ end else begin
+ q <= d;
+ end
+end
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_fsm_full.v b/tests/asicworld/code_verilog_tutorial_fsm_full.v
new file mode 100644
index 000000000..fd2d559bb
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_fsm_full.v
@@ -0,0 +1,114 @@
+module fsm_full(
+clock , // Clock
+reset , // Active high reset
+req_0 , // Active high request from agent 0
+req_1 , // Active high request from agent 1
+req_2 , // Active high request from agent 2
+req_3 , // Active high request from agent 3
+gnt_0 , // Active high grant to agent 0
+gnt_1 , // Active high grant to agent 1
+gnt_2 , // Active high grant to agent 2
+gnt_3 // Active high grant to agent 3
+);
+// Port declaration here
+input clock ; // Clock
+input reset ; // Active high reset
+input req_0 ; // Active high request from agent 0
+input req_1 ; // Active high request from agent 1
+input req_2 ; // Active high request from agent 2
+input req_3 ; // Active high request from agent 3
+output gnt_0 ; // Active high grant to agent 0
+output gnt_1 ; // Active high grant to agent 1
+output gnt_2 ; // Active high grant to agent 2
+output gnt_3 ; // Active high grant to agent
+
+// Internal Variables
+reg gnt_0 ; // Active high grant to agent 0
+reg gnt_1 ; // Active high grant to agent 1
+reg gnt_2 ; // Active high grant to agent 2
+reg gnt_3 ; // Active high grant to agent
+
+parameter [2:0] IDLE = 3'b000;
+parameter [2:0] GNT0 = 3'b001;
+parameter [2:0] GNT1 = 3'b010;
+parameter [2:0] GNT2 = 3'b011;
+parameter [2:0] GNT3 = 3'b100;
+
+reg [2:0] state, next_state;
+
+always @ (state or req_0 or req_1 or req_2 or req_3)
+begin
+ next_state = 0;
+ case(state)
+ IDLE : if (req_0 == 1'b1) begin
+ next_state = GNT0;
+ end else if (req_1 == 1'b1) begin
+ next_state= GNT1;
+ end else if (req_2 == 1'b1) begin
+ next_state= GNT2;
+ end else if (req_3 == 1'b1) begin
+ next_state= GNT3;
+ end else begin
+ next_state = IDLE;
+ end
+ GNT0 : if (req_0 == 1'b0) begin
+ next_state = IDLE;
+ end else begin
+ next_state = GNT0;
+ end
+ GNT1 : if (req_1 == 1'b0) begin
+ next_state = IDLE;
+ end else begin
+ next_state = GNT1;
+ end
+ GNT2 : if (req_2 == 1'b0) begin
+ next_state = IDLE;
+ end else begin
+ next_state = GNT2;
+ end
+ GNT3 : if (req_3 == 1'b0) begin
+ next_state = IDLE;
+ end else begin
+ next_state = GNT3;
+ end
+ default : next_state = IDLE;
+ endcase
+end
+
+always @ (posedge clock)
+begin : OUTPUT_LOGIC
+ if (reset) begin
+ gnt_0 <= 1'b0;
+ gnt_1 <= 1'b0;
+ gnt_2 <= 1'b0;
+ gnt_3 <= 1'b0;
+ state <= IDLE;
+ end else begin
+ state <= next_state;
+ case(state)
+ IDLE : begin
+ gnt_0 <= 1'b0;
+ gnt_1 <= 1'b0;
+ gnt_2 <= 1'b0;
+ gnt_3 <= 1'b0;
+ end
+ GNT0 : begin
+ gnt_0 <= 1'b1;
+ end
+ GNT1 : begin
+ gnt_1 <= 1'b1;
+ end
+ GNT2 : begin
+ gnt_2 <= 1'b1;
+ end
+ GNT3 : begin
+ gnt_3 <= 1'b1;
+ end
+ default : begin
+ state <= IDLE;
+ end
+ endcase
+ end
+end
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_fsm_full_tb.v b/tests/asicworld/code_verilog_tutorial_fsm_full_tb.v
new file mode 100644
index 000000000..0097b1c98
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_fsm_full_tb.v
@@ -0,0 +1,48 @@
+module testbench();
+reg clock , reset ;
+reg req_0 , req_1 , req_2 , req_3;
+wire gnt_0 , gnt_1 , gnt_2 , gnt_3 ;
+
+initial begin
+ $display("Time\t R0 R1 R2 R3 G0 G1 G2 G3");
+ $monitor("%g\t %b %b %b %b %b %b %b %b",
+ $time, req_0, req_1, req_2, req_3, gnt_0, gnt_1, gnt_2, gnt_3);
+ clock = 0;
+ reset = 0;
+ req_0 = 0;
+ req_1 = 0;
+ req_2 = 0;
+ req_3 = 0;
+ #10 reset = 1;
+ #10 reset = 0;
+ #10 req_0 = 1;
+ #20 req_0 = 0;
+ #10 req_1 = 1;
+ #20 req_1 = 0;
+ #10 req_2 = 1;
+ #20 req_2 = 0;
+ #10 req_3 = 1;
+ #20 req_3 = 0;
+ #10 $finish;
+end
+
+initial begin
+ #1;
+ forever
+ #2 clock = ~clock;
+end
+
+fsm_full U_fsm_full(
+clock , // Clock
+reset , // Active high reset
+req_0 , // Active high request from agent 0
+req_1 , // Active high request from agent 1
+req_2 , // Active high request from agent 2
+req_3 , // Active high request from agent 3
+gnt_0 , // Active high grant to agent 0
+gnt_1 , // Active high grant to agent 1
+gnt_2 , // Active high grant to agent 2
+gnt_3 // Active high grant to agent 3
+);
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_good_code.v b/tests/asicworld/code_verilog_tutorial_good_code.v
new file mode 100644
index 000000000..6ba776446
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_good_code.v
@@ -0,0 +1,18 @@
+ module addbit (
+ a,
+ b,
+ ci,
+ sum,
+ co);
+ input a;
+ input b;
+ input ci;
+ output sum;
+ output co;
+ wire a;
+ wire b;
+ wire ci;
+ wire sum;
+ wire co;
+
+ endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_if_else.v b/tests/asicworld/code_verilog_tutorial_if_else.v
new file mode 100644
index 000000000..19b91d3f2
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_if_else.v
@@ -0,0 +1,13 @@
+module if_else();
+
+reg dff;
+wire clk,din,reset;
+
+always @ (posedge clk)
+if (reset) begin
+ dff <= 0;
+end else begin
+ dff <= din;
+end
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_multiply.v b/tests/asicworld/code_verilog_tutorial_multiply.v
new file mode 100644
index 000000000..1912e1e26
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_multiply.v
@@ -0,0 +1,8 @@
+module muliply (a,product);
+ input [3:0] a;
+ output [4:0] product;
+ wire [4:0] product;
+
+ assign product = a << 1;
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_mux_21.v b/tests/asicworld/code_verilog_tutorial_mux_21.v
new file mode 100644
index 000000000..a6a0d35eb
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_mux_21.v
@@ -0,0 +1,9 @@
+module mux_21 (a,b,sel,y);
+ input a, b;
+ output y;
+ input sel;
+ wire y;
+
+ assign y = (sel) ? b : a;
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_n_out_primitive.v b/tests/asicworld/code_verilog_tutorial_n_out_primitive.v
new file mode 100644
index 000000000..814385a45
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_n_out_primitive.v
@@ -0,0 +1,13 @@
+module n_out_primitive();
+
+wire out,out_0,out_1,out_2,out_3,out_a,out_b,out_c;
+wire in;
+
+// one output Buffer gate
+buf u_buf0 (out,in);
+// four output Buffer gate
+buf u_buf1 (out_0, out_1, out_2, out_3, in);
+// three output Invertor gate
+not u_not0 (out_a, out_b, out_c, in);
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_parallel_if.v b/tests/asicworld/code_verilog_tutorial_parallel_if.v
new file mode 100644
index 000000000..1dbe737eb
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_parallel_if.v
@@ -0,0 +1,21 @@
+module parallel_if();
+
+reg [3:0] counter;
+wire clk,reset,enable, up_en, down_en;
+
+always @ (posedge clk)
+// If reset is asserted
+if (reset == 1'b0) begin
+ counter <= 4'b0000;
+end else begin
+ // If counter is enable and up count is mode
+ if (enable == 1'b1 && up_en == 1'b1) begin
+ counter <= counter + 1'b1;
+ end
+ // If counter is enable and down count is mode
+ if (enable == 1'b1 && down_en == 1'b1) begin
+ counter <= counter - 1'b1;
+ end
+end
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_parity.v b/tests/asicworld/code_verilog_tutorial_parity.v
new file mode 100644
index 000000000..764396c2f
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_parity.v
@@ -0,0 +1,41 @@
+//-----------------------------------------------------
+// This is simple parity Program
+// Design Name : parity
+// File Name : parity.v
+// Function : This program shows how a verilog
+// primitive/module port connection are done
+// Coder : Deepak
+//-----------------------------------------------------
+module parity (
+a , // First input
+b , // Second input
+c , // Third Input
+d , // Fourth Input
+y // Parity output
+);
+
+// Input Declaration
+input a ;
+input b ;
+input c ;
+input d ;
+// Ouput Declaration
+output y ;
+// port data types
+wire a ;
+wire b ;
+wire c ;
+wire d ;
+wire y ;
+// Internal variables
+wire out_0 ;
+wire out_1 ;
+
+// Code starts Here
+xor u0 (out_0,a,b);
+
+xor u1 (out_1,c,d);
+
+xor u2 (y,out_0,out_1);
+
+endmodule // End Of Module parity
diff --git a/tests/asicworld/code_verilog_tutorial_simple_function.v b/tests/asicworld/code_verilog_tutorial_simple_function.v
new file mode 100644
index 000000000..5818a1d4a
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_simple_function.v
@@ -0,0 +1,10 @@
+module simple_function();
+
+function myfunction;
+input a, b, c, d;
+begin
+ myfunction = ((a+b) + (c-d));
+end
+endfunction
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_simple_if.v b/tests/asicworld/code_verilog_tutorial_simple_if.v
new file mode 100644
index 000000000..a68cc4a87
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_simple_if.v
@@ -0,0 +1,11 @@
+module simple_if();
+
+reg latch;
+wire enable,din;
+
+always @ (enable or din)
+if (enable) begin
+ latch <= din;
+end
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_task_global.v b/tests/asicworld/code_verilog_tutorial_task_global.v
new file mode 100644
index 000000000..3ae862797
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_task_global.v
@@ -0,0 +1,12 @@
+module task_global();
+
+reg [7:0] temp_out;
+reg [7:0] temp_in;
+
+task convert;
+begin
+ temp_out = (9/5) *( temp_in + 32);
+end
+endtask
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_tri_buf.v b/tests/asicworld/code_verilog_tutorial_tri_buf.v
new file mode 100644
index 000000000..a55b29caa
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_tri_buf.v
@@ -0,0 +1,9 @@
+module tri_buf (a,b,enable);
+ input a;
+ output b;
+ input enable;
+ wire b;
+
+assign b = (enable) ? a : 1'bz;
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_v2k_reg.v b/tests/asicworld/code_verilog_tutorial_v2k_reg.v
new file mode 100644
index 000000000..537a9e854
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_v2k_reg.v
@@ -0,0 +1,24 @@
+module v2k_reg();
+
+// v2k allows to init variables
+reg a = 0;
+// Here only last variable is set to 0, i.e d = 0
+// Rest b, c are set to x
+reg b, c, d = 0;
+// reg data type can be signed in v2k
+// We can assign with signed constants
+reg signed [7:0] data = 8'shF0;
+
+// Function can return signed values
+// Its ports can contain signed ports
+function signed [7:0] adder;
+ input a_in;
+ input b_in;
+ input c_in;
+ input signed [7:0] data_in;
+ begin
+ adder = a_in + b_in + c_in + data_in;
+ end
+endfunction
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_which_clock.v b/tests/asicworld/code_verilog_tutorial_which_clock.v
new file mode 100644
index 000000000..418a2cfac
--- /dev/null
+++ b/tests/asicworld/code_verilog_tutorial_which_clock.v
@@ -0,0 +1,12 @@
+module which_clock (x,y,q,d);
+input x,y,d;
+output q;
+reg q;
+
+always @ (posedge x or posedge y)
+ if (x)
+ q <= 1'b0;
+ else
+ q <= d;
+
+endmodule
diff --git a/tests/asicworld/run-test.sh b/tests/asicworld/run-test.sh
new file mode 100755
index 000000000..bf27d15f8
--- /dev/null
+++ b/tests/asicworld/run-test.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+make -C ../.. || exit 1
+exec bash ../tools/autotest.sh *.v
diff --git a/tests/hana/README b/tests/hana/README
new file mode 100644
index 000000000..37049405d
--- /dev/null
+++ b/tests/hana/README
@@ -0,0 +1,14 @@
+
+This test cases are copied from the hana project:
+https://sourceforge.net/projects/sim-sim/
+
+** Copy tests from hana: **
+while read fn; do cp -v $fn ALL_TESTS/${fn//\//_}; done < <(find test -name '*.v' ! -name '*_gold.v')
+
+** Eliminate test's we can't parse atm: **
+rm -f test_synthesizability*.v
+rm -f test_parse2synthtrans_latch_1_test.v
+rm -f test_parse2synthtrans_always_1_test.v
+rm -f test_parse2synthtrans_always_2_test.v
+for x in test_*.v; do ../../yosys -b "" $x || rm $x; done
+
diff --git a/tests/hana/hana_vlib.v b/tests/hana/hana_vlib.v
new file mode 100644
index 000000000..fc82f1389
--- /dev/null
+++ b/tests/hana/hana_vlib.v
@@ -0,0 +1,1139 @@
+/*
+Copyright (C) 2009-2010 Parvez Ahmad
+Written by Parvez Ahmad <parvez_ahmad@yahoo.co.uk>.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+
+module BUF (input in, output out);
+
+assign out = in;
+
+endmodule
+
+module TRIBUF(input in, enable, output out);
+
+assign out = enable ? in : 1'bz;
+
+endmodule
+
+module INV(input in, output out);
+
+assign out = ~in;
+
+endmodule
+
+module AND2 #(parameter SIZE = 2) (input [SIZE-1:0] in, output out);
+
+assign out = &in;
+
+endmodule
+
+module AND3 #(parameter SIZE = 3) (input [SIZE-1:0] in, output out);
+
+assign out = &in;
+
+endmodule
+
+module AND4 #(parameter SIZE = 4) (input [SIZE-1:0] in, output out);
+
+assign out = &in;
+
+endmodule
+
+module OR2 #(parameter SIZE = 2) (input [SIZE-1:0] in, output out);
+
+assign out = |in;
+
+endmodule
+
+module OR3 #(parameter SIZE = 3) (input [SIZE-1:0] in, output out);
+
+assign out = |in;
+
+endmodule
+
+module OR4 #(parameter SIZE = 4) (input [SIZE-1:0] in, output out);
+
+assign out = |in;
+
+endmodule
+
+
+module NAND2 #(parameter SIZE = 2) (input [SIZE-1:0] in, output out);
+
+assign out = ~&in;
+
+endmodule
+
+module NAND3 #(parameter SIZE = 3) (input [SIZE-1:0] in, output out);
+
+assign out = ~&in;
+
+endmodule
+
+module NAND4 #(parameter SIZE = 4) (input [SIZE-1:0] in, output out);
+
+assign out = ~&in;
+
+endmodule
+
+module NOR2 #(parameter SIZE = 2) (input [SIZE-1:0] in, output out);
+
+assign out = ~|in;
+
+endmodule
+
+module NOR3 #(parameter SIZE = 3) (input [SIZE-1:0] in, output out);
+
+assign out = ~|in;
+
+endmodule
+
+module NOR4 #(parameter SIZE = 4) (input [SIZE-1:0] in, output out);
+
+assign out = ~|in;
+
+endmodule
+
+
+module XOR2 #(parameter SIZE = 2) (input [SIZE-1:0] in, output out);
+
+assign out = ^in;
+
+endmodule
+
+module XOR3 #(parameter SIZE = 3) (input [SIZE-1:0] in, output out);
+
+assign out = ^in;
+
+endmodule
+
+module XOR4 #(parameter SIZE = 4) (input [SIZE-1:0] in, output out);
+
+assign out = ^in;
+
+endmodule
+
+
+module XNOR2 #(parameter SIZE = 2) (input [SIZE-1:0] in, output out);
+
+assign out = ~^in;
+
+endmodule
+
+module XNOR3 #(parameter SIZE = 3) (input [SIZE-1:0] in, output out);
+
+assign out = ~^in;
+
+endmodule
+
+module XNOR4 #(parameter SIZE = 4) (input [SIZE-1:0] in, output out);
+
+assign out = ~^in;
+
+endmodule
+
+module DEC1 (input in, enable, output reg [1:0] out);
+
+always @(in or enable)
+ if(!enable)
+ out = 2'b00;
+ else begin
+ case (in)
+ 1'b0 : out = 2'b01;
+ 1'b1 : out = 2'b10;
+ endcase
+ end
+endmodule
+
+module DEC2 (input [1:0] in, input enable, output reg [3:0] out);
+
+always @(in or enable)
+ if(!enable)
+ out = 4'b0000;
+ else begin
+ case (in)
+ 2'b00 : out = 4'b0001;
+ 2'b01 : out = 4'b0010;
+ 2'b10 : out = 4'b0100;
+ 2'b11 : out = 4'b1000;
+ endcase
+ end
+endmodule
+
+module DEC3 (input [2:0] in, input enable, output reg [7:0] out);
+
+always @(in or enable)
+ if(!enable)
+ out = 8'b00000000;
+ else begin
+ case (in)
+ 3'b000 : out = 8'b00000001;
+ 3'b001 : out = 8'b00000010;
+ 3'b010 : out = 8'b00000100;
+ 3'b011 : out = 8'b00001000;
+ 3'b100 : out = 8'b00010000;
+ 3'b101 : out = 8'b00100000;
+ 3'b110 : out = 8'b01000000;
+ 3'b111 : out = 8'b10000000;
+ endcase
+ end
+endmodule
+
+module DEC4 (input [3:0] in, input enable, output reg [15:0] out);
+
+always @(in or enable)
+ if(!enable)
+ out = 16'b0000000000000000;
+ else begin
+ case (in)
+ 4'b0000 : out = 16'b0000000000000001;
+ 4'b0001 : out = 16'b0000000000000010;
+ 4'b0010 : out = 16'b0000000000000100;
+ 4'b0011 : out = 16'b0000000000001000;
+ 4'b0100 : out = 16'b0000000000010000;
+ 4'b0101 : out = 16'b0000000000100000;
+ 4'b0110 : out = 16'b0000000001000000;
+ 4'b0111 : out = 16'b0000000010000000;
+ 4'b1000 : out = 16'b0000000100000000;
+ 4'b1001 : out = 16'b0000001000000000;
+ 4'b1010 : out = 16'b0000010000000000;
+ 4'b1011 : out = 16'b0000100000000000;
+ 4'b1100 : out = 16'b0001000000000000;
+ 4'b1101 : out = 16'b0010000000000000;
+ 4'b1110 : out = 16'b0100000000000000;
+ 4'b1111 : out = 16'b1000000000000000;
+ endcase
+ end
+endmodule
+module DEC5 (input [4:0] in, input enable, output reg [31:0] out);
+
+always @(in or enable)
+ if(!enable)
+ out = 32'b00000000000000000000000000000000;
+ else begin
+ case (in)
+ 5'b00000 : out = 32'b00000000000000000000000000000001;
+ 5'b00001 : out = 32'b00000000000000000000000000000010;
+ 5'b00010 : out = 32'b00000000000000000000000000000100;
+ 5'b00011 : out = 32'b00000000000000000000000000001000;
+ 5'b00100 : out = 32'b00000000000000000000000000010000;
+ 5'b00101 : out = 32'b00000000000000000000000000100000;
+ 5'b00110 : out = 32'b00000000000000000000000001000000;
+ 5'b00111 : out = 32'b00000000000000000000000010000000;
+ 5'b01000 : out = 32'b00000000000000000000000100000000;
+ 5'b01001 : out = 32'b00000000000000000000001000000000;
+ 5'b01010 : out = 32'b00000000000000000000010000000000;
+ 5'b01011 : out = 32'b00000000000000000000100000000000;
+ 5'b01100 : out = 32'b00000000000000000001000000000000;
+ 5'b01101 : out = 32'b00000000000000000010000000000000;
+ 5'b01110 : out = 32'b00000000000000000100000000000000;
+ 5'b01111 : out = 32'b00000000000000001000000000000000;
+ 5'b10000 : out = 32'b00000000000000010000000000000000;
+ 5'b10001 : out = 32'b00000000000000100000000000000000;
+ 5'b10010 : out = 32'b00000000000001000000000000000000;
+ 5'b10011 : out = 32'b00000000000010000000000000000000;
+ 5'b10100 : out = 32'b00000000000100000000000000000000;
+ 5'b10101 : out = 32'b00000000001000000000000000000000;
+ 5'b10110 : out = 32'b00000000010000000000000000000000;
+ 5'b10111 : out = 32'b00000000100000000000000000000000;
+ 5'b11000 : out = 32'b00000001000000000000000000000000;
+ 5'b11001 : out = 32'b00000010000000000000000000000000;
+ 5'b11010 : out = 32'b00000100000000000000000000000000;
+ 5'b11011 : out = 32'b00001000000000000000000000000000;
+ 5'b11100 : out = 32'b00010000000000000000000000000000;
+ 5'b11101 : out = 32'b00100000000000000000000000000000;
+ 5'b11110 : out = 32'b01000000000000000000000000000000;
+ 5'b11111 : out = 32'b10000000000000000000000000000000;
+ endcase
+ end
+endmodule
+
+module DEC6 (input [5:0] in, input enable, output reg [63:0] out);
+
+always @(in or enable)
+ if(!enable)
+ out = 64'b0000000000000000000000000000000000000000000000000000000000000000;
+ else begin
+ case (in)
+ 6'b000000 : out = 64'b0000000000000000000000000000000000000000000000000000000000000001;
+ 6'b000001 : out = 64'b0000000000000000000000000000000000000000000000000000000000000010;
+ 6'b000010 : out = 64'b0000000000000000000000000000000000000000000000000000000000000100;
+ 6'b000011 : out = 64'b0000000000000000000000000000000000000000000000000000000000001000;
+ 6'b000100 : out = 64'b0000000000000000000000000000000000000000000000000000000000010000;
+ 6'b000101 : out = 64'b0000000000000000000000000000000000000000000000000000000000100000;
+ 6'b000110 : out = 64'b0000000000000000000000000000000000000000000000000000000001000000;
+ 6'b000111 : out = 64'b0000000000000000000000000000000000000000000000000000000010000000;
+ 6'b001000 : out = 64'b0000000000000000000000000000000000000000000000000000000100000000;
+ 6'b001001 : out = 64'b0000000000000000000000000000000000000000000000000000001000000000;
+ 6'b001010 : out = 64'b0000000000000000000000000000000000000000000000000000010000000000;
+ 6'b001011 : out = 64'b0000000000000000000000000000000000000000000000000000100000000000;
+ 6'b001100 : out = 64'b0000000000000000000000000000000000000000000000000001000000000000;
+ 6'b001101 : out = 64'b0000000000000000000000000000000000000000000000000010000000000000;
+ 6'b001110 : out = 64'b0000000000000000000000000000000000000000000000000100000000000000;
+ 6'b001111 : out = 64'b0000000000000000000000000000000000000000000000001000000000000000;
+ 6'b010000 : out = 64'b0000000000000000000000000000000000000000000000010000000000000000;
+ 6'b010001 : out = 64'b0000000000000000000000000000000000000000000000100000000000000000;
+ 6'b010010 : out = 64'b0000000000000000000000000000000000000000000001000000000000000000;
+ 6'b010011 : out = 64'b0000000000000000000000000000000000000000000010000000000000000000;
+ 6'b010100 : out = 64'b0000000000000000000000000000000000000000000100000000000000000000;
+ 6'b010101 : out = 64'b0000000000000000000000000000000000000000001000000000000000000000;
+ 6'b010110 : out = 64'b0000000000000000000000000000000000000000010000000000000000000000;
+ 6'b010111 : out = 64'b0000000000000000000000000000000000000000100000000000000000000000;
+ 6'b011000 : out = 64'b0000000000000000000000000000000000000001000000000000000000000000;
+ 6'b011001 : out = 64'b0000000000000000000000000000000000000010000000000000000000000000;
+ 6'b011010 : out = 64'b0000000000000000000000000000000000000100000000000000000000000000;
+ 6'b011011 : out = 64'b0000000000000000000000000000000000001000000000000000000000000000;
+ 6'b011100 : out = 64'b0000000000000000000000000000000000010000000000000000000000000000;
+ 6'b011101 : out = 64'b0000000000000000000000000000000000100000000000000000000000000000;
+ 6'b011110 : out = 64'b0000000000000000000000000000000001000000000000000000000000000000;
+ 6'b011111 : out = 64'b0000000000000000000000000000000010000000000000000000000000000000;
+
+ 6'b100000 : out = 64'b0000000000000000000000000000000100000000000000000000000000000000;
+ 6'b100001 : out = 64'b0000000000000000000000000000001000000000000000000000000000000000;
+ 6'b100010 : out = 64'b0000000000000000000000000000010000000000000000000000000000000000;
+ 6'b100011 : out = 64'b0000000000000000000000000000100000000000000000000000000000000000;
+ 6'b100100 : out = 64'b0000000000000000000000000001000000000000000000000000000000000000;
+ 6'b100101 : out = 64'b0000000000000000000000000010000000000000000000000000000000000000;
+ 6'b100110 : out = 64'b0000000000000000000000000100000000000000000000000000000000000000;
+ 6'b100111 : out = 64'b0000000000000000000000001000000000000000000000000000000000000000;
+ 6'b101000 : out = 64'b0000000000000000000000010000000000000000000000000000000000000000;
+ 6'b101001 : out = 64'b0000000000000000000000100000000000000000000000000000000000000000;
+ 6'b101010 : out = 64'b0000000000000000000001000000000000000000000000000000000000000000;
+ 6'b101011 : out = 64'b0000000000000000000010000000000000000000000000000000000000000000;
+ 6'b101100 : out = 64'b0000000000000000000100000000000000000000000000000000000000000000;
+ 6'b101101 : out = 64'b0000000000000000001000000000000000000000000000000000000000000000;
+ 6'b101110 : out = 64'b0000000000000000010000000000000000000000000000000000000000000000;
+ 6'b101111 : out = 64'b0000000000000000100000000000000000000000000000000000000000000000;
+ 6'b110000 : out = 64'b0000000000000001000000000000000000000000000000000000000000000000;
+ 6'b110001 : out = 64'b0000000000000010000000000000000000000000000000000000000000000000;
+ 6'b110010 : out = 64'b0000000000000100000000000000000000000000000000000000000000000000;
+ 6'b110011 : out = 64'b0000000000001000000000000000000000000000000000000000000000000000;
+ 6'b110100 : out = 64'b0000000000010000000000000000000000000000000000000000000000000000;
+ 6'b110101 : out = 64'b0000000000100000000000000000000000000000000000000000000000000000;
+ 6'b110110 : out = 64'b0000000001000000000000000000000000000000000000000000000000000000;
+ 6'b110111 : out = 64'b0000000010000000000000000000000000000000000000000000000000000000;
+ 6'b111000 : out = 64'b0000000100000000000000000000000000000000000000000000000000000000;
+ 6'b111001 : out = 64'b0000001000000000000000000000000000000000000000000000000000000000;
+ 6'b111010 : out = 64'b0000010000000000000000000000000000000000000000000000000000000000;
+ 6'b111011 : out = 64'b0000100000000000000000000000000000000000000000000000000000000000;
+ 6'b111100 : out = 64'b0001000000000000000000000000000000000000000000000000000000000000;
+ 6'b111101 : out = 64'b0010000000000000000000000000000000000000000000000000000000000000;
+ 6'b111110 : out = 64'b0100000000000000000000000000000000000000000000000000000000000000;
+ 6'b111111 : out = 64'b1000000000000000000000000000000000000000000000000000000000000000;
+ endcase
+ end
+endmodule
+
+
+module MUX2(input [1:0] in, input select, output reg out);
+
+always @( in or select)
+ case (select)
+ 0: out = in[0];
+ 1: out = in[1];
+ endcase
+endmodule
+
+
+module MUX4(input [3:0] in, input [1:0] select, output reg out);
+
+always @( in or select)
+ case (select)
+ 0: out = in[0];
+ 1: out = in[1];
+ 2: out = in[2];
+ 3: out = in[3];
+ endcase
+endmodule
+
+
+module MUX8(input [7:0] in, input [2:0] select, output reg out);
+
+always @( in or select)
+ case (select)
+ 0: out = in[0];
+ 1: out = in[1];
+ 2: out = in[2];
+ 3: out = in[3];
+ 4: out = in[4];
+ 5: out = in[5];
+ 6: out = in[6];
+ 7: out = in[7];
+ endcase
+endmodule
+
+module MUX16(input [15:0] in, input [3:0] select, output reg out);
+
+always @( in or select)
+ case (select)
+ 0: out = in[0];
+ 1: out = in[1];
+ 2: out = in[2];
+ 3: out = in[3];
+ 4: out = in[4];
+ 5: out = in[5];
+ 6: out = in[6];
+ 7: out = in[7];
+ 8: out = in[8];
+ 9: out = in[9];
+ 10: out = in[10];
+ 11: out = in[11];
+ 12: out = in[12];
+ 13: out = in[13];
+ 14: out = in[14];
+ 15: out = in[15];
+ endcase
+endmodule
+
+module MUX32(input [31:0] in, input [4:0] select, output reg out);
+
+always @( in or select)
+ case (select)
+ 0: out = in[0];
+ 1: out = in[1];
+ 2: out = in[2];
+ 3: out = in[3];
+ 4: out = in[4];
+ 5: out = in[5];
+ 6: out = in[6];
+ 7: out = in[7];
+ 8: out = in[8];
+ 9: out = in[9];
+ 10: out = in[10];
+ 11: out = in[11];
+ 12: out = in[12];
+ 13: out = in[13];
+ 14: out = in[14];
+ 15: out = in[15];
+ 16: out = in[16];
+ 17: out = in[17];
+ 18: out = in[18];
+ 19: out = in[19];
+ 20: out = in[20];
+ 21: out = in[21];
+ 22: out = in[22];
+ 23: out = in[23];
+ 24: out = in[24];
+ 25: out = in[25];
+ 26: out = in[26];
+ 27: out = in[27];
+ 28: out = in[28];
+ 29: out = in[29];
+ 30: out = in[30];
+ 31: out = in[31];
+ endcase
+endmodule
+
+module MUX64(input [63:0] in, input [5:0] select, output reg out);
+
+always @( in or select)
+ case (select)
+ 0: out = in[0];
+ 1: out = in[1];
+ 2: out = in[2];
+ 3: out = in[3];
+ 4: out = in[4];
+ 5: out = in[5];
+ 6: out = in[6];
+ 7: out = in[7];
+ 8: out = in[8];
+ 9: out = in[9];
+ 10: out = in[10];
+ 11: out = in[11];
+ 12: out = in[12];
+ 13: out = in[13];
+ 14: out = in[14];
+ 15: out = in[15];
+ 16: out = in[16];
+ 17: out = in[17];
+ 18: out = in[18];
+ 19: out = in[19];
+ 20: out = in[20];
+ 21: out = in[21];
+ 22: out = in[22];
+ 23: out = in[23];
+ 24: out = in[24];
+ 25: out = in[25];
+ 26: out = in[26];
+ 27: out = in[27];
+ 28: out = in[28];
+ 29: out = in[29];
+ 30: out = in[30];
+ 31: out = in[31];
+ 32: out = in[32];
+ 33: out = in[33];
+ 34: out = in[34];
+ 35: out = in[35];
+ 36: out = in[36];
+ 37: out = in[37];
+ 38: out = in[38];
+ 39: out = in[39];
+ 40: out = in[40];
+ 41: out = in[41];
+ 42: out = in[42];
+ 43: out = in[43];
+ 44: out = in[44];
+ 45: out = in[45];
+ 46: out = in[46];
+ 47: out = in[47];
+ 48: out = in[48];
+ 49: out = in[49];
+ 50: out = in[50];
+ 51: out = in[51];
+ 52: out = in[52];
+ 53: out = in[53];
+ 54: out = in[54];
+ 55: out = in[55];
+ 56: out = in[56];
+ 57: out = in[57];
+ 58: out = in[58];
+ 59: out = in[59];
+ 60: out = in[60];
+ 61: out = in[61];
+ 62: out = in[62];
+ 63: out = in[63];
+ endcase
+endmodule
+
+module ADD1(input in1, in2, cin, output out, cout);
+
+assign {cout, out} = in1 + in2 + cin;
+
+endmodule
+
+module ADD2 #(parameter SIZE = 2)(input [SIZE-1:0] in1, in2,
+ input cin, output [SIZE-1:0] out, output cout);
+
+assign {cout, out} = in1 + in2 + cin;
+
+endmodule
+
+module ADD4 #(parameter SIZE = 4)(input [SIZE-1:0] in1, in2,
+ input cin, output [SIZE-1:0] out, output cout);
+
+assign {cout, out} = in1 + in2 + cin;
+
+endmodule
+
+module ADD8 #(parameter SIZE = 8)(input [SIZE-1:0] in1, in2,
+ input cin, output [SIZE-1:0] out, output cout);
+
+assign {cout, out} = in1 + in2 + cin;
+
+endmodule
+
+module ADD16 #(parameter SIZE = 16)(input [SIZE-1:0] in1, in2,
+ input cin, output [SIZE-1:0] out, output cout);
+
+assign {cout, out} = in1 + in2 + cin;
+
+endmodule
+
+module ADD32 #(parameter SIZE = 32)(input [SIZE-1:0] in1, in2,
+ input cin, output [SIZE-1:0] out, output cout);
+
+assign {cout, out} = in1 + in2 + cin;
+
+endmodule
+module ADD64 #(parameter SIZE = 64)(input [SIZE-1:0] in1, in2,
+ input cin, output [SIZE-1:0] out, output cout);
+
+assign {cout, out} = in1 + in2 + cin;
+
+endmodule
+
+module SUB1(input in1, in2, cin, output out, cout);
+
+assign {cout, out} = in1 - in2 - cin;
+
+endmodule
+
+module SUB2 #(parameter SIZE = 2)(input [SIZE-1:0] in1, in2,
+ input cin, output [SIZE-1:0] out, output cout);
+
+assign {cout, out} = in1 - in2 - cin;
+
+endmodule
+
+module SUB4 #(parameter SIZE = 4)(input [SIZE-1:0] in1, in2,
+ input cin, output [SIZE-1:0] out, output cout);
+
+assign {cout, out} = in1 - in2 - cin;
+
+endmodule
+
+module SUB8 #(parameter SIZE = 8)(input [SIZE-1:0] in1, in2,
+ input cin, output [SIZE-1:0] out, output cout);
+
+assign {cout, out} = in1 - in2 - cin;
+
+endmodule
+
+module SUB16 #(parameter SIZE = 16)(input [SIZE-1:0] in1, in2,
+ input cin, output [SIZE-1:0] out, output cout);
+
+assign {cout, out} = in1 - in2 - cin;
+
+endmodule
+
+module SUB32 #(parameter SIZE = 32)(input [SIZE-1:0] in1, in2,
+ input cin, output [SIZE-1:0] out, output cout);
+
+assign {cout, out} = in1 - in2 - cin;
+
+endmodule
+module SUB64 #(parameter SIZE = 64)(input [SIZE-1:0] in1, in2,
+ input cin, output [SIZE-1:0] out, output cout);
+
+assign {cout, out} = in1 - in2 - cin;
+
+endmodule
+
+module MUL1 #(parameter SIZE = 1)(input in1, in2, output [2*SIZE-1:0] out);
+
+assign out = in1*in2;
+
+endmodule
+
+module MUL2 #(parameter SIZE = 2)(input [SIZE-1:0] in1, in2, output [2*SIZE-1:0] out);
+
+assign out = in1*in2;
+
+endmodule
+
+module MUL4 #(parameter SIZE = 4)(input [SIZE-1:0] in1, in2, output [2*SIZE-1:0] out);
+
+assign out = in1*in2;
+
+endmodule
+
+module MUL8 #(parameter SIZE = 8)(input [SIZE-1:0] in1, in2, output [2*SIZE-1:0] out);
+
+assign out = in1*in2;
+
+endmodule
+
+module MUL16 #(parameter SIZE = 16)(input [SIZE-1:0] in1, in2, output [2*SIZE-1:0] out);
+
+assign out = in1*in2;
+
+endmodule
+
+module MUL32 #(parameter SIZE = 32)(input [SIZE-1:0] in1, in2, output [2*SIZE-1:0] out);
+
+assign out = in1*in2;
+
+endmodule
+
+module MUL64 #(parameter SIZE = 64)(input [SIZE-1:0] in1, in2, output [2*SIZE-1:0] out);
+
+assign out = in1*in2;
+
+endmodule
+
+module DIV1 #(parameter SIZE = 1)(input in1, in2, output out, rem);
+
+assign out = in1/in2;
+assign rem = in1%in2;
+
+endmodule
+
+module DIV2 #(parameter SIZE = 2)(input [SIZE-1:0] in1, in2,
+ output [SIZE-1:0] out, rem);
+
+assign out = in1/in2;
+assign rem = in1%in2;
+
+endmodule
+
+module DIV4 #(parameter SIZE = 4)(input [SIZE-1:0] in1, in2,
+ output [SIZE-1:0] out, rem);
+
+assign out = in1/in2;
+assign rem = in1%in2;
+
+endmodule
+
+module DIV8 #(parameter SIZE = 8)(input [SIZE-1:0] in1, in2,
+ output [SIZE-1:0] out, rem);
+
+assign out = in1/in2;
+assign rem = in1%in2;
+
+endmodule
+
+module DIV16 #(parameter SIZE = 16)(input [SIZE-1:0] in1, in2,
+ output [SIZE-1:0] out, rem);
+
+assign out = in1/in2;
+assign rem = in1%in2;
+
+endmodule
+
+module DIV32 #(parameter SIZE = 32)(input [SIZE-1:0] in1, in2,
+ output [SIZE-1:0] out, rem);
+
+assign out = in1/in2;
+assign rem = in1%in2;
+
+endmodule
+
+module DIV64 #(parameter SIZE = 64)(input [SIZE-1:0] in1, in2,
+ output [SIZE-1:0] out, rem);
+
+assign out = in1/in2;
+assign rem = in1%in2;
+
+endmodule
+
+module FF (input d, clk, output reg q);
+always @( posedge clk)
+ q <= d;
+endmodule
+
+
+module RFF(input d, clk, reset, output reg q);
+always @(posedge clk or posedge reset)
+ if(reset)
+ q <= 0;
+ else
+ q <= d;
+endmodule
+
+module SFF(input d, clk, set, output reg q);
+always @(posedge clk or posedge set)
+ if(set)
+ q <= 1;
+ else
+ q <= d;
+endmodule
+
+module RSFF(input d, clk, set, reset, output reg q);
+always @(posedge clk or posedge reset or posedge set)
+ if(reset)
+ q <= 0;
+ else if(set)
+ q <= 1;
+ else
+ q <= d;
+endmodule
+
+module SRFF(input d, clk, set, reset, output reg q);
+always @(posedge clk or posedge set or posedge reset)
+ if(set)
+ q <= 1;
+ else if(reset)
+ q <= 0;
+ else
+ q <= d;
+endmodule
+
+module LATCH(input d, enable, output reg q);
+always @( d or enable)
+ if(enable)
+ q <= d;
+endmodule
+
+module RLATCH(input d, reset, enable, output reg q);
+always @( d or enable or reset)
+ if(enable)
+ if(reset)
+ q <= 0;
+ else
+ q <= d;
+endmodule
+
+module LSHIFT1 #(parameter SIZE = 1)(input in, shift, val, output reg out);
+
+always @ (in, shift, val) begin
+ if(shift)
+ out = val;
+ else
+ out = in;
+end
+
+endmodule
+
+
+module LSHIFT2 #(parameter SIZE = 2)(input [SIZE-1:0] in,
+ input [SIZE-1:0] shift, input val,
+ output reg [SIZE-1:0] out);
+
+always @(in or shift or val) begin
+ out = in << shift;
+ if(val)
+ out = out | ({SIZE-1 {1'b1} } >> (SIZE-1-shift));
+end
+endmodule
+
+module LSHIFT4 #(parameter SIZE = 4)(input [SIZE-1:0] in,
+ input [2:0] shift, input val, output reg [SIZE-1:0] out);
+
+always @(in or shift or val) begin
+ out = in << shift;
+ if(val)
+ out = out | ({SIZE-1 {1'b1} } >> (SIZE-1-shift));
+end
+endmodule
+
+
+module LSHIFT8 #(parameter SIZE = 8)(input [SIZE-1:0] in,
+ input [3:0] shift, input val, output reg [SIZE-1:0] out);
+
+always @(in or shift or val) begin
+ out = in << shift;
+ if(val)
+ out = out | ({SIZE-1 {1'b1} } >> (SIZE-1-shift));
+end
+endmodule
+
+module LSHIFT16 #(parameter SIZE = 16)(input [SIZE-1:0] in,
+ input [4:0] shift, input val, output reg [SIZE-1:0] out);
+
+always @(in or shift or val) begin
+ out = in << shift;
+ if(val)
+ out = out | ({SIZE-1 {1'b1} } >> (SIZE-1-shift));
+end
+endmodule
+
+module LSHIFT32 #(parameter SIZE = 32)(input [SIZE-1:0] in,
+ input [5:0] shift, input val, output reg [SIZE-1:0] out);
+
+always @(in or shift or val) begin
+ out = in << shift;
+ if(val)
+ out = out | ({SIZE-1 {1'b1} } >> (SIZE-1-shift));
+end
+endmodule
+
+module LSHIFT64 #(parameter SIZE = 64)(input [SIZE-1:0] in,
+ input [6:0] shift, input val, output reg [SIZE-1:0] out);
+
+always @(in or shift or val) begin
+ out = in << shift;
+ if(val)
+ out = out | ({SIZE-1 {1'b1} } >> (SIZE-1-shift));
+end
+endmodule
+
+module RSHIFT1 #(parameter SIZE = 1)(input in, shift, val, output reg out);
+
+always @ (in, shift, val) begin
+ if(shift)
+ out = val;
+ else
+ out = in;
+end
+
+endmodule
+
+module RSHIFT2 #(parameter SIZE = 2)(input [SIZE-1:0] in,
+ input [SIZE-1:0] shift, input val,
+ output reg [SIZE-1:0] out);
+
+always @(in or shift or val) begin
+ out = in >> shift;
+ if(val)
+ out = out | ({SIZE-1 {1'b1} } << (SIZE-1-shift));
+end
+
+endmodule
+
+
+module RSHIFT4 #(parameter SIZE = 4)(input [SIZE-1:0] in,
+ input [2:0] shift, input val,
+ output reg [SIZE-1:0] out);
+
+always @(in or shift or val) begin
+ out = in >> shift;
+ if(val)
+ out = out | ({SIZE-1 {1'b1} } << (SIZE-1-shift));
+end
+endmodule
+
+module RSHIFT8 #(parameter SIZE = 8)(input [SIZE-1:0] in,
+ input [3:0] shift, input val,
+ output reg [SIZE-1:0] out);
+
+always @(in or shift or val) begin
+ out = in >> shift;
+ if(val)
+ out = out | ({SIZE-1 {1'b1} } << (SIZE-1-shift));
+end
+
+endmodule
+
+module RSHIFT16 #(parameter SIZE = 16)(input [SIZE-1:0] in,
+ input [4:0] shift, input val,
+ output reg [SIZE-1:0] out);
+
+always @(in or shift or val) begin
+ out = in >> shift;
+ if(val)
+ out = out | ({SIZE-1 {1'b1} } << (SIZE-1-shift));
+end
+endmodule
+
+
+module RSHIFT32 #(parameter SIZE = 32)(input [SIZE-1:0] in,
+ input [5:0] shift, input val,
+ output reg [SIZE-1:0] out);
+
+always @(in or shift or val) begin
+ out = in >> shift;
+ if(val)
+ out = out | ({SIZE-1 {1'b1} } << (SIZE-1-shift));
+end
+endmodule
+
+module RSHIFT64 #(parameter SIZE = 64)(input [SIZE-1:0] in,
+ input [6:0] shift, input val,
+ output reg [SIZE-1:0] out);
+
+always @(in or shift or val) begin
+ out = in >> shift;
+ if(val)
+ out = out | ({SIZE-1 {1'b1} } << (SIZE-1-shift));
+end
+endmodule
+
+module CMP1 #(parameter SIZE = 1) (input in1, in2,
+ output reg equal, unequal, greater, lesser);
+
+always @ (in1 or in2) begin
+ if(in1 == in2) begin
+ equal = 1;
+ unequal = 0;
+ greater = 0;
+ lesser = 0;
+ end
+ else begin
+ equal = 0;
+ unequal = 1;
+
+ if(in1 < in2) begin
+ greater = 0;
+ lesser = 1;
+ end
+ else begin
+ greater = 1;
+ lesser = 0;
+ end
+ end
+end
+endmodule
+
+
+module CMP2 #(parameter SIZE = 2) (input [SIZE-1:0] in1, in2,
+ output reg equal, unequal, greater, lesser);
+
+always @ (in1 or in2) begin
+ if(in1 == in2) begin
+ equal = 1;
+ unequal = 0;
+ greater = 0;
+ lesser = 0;
+ end
+ else begin
+ equal = 0;
+ unequal = 1;
+
+ if(in1 < in2) begin
+ greater = 0;
+ lesser = 1;
+ end
+ else begin
+ greater = 1;
+ lesser = 0;
+ end
+ end
+end
+endmodule
+
+module CMP4 #(parameter SIZE = 4) (input [SIZE-1:0] in1, in2,
+ output reg equal, unequal, greater, lesser);
+
+always @ (in1 or in2) begin
+ if(in1 == in2) begin
+ equal = 1;
+ unequal = 0;
+ greater = 0;
+ lesser = 0;
+ end
+ else begin
+ equal = 0;
+ unequal = 1;
+
+ if(in1 < in2) begin
+ greater = 0;
+ lesser = 1;
+ end
+ else begin
+ greater = 1;
+ lesser = 0;
+ end
+ end
+end
+endmodule
+
+module CMP8 #(parameter SIZE = 8) (input [SIZE-1:0] in1, in2,
+ output reg equal, unequal, greater, lesser);
+
+always @ (in1 or in2) begin
+ if(in1 == in2) begin
+ equal = 1;
+ unequal = 0;
+ greater = 0;
+ lesser = 0;
+ end
+ else begin
+ equal = 0;
+ unequal = 1;
+
+ if(in1 < in2) begin
+ greater = 0;
+ lesser = 1;
+ end
+ else begin
+ greater = 1;
+ lesser = 0;
+ end
+ end
+end
+endmodule
+
+module CMP16 #(parameter SIZE = 16) (input [SIZE-1:0] in1, in2,
+ output reg equal, unequal, greater, lesser);
+
+always @ (in1 or in2) begin
+ if(in1 == in2) begin
+ equal = 1;
+ unequal = 0;
+ greater = 0;
+ lesser = 0;
+ end
+ else begin
+ equal = 0;
+ unequal = 1;
+
+ if(in1 < in2) begin
+ greater = 0;
+ lesser = 1;
+ end
+ else begin
+ greater = 1;
+ lesser = 0;
+ end
+ end
+end
+endmodule
+
+module CMP32 #(parameter SIZE = 32) (input [SIZE-1:0] in1, in2,
+ output reg equal, unequal, greater, lesser);
+
+always @ (in1 or in2) begin
+ if(in1 == in2) begin
+ equal = 1;
+ unequal = 0;
+ greater = 0;
+ lesser = 0;
+ end
+ else begin
+ equal = 0;
+ unequal = 1;
+
+ if(in1 < in2) begin
+ greater = 0;
+ lesser = 1;
+ end
+ else begin
+ greater = 1;
+ lesser = 0;
+ end
+ end
+end
+endmodule
+
+module CMP64 #(parameter SIZE = 64) (input [SIZE-1:0] in1, in2,
+ output reg equal, unequal, greater, lesser);
+
+always @ (in1 or in2) begin
+ if(in1 == in2) begin
+ equal = 1;
+ unequal = 0;
+ greater = 0;
+ lesser = 0;
+ end
+ else begin
+ equal = 0;
+ unequal = 1;
+
+ if(in1 < in2) begin
+ greater = 0;
+ lesser = 1;
+ end
+ else begin
+ greater = 1;
+ lesser = 0;
+ end
+ end
+end
+endmodule
+
+module VCC (output supply1 out);
+endmodule
+
+module GND (output supply0 out);
+endmodule
+
+
+module INC1 #(parameter SIZE = 1) (input in, output [SIZE:0] out);
+
+assign out = in + 1;
+
+endmodule
+
+module INC2 #(parameter SIZE = 2) (input [SIZE-1:0] in, output [SIZE:0] out);
+
+assign out = in + 1;
+
+endmodule
+
+module INC4 #(parameter SIZE = 4) (input [SIZE-1:0] in, output [SIZE:0] out);
+assign out = in + 1;
+
+endmodule
+
+module INC8 #(parameter SIZE = 8) (input [SIZE-1:0] in, output [SIZE:0] out);
+assign out = in + 1;
+
+endmodule
+
+module INC16 #(parameter SIZE = 16) (input [SIZE-1:0] in, output [SIZE:0] out);
+assign out = in + 1;
+
+endmodule
+
+module INC32 #(parameter SIZE = 32) (input [SIZE-1:0] in, output [SIZE:0] out);
+assign out = in + 1;
+
+endmodule
+module INC64 #(parameter SIZE = 64) (input [SIZE-1:0] in, output [SIZE:0] out);
+assign out = in + 1;
+
+endmodule
+
diff --git a/tests/hana/run-test.sh b/tests/hana/run-test.sh
new file mode 100755
index 000000000..b8e7231c7
--- /dev/null
+++ b/tests/hana/run-test.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+make -C ../.. || exit 1
+exec bash ../tools/autotest.sh -l hana_vlib.v test_*.v
diff --git a/tests/hana/test_intermout_always_comb_1_test.v b/tests/hana/test_intermout_always_comb_1_test.v
new file mode 100644
index 000000000..2d5abc4a6
--- /dev/null
+++ b/tests/hana/test_intermout_always_comb_1_test.v
@@ -0,0 +1,13 @@
+module test(a, b, c, d, z);
+input a, b, c, d;
+output z;
+reg z, temp1, temp2;
+
+always @(a or b or c or d)
+begin
+ temp1 = a ^ b;
+ temp2 = c ^ d;
+ z = temp1 ^ temp2;
+end
+
+endmodule
diff --git a/tests/hana/test_intermout_always_comb_3_test.v b/tests/hana/test_intermout_always_comb_3_test.v
new file mode 100644
index 000000000..234407efd
--- /dev/null
+++ b/tests/hana/test_intermout_always_comb_3_test.v
@@ -0,0 +1,10 @@
+module test (in1, in2, out);
+input in1, in2;
+output reg out;
+
+always @ ( in1 or in2)
+ if(in1 > in2)
+ out = in1;
+ else
+ out = in2;
+endmodule
diff --git a/tests/hana/test_intermout_always_comb_4_test.v b/tests/hana/test_intermout_always_comb_4_test.v
new file mode 100644
index 000000000..b0a94f299
--- /dev/null
+++ b/tests/hana/test_intermout_always_comb_4_test.v
@@ -0,0 +1,9 @@
+module test(a, b, c);
+input b, c;
+output reg a;
+
+always @(b or c) begin
+a = b;
+a = c;
+end
+endmodule
diff --git a/tests/hana/test_intermout_always_comb_5_test.v b/tests/hana/test_intermout_always_comb_5_test.v
new file mode 100644
index 000000000..5152781df
--- /dev/null
+++ b/tests/hana/test_intermout_always_comb_5_test.v
@@ -0,0 +1,11 @@
+module test(ctrl, in1, in2, out);
+input ctrl;
+input in1, in2;
+output reg out;
+
+always @ (ctrl or in1 or in2)
+ if(ctrl)
+ out = in1 & in2;
+ else
+ out = in1 | in2;
+endmodule
diff --git a/tests/hana/test_intermout_always_ff_3_test.v b/tests/hana/test_intermout_always_ff_3_test.v
new file mode 100644
index 000000000..ed8630c37
--- /dev/null
+++ b/tests/hana/test_intermout_always_ff_3_test.v
@@ -0,0 +1,15 @@
+module NonBlockingEx(clk, merge, er, xmit, fddi, claim);
+input clk, merge, er, xmit, fddi;
+output reg claim;
+reg fcr;
+
+always @(posedge clk)
+begin
+ fcr = er | xmit;
+
+ if(merge)
+ claim = fcr & fddi;
+ else
+ claim = fddi;
+end
+endmodule
diff --git a/tests/hana/test_intermout_always_ff_4_test.v b/tests/hana/test_intermout_always_ff_4_test.v
new file mode 100644
index 000000000..cac420a47
--- /dev/null
+++ b/tests/hana/test_intermout_always_ff_4_test.v
@@ -0,0 +1,11 @@
+module FlipFlop(clk, cs, ns);
+input clk;
+input [31:0] cs;
+output [31:0] ns;
+integer is;
+
+always @(posedge clk)
+ is <= cs;
+
+assign ns = is;
+endmodule
diff --git a/tests/hana/test_intermout_always_ff_5_test.v b/tests/hana/test_intermout_always_ff_5_test.v
new file mode 100644
index 000000000..669b2a5f9
--- /dev/null
+++ b/tests/hana/test_intermout_always_ff_5_test.v
@@ -0,0 +1,13 @@
+module FlipFlop(clock, cs, ns);
+input clock;
+input [3:0] cs;
+output reg [3:0] ns;
+reg [3:0] temp;
+
+always @(posedge clock)
+begin
+ temp = cs;
+ ns = temp;
+end
+
+endmodule
diff --git a/tests/hana/test_intermout_always_ff_6_test.v b/tests/hana/test_intermout_always_ff_6_test.v
new file mode 100644
index 000000000..ad0a0df6e
--- /dev/null
+++ b/tests/hana/test_intermout_always_ff_6_test.v
@@ -0,0 +1,7 @@
+module inc(clock, counter);
+
+input clock;
+output reg [3:0] counter;
+always @(posedge clock)
+ counter <= counter + 1;
+endmodule
diff --git a/tests/hana/test_intermout_always_ff_8_test.v b/tests/hana/test_intermout_always_ff_8_test.v
new file mode 100644
index 000000000..0f29ea0a4
--- /dev/null
+++ b/tests/hana/test_intermout_always_ff_8_test.v
@@ -0,0 +1,11 @@
+module NegEdgeClock(q, d, clk, reset);
+input d, clk, reset;
+output reg q;
+
+always @(negedge clk or negedge reset)
+ if(!reset)
+ q <= 1'b0;
+ else
+ q <= d;
+
+endmodule
diff --git a/tests/hana/test_intermout_always_ff_9_test.v b/tests/hana/test_intermout_always_ff_9_test.v
new file mode 100644
index 000000000..f1f13bbe7
--- /dev/null
+++ b/tests/hana/test_intermout_always_ff_9_test.v
@@ -0,0 +1,14 @@
+module MyCounter (clock, preset, updown, presetdata, counter);
+input clock, preset, updown;
+input [1: 0] presetdata;
+output reg [1:0] counter;
+
+always @(posedge clock)
+ if(preset)
+ counter <= presetdata;
+ else
+ if(updown)
+ counter <= counter + 1;
+ else
+ counter <= counter - 1;
+endmodule
diff --git a/tests/hana/test_intermout_always_latch_1_test.v b/tests/hana/test_intermout_always_latch_1_test.v
new file mode 100644
index 000000000..a83be20d1
--- /dev/null
+++ b/tests/hana/test_intermout_always_latch_1_test.v
@@ -0,0 +1,9 @@
+module test(en, in, out);
+input en;
+input [1:0] in;
+output reg [2:0] out;
+
+always @ (en or in)
+ if(en)
+ out = in + 1;
+endmodule
diff --git a/tests/hana/test_intermout_bufrm_1_test.v b/tests/hana/test_intermout_bufrm_1_test.v
new file mode 100644
index 000000000..8e3d4222e
--- /dev/null
+++ b/tests/hana/test_intermout_bufrm_1_test.v
@@ -0,0 +1,4 @@
+module test(input in, output out);
+//no buffer removal
+assign out = in;
+endmodule
diff --git a/tests/hana/test_intermout_bufrm_2_test.v b/tests/hana/test_intermout_bufrm_2_test.v
new file mode 100644
index 000000000..853f1dc9a
--- /dev/null
+++ b/tests/hana/test_intermout_bufrm_2_test.v
@@ -0,0 +1,7 @@
+module test(input in, output out);
+//intermediate buffers should be removed
+wire w1, w2;
+assign w1 = in;
+assign w2 = w1;
+assign out = w2;
+endmodule
diff --git a/tests/hana/test_intermout_bufrm_6_test.v b/tests/hana/test_intermout_bufrm_6_test.v
new file mode 100644
index 000000000..d4f3878d5
--- /dev/null
+++ b/tests/hana/test_intermout_bufrm_6_test.v
@@ -0,0 +1,22 @@
+module test(in, out);
+input in;
+output out;
+
+wire w1, w2, w3, w4;
+assign w1 = in;
+assign w2 = w1;
+assign w4 = w3;
+assign out = w4;
+mybuf _mybuf(w2, w3);
+endmodule
+
+module mybuf(in, out);
+input in;
+output out;
+wire w1, w2, w3, w4;
+
+assign w1 = in;
+assign w2 = w1;
+assign out = w2;
+endmodule
+
diff --git a/tests/hana/test_intermout_bufrm_7_test.v b/tests/hana/test_intermout_bufrm_7_test.v
new file mode 100644
index 000000000..7b651302a
--- /dev/null
+++ b/tests/hana/test_intermout_bufrm_7_test.v
@@ -0,0 +1,33 @@
+module test(in1, in2, out);
+input in1, in2;
+output out;
+// Y with cluster of mybuf instances at the junction
+
+wire w1, w2, w3, w4, w5, w6, w7, w8, w9, w10;
+assign w1 = in1;
+assign w2 = w1;
+assign w5 = in2;
+assign w6 = w5;
+assign w10 = w9;
+assign out = w10;
+
+mybuf _mybuf0(w2, w3);
+mybuf _mybuf1(w3, w4);
+
+mybuf _mybuf2(w6, w7);
+mybuf _mybuf3(w7, w4);
+
+mybuf _mybuf4(w4, w8);
+mybuf _mybuf5(w8, w9);
+endmodule
+
+module mybuf(in, out);
+input in;
+output out;
+wire w1, w2, w3, w4;
+
+assign w1 = in;
+assign w2 = w1;
+assign out = w2;
+endmodule
+
diff --git a/tests/hana/test_intermout_exprs_add_test.v b/tests/hana/test_intermout_exprs_add_test.v
new file mode 100644
index 000000000..ec70f347b
--- /dev/null
+++ b/tests/hana/test_intermout_exprs_add_test.v
@@ -0,0 +1,10 @@
+module test(out, in1, in2, vin1, vin2, vout1);
+output out;
+input in1, in2;
+input [1:0] vin1;
+input [2:0] vin2;
+output [3:0] vout1;
+
+assign out = in1 + in2;
+assign vout1 = vin1 + vin2;
+endmodule
diff --git a/tests/hana/test_intermout_exprs_binlogic_test.v b/tests/hana/test_intermout_exprs_binlogic_test.v
new file mode 100644
index 000000000..eec8c4b1a
--- /dev/null
+++ b/tests/hana/test_intermout_exprs_binlogic_test.v
@@ -0,0 +1,13 @@
+module test(in1, in2, vin1, vin2, out, vout, vin3, vin4, vout1 );
+input in1, in2;
+input [1:0] vin1;
+input [3:0] vin2;
+input [1:0] vin3;
+input [3:0] vin4;
+output vout, vout1;
+output out;
+
+assign out = in1 && in2;
+assign vout = vin1 && vin2;
+assign vout1 = vin3 || vin4;
+endmodule
diff --git a/tests/hana/test_intermout_exprs_bitwiseneg_test.v b/tests/hana/test_intermout_exprs_bitwiseneg_test.v
new file mode 100644
index 000000000..5b62bef09
--- /dev/null
+++ b/tests/hana/test_intermout_exprs_bitwiseneg_test.v
@@ -0,0 +1,5 @@
+module test(output out, input in, output [1:0] vout, input [1:0] vin);
+
+assign out = ~in;
+assign vout = ~vin;
+endmodule
diff --git a/tests/hana/test_intermout_exprs_buffer_test.v b/tests/hana/test_intermout_exprs_buffer_test.v
new file mode 100644
index 000000000..2b4cbc3ed
--- /dev/null
+++ b/tests/hana/test_intermout_exprs_buffer_test.v
@@ -0,0 +1,9 @@
+module buffer(in, out, vin, vout);
+input in;
+output out;
+input [1:0] vin;
+output [1:0] vout;
+
+assign out = in;
+assign vout = vin;
+endmodule
diff --git a/tests/hana/test_intermout_exprs_condexpr_mux_test.v b/tests/hana/test_intermout_exprs_condexpr_mux_test.v
new file mode 100644
index 000000000..11006e8b3
--- /dev/null
+++ b/tests/hana/test_intermout_exprs_condexpr_mux_test.v
@@ -0,0 +1,11 @@
+module test(in1, in2, out, vin1, vin2, vin3, vin4, vout1, vout2, en1, ven1, ven2);
+input in1, in2, en1, ven1;
+input [1:0] ven2;
+output out;
+input [1:0] vin1, vin2, vin3, vin4;
+output [1:0] vout1, vout2;
+
+assign out = en1 ? in1 : in2;
+assign vout1 = ven1 ? vin1 : vin2;
+assign vout2 = ven2 ? vin3 : vin4;
+endmodule
diff --git a/tests/hana/test_intermout_exprs_condexpr_tribuf_test.v b/tests/hana/test_intermout_exprs_condexpr_tribuf_test.v
new file mode 100644
index 000000000..5b778fe98
--- /dev/null
+++ b/tests/hana/test_intermout_exprs_condexpr_tribuf_test.v
@@ -0,0 +1,9 @@
+module test(in, out, en, vin1, vout1, en1);
+input in, en, en1;
+output out;
+input [1:0] vin1;
+output [1:0] vout1;
+
+assign out = en ? in : 1'bz;
+assign vout1 = en1 ? vin1 : 2'bzz;
+endmodule
diff --git a/tests/hana/test_intermout_exprs_const_test.v b/tests/hana/test_intermout_exprs_const_test.v
new file mode 100644
index 000000000..484d81032
--- /dev/null
+++ b/tests/hana/test_intermout_exprs_const_test.v
@@ -0,0 +1,7 @@
+module test (out, vout);
+output out;
+output [7:0] vout;
+
+assign out = 1'b1;
+assign vout = 9;
+endmodule
diff --git a/tests/hana/test_intermout_exprs_constshift_test.v b/tests/hana/test_intermout_exprs_constshift_test.v
new file mode 100644
index 000000000..eb21315d7
--- /dev/null
+++ b/tests/hana/test_intermout_exprs_constshift_test.v
@@ -0,0 +1,12 @@
+module test(in, out, vin, vout, vin1, vout1, vin2, vout2);
+
+input in;
+input [3:0] vin, vin1, vin2;
+output [3:0] vout, vout1, vout2;
+output out;
+
+assign out = in << 1;
+assign vout = vin << 2;
+assign vout1 = vin1 >> 2;
+assign vout2 = vin2 >>> 2;
+endmodule
diff --git a/tests/hana/test_intermout_exprs_div_test.v b/tests/hana/test_intermout_exprs_div_test.v
new file mode 100644
index 000000000..21765fcdf
--- /dev/null
+++ b/tests/hana/test_intermout_exprs_div_test.v
@@ -0,0 +1,10 @@
+module test(out, in1, in2, vin1, vin2, vout1);
+output out;
+input in1, in2;
+input [1:0] vin1;
+input [2:0] vin2;
+output [3:0] vout1;
+
+assign out = in1 / in2;
+assign vout1 = vin1 / vin2;
+endmodule
diff --git a/tests/hana/test_intermout_exprs_logicneg_test.v b/tests/hana/test_intermout_exprs_logicneg_test.v
new file mode 100644
index 000000000..b45b32b9c
--- /dev/null
+++ b/tests/hana/test_intermout_exprs_logicneg_test.v
@@ -0,0 +1,7 @@
+module test(out, vout, in, vin);
+output out, vout;
+input in;
+input [3:0] vin;
+assign out = !in;
+assign vout = !vin;
+endmodule
diff --git a/tests/hana/test_intermout_exprs_mod_test.v b/tests/hana/test_intermout_exprs_mod_test.v
new file mode 100644
index 000000000..cea6b02d7
--- /dev/null
+++ b/tests/hana/test_intermout_exprs_mod_test.v
@@ -0,0 +1,10 @@
+module test(out, in1, in2, vin1, vin2, vout1);
+output out;
+input in1, in2;
+input [1:0] vin1;
+input [2:0] vin2;
+output [3:0] vout1;
+
+assign out = in1 % in2;
+assign vout1 = vin1 % vin2;
+endmodule
diff --git a/tests/hana/test_intermout_exprs_mul_test.v b/tests/hana/test_intermout_exprs_mul_test.v
new file mode 100644
index 000000000..f9973dadc
--- /dev/null
+++ b/tests/hana/test_intermout_exprs_mul_test.v
@@ -0,0 +1,10 @@
+module test(out, in1, in2, vin1, vin2, vout1);
+output out;
+input in1, in2;
+input [1:0] vin1;
+input [2:0] vin2;
+output [3:0] vout1;
+
+assign out = in1 * in2;
+assign vout1 = vin1 * vin2;
+endmodule
diff --git a/tests/hana/test_intermout_exprs_redand_test.v b/tests/hana/test_intermout_exprs_redand_test.v
new file mode 100644
index 000000000..35fdf73ac
--- /dev/null
+++ b/tests/hana/test_intermout_exprs_redand_test.v
@@ -0,0 +1,5 @@
+module test(output out, input [1:0] vin, output out1, input [3:0] vin1);
+
+assign out = &vin;
+assign out1 = &vin1;
+endmodule
diff --git a/tests/hana/test_intermout_exprs_redop_test.v b/tests/hana/test_intermout_exprs_redop_test.v
new file mode 100644
index 000000000..93fdb2e57
--- /dev/null
+++ b/tests/hana/test_intermout_exprs_redop_test.v
@@ -0,0 +1,16 @@
+module Reduction (A1, A2, A3, A4, A5, A6, Y1, Y2, Y3, Y4, Y5, Y6);
+input [1:0] A1;
+input [1:0] A2;
+input [1:0] A3;
+input [1:0] A4;
+input [1:0] A5;
+input [1:0] A6;
+output Y1, Y2, Y3, Y4, Y5, Y6;
+//reg Y1, Y2, Y3, Y4, Y5, Y6;
+assign Y1=&A1; //reduction AND
+assign Y2=|A2; //reduction OR
+assign Y3=~&A3; //reduction NAND
+assign Y4=~|A4; //reduction NOR
+assign Y5=^A5; //reduction XOR
+assign Y6=~^A6; //reduction XNOR
+endmodule
diff --git a/tests/hana/test_intermout_exprs_sub_test.v b/tests/hana/test_intermout_exprs_sub_test.v
new file mode 100644
index 000000000..06e3a8149
--- /dev/null
+++ b/tests/hana/test_intermout_exprs_sub_test.v
@@ -0,0 +1,10 @@
+module test(out, in1, in2, vin1, vin2, vout1);
+output out;
+input in1, in2;
+input [1:0] vin1;
+input [2:0] vin2;
+output [3:0] vout1;
+
+assign out = in1 - in2;
+assign vout1 = vin1 - vin2;
+endmodule
diff --git a/tests/hana/test_intermout_exprs_unaryminus_test.v b/tests/hana/test_intermout_exprs_unaryminus_test.v
new file mode 100644
index 000000000..ee3f229a8
--- /dev/null
+++ b/tests/hana/test_intermout_exprs_unaryminus_test.v
@@ -0,0 +1,5 @@
+module test(output out, input in, output [31:0] vout, input [31:0] vin);
+
+assign out = -in;
+assign vout = -vin;
+endmodule
diff --git a/tests/hana/test_intermout_exprs_unaryplus_test.v b/tests/hana/test_intermout_exprs_unaryplus_test.v
new file mode 100644
index 000000000..07be5b240
--- /dev/null
+++ b/tests/hana/test_intermout_exprs_unaryplus_test.v
@@ -0,0 +1,4 @@
+module test(output out, input in);
+
+assign out = +in;
+endmodule
diff --git a/tests/hana/test_intermout_exprs_varshift_test.v b/tests/hana/test_intermout_exprs_varshift_test.v
new file mode 100644
index 000000000..2ca35c091
--- /dev/null
+++ b/tests/hana/test_intermout_exprs_varshift_test.v
@@ -0,0 +1,10 @@
+module test(vin0, vout0);
+input [2:0] vin0;
+output reg [7:0] vout0;
+
+wire [7:0] myreg0, myreg1, myreg2;
+integer i;
+assign myreg0 = vout0 << vin0;
+
+assign myreg1 = myreg2 >> i;
+endmodule
diff --git a/tests/hana/test_parse2synthtrans_behavopt_1_test.v b/tests/hana/test_parse2synthtrans_behavopt_1_test.v
new file mode 100644
index 000000000..c825739c6
--- /dev/null
+++ b/tests/hana/test_parse2synthtrans_behavopt_1_test.v
@@ -0,0 +1,22 @@
+module test(in, out, clk, reset);
+input in, reset;
+output reg out;
+input clk;
+reg signed [3:0] a;
+reg signed [3:0] b;
+reg signed [3:0] c;
+reg [5:0] d;
+reg [5:0] e;
+
+always @(clk or reset) begin
+ a = -4;
+ b = 2;
+ c = a + b;
+ d = a + b + c;
+ d = d*d;
+ if(b)
+ e = d*d;
+ else
+ e = d + d;
+end
+endmodule
diff --git a/tests/hana/test_parse2synthtrans_case_1_test.v b/tests/hana/test_parse2synthtrans_case_1_test.v
new file mode 100644
index 000000000..348c566ad
--- /dev/null
+++ b/tests/hana/test_parse2synthtrans_case_1_test.v
@@ -0,0 +1,26 @@
+module demultiplexer1_to_4 (out0, out1, out2, out3, in, s1, s0);
+output out0, out1, out2, out3;
+reg out0, out1, out2, out3;
+input in;
+input s1, s0;
+reg [3:0] encoding;
+reg [1:0] state;
+ always @(encoding) begin
+ case (encoding)
+ 4'bxx11: state = 1;
+ 4'bx0xx: state = 3;
+ 4'b11xx: state = 4;
+ 4'bx1xx: state = 2;
+ 4'bxx1x: state = 1;
+ 4'bxxx1: state = 0;
+ default: state = 0;
+ endcase
+ end
+
+ always @(encoding) begin
+ case (encoding)
+ 4'b0000: state = 1;
+ default: state = 0;
+ endcase
+ end
+endmodule
diff --git a/tests/hana/test_parse2synthtrans_contassign_1_test.v b/tests/hana/test_parse2synthtrans_contassign_1_test.v
new file mode 100644
index 000000000..78bf00775
--- /dev/null
+++ b/tests/hana/test_parse2synthtrans_contassign_1_test.v
@@ -0,0 +1,7 @@
+module test(in, out);
+
+input wire in;
+output out;
+assign out = (in+in);
+assign out = 74;
+endmodule
diff --git a/tests/hana/test_parse2synthtrans_module_basic0_test.v b/tests/hana/test_parse2synthtrans_module_basic0_test.v
new file mode 100644
index 000000000..67a272df0
--- /dev/null
+++ b/tests/hana/test_parse2synthtrans_module_basic0_test.v
@@ -0,0 +1,2 @@
+module test;
+endmodule
diff --git a/tests/hana/test_parse2synthtrans_operators_1_test.v b/tests/hana/test_parse2synthtrans_operators_1_test.v
new file mode 100644
index 000000000..93b5691f3
--- /dev/null
+++ b/tests/hana/test_parse2synthtrans_operators_1_test.v
@@ -0,0 +1,11 @@
+module test(in, out);
+input in;
+output out;
+parameter p1 = 10;
+parameter p2 = 5;
+
+assign out = +p1;
+assign out = -p2;
+assign out = p1 + p2;
+assign out = p1 - p2;
+endmodule
diff --git a/tests/hana/test_parse2synthtrans_param_1_test.v b/tests/hana/test_parse2synthtrans_param_1_test.v
new file mode 100644
index 000000000..146eedf42
--- /dev/null
+++ b/tests/hana/test_parse2synthtrans_param_1_test.v
@@ -0,0 +1,7 @@
+module test(in, out);
+input in;
+output out;
+parameter p = 10;
+
+assign out = p;
+endmodule
diff --git a/tests/hana/test_parse2synthtrans_port_scalar_1_test.v b/tests/hana/test_parse2synthtrans_port_scalar_1_test.v
new file mode 100644
index 000000000..8cdf495a0
--- /dev/null
+++ b/tests/hana/test_parse2synthtrans_port_scalar_1_test.v
@@ -0,0 +1,6 @@
+module test(in, out, io);
+inout io;
+output out;
+input in;
+
+endmodule
diff --git a/tests/hana/test_parse2synthtrans_port_vector_1_test.v b/tests/hana/test_parse2synthtrans_port_vector_1_test.v
new file mode 100644
index 000000000..a740282b3
--- /dev/null
+++ b/tests/hana/test_parse2synthtrans_port_vector_1_test.v
@@ -0,0 +1,9 @@
+module test(in1, in2, out1, out2, io1, io2);
+inout [1:0] io1;
+inout [0:1] io2;
+output [1:0] out1;
+output [0:1] out2;
+input [1:0] in1;
+input [0:1] in2;
+
+endmodule
diff --git a/tests/hana/test_parse2synthtrans_v2k_comb_logic_sens_list_test.v b/tests/hana/test_parse2synthtrans_v2k_comb_logic_sens_list_test.v
new file mode 100644
index 000000000..50f1d3531
--- /dev/null
+++ b/tests/hana/test_parse2synthtrans_v2k_comb_logic_sens_list_test.v
@@ -0,0 +1,9 @@
+module test(q, d, clk, reset);
+output reg q;
+input d, clk, reset;
+
+always @ (posedge clk, negedge reset)
+ if(!reset) q <= 0;
+ else q <= d;
+
+endmodule
diff --git a/tests/hana/test_parser_constructs_module_basic1_test.v b/tests/hana/test_parser_constructs_module_basic1_test.v
new file mode 100644
index 000000000..67a272df0
--- /dev/null
+++ b/tests/hana/test_parser_constructs_module_basic1_test.v
@@ -0,0 +1,2 @@
+module test;
+endmodule
diff --git a/tests/hana/test_parser_constructs_param_basic0_test.v b/tests/hana/test_parser_constructs_param_basic0_test.v
new file mode 100644
index 000000000..fd679230e
--- /dev/null
+++ b/tests/hana/test_parser_constructs_param_basic0_test.v
@@ -0,0 +1,10 @@
+module test #( parameter v2kparam = 5)
+(in, out, io, vin, vout, vio);
+input in;
+output out;
+inout io;
+input [3:0] vin;
+output [v2kparam:0] vout;
+inout [0:3] vio;
+parameter myparam = 10;
+endmodule
diff --git a/tests/hana/test_parser_constructs_port_basic0_test.v b/tests/hana/test_parser_constructs_port_basic0_test.v
new file mode 100644
index 000000000..8478e31da
--- /dev/null
+++ b/tests/hana/test_parser_constructs_port_basic0_test.v
@@ -0,0 +1,8 @@
+module test(in, out, io, vin, vout, vio);
+input in;
+output out;
+inout io;
+input [3:0] vin;
+output [3:0] vout;
+inout [0:3] vio;
+endmodule
diff --git a/tests/hana/test_parser_directives_define_simpledef_test.v b/tests/hana/test_parser_directives_define_simpledef_test.v
new file mode 100644
index 000000000..4a5d2345c
--- /dev/null
+++ b/tests/hana/test_parser_directives_define_simpledef_test.v
@@ -0,0 +1,9 @@
+`define parvez ahmad
+`define WIRE wire
+`define TEN 10
+
+module `parvez();
+parameter param = `TEN;
+`WIRE w;
+assign w = `TEN;
+endmodule
diff --git a/tests/hana/test_parser_misc_operators_test.v b/tests/hana/test_parser_misc_operators_test.v
new file mode 100644
index 000000000..8fe8e7bad
--- /dev/null
+++ b/tests/hana/test_parser_misc_operators_test.v
@@ -0,0 +1,29 @@
+module test(out, i0, i1, i2, i3, s1, s0);
+output out;
+input i0, i1, i2, i3;
+input s1, s0;
+
+assign out = (~s1 & s0 & i0) |
+ (~s1 & s0 & i1) |
+ (s1 & ~s0 & i2) |
+ (s1 & s0 & i3);
+
+endmodule
+
+module ternaryop(out, i0, i1, i2, i3, s1, s0);
+output out;
+input i0, i1, i2, i3;
+input s1, s0;
+
+assign out = s1 ? (s0 ? i3 : i2) : (s0 ? i1 : i0);
+
+endmodule
+
+module fulladd4(sum, c_out, a, b, c_in);
+output [3:0] sum;
+output c_out;
+input [3:0] a, b;
+input c_in;
+
+assign {c_out, sum} = a + b + c_in;
+endmodule
diff --git a/tests/hana/test_parser_v2k_comb_port_data_type_test.v b/tests/hana/test_parser_v2k_comb_port_data_type_test.v
new file mode 100644
index 000000000..099585b56
--- /dev/null
+++ b/tests/hana/test_parser_v2k_comb_port_data_type_test.v
@@ -0,0 +1,6 @@
+module adder(sum , co, a, b, ci);
+output reg [31:0] sum;
+output reg co;
+input wire [31:0] a, b;
+input wire ci;
+endmodule
diff --git a/tests/hana/test_parser_v2k_comma_sep_sens_list_test.v b/tests/hana/test_parser_v2k_comma_sep_sens_list_test.v
new file mode 100644
index 000000000..50f1d3531
--- /dev/null
+++ b/tests/hana/test_parser_v2k_comma_sep_sens_list_test.v
@@ -0,0 +1,9 @@
+module test(q, d, clk, reset);
+output reg q;
+input d, clk, reset;
+
+always @ (posedge clk, negedge reset)
+ if(!reset) q <= 0;
+ else q <= d;
+
+endmodule
diff --git a/tests/hana/test_simulation_always_15_test.v b/tests/hana/test_simulation_always_15_test.v
new file mode 100644
index 000000000..5c5fed5b6
--- /dev/null
+++ b/tests/hana/test_simulation_always_15_test.v
@@ -0,0 +1,5 @@
+module test(input [1:0] in, output reg [1:0] out);
+
+always @(in)
+ out = in;
+endmodule
diff --git a/tests/hana/test_simulation_always_17_test.v b/tests/hana/test_simulation_always_17_test.v
new file mode 100644
index 000000000..2d5abc4a6
--- /dev/null
+++ b/tests/hana/test_simulation_always_17_test.v
@@ -0,0 +1,13 @@
+module test(a, b, c, d, z);
+input a, b, c, d;
+output z;
+reg z, temp1, temp2;
+
+always @(a or b or c or d)
+begin
+ temp1 = a ^ b;
+ temp2 = c ^ d;
+ z = temp1 ^ temp2;
+end
+
+endmodule
diff --git a/tests/hana/test_simulation_always_18_test.v b/tests/hana/test_simulation_always_18_test.v
new file mode 100644
index 000000000..234407efd
--- /dev/null
+++ b/tests/hana/test_simulation_always_18_test.v
@@ -0,0 +1,10 @@
+module test (in1, in2, out);
+input in1, in2;
+output reg out;
+
+always @ ( in1 or in2)
+ if(in1 > in2)
+ out = in1;
+ else
+ out = in2;
+endmodule
diff --git a/tests/hana/test_simulation_always_19_test.v b/tests/hana/test_simulation_always_19_test.v
new file mode 100644
index 000000000..5152781df
--- /dev/null
+++ b/tests/hana/test_simulation_always_19_test.v
@@ -0,0 +1,11 @@
+module test(ctrl, in1, in2, out);
+input ctrl;
+input in1, in2;
+output reg out;
+
+always @ (ctrl or in1 or in2)
+ if(ctrl)
+ out = in1 & in2;
+ else
+ out = in1 | in2;
+endmodule
diff --git a/tests/hana/test_simulation_always_1_test.v b/tests/hana/test_simulation_always_1_test.v
new file mode 100644
index 000000000..211369cb6
--- /dev/null
+++ b/tests/hana/test_simulation_always_1_test.v
@@ -0,0 +1,5 @@
+module test(input in, output reg out);
+
+always @(in)
+ out = in;
+endmodule
diff --git a/tests/hana/test_simulation_always_20_test.v b/tests/hana/test_simulation_always_20_test.v
new file mode 100644
index 000000000..6b3e861dc
--- /dev/null
+++ b/tests/hana/test_simulation_always_20_test.v
@@ -0,0 +1,15 @@
+module NonBlockingEx(clk, merge, er, xmit, fddi, claim);
+input clk, merge, er, xmit, fddi;
+output reg claim;
+reg fcr;
+
+always @(posedge clk)
+begin
+ fcr <= er | xmit;
+
+ if(merge)
+ claim <= fcr & fddi;
+ else
+ claim <= fddi;
+end
+endmodule
diff --git a/tests/hana/test_simulation_always_21_test.v b/tests/hana/test_simulation_always_21_test.v
new file mode 100644
index 000000000..6c47b4bdf
--- /dev/null
+++ b/tests/hana/test_simulation_always_21_test.v
@@ -0,0 +1,11 @@
+module FlipFlop(clk, cs, ns);
+input clk;
+input [7:0] cs;
+output [7:0] ns;
+integer is;
+
+always @(posedge clk)
+ is <= cs;
+
+assign ns = is;
+endmodule
diff --git a/tests/hana/test_simulation_always_22_test.v b/tests/hana/test_simulation_always_22_test.v
new file mode 100644
index 000000000..8d91f8154
--- /dev/null
+++ b/tests/hana/test_simulation_always_22_test.v
@@ -0,0 +1,7 @@
+module inc(clock, counter);
+
+input clock;
+output reg [7:0] counter;
+always @(posedge clock)
+ counter <= counter + 1;
+endmodule
diff --git a/tests/hana/test_simulation_always_23_test.v b/tests/hana/test_simulation_always_23_test.v
new file mode 100644
index 000000000..f1f13bbe7
--- /dev/null
+++ b/tests/hana/test_simulation_always_23_test.v
@@ -0,0 +1,14 @@
+module MyCounter (clock, preset, updown, presetdata, counter);
+input clock, preset, updown;
+input [1: 0] presetdata;
+output reg [1:0] counter;
+
+always @(posedge clock)
+ if(preset)
+ counter <= presetdata;
+ else
+ if(updown)
+ counter <= counter + 1;
+ else
+ counter <= counter - 1;
+endmodule
diff --git a/tests/hana/test_simulation_always_27_test.v b/tests/hana/test_simulation_always_27_test.v
new file mode 100644
index 000000000..577378fd6
--- /dev/null
+++ b/tests/hana/test_simulation_always_27_test.v
@@ -0,0 +1,13 @@
+module FlipFlop(clock, cs, ns);
+input clock;
+input cs;
+output reg ns;
+reg temp;
+
+always @(posedge clock)
+begin
+ temp <= cs;
+ ns <= temp;
+end
+
+endmodule
diff --git a/tests/hana/test_simulation_always_29_test.v b/tests/hana/test_simulation_always_29_test.v
new file mode 100644
index 000000000..55606832a
--- /dev/null
+++ b/tests/hana/test_simulation_always_29_test.v
@@ -0,0 +1,9 @@
+module test(input in, output reg [1:0] out);
+
+ always @(in)
+ begin
+ out = in;
+ out = out + in;
+ end
+
+endmodule
diff --git a/tests/hana/test_simulation_always_31_tt.v b/tests/hana/test_simulation_always_31_tt.v
new file mode 100644
index 000000000..299c0ca46
--- /dev/null
+++ b/tests/hana/test_simulation_always_31_tt.v
@@ -0,0 +1,50 @@
+module test(clk, cond, data);
+input cond;
+input clk;
+output data;
+
+wire synth_net;
+wire synth_net_0;
+wire synth_net_1;
+wire synth_net_2;
+
+wire synth_net_3;
+wire synth_net_4;
+wire synth_net_5;
+wire synth_net_6;
+
+wire synth_net_7;
+wire synth_net_8;
+wire synth_net_9;
+wire synth_net_10;
+
+wire synth_net_11;
+wire tmp;
+AND2 synth_AND(.in({synth_net_0, synth_net_1}), .
+ out(synth_net_2));
+AND2 synth_AND_0(.in({synth_net_3, synth_net_4}), .out(
+ synth_net_5));
+AND2 synth_AND_1(.in({synth_net_6, synth_net_7}), .out(
+ synth_net_8));
+AND2 synth_AND_2(.in({synth_net_9, synth_net_10}), .out(
+ synth_net_11));
+BUF synth_BUF(.in(synth_net), .out(synth_net_0));
+BUF
+ synth_BUF_0(.in(data), .out(synth_net_3));
+BUF synth_BUF_1(.in(synth_net_8)
+ , .out(tmp));
+BUF synth_BUF_2(.in(tmp), .out(synth_net_9));
+MUX2 synth_MUX(.
+ in({synth_net_2, synth_net_5}), .select(cond), .out(synth_net_6));
+MUX2
+ synth_MUX_0(.in({synth_net_1, synth_net_4}), .select(cond), .out(synth_net_7
+ ));
+FF synth_FF(.d(synth_net_11), .clk(clk), .q(data));
+VCC synth_VCC(.out(
+ synth_net));
+VCC synth_VCC_0(.out(synth_net_1));
+VCC synth_VCC_1(.out(
+ synth_net_4));
+VCC synth_VCC_2(.out(synth_net_10));
+endmodule
+
diff --git a/tests/hana/test_simulation_and_1_test.v b/tests/hana/test_simulation_and_1_test.v
new file mode 100644
index 000000000..fba639ca8
--- /dev/null
+++ b/tests/hana/test_simulation_and_1_test.v
@@ -0,0 +1,3 @@
+module test(input [1:0] in, output out);
+assign out = in[0] & in[1];
+endmodule
diff --git a/tests/hana/test_simulation_and_2_test.v b/tests/hana/test_simulation_and_2_test.v
new file mode 100644
index 000000000..715bc7ca6
--- /dev/null
+++ b/tests/hana/test_simulation_and_2_test.v
@@ -0,0 +1,3 @@
+module test(input [1:0] in, output out);
+assign out = in[0] && in[1];
+endmodule
diff --git a/tests/hana/test_simulation_and_3_test.v b/tests/hana/test_simulation_and_3_test.v
new file mode 100644
index 000000000..74dccabf8
--- /dev/null
+++ b/tests/hana/test_simulation_and_3_test.v
@@ -0,0 +1,3 @@
+module test(input [2:0] in, output out);
+assign out = in[0] & in[1] & in[2];
+endmodule
diff --git a/tests/hana/test_simulation_and_4_test.v b/tests/hana/test_simulation_and_4_test.v
new file mode 100644
index 000000000..48ed9102a
--- /dev/null
+++ b/tests/hana/test_simulation_and_4_test.v
@@ -0,0 +1,3 @@
+module test(input [2:0] in, output out);
+assign out = in[0] && in[1] && in[2];
+endmodule
diff --git a/tests/hana/test_simulation_and_5_test.v b/tests/hana/test_simulation_and_5_test.v
new file mode 100644
index 000000000..29a355786
--- /dev/null
+++ b/tests/hana/test_simulation_and_5_test.v
@@ -0,0 +1,3 @@
+module test(input [3:0] in, output out);
+assign out = in[0] & in[1] & in[2] & in[3];
+endmodule
diff --git a/tests/hana/test_simulation_and_6_test.v b/tests/hana/test_simulation_and_6_test.v
new file mode 100644
index 000000000..ebce4eebf
--- /dev/null
+++ b/tests/hana/test_simulation_and_6_test.v
@@ -0,0 +1,3 @@
+module test(input [3:0] in, output out);
+assign out = in[0] && in[1] && in[2] && in[3];
+endmodule
diff --git a/tests/hana/test_simulation_and_7_test.v b/tests/hana/test_simulation_and_7_test.v
new file mode 100644
index 000000000..d394adad7
--- /dev/null
+++ b/tests/hana/test_simulation_and_7_test.v
@@ -0,0 +1,3 @@
+module test(input [3:0] in, output out);
+and myand(out, in[0], in[1], in[2], in[3]);
+endmodule
diff --git a/tests/hana/test_simulation_buffer_1_test.v b/tests/hana/test_simulation_buffer_1_test.v
new file mode 100644
index 000000000..e9bb7f617
--- /dev/null
+++ b/tests/hana/test_simulation_buffer_1_test.v
@@ -0,0 +1,3 @@
+module test(input in, output out);
+assign out = in;
+endmodule
diff --git a/tests/hana/test_simulation_buffer_2_test.v b/tests/hana/test_simulation_buffer_2_test.v
new file mode 100644
index 000000000..9a3f5aa3a
--- /dev/null
+++ b/tests/hana/test_simulation_buffer_2_test.v
@@ -0,0 +1,4 @@
+module test(input [1:0] in, output [1:0] out);
+assign out[0] = in[0];
+assign out[1] = in[1];
+endmodule
diff --git a/tests/hana/test_simulation_buffer_3_test.v b/tests/hana/test_simulation_buffer_3_test.v
new file mode 100644
index 000000000..9bca426d1
--- /dev/null
+++ b/tests/hana/test_simulation_buffer_3_test.v
@@ -0,0 +1,4 @@
+module test(input in, output [1:0] out);
+assign out[0] = in;
+assign out[1] = in;
+endmodule
diff --git a/tests/hana/test_simulation_decoder_2_test.v b/tests/hana/test_simulation_decoder_2_test.v
new file mode 100644
index 000000000..5bdf19717
--- /dev/null
+++ b/tests/hana/test_simulation_decoder_2_test.v
@@ -0,0 +1,14 @@
+module test (input [1:0] in, input enable, output reg out);
+
+always @(in or enable)
+ if(!enable)
+ out = 4'b0000;
+ else begin
+ case (in)
+ 2'b00 : out = 0 ;
+ 2'b01 : out = 1;
+ 2'b10 : out = 0;
+ 2'b11 : out = 1;
+ endcase
+ end
+endmodule
diff --git a/tests/hana/test_simulation_decoder_3_test.v b/tests/hana/test_simulation_decoder_3_test.v
new file mode 100644
index 000000000..44f5de12b
--- /dev/null
+++ b/tests/hana/test_simulation_decoder_3_test.v
@@ -0,0 +1,14 @@
+module test (input [1:0] in, input enable, output reg [2:0] out);
+
+always @(in or enable)
+ if(!enable)
+ out = 3'b000;
+ else begin
+ case (in)
+ 2'b00 : out = 3'b001 ;
+ 2'b01 : out = 3'b010;
+ 2'b10 : out = 3'b010;
+ 2'b11 : out = 3'b100;
+ endcase
+ end
+endmodule
diff --git a/tests/hana/test_simulation_decoder_4_test.v b/tests/hana/test_simulation_decoder_4_test.v
new file mode 100644
index 000000000..871a5bbfd
--- /dev/null
+++ b/tests/hana/test_simulation_decoder_4_test.v
@@ -0,0 +1,14 @@
+module test (input [2:0] in, output reg [7:0] out);
+
+always @(in )
+ case (in)
+ 3'b000 : out = 8'b00000001;
+ 3'b001 : out = 8'b00000010;
+ 3'b010 : out = 8'b00000100;
+ 3'b011 : out = 8'b00001000;
+ 3'b100 : out = 8'b00010000;
+ 3'b101 : out = 8'b00100000;
+ 3'b110 : out = 8'b01000000;
+ 3'b111 : out = 8'b10000000;
+ endcase
+endmodule
diff --git a/tests/hana/test_simulation_decoder_5_test.v b/tests/hana/test_simulation_decoder_5_test.v
new file mode 100644
index 000000000..497fa4bfd
--- /dev/null
+++ b/tests/hana/test_simulation_decoder_5_test.v
@@ -0,0 +1,17 @@
+module test (input [2:0] in, input enable, output reg [7:0] out);
+
+always @(in or enable )
+ if(!enable)
+ out = 8'b00000000;
+ else
+ case (in)
+ 3'b000 : out = 8'b00000001;
+ 3'b001 : out = 8'b00000010;
+ 3'b010 : out = 8'b00000100;
+ 3'b011 : out = 8'b00001000;
+ 3'b100 : out = 8'b00010000;
+ 3'b101 : out = 8'b00100000;
+ 3'b110 : out = 8'b01000000;
+ 3'b111 : out = 8'b10000000;
+ endcase
+endmodule
diff --git a/tests/hana/test_simulation_decoder_6_test.v b/tests/hana/test_simulation_decoder_6_test.v
new file mode 100644
index 000000000..fd19ad609
--- /dev/null
+++ b/tests/hana/test_simulation_decoder_6_test.v
@@ -0,0 +1,27 @@
+module test (input [3:0] in, input enable, output reg [15:0] out);
+
+always @(in or enable)
+ if(!enable)
+ out = 16'b0000000000000000;
+ else begin
+ case (in)
+ 4'b0000 : out = 16'b0000000000000001;
+ 4'b0001 : out = 16'b0000000000000010;
+ 4'b0010 : out = 16'b0000000000000100;
+ 4'b0011 : out = 16'b0000000000001000;
+ 4'b0100 : out = 16'b0000000000010000;
+ 4'b0101 : out = 16'b0000000000100000;
+ 4'b0110 : out = 16'b0000000001000000;
+ 4'b0111 : out = 16'b0000000010000000;
+ 4'b1000 : out = 16'b0000000100000000;
+ 4'b1001 : out = 16'b0000001000000000;
+ 4'b1010 : out = 16'b0000010000000000;
+ 4'b1011 : out = 16'b0000100000000000;
+ 4'b1100 : out = 16'b0001000000000000;
+ 4'b1101 : out = 16'b0010000000000000;
+ 4'b1110 : out = 16'b0100000000000000;
+ 4'b1111 : out = 16'b1000000000000000;
+ endcase
+ end
+endmodule
+
diff --git a/tests/hana/test_simulation_decoder_7_test.v b/tests/hana/test_simulation_decoder_7_test.v
new file mode 100644
index 000000000..462e94199
--- /dev/null
+++ b/tests/hana/test_simulation_decoder_7_test.v
@@ -0,0 +1,43 @@
+module test (input [4:0] in, input enable, output reg [31:0] out);
+
+always @(in or enable)
+ if(!enable)
+ out = 32'b00000000000000000000000000000000;
+ else begin
+ case (in)
+ 5'b00000 : out = 32'b00000000000000000000000000000001;
+ 5'b00001 : out = 32'b00000000000000000000000000000010;
+ 5'b00010 : out = 32'b00000000000000000000000000000100;
+ 5'b00011 : out = 32'b00000000000000000000000000001000;
+ 5'b00100 : out = 32'b00000000000000000000000000010000;
+ 5'b00101 : out = 32'b00000000000000000000000000100000;
+ 5'b00110 : out = 32'b00000000000000000000000001000000;
+ 5'b00111 : out = 32'b00000000000000000000000010000000;
+ 5'b01000 : out = 32'b00000000000000000000000100000000;
+ 5'b01001 : out = 32'b00000000000000000000001000000000;
+ 5'b01010 : out = 32'b00000000000000000000010000000000;
+ 5'b01011 : out = 32'b00000000000000000000100000000000;
+ 5'b01100 : out = 32'b00000000000000000001000000000000;
+ 5'b01101 : out = 32'b00000000000000000010000000000000;
+ 5'b01110 : out = 32'b00000000000000000100000000000000;
+ 5'b01111 : out = 32'b00000000000000001000000000000000;
+ 5'b10000 : out = 32'b00000000000000010000000000000000;
+ 5'b10001 : out = 32'b00000000000000100000000000000000;
+ 5'b10010 : out = 32'b00000000000001000000000000000000;
+ 5'b10011 : out = 32'b00000000000010000000000000000000;
+ 5'b10100 : out = 32'b00000000000100000000000000000000;
+ 5'b10101 : out = 32'b00000000001000000000000000000000;
+ 5'b10110 : out = 32'b00000000010000000000000000000000;
+ 5'b10111 : out = 32'b00000000100000000000000000000000;
+ 5'b11000 : out = 32'b00000001000000000000000000000000;
+ 5'b11001 : out = 32'b00000010000000000000000000000000;
+ 5'b11010 : out = 32'b00000100000000000000000000000000;
+ 5'b11011 : out = 32'b00001000000000000000000000000000;
+ 5'b11100 : out = 32'b00010000000000000000000000000000;
+ 5'b11101 : out = 32'b00100000000000000000000000000000;
+ 5'b11110 : out = 32'b01000000000000000000000000000000;
+ 5'b11111 : out = 32'b10000000000000000000000000000000;
+ endcase
+ end
+endmodule
+
diff --git a/tests/hana/test_simulation_decoder_8_test.v b/tests/hana/test_simulation_decoder_8_test.v
new file mode 100644
index 000000000..751d60f67
--- /dev/null
+++ b/tests/hana/test_simulation_decoder_8_test.v
@@ -0,0 +1,76 @@
+module test (input [5:0] in, input enable, output reg [63:0] out);
+
+always @(in or enable)
+ if(!enable)
+ out = 64'b0000000000000000000000000000000000000000000000000000000000000000;
+ else begin
+ case (in)
+ 6'b000000 : out = 64'b0000000000000000000000000000000000000000000000000000000000000001;
+ 6'b000001 : out = 64'b0000000000000000000000000000000000000000000000000000000000000010;
+ 6'b000010 : out = 64'b0000000000000000000000000000000000000000000000000000000000000100;
+ 6'b000011 : out = 64'b0000000000000000000000000000000000000000000000000000000000001000;
+ 6'b000100 : out = 64'b0000000000000000000000000000000000000000000000000000000000010000;
+ 6'b000101 : out = 64'b0000000000000000000000000000000000000000000000000000000000100000;
+ 6'b000110 : out = 64'b0000000000000000000000000000000000000000000000000000000001000000;
+ 6'b000111 : out = 64'b0000000000000000000000000000000000000000000000000000000010000000;
+ 6'b001000 : out = 64'b0000000000000000000000000000000000000000000000000000000100000000;
+ 6'b001001 : out = 64'b0000000000000000000000000000000000000000000000000000001000000000;
+ 6'b001010 : out = 64'b0000000000000000000000000000000000000000000000000000010000000000;
+ 6'b001011 : out = 64'b0000000000000000000000000000000000000000000000000000100000000000;
+ 6'b001100 : out = 64'b0000000000000000000000000000000000000000000000000001000000000000;
+ 6'b001101 : out = 64'b0000000000000000000000000000000000000000000000000010000000000000;
+ 6'b001110 : out = 64'b0000000000000000000000000000000000000000000000000100000000000000;
+ 6'b001111 : out = 64'b0000000000000000000000000000000000000000000000001000000000000000;
+ 6'b010000 : out = 64'b0000000000000000000000000000000000000000000000010000000000000000;
+ 6'b010001 : out = 64'b0000000000000000000000000000000000000000000000100000000000000000;
+ 6'b010010 : out = 64'b0000000000000000000000000000000000000000000001000000000000000000;
+ 6'b010011 : out = 64'b0000000000000000000000000000000000000000000010000000000000000000;
+ 6'b010100 : out = 64'b0000000000000000000000000000000000000000000100000000000000000000;
+ 6'b010101 : out = 64'b0000000000000000000000000000000000000000001000000000000000000000;
+ 6'b010110 : out = 64'b0000000000000000000000000000000000000000010000000000000000000000;
+ 6'b010111 : out = 64'b0000000000000000000000000000000000000000100000000000000000000000;
+ 6'b011000 : out = 64'b0000000000000000000000000000000000000001000000000000000000000000;
+ 6'b011001 : out = 64'b0000000000000000000000000000000000000010000000000000000000000000;
+ 6'b011010 : out = 64'b0000000000000000000000000000000000000100000000000000000000000000;
+ 6'b011011 : out = 64'b0000000000000000000000000000000000001000000000000000000000000000;
+ 6'b011100 : out = 64'b0000000000000000000000000000000000010000000000000000000000000000;
+ 6'b011101 : out = 64'b0000000000000000000000000000000000100000000000000000000000000000;
+ 6'b011110 : out = 64'b0000000000000000000000000000000001000000000000000000000000000000;
+ 6'b011111 : out = 64'b0000000000000000000000000000000010000000000000000000000000000000;
+
+ 6'b100000 : out = 64'b0000000000000000000000000000000100000000000000000000000000000000;
+ 6'b100001 : out = 64'b0000000000000000000000000000001000000000000000000000000000000000;
+ 6'b100010 : out = 64'b0000000000000000000000000000010000000000000000000000000000000000;
+ 6'b100011 : out = 64'b0000000000000000000000000000100000000000000000000000000000000000;
+ 6'b100100 : out = 64'b0000000000000000000000000001000000000000000000000000000000000000;
+ 6'b100101 : out = 64'b0000000000000000000000000010000000000000000000000000000000000000;
+ 6'b100110 : out = 64'b0000000000000000000000000100000000000000000000000000000000000000;
+ 6'b100111 : out = 64'b0000000000000000000000001000000000000000000000000000000000000000;
+ 6'b101000 : out = 64'b0000000000000000000000010000000000000000000000000000000000000000;
+ 6'b101001 : out = 64'b0000000000000000000000100000000000000000000000000000000000000000;
+ 6'b101010 : out = 64'b0000000000000000000001000000000000000000000000000000000000000000;
+ 6'b101011 : out = 64'b0000000000000000000010000000000000000000000000000000000000000000;
+ 6'b101100 : out = 64'b0000000000000000000100000000000000000000000000000000000000000000;
+ 6'b101101 : out = 64'b0000000000000000001000000000000000000000000000000000000000000000;
+ 6'b101110 : out = 64'b0000000000000000010000000000000000000000000000000000000000000000;
+ 6'b101111 : out = 64'b0000000000000000100000000000000000000000000000000000000000000000;
+ 6'b110000 : out = 64'b0000000000000001000000000000000000000000000000000000000000000000;
+ 6'b110001 : out = 64'b0000000000000010000000000000000000000000000000000000000000000000;
+ 6'b110010 : out = 64'b0000000000000100000000000000000000000000000000000000000000000000;
+ 6'b110011 : out = 64'b0000000000001000000000000000000000000000000000000000000000000000;
+ 6'b110100 : out = 64'b0000000000010000000000000000000000000000000000000000000000000000;
+ 6'b110101 : out = 64'b0000000000100000000000000000000000000000000000000000000000000000;
+ 6'b110110 : out = 64'b0000000001000000000000000000000000000000000000000000000000000000;
+ 6'b110111 : out = 64'b0000000010000000000000000000000000000000000000000000000000000000;
+ 6'b111000 : out = 64'b0000000100000000000000000000000000000000000000000000000000000000;
+ 6'b111001 : out = 64'b0000001000000000000000000000000000000000000000000000000000000000;
+ 6'b111010 : out = 64'b0000010000000000000000000000000000000000000000000000000000000000;
+ 6'b111011 : out = 64'b0000100000000000000000000000000000000000000000000000000000000000;
+ 6'b111100 : out = 64'b0001000000000000000000000000000000000000000000000000000000000000;
+ 6'b111101 : out = 64'b0010000000000000000000000000000000000000000000000000000000000000;
+ 6'b111110 : out = 64'b0100000000000000000000000000000000000000000000000000000000000000;
+ 6'b111111 : out = 64'b1000000000000000000000000000000000000000000000000000000000000000;
+ endcase
+ end
+endmodule
+
diff --git a/tests/hana/test_simulation_inc_16_test.v b/tests/hana/test_simulation_inc_16_test.v
new file mode 100644
index 000000000..7ff42ff50
--- /dev/null
+++ b/tests/hana/test_simulation_inc_16_test.v
@@ -0,0 +1,5 @@
+module test(input [15:0] in, output [15:0] out);
+
+assign out = -in;
+
+endmodule
diff --git a/tests/hana/test_simulation_inc_1_test.v b/tests/hana/test_simulation_inc_1_test.v
new file mode 100644
index 000000000..02bec2c27
--- /dev/null
+++ b/tests/hana/test_simulation_inc_1_test.v
@@ -0,0 +1,5 @@
+module test(input in, output out);
+
+assign out = -in;
+
+endmodule
diff --git a/tests/hana/test_simulation_inc_2_test.v b/tests/hana/test_simulation_inc_2_test.v
new file mode 100644
index 000000000..b96e05a2d
--- /dev/null
+++ b/tests/hana/test_simulation_inc_2_test.v
@@ -0,0 +1,5 @@
+module test(input [1:0] in, output [1:0] out);
+
+assign out = -in;
+
+endmodule
diff --git a/tests/hana/test_simulation_inc_32_test.v b/tests/hana/test_simulation_inc_32_test.v
new file mode 100644
index 000000000..5700d0ce7
--- /dev/null
+++ b/tests/hana/test_simulation_inc_32_test.v
@@ -0,0 +1,5 @@
+module test(input [31:0] in, output [31:0] out);
+
+assign out = -in;
+
+endmodule
diff --git a/tests/hana/test_simulation_inc_4_test.v b/tests/hana/test_simulation_inc_4_test.v
new file mode 100644
index 000000000..34940d63e
--- /dev/null
+++ b/tests/hana/test_simulation_inc_4_test.v
@@ -0,0 +1,5 @@
+module test(input [3:0] in, output [3:0] out);
+
+assign out = -in;
+
+endmodule
diff --git a/tests/hana/test_simulation_inc_8_test.v b/tests/hana/test_simulation_inc_8_test.v
new file mode 100644
index 000000000..c36d69f07
--- /dev/null
+++ b/tests/hana/test_simulation_inc_8_test.v
@@ -0,0 +1,5 @@
+module test(input [7:0] in, output [7:0] out);
+
+assign out = -in;
+
+endmodule
diff --git a/tests/hana/test_simulation_mod_1_xx.v b/tests/hana/test_simulation_mod_1_xx.v
new file mode 100644
index 000000000..75144a8e5
--- /dev/null
+++ b/tests/hana/test_simulation_mod_1_xx.v
@@ -0,0 +1,13 @@
+module test(in1, in2, out);
+input in1;
+input in2;
+output out;
+
+wire synth_net_0;
+wire synth_net_1;
+BUF synth_BUF_0(.in(synth_net_1), .out(out
+ ));
+DIV1 synth_DIV(.in1(in1), .in2(in2), .rem(synth_net_0), .out(synth_net_1
+ ));
+endmodule
+
diff --git a/tests/hana/test_simulation_mux_16_test.v b/tests/hana/test_simulation_mux_16_test.v
new file mode 100644
index 000000000..de4b6f8e9
--- /dev/null
+++ b/tests/hana/test_simulation_mux_16_test.v
@@ -0,0 +1,22 @@
+module test(input [15:0] in, input [3:0] select, output reg out);
+
+always @( in or select)
+ case (select)
+ 0: out = in[0];
+ 1: out = in[1];
+ 2: out = in[2];
+ 3: out = in[3];
+ 4: out = in[4];
+ 5: out = in[5];
+ 6: out = in[6];
+ 7: out = in[7];
+ 8: out = in[8];
+ 9: out = in[9];
+ 10: out = in[10];
+ 11: out = in[11];
+ 12: out = in[12];
+ 13: out = in[13];
+ 14: out = in[14];
+ 15: out = in[15];
+ endcase
+endmodule
diff --git a/tests/hana/test_simulation_mux_2_test.v b/tests/hana/test_simulation_mux_2_test.v
new file mode 100644
index 000000000..bc676c70b
--- /dev/null
+++ b/tests/hana/test_simulation_mux_2_test.v
@@ -0,0 +1,8 @@
+module test(input [1:0] in, input select, output reg out);
+
+always @( in or select)
+ case (select)
+ 0: out = in[0];
+ 1: out = in[1];
+ endcase
+endmodule
diff --git a/tests/hana/test_simulation_mux_32_test.v b/tests/hana/test_simulation_mux_32_test.v
new file mode 100644
index 000000000..16de4d7f7
--- /dev/null
+++ b/tests/hana/test_simulation_mux_32_test.v
@@ -0,0 +1,39 @@
+module test(input [31:0] in, input [4:0] select, output reg out);
+
+always @( in or select)
+ case (select)
+ 0: out = in[0];
+ 1: out = in[1];
+ 2: out = in[2];
+ 3: out = in[3];
+ 4: out = in[4];
+ 5: out = in[5];
+ 6: out = in[6];
+ 7: out = in[7];
+ 8: out = in[8];
+ 9: out = in[9];
+ 10: out = in[10];
+ 11: out = in[11];
+ 12: out = in[12];
+ 13: out = in[13];
+ 14: out = in[14];
+ 15: out = in[15];
+ 16: out = in[16];
+ 17: out = in[17];
+ 18: out = in[18];
+ 19: out = in[19];
+ 20: out = in[20];
+ 21: out = in[21];
+ 22: out = in[22];
+ 23: out = in[23];
+ 24: out = in[24];
+ 25: out = in[25];
+ 26: out = in[26];
+ 27: out = in[27];
+ 28: out = in[28];
+ 29: out = in[29];
+ 30: out = in[30];
+ 31: out = in[31];
+ endcase
+endmodule
+
diff --git a/tests/hana/test_simulation_mux_4_test.v b/tests/hana/test_simulation_mux_4_test.v
new file mode 100644
index 000000000..6a112c6a9
--- /dev/null
+++ b/tests/hana/test_simulation_mux_4_test.v
@@ -0,0 +1,10 @@
+module test(input [3:0] in, input [1:0] select, output reg out);
+
+always @( in or select)
+ case (select)
+ 0: out = in[0];
+ 1: out = in[1];
+ 2: out = in[2];
+ 3: out = in[3];
+ endcase
+endmodule
diff --git a/tests/hana/test_simulation_mux_64_test.v b/tests/hana/test_simulation_mux_64_test.v
new file mode 100644
index 000000000..420239c6e
--- /dev/null
+++ b/tests/hana/test_simulation_mux_64_test.v
@@ -0,0 +1,71 @@
+module test(input [63:0] in, input [5:0] select, output reg out);
+
+always @( in or select)
+ case (select)
+ 0: out = in[0];
+ 1: out = in[1];
+ 2: out = in[2];
+ 3: out = in[3];
+ 4: out = in[4];
+ 5: out = in[5];
+ 6: out = in[6];
+ 7: out = in[7];
+ 8: out = in[8];
+ 9: out = in[9];
+ 10: out = in[10];
+ 11: out = in[11];
+ 12: out = in[12];
+ 13: out = in[13];
+ 14: out = in[14];
+ 15: out = in[15];
+ 16: out = in[16];
+ 17: out = in[17];
+ 18: out = in[18];
+ 19: out = in[19];
+ 20: out = in[20];
+ 21: out = in[21];
+ 22: out = in[22];
+ 23: out = in[23];
+ 24: out = in[24];
+ 25: out = in[25];
+ 26: out = in[26];
+ 27: out = in[27];
+ 28: out = in[28];
+ 29: out = in[29];
+ 30: out = in[30];
+ 31: out = in[31];
+ 32: out = in[32];
+ 33: out = in[33];
+ 34: out = in[34];
+ 35: out = in[35];
+ 36: out = in[36];
+ 37: out = in[37];
+ 38: out = in[38];
+ 39: out = in[39];
+ 40: out = in[40];
+ 41: out = in[41];
+ 42: out = in[42];
+ 43: out = in[43];
+ 44: out = in[44];
+ 45: out = in[45];
+ 46: out = in[46];
+ 47: out = in[47];
+ 48: out = in[48];
+ 49: out = in[49];
+ 50: out = in[50];
+ 51: out = in[51];
+ 52: out = in[52];
+ 53: out = in[53];
+ 54: out = in[54];
+ 55: out = in[55];
+ 56: out = in[56];
+ 57: out = in[57];
+ 58: out = in[58];
+ 59: out = in[59];
+ 60: out = in[60];
+ 61: out = in[61];
+ 62: out = in[62];
+ 63: out = in[63];
+ endcase
+endmodule
+
diff --git a/tests/hana/test_simulation_mux_8_test.v b/tests/hana/test_simulation_mux_8_test.v
new file mode 100644
index 000000000..f53a2c570
--- /dev/null
+++ b/tests/hana/test_simulation_mux_8_test.v
@@ -0,0 +1,14 @@
+module test(input [7:0] in, input [2:0] select, output reg out);
+
+always @( in or select)
+ case (select)
+ 0: out = in[0];
+ 1: out = in[1];
+ 2: out = in[2];
+ 3: out = in[3];
+ 4: out = in[4];
+ 5: out = in[5];
+ 6: out = in[6];
+ 7: out = in[7];
+ endcase
+endmodule
diff --git a/tests/hana/test_simulation_nand_1_test.v b/tests/hana/test_simulation_nand_1_test.v
new file mode 100644
index 000000000..d8f34ee1f
--- /dev/null
+++ b/tests/hana/test_simulation_nand_1_test.v
@@ -0,0 +1,3 @@
+module test(input [1:0] in, output out);
+assign out = ~(in[0] & in[1]);
+endmodule
diff --git a/tests/hana/test_simulation_nand_3_test.v b/tests/hana/test_simulation_nand_3_test.v
new file mode 100644
index 000000000..8926cebb9
--- /dev/null
+++ b/tests/hana/test_simulation_nand_3_test.v
@@ -0,0 +1,3 @@
+module test(input [2:0] in, output out);
+assign out = !(in[0] & in[1] & in[2]);
+endmodule
diff --git a/tests/hana/test_simulation_nand_4_test.v b/tests/hana/test_simulation_nand_4_test.v
new file mode 100644
index 000000000..703a2de45
--- /dev/null
+++ b/tests/hana/test_simulation_nand_4_test.v
@@ -0,0 +1,3 @@
+module test(input [2:0] in, output out);
+assign out = ~(in[0] && in[1] && in[2]);
+endmodule
diff --git a/tests/hana/test_simulation_nand_5_test.v b/tests/hana/test_simulation_nand_5_test.v
new file mode 100644
index 000000000..adef3c903
--- /dev/null
+++ b/tests/hana/test_simulation_nand_5_test.v
@@ -0,0 +1,3 @@
+module test(input [3:0] in, output out);
+assign out = !(in[0] & in[1] & in[2] & in[3]);
+endmodule
diff --git a/tests/hana/test_simulation_nand_6_test.v b/tests/hana/test_simulation_nand_6_test.v
new file mode 100644
index 000000000..a2136f211
--- /dev/null
+++ b/tests/hana/test_simulation_nand_6_test.v
@@ -0,0 +1,3 @@
+module test(input [3:0] in, output out);
+assign out = !(in[0] && in[1] && in[2] && in[3]);
+endmodule
diff --git a/tests/hana/test_simulation_nor_1_test.v b/tests/hana/test_simulation_nor_1_test.v
new file mode 100644
index 000000000..df4e8bfaa
--- /dev/null
+++ b/tests/hana/test_simulation_nor_1_test.v
@@ -0,0 +1,3 @@
+module test(input [1:0] in, output out);
+assign out = ~(in[0] | in[1]);
+endmodule
diff --git a/tests/hana/test_simulation_nor_2_test.v b/tests/hana/test_simulation_nor_2_test.v
new file mode 100644
index 000000000..2cfffc45f
--- /dev/null
+++ b/tests/hana/test_simulation_nor_2_test.v
@@ -0,0 +1,3 @@
+module test(input [2:0] in, output out);
+assign out = ~(in[0] | in[1] | in[2]);
+endmodule
diff --git a/tests/hana/test_simulation_nor_3_test.v b/tests/hana/test_simulation_nor_3_test.v
new file mode 100644
index 000000000..9f1ef8fec
--- /dev/null
+++ b/tests/hana/test_simulation_nor_3_test.v
@@ -0,0 +1,3 @@
+module test(input [3:0] in, output out);
+assign out = ~(in[0] | in[1] | in[2] | in[3]);
+endmodule
diff --git a/tests/hana/test_simulation_nor_4_test.v b/tests/hana/test_simulation_nor_4_test.v
new file mode 100644
index 000000000..d8e685049
--- /dev/null
+++ b/tests/hana/test_simulation_nor_4_test.v
@@ -0,0 +1,3 @@
+module test(input [3:0] in, output out);
+nor mynor(out, in[0], in[1], in[2], in[3]);
+endmodule
diff --git a/tests/hana/test_simulation_opt_constprop_contassign_1_test.v b/tests/hana/test_simulation_opt_constprop_contassign_1_test.v
new file mode 100644
index 000000000..a39b58b42
--- /dev/null
+++ b/tests/hana/test_simulation_opt_constprop_contassign_1_test.v
@@ -0,0 +1,3 @@
+module test(input in, output out);
+assign out = 1'b1;
+endmodule
diff --git a/tests/hana/test_simulation_or_1_test.v b/tests/hana/test_simulation_or_1_test.v
new file mode 100644
index 000000000..bdfffd3d7
--- /dev/null
+++ b/tests/hana/test_simulation_or_1_test.v
@@ -0,0 +1,3 @@
+module test(input [1:0] in, output out);
+assign out = in[0] | in[1];
+endmodule
diff --git a/tests/hana/test_simulation_or_2_test.v b/tests/hana/test_simulation_or_2_test.v
new file mode 100644
index 000000000..291c8c765
--- /dev/null
+++ b/tests/hana/test_simulation_or_2_test.v
@@ -0,0 +1,3 @@
+module test(input [1:0] in, output out);
+assign out = in[0] || in[1];
+endmodule
diff --git a/tests/hana/test_simulation_or_3_test.v b/tests/hana/test_simulation_or_3_test.v
new file mode 100644
index 000000000..ad00c7084
--- /dev/null
+++ b/tests/hana/test_simulation_or_3_test.v
@@ -0,0 +1,3 @@
+module test(input [2:0] in, output out);
+assign out = in[0] | in[1] | in[2];
+endmodule
diff --git a/tests/hana/test_simulation_or_4_test.v b/tests/hana/test_simulation_or_4_test.v
new file mode 100644
index 000000000..2ec57fa93
--- /dev/null
+++ b/tests/hana/test_simulation_or_4_test.v
@@ -0,0 +1,3 @@
+module test(input [2:0] in, output out);
+assign out = in[0] || in[1] || in[2];
+endmodule
diff --git a/tests/hana/test_simulation_or_5_test.v b/tests/hana/test_simulation_or_5_test.v
new file mode 100644
index 000000000..f6a2d14d4
--- /dev/null
+++ b/tests/hana/test_simulation_or_5_test.v
@@ -0,0 +1,3 @@
+module test(input [3:0] in, output out);
+assign out = in[0] | in[1] | in[2] | in[3];
+endmodule
diff --git a/tests/hana/test_simulation_or_6_test.v b/tests/hana/test_simulation_or_6_test.v
new file mode 100644
index 000000000..ecd85c363
--- /dev/null
+++ b/tests/hana/test_simulation_or_6_test.v
@@ -0,0 +1,3 @@
+module test(input [3:0] in, output out);
+assign out = in[0] || in[1] || in[2] || in[3];
+endmodule
diff --git a/tests/hana/test_simulation_seq_ff_1_test.v b/tests/hana/test_simulation_seq_ff_1_test.v
new file mode 100644
index 000000000..5aac49c03
--- /dev/null
+++ b/tests/hana/test_simulation_seq_ff_1_test.v
@@ -0,0 +1,4 @@
+module test(input in, input clk, output reg out);
+always @(posedge clk)
+ out <= in;
+endmodule
diff --git a/tests/hana/test_simulation_seq_ff_2_test.v b/tests/hana/test_simulation_seq_ff_2_test.v
new file mode 100644
index 000000000..f1d2b7b42
--- /dev/null
+++ b/tests/hana/test_simulation_seq_ff_2_test.v
@@ -0,0 +1,4 @@
+module test(input in, input clk, output reg out);
+always @(negedge clk)
+ out <= in;
+endmodule
diff --git a/tests/hana/test_simulation_shifter_left_16_test.v b/tests/hana/test_simulation_shifter_left_16_test.v
new file mode 100644
index 000000000..a57dac499
--- /dev/null
+++ b/tests/hana/test_simulation_shifter_left_16_test.v
@@ -0,0 +1,4 @@
+module test(input [15:0] IN, input [4:0] SHIFT, output [15:0] OUT);
+
+assign OUT = IN << SHIFT;
+endmodule
diff --git a/tests/hana/test_simulation_shifter_left_32_test.v b/tests/hana/test_simulation_shifter_left_32_test.v
new file mode 100644
index 000000000..672938ace
--- /dev/null
+++ b/tests/hana/test_simulation_shifter_left_32_test.v
@@ -0,0 +1,4 @@
+module test(input [31:0] IN, input [5:0] SHIFT, output [31:0] OUT);
+
+assign OUT = IN << SHIFT;
+endmodule
diff --git a/tests/hana/test_simulation_shifter_left_4_test.v b/tests/hana/test_simulation_shifter_left_4_test.v
new file mode 100644
index 000000000..c525401f1
--- /dev/null
+++ b/tests/hana/test_simulation_shifter_left_4_test.v
@@ -0,0 +1,4 @@
+module test(input [3:0] IN, input [2:0] SHIFT, output [3:0] OUT);
+
+assign OUT = IN << SHIFT;
+endmodule
diff --git a/tests/hana/test_simulation_shifter_left_64_test.v b/tests/hana/test_simulation_shifter_left_64_test.v
new file mode 100644
index 000000000..276a7c5a8
--- /dev/null
+++ b/tests/hana/test_simulation_shifter_left_64_test.v
@@ -0,0 +1,4 @@
+module test(input [63:0] IN, input [6:0] SHIFT, output [63:0] OUT);
+
+assign OUT = IN << SHIFT;
+endmodule
diff --git a/tests/hana/test_simulation_shifter_left_8_test.v b/tests/hana/test_simulation_shifter_left_8_test.v
new file mode 100644
index 000000000..c17277001
--- /dev/null
+++ b/tests/hana/test_simulation_shifter_left_8_test.v
@@ -0,0 +1,4 @@
+module test(input [7:0] IN, input [3:0] SHIFT, output [7:0] OUT);
+
+assign OUT = IN << SHIFT;
+endmodule
diff --git a/tests/hana/test_simulation_shifter_right_16_test.v b/tests/hana/test_simulation_shifter_right_16_test.v
new file mode 100644
index 000000000..6152adc06
--- /dev/null
+++ b/tests/hana/test_simulation_shifter_right_16_test.v
@@ -0,0 +1,4 @@
+module test(input [15:0] IN, input [4:0] SHIFT, output [15:0] OUT);
+
+assign OUT = IN >> SHIFT;
+endmodule
diff --git a/tests/hana/test_simulation_shifter_right_32_test.v b/tests/hana/test_simulation_shifter_right_32_test.v
new file mode 100644
index 000000000..e910cdd6d
--- /dev/null
+++ b/tests/hana/test_simulation_shifter_right_32_test.v
@@ -0,0 +1,4 @@
+module test(input [31:0] IN, input [5:0] SHIFT, output [31:0] OUT);
+
+assign OUT = IN >> SHIFT;
+endmodule
diff --git a/tests/hana/test_simulation_shifter_right_4_test.v b/tests/hana/test_simulation_shifter_right_4_test.v
new file mode 100644
index 000000000..608c196de
--- /dev/null
+++ b/tests/hana/test_simulation_shifter_right_4_test.v
@@ -0,0 +1,4 @@
+module test(input [3:0] IN, input [2:0] SHIFT, output [3:0] OUT);
+
+assign OUT = IN >> SHIFT;
+endmodule
diff --git a/tests/hana/test_simulation_shifter_right_64_test.v b/tests/hana/test_simulation_shifter_right_64_test.v
new file mode 100644
index 000000000..c26d5938e
--- /dev/null
+++ b/tests/hana/test_simulation_shifter_right_64_test.v
@@ -0,0 +1,4 @@
+module test(input [63:0] IN, input [6:0] SHIFT, output [63:0] OUT);
+
+assign OUT = IN >> SHIFT;
+endmodule
diff --git a/tests/hana/test_simulation_shifter_right_8_test.v b/tests/hana/test_simulation_shifter_right_8_test.v
new file mode 100644
index 000000000..a91c594e5
--- /dev/null
+++ b/tests/hana/test_simulation_shifter_right_8_test.v
@@ -0,0 +1,4 @@
+module test(input [7:0] IN, input [3:0] SHIFT, output [7:0] OUT);
+
+assign OUT = IN >> SHIFT;
+endmodule
diff --git a/tests/hana/test_simulation_sop_basic_10_test.v b/tests/hana/test_simulation_sop_basic_10_test.v
new file mode 100644
index 000000000..bc676c70b
--- /dev/null
+++ b/tests/hana/test_simulation_sop_basic_10_test.v
@@ -0,0 +1,8 @@
+module test(input [1:0] in, input select, output reg out);
+
+always @( in or select)
+ case (select)
+ 0: out = in[0];
+ 1: out = in[1];
+ endcase
+endmodule
diff --git a/tests/hana/test_simulation_sop_basic_11_test.v b/tests/hana/test_simulation_sop_basic_11_test.v
new file mode 100644
index 000000000..6a112c6a9
--- /dev/null
+++ b/tests/hana/test_simulation_sop_basic_11_test.v
@@ -0,0 +1,10 @@
+module test(input [3:0] in, input [1:0] select, output reg out);
+
+always @( in or select)
+ case (select)
+ 0: out = in[0];
+ 1: out = in[1];
+ 2: out = in[2];
+ 3: out = in[3];
+ endcase
+endmodule
diff --git a/tests/hana/test_simulation_sop_basic_12_test.v b/tests/hana/test_simulation_sop_basic_12_test.v
new file mode 100644
index 000000000..f53a2c570
--- /dev/null
+++ b/tests/hana/test_simulation_sop_basic_12_test.v
@@ -0,0 +1,14 @@
+module test(input [7:0] in, input [2:0] select, output reg out);
+
+always @( in or select)
+ case (select)
+ 0: out = in[0];
+ 1: out = in[1];
+ 2: out = in[2];
+ 3: out = in[3];
+ 4: out = in[4];
+ 5: out = in[5];
+ 6: out = in[6];
+ 7: out = in[7];
+ endcase
+endmodule
diff --git a/tests/hana/test_simulation_sop_basic_18_test.v b/tests/hana/test_simulation_sop_basic_18_test.v
new file mode 100644
index 000000000..03fc35b32
--- /dev/null
+++ b/tests/hana/test_simulation_sop_basic_18_test.v
@@ -0,0 +1,5 @@
+module test(input [7:0] in, output out);
+
+assign out = ~^in;
+
+endmodule
diff --git a/tests/hana/test_simulation_sop_basic_3_test.v b/tests/hana/test_simulation_sop_basic_3_test.v
new file mode 100644
index 000000000..81759c25d
--- /dev/null
+++ b/tests/hana/test_simulation_sop_basic_3_test.v
@@ -0,0 +1,3 @@
+module test(input in, output out);
+assign out = ~in;
+endmodule
diff --git a/tests/hana/test_simulation_sop_basic_7_test.v b/tests/hana/test_simulation_sop_basic_7_test.v
new file mode 100644
index 000000000..e9bb7f617
--- /dev/null
+++ b/tests/hana/test_simulation_sop_basic_7_test.v
@@ -0,0 +1,3 @@
+module test(input in, output out);
+assign out = in;
+endmodule
diff --git a/tests/hana/test_simulation_sop_basic_8_test.v b/tests/hana/test_simulation_sop_basic_8_test.v
new file mode 100644
index 000000000..a51ead0b2
--- /dev/null
+++ b/tests/hana/test_simulation_sop_basic_8_test.v
@@ -0,0 +1,3 @@
+module test(output out);
+assign out = 1'b0;
+endmodule
diff --git a/tests/hana/test_simulation_sop_basic_9_test.v b/tests/hana/test_simulation_sop_basic_9_test.v
new file mode 100644
index 000000000..81759c25d
--- /dev/null
+++ b/tests/hana/test_simulation_sop_basic_9_test.v
@@ -0,0 +1,3 @@
+module test(input in, output out);
+assign out = ~in;
+endmodule
diff --git a/tests/hana/test_simulation_techmap_and_19_tech.v b/tests/hana/test_simulation_techmap_and_19_tech.v
new file mode 100644
index 000000000..2491087cd
--- /dev/null
+++ b/tests/hana/test_simulation_techmap_and_19_tech.v
@@ -0,0 +1,7 @@
+module TECH_AND18(input [17:0] in, output out);
+assign out = &in;
+endmodule
+
+module TECH_AND4(input [3:0] in, output out);
+assign out = &in;
+endmodule
diff --git a/tests/hana/test_simulation_techmap_and_5_tech.v b/tests/hana/test_simulation_techmap_and_5_tech.v
new file mode 100644
index 000000000..6ec6a61c4
--- /dev/null
+++ b/tests/hana/test_simulation_techmap_and_5_tech.v
@@ -0,0 +1,3 @@
+module TECH_AND5(input [4:0] in, output out);
+assign out = &in;
+endmodule
diff --git a/tests/hana/test_simulation_techmap_buf_test.v b/tests/hana/test_simulation_techmap_buf_test.v
new file mode 100644
index 000000000..e9bb7f617
--- /dev/null
+++ b/tests/hana/test_simulation_techmap_buf_test.v
@@ -0,0 +1,3 @@
+module test(input in, output out);
+assign out = in;
+endmodule
diff --git a/tests/hana/test_simulation_techmap_inv_test.v b/tests/hana/test_simulation_techmap_inv_test.v
new file mode 100644
index 000000000..81759c25d
--- /dev/null
+++ b/tests/hana/test_simulation_techmap_inv_test.v
@@ -0,0 +1,3 @@
+module test(input in, output out);
+assign out = ~in;
+endmodule
diff --git a/tests/hana/test_simulation_techmap_mux_0_test.v b/tests/hana/test_simulation_techmap_mux_0_test.v
new file mode 100644
index 000000000..bc676c70b
--- /dev/null
+++ b/tests/hana/test_simulation_techmap_mux_0_test.v
@@ -0,0 +1,8 @@
+module test(input [1:0] in, input select, output reg out);
+
+always @( in or select)
+ case (select)
+ 0: out = in[0];
+ 1: out = in[1];
+ endcase
+endmodule
diff --git a/tests/hana/test_simulation_techmap_mux_128_test.v b/tests/hana/test_simulation_techmap_mux_128_test.v
new file mode 100644
index 000000000..544c016a8
--- /dev/null
+++ b/tests/hana/test_simulation_techmap_mux_128_test.v
@@ -0,0 +1,134 @@
+module test(input [127:0] in, input [6:0] select, output reg out);
+
+always @( in or select)
+ case (select)
+ 0: out = in[0];
+ 1: out = in[1];
+ 2: out = in[2];
+ 3: out = in[3];
+ 4: out = in[4];
+ 5: out = in[5];
+ 6: out = in[6];
+ 7: out = in[7];
+ 8: out = in[8];
+ 9: out = in[9];
+ 10: out = in[10];
+ 11: out = in[11];
+ 12: out = in[12];
+ 13: out = in[13];
+ 14: out = in[14];
+ 15: out = in[15];
+ 16: out = in[16];
+ 17: out = in[17];
+ 18: out = in[18];
+ 19: out = in[19];
+ 20: out = in[20];
+ 21: out = in[21];
+ 22: out = in[22];
+ 23: out = in[23];
+ 24: out = in[24];
+ 25: out = in[25];
+ 26: out = in[26];
+ 27: out = in[27];
+ 28: out = in[28];
+ 29: out = in[29];
+ 30: out = in[30];
+ 31: out = in[31];
+ 32: out = in[32];
+ 33: out = in[33];
+ 34: out = in[34];
+ 35: out = in[35];
+ 36: out = in[36];
+ 37: out = in[37];
+ 38: out = in[38];
+ 39: out = in[39];
+ 40: out = in[40];
+ 41: out = in[41];
+ 42: out = in[42];
+ 43: out = in[43];
+ 44: out = in[44];
+ 45: out = in[45];
+ 46: out = in[46];
+ 47: out = in[47];
+ 48: out = in[48];
+ 49: out = in[49];
+ 50: out = in[50];
+ 51: out = in[51];
+ 52: out = in[52];
+ 53: out = in[53];
+ 54: out = in[54];
+ 55: out = in[55];
+ 56: out = in[56];
+ 57: out = in[57];
+ 58: out = in[58];
+ 59: out = in[59];
+ 60: out = in[60];
+ 61: out = in[61];
+ 62: out = in[62];
+ 63: out = in[63];
+ 64: out = in[64];
+ 65: out = in[65];
+ 66: out = in[66];
+ 67: out = in[67];
+ 68: out = in[68];
+ 69: out = in[69];
+ 70: out = in[70];
+ 71: out = in[71];
+ 72: out = in[72];
+ 73: out = in[73];
+ 74: out = in[74];
+ 75: out = in[75];
+ 76: out = in[76];
+ 77: out = in[77];
+ 78: out = in[78];
+ 79: out = in[79];
+ 80: out = in[80];
+ 81: out = in[81];
+ 82: out = in[82];
+ 83: out = in[83];
+ 84: out = in[84];
+ 85: out = in[85];
+ 86: out = in[86];
+ 87: out = in[87];
+ 88: out = in[88];
+ 89: out = in[89];
+ 90: out = in[90];
+ 91: out = in[91];
+ 92: out = in[92];
+ 93: out = in[93];
+ 94: out = in[94];
+ 95: out = in[95];
+ 96: out = in[96];
+ 97: out = in[97];
+ 98: out = in[98];
+ 99: out = in[99];
+ 100: out = in[100];
+ 101: out = in[101];
+ 102: out = in[102];
+ 103: out = in[103];
+ 104: out = in[104];
+ 105: out = in[105];
+ 106: out = in[106];
+ 107: out = in[107];
+ 108: out = in[108];
+ 109: out = in[109];
+ 110: out = in[110];
+ 111: out = in[111];
+ 112: out = in[112];
+ 113: out = in[113];
+ 114: out = in[114];
+ 115: out = in[115];
+ 116: out = in[116];
+ 117: out = in[117];
+ 118: out = in[118];
+ 119: out = in[119];
+ 120: out = in[120];
+ 121: out = in[121];
+ 122: out = in[122];
+ 123: out = in[123];
+ 124: out = in[124];
+ 125: out = in[125];
+ 126: out = in[126];
+ 127: out = in[127];
+ endcase
+endmodule
diff --git a/tests/hana/test_simulation_techmap_mux_8_test.v b/tests/hana/test_simulation_techmap_mux_8_test.v
new file mode 100644
index 000000000..f53a2c570
--- /dev/null
+++ b/tests/hana/test_simulation_techmap_mux_8_test.v
@@ -0,0 +1,14 @@
+module test(input [7:0] in, input [2:0] select, output reg out);
+
+always @( in or select)
+ case (select)
+ 0: out = in[0];
+ 1: out = in[1];
+ 2: out = in[2];
+ 3: out = in[3];
+ 4: out = in[4];
+ 5: out = in[5];
+ 6: out = in[6];
+ 7: out = in[7];
+ endcase
+endmodule
diff --git a/tests/hana/test_simulation_techmap_nand_19_tech.v b/tests/hana/test_simulation_techmap_nand_19_tech.v
new file mode 100644
index 000000000..6a119e1ee
--- /dev/null
+++ b/tests/hana/test_simulation_techmap_nand_19_tech.v
@@ -0,0 +1,11 @@
+module TECH_NAND18(input [17:0] in, output out);
+assign out = ~(&in);
+endmodule
+
+module TECH_NAND4(input [3:0] in, output out);
+assign out = ~(&in);
+endmodule
+
+module TECH_NAND2(input [1:0] in, output out);
+assign out = ~(&in);
+endmodule
diff --git a/tests/hana/test_simulation_techmap_nand_2_tech.v b/tests/hana/test_simulation_techmap_nand_2_tech.v
new file mode 100644
index 000000000..6a119e1ee
--- /dev/null
+++ b/tests/hana/test_simulation_techmap_nand_2_tech.v
@@ -0,0 +1,11 @@
+module TECH_NAND18(input [17:0] in, output out);
+assign out = ~(&in);
+endmodule
+
+module TECH_NAND4(input [3:0] in, output out);
+assign out = ~(&in);
+endmodule
+
+module TECH_NAND2(input [1:0] in, output out);
+assign out = ~(&in);
+endmodule
diff --git a/tests/hana/test_simulation_techmap_nand_5_tech.v b/tests/hana/test_simulation_techmap_nand_5_tech.v
new file mode 100644
index 000000000..6a119e1ee
--- /dev/null
+++ b/tests/hana/test_simulation_techmap_nand_5_tech.v
@@ -0,0 +1,11 @@
+module TECH_NAND18(input [17:0] in, output out);
+assign out = ~(&in);
+endmodule
+
+module TECH_NAND4(input [3:0] in, output out);
+assign out = ~(&in);
+endmodule
+
+module TECH_NAND2(input [1:0] in, output out);
+assign out = ~(&in);
+endmodule
diff --git a/tests/hana/test_simulation_techmap_nor_19_tech.v b/tests/hana/test_simulation_techmap_nor_19_tech.v
new file mode 100644
index 000000000..89fb2c7e8
--- /dev/null
+++ b/tests/hana/test_simulation_techmap_nor_19_tech.v
@@ -0,0 +1,11 @@
+module TECH_NOR18(input [17:0] in, output out);
+assign out = ~(|in);
+endmodule
+
+module TECH_NOR4(input [3:0] in, output out);
+assign out = ~(|in);
+endmodule
+
+module TECH_NOR2(input [1:0] in, output out);
+assign out = ~(|in);
+endmodule
diff --git a/tests/hana/test_simulation_techmap_nor_2_tech.v b/tests/hana/test_simulation_techmap_nor_2_tech.v
new file mode 100644
index 000000000..89fb2c7e8
--- /dev/null
+++ b/tests/hana/test_simulation_techmap_nor_2_tech.v
@@ -0,0 +1,11 @@
+module TECH_NOR18(input [17:0] in, output out);
+assign out = ~(|in);
+endmodule
+
+module TECH_NOR4(input [3:0] in, output out);
+assign out = ~(|in);
+endmodule
+
+module TECH_NOR2(input [1:0] in, output out);
+assign out = ~(|in);
+endmodule
diff --git a/tests/hana/test_simulation_techmap_nor_5_tech.v b/tests/hana/test_simulation_techmap_nor_5_tech.v
new file mode 100644
index 000000000..89fb2c7e8
--- /dev/null
+++ b/tests/hana/test_simulation_techmap_nor_5_tech.v
@@ -0,0 +1,11 @@
+module TECH_NOR18(input [17:0] in, output out);
+assign out = ~(|in);
+endmodule
+
+module TECH_NOR4(input [3:0] in, output out);
+assign out = ~(|in);
+endmodule
+
+module TECH_NOR2(input [1:0] in, output out);
+assign out = ~(|in);
+endmodule
diff --git a/tests/hana/test_simulation_techmap_or_19_tech.v b/tests/hana/test_simulation_techmap_or_19_tech.v
new file mode 100644
index 000000000..745d7b71c
--- /dev/null
+++ b/tests/hana/test_simulation_techmap_or_19_tech.v
@@ -0,0 +1,7 @@
+module TECH_OR18(input [17:0] in, output out);
+assign out = |in;
+endmodule
+
+module TECH_OR4(input [3:0] in, output out);
+assign out = |in;
+endmodule
diff --git a/tests/hana/test_simulation_techmap_or_5_tech.v b/tests/hana/test_simulation_techmap_or_5_tech.v
new file mode 100644
index 000000000..05c38b670
--- /dev/null
+++ b/tests/hana/test_simulation_techmap_or_5_tech.v
@@ -0,0 +1,3 @@
+module TECH_OR5(input [4:0] in, output out);
+assign out = |in;
+endmodule
diff --git a/tests/hana/test_simulation_techmap_xnor_2_tech.v b/tests/hana/test_simulation_techmap_xnor_2_tech.v
new file mode 100644
index 000000000..4eb05683f
--- /dev/null
+++ b/tests/hana/test_simulation_techmap_xnor_2_tech.v
@@ -0,0 +1,6 @@
+module TECH_XOR5(input [4:0] in, output out);
+assign out = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4];
+endmodule
+module TECH_XOR2(input [1:0] in, output out);
+assign out = in[0] ^ in[1];
+endmodule
diff --git a/tests/hana/test_simulation_techmap_xnor_5_tech.v b/tests/hana/test_simulation_techmap_xnor_5_tech.v
new file mode 100644
index 000000000..4eb05683f
--- /dev/null
+++ b/tests/hana/test_simulation_techmap_xnor_5_tech.v
@@ -0,0 +1,6 @@
+module TECH_XOR5(input [4:0] in, output out);
+assign out = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4];
+endmodule
+module TECH_XOR2(input [1:0] in, output out);
+assign out = in[0] ^ in[1];
+endmodule
diff --git a/tests/hana/test_simulation_techmap_xor_19_tech.v b/tests/hana/test_simulation_techmap_xor_19_tech.v
new file mode 100644
index 000000000..2042a0ad0
--- /dev/null
+++ b/tests/hana/test_simulation_techmap_xor_19_tech.v
@@ -0,0 +1,3 @@
+module TECH_XOR2(input [1:0] in, output out);
+assign out = in[0] ^ in[1];
+endmodule
diff --git a/tests/hana/test_simulation_techmap_xor_2_tech.v b/tests/hana/test_simulation_techmap_xor_2_tech.v
new file mode 100644
index 000000000..4eb05683f
--- /dev/null
+++ b/tests/hana/test_simulation_techmap_xor_2_tech.v
@@ -0,0 +1,6 @@
+module TECH_XOR5(input [4:0] in, output out);
+assign out = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4];
+endmodule
+module TECH_XOR2(input [1:0] in, output out);
+assign out = in[0] ^ in[1];
+endmodule
diff --git a/tests/hana/test_simulation_techmap_xor_5_tech.v b/tests/hana/test_simulation_techmap_xor_5_tech.v
new file mode 100644
index 000000000..4eb05683f
--- /dev/null
+++ b/tests/hana/test_simulation_techmap_xor_5_tech.v
@@ -0,0 +1,6 @@
+module TECH_XOR5(input [4:0] in, output out);
+assign out = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4];
+endmodule
+module TECH_XOR2(input [1:0] in, output out);
+assign out = in[0] ^ in[1];
+endmodule
diff --git a/tests/hana/test_simulation_tribuf_2_test.v b/tests/hana/test_simulation_tribuf_2_test.v
new file mode 100644
index 000000000..1e82aaf04
--- /dev/null
+++ b/tests/hana/test_simulation_tribuf_2_test.v
@@ -0,0 +1,3 @@
+module test(input [1:0] in, input enable, output [1:0] out);
+assign out = enable ? in : 2'bzz;
+endmodule
diff --git a/tests/hana/test_simulation_xnor_1_test.v b/tests/hana/test_simulation_xnor_1_test.v
new file mode 100644
index 000000000..adc6ae5ca
--- /dev/null
+++ b/tests/hana/test_simulation_xnor_1_test.v
@@ -0,0 +1,3 @@
+module test(input [1:0] in, output out);
+assign out = ~(in[0] ^ in[1]);
+endmodule
diff --git a/tests/hana/test_simulation_xnor_2_test.v b/tests/hana/test_simulation_xnor_2_test.v
new file mode 100644
index 000000000..701bcc775
--- /dev/null
+++ b/tests/hana/test_simulation_xnor_2_test.v
@@ -0,0 +1,3 @@
+module test(input [2:0] in, output out);
+assign out = ~(in[0] ^ in[1] ^ in[2]);
+endmodule
diff --git a/tests/hana/test_simulation_xnor_3_test.v b/tests/hana/test_simulation_xnor_3_test.v
new file mode 100644
index 000000000..a8c87cc62
--- /dev/null
+++ b/tests/hana/test_simulation_xnor_3_test.v
@@ -0,0 +1,3 @@
+module test(input [3:0] in, output out);
+assign out = ~(in[0] ^ in[1] ^ in[2] ^ in[3]);
+endmodule
diff --git a/tests/hana/test_simulation_xnor_4_test.v b/tests/hana/test_simulation_xnor_4_test.v
new file mode 100644
index 000000000..fa671ff93
--- /dev/null
+++ b/tests/hana/test_simulation_xnor_4_test.v
@@ -0,0 +1,3 @@
+module test(input [3:0] in, output out);
+xnor myxnor(out, in[0], in[1], in[2], in[3]);
+endmodule
diff --git a/tests/hana/test_simulation_xor_1_test.v b/tests/hana/test_simulation_xor_1_test.v
new file mode 100644
index 000000000..f6447f817
--- /dev/null
+++ b/tests/hana/test_simulation_xor_1_test.v
@@ -0,0 +1,3 @@
+module test(input [1:0] in, output out);
+assign out = (in[0] ^ in[1]);
+endmodule
diff --git a/tests/hana/test_simulation_xor_2_test.v b/tests/hana/test_simulation_xor_2_test.v
new file mode 100644
index 000000000..d94081df7
--- /dev/null
+++ b/tests/hana/test_simulation_xor_2_test.v
@@ -0,0 +1,3 @@
+module test(input [2:0] in, output out);
+assign out = (in[0] ^ in[1] ^ in[2]);
+endmodule
diff --git a/tests/hana/test_simulation_xor_3_test.v b/tests/hana/test_simulation_xor_3_test.v
new file mode 100644
index 000000000..cfa13187f
--- /dev/null
+++ b/tests/hana/test_simulation_xor_3_test.v
@@ -0,0 +1,3 @@
+module test(input [3:0] in, output out);
+assign out = (in[0] ^ in[1] ^ in[2] ^ in[3]);
+endmodule
diff --git a/tests/hana/test_simulation_xor_4_test.v b/tests/hana/test_simulation_xor_4_test.v
new file mode 100644
index 000000000..be6cab633
--- /dev/null
+++ b/tests/hana/test_simulation_xor_4_test.v
@@ -0,0 +1,3 @@
+module test(input [3:0] in, output out);
+xor myxor(out, in[0], in[1], in[2], in[3]);
+endmodule
diff --git a/tests/i2c_bench/i2c_master_bit_ctrl.v b/tests/i2c_bench/i2c_master_bit_ctrl.v
new file mode 100644
index 000000000..6594fd60c
--- /dev/null
+++ b/tests/i2c_bench/i2c_master_bit_ctrl.v
@@ -0,0 +1,576 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// WISHBONE rev.B2 compliant I2C Master bit-controller ////
+//// ////
+//// ////
+//// Author: Richard Herveille ////
+//// richard@asics.ws ////
+//// www.asics.ws ////
+//// ////
+//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 Richard Herveille ////
+//// richard@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: i2c_master_bit_ctrl.v,v 1.14 2009-01-20 10:25:29 rherveille Exp $
+//
+// $Date: 2009-01-20 10:25:29 $
+// $Revision: 1.14 $
+// $Author: rherveille $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: $
+// Revision 1.14 2009/01/20 10:25:29 rherveille
+// Added clock synchronization logic
+// Fixed slave_wait signal
+//
+// Revision 1.13 2009/01/19 20:29:26 rherveille
+// Fixed synopsys miss spell (synopsis)
+// Fixed cr[0] register width
+// Fixed ! usage instead of ~
+// Fixed bit controller parameter width to 18bits
+//
+// Revision 1.12 2006/09/04 09:08:13 rherveille
+// fixed short scl high pulse after clock stretch
+// fixed slave model not returning correct '(n)ack' signal
+//
+// Revision 1.11 2004/05/07 11:02:26 rherveille
+// Fixed a bug where the core would signal an arbitration lost (AL bit set), when another master controls the bus and the other master generates a STOP bit.
+//
+// Revision 1.10 2003/08/09 07:01:33 rherveille
+// Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
+// Fixed a potential bug in the byte controller's host-acknowledge generation.
+//
+// Revision 1.9 2003/03/10 14:26:37 rherveille
+// Fixed cmd_ack generation item (no bug).
+//
+// Revision 1.8 2003/02/05 00:06:10 rherveille
+// Fixed a bug where the core would trigger an erroneous 'arbitration lost' interrupt after being reset, when the reset pulse width < 3 clk cycles.
+//
+// Revision 1.7 2002/12/26 16:05:12 rherveille
+// Small code simplifications
+//
+// Revision 1.6 2002/12/26 15:02:32 rherveille
+// Core is now a Multimaster I2C controller
+//
+// Revision 1.5 2002/11/30 22:24:40 rherveille
+// Cleaned up code
+//
+// Revision 1.4 2002/10/30 18:10:07 rherveille
+// Fixed some reported minor start/stop generation timing issuess.
+//
+// Revision 1.3 2002/06/15 07:37:03 rherveille
+// Fixed a small timing bug in the bit controller.\nAdded verilog simulation environment.
+//
+// Revision 1.2 2001/11/05 11:59:25 rherveille
+// Fixed wb_ack_o generation bug.
+// Fixed bug in the byte_controller statemachine.
+// Added headers.
+//
+
+//
+/////////////////////////////////////
+// Bit controller section
+/////////////////////////////////////
+//
+// Translate simple commands into SCL/SDA transitions
+// Each command has 5 states, A/B/C/D/idle
+//
+// start: SCL ~~~~~~~~~~\____
+// SDA ~~~~~~~~\______
+// x | A | B | C | D | i
+//
+// repstart SCL ____/~~~~\___
+// SDA __/~~~\______
+// x | A | B | C | D | i
+//
+// stop SCL ____/~~~~~~~~
+// SDA ==\____/~~~~~
+// x | A | B | C | D | i
+//
+//- write SCL ____/~~~~\____
+// SDA ==X=========X=
+// x | A | B | C | D | i
+//
+//- read SCL ____/~~~~\____
+// SDA XXXX=====XXXX
+// x | A | B | C | D | i
+//
+
+// Timing: Normal mode Fast mode
+///////////////////////////////////////////////////////////////////////
+// Fscl 100KHz 400KHz
+// Th_scl 4.0us 0.6us High period of SCL
+// Tl_scl 4.7us 1.3us Low period of SCL
+// Tsu:sta 4.7us 0.6us setup time for a repeated start condition
+// Tsu:sto 4.0us 0.6us setup time for a stop conditon
+// Tbuf 4.7us 1.3us Bus free time between a stop and start condition
+//
+
+// synopsys translate_off
+`include "timescale.v"
+// synopsys translate_on
+
+`include "i2c_master_defines.v"
+
+module i2c_master_bit_ctrl (
+ input clk, // system clock
+ input rst, // synchronous active high reset
+ input nReset, // asynchronous active low reset
+ input ena, // core enable signal
+
+ input [15:0] clk_cnt, // clock prescale value
+
+ input [ 3:0] cmd, // command (from byte controller)
+ output reg cmd_ack, // command complete acknowledge
+ output reg busy, // i2c bus busy
+ output reg al, // i2c bus arbitration lost
+
+ input din,
+ output reg dout,
+
+ input scl_i, // i2c clock line input
+ output scl_o, // i2c clock line output
+ output reg scl_oen, // i2c clock line output enable (active low)
+ input sda_i, // i2c data line input
+ output sda_o, // i2c data line output
+ output reg sda_oen // i2c data line output enable (active low)
+);
+
+
+ //
+ // variable declarations
+ //
+
+ reg [ 1:0] cSCL, cSDA; // capture SCL and SDA
+ reg [ 2:0] fSCL, fSDA; // SCL and SDA filter inputs
+ reg sSCL, sSDA; // filtered and synchronized SCL and SDA inputs
+ reg dSCL, dSDA; // delayed versions of sSCL and sSDA
+ reg dscl_oen; // delayed scl_oen
+ reg sda_chk; // check SDA output (Multi-master arbitration)
+ reg clk_en; // clock generation signals
+ reg slave_wait; // slave inserts wait states
+ reg [15:0] cnt; // clock divider counter (synthesis)
+ reg [13:0] filter_cnt; // clock divider for filter
+
+
+ // state machine variable
+ reg [17:0] c_state; // synopsys enum_state
+
+ //
+ // module body
+ //
+
+ // whenever the slave is not ready it can delay the cycle by pulling SCL low
+ // delay scl_oen
+ always @(posedge clk)
+ dscl_oen <= scl_oen;
+
+ // slave_wait is asserted when master wants to drive SCL high, but the slave pulls it low
+ // slave_wait remains asserted until the slave releases SCL
+ always @(posedge clk or negedge nReset)
+ if (!nReset) slave_wait <= 1'b0;
+ else slave_wait <= (scl_oen & ~dscl_oen & ~sSCL) | (slave_wait & ~sSCL);
+
+ // master drives SCL high, but another master pulls it low
+ // master start counting down its low cycle now (clock synchronization)
+ wire scl_sync = dSCL & ~sSCL & scl_oen;
+
+
+ // generate clk enable signal
+ always @(posedge clk or negedge nReset)
+ if (~nReset)
+ begin
+ cnt <= 16'h0;
+ clk_en <= 1'b1;
+ end
+ else if (rst || ~|cnt || !ena || scl_sync)
+ begin
+ cnt <= clk_cnt;
+ clk_en <= 1'b1;
+ end
+ else if (slave_wait)
+ begin
+ cnt <= cnt;
+ clk_en <= 1'b0;
+ end
+ else
+ begin
+ cnt <= cnt - 16'h1;
+ clk_en <= 1'b0;
+ end
+
+
+ // generate bus status controller
+
+ // capture SDA and SCL
+ // reduce metastability risk
+ always @(posedge clk or negedge nReset)
+ if (!nReset)
+ begin
+ cSCL <= 2'b00;
+ cSDA <= 2'b00;
+ end
+ else if (rst)
+ begin
+ cSCL <= 2'b00;
+ cSDA <= 2'b00;
+ end
+ else
+ begin
+ cSCL <= {cSCL[0],scl_i};
+ cSDA <= {cSDA[0],sda_i};
+ end
+
+
+ // filter SCL and SDA signals; (attempt to) remove glitches
+ always @(posedge clk or negedge nReset)
+ if (!nReset ) filter_cnt <= 14'h0;
+ else if (rst || !ena ) filter_cnt <= 14'h0;
+ else if (~|filter_cnt) filter_cnt <= clk_cnt[15:2]; //16x I2C bus frequency
+ else filter_cnt <= filter_cnt -1;
+
+
+ always @(posedge clk or negedge nReset)
+ if (!nReset)
+ begin
+ fSCL <= 3'b111;
+ fSDA <= 3'b111;
+ end
+ else if (rst)
+ begin
+ fSCL <= 3'b111;
+ fSDA <= 3'b111;
+ end
+ else if (~|filter_cnt)
+ begin
+ fSCL <= {fSCL[1:0],cSCL[1]};
+ fSDA <= {fSDA[1:0],cSDA[1]};
+ end
+
+
+ // generate filtered SCL and SDA signals
+ always @(posedge clk or negedge nReset)
+ if (~nReset)
+ begin
+ sSCL <= 1'b1;
+ sSDA <= 1'b1;
+
+ dSCL <= 1'b1;
+ dSDA <= 1'b1;
+ end
+ else if (rst)
+ begin
+ sSCL <= 1'b1;
+ sSDA <= 1'b1;
+
+ dSCL <= 1'b1;
+ dSDA <= 1'b1;
+ end
+ else
+ begin
+ sSCL <= &fSCL[2:1] | &fSCL[1:0] | (fSCL[2] & fSCL[0]);
+ sSDA <= &fSDA[2:1] | &fSDA[1:0] | (fSDA[2] & fSDA[0]);
+
+ dSCL <= sSCL;
+ dSDA <= sSDA;
+ end
+
+ // detect start condition => detect falling edge on SDA while SCL is high
+ // detect stop condition => detect rising edge on SDA while SCL is high
+ reg sta_condition;
+ reg sto_condition;
+ always @(posedge clk or negedge nReset)
+ if (~nReset)
+ begin
+ sta_condition <= 1'b0;
+ sto_condition <= 1'b0;
+ end
+ else if (rst)
+ begin
+ sta_condition <= 1'b0;
+ sto_condition <= 1'b0;
+ end
+ else
+ begin
+ sta_condition <= ~sSDA & dSDA & sSCL;
+ sto_condition <= sSDA & ~dSDA & sSCL;
+ end
+
+
+ // generate i2c bus busy signal
+ always @(posedge clk or negedge nReset)
+ if (!nReset) busy <= 1'b0;
+ else if (rst ) busy <= 1'b0;
+ else busy <= (sta_condition | busy) & ~sto_condition;
+
+
+ // generate arbitration lost signal
+ // aribitration lost when:
+ // 1) master drives SDA high, but the i2c bus is low
+ // 2) stop detected while not requested
+ reg cmd_stop;
+ always @(posedge clk or negedge nReset)
+ if (~nReset)
+ cmd_stop <= 1'b0;
+ else if (rst)
+ cmd_stop <= 1'b0;
+ else if (clk_en)
+ cmd_stop <= cmd == `I2C_CMD_STOP;
+
+ always @(posedge clk or negedge nReset)
+ if (~nReset)
+ al <= 1'b0;
+ else if (rst)
+ al <= 1'b0;
+ else
+ al <= (sda_chk & ~sSDA & sda_oen) | (|c_state & sto_condition & ~cmd_stop);
+
+
+ // generate dout signal (store SDA on rising edge of SCL)
+ always @(posedge clk)
+ if (sSCL & ~dSCL) dout <= sSDA;
+
+
+ // generate statemachine
+
+ // nxt_state decoder
+ parameter [17:0] idle = 18'b0_0000_0000_0000_0000;
+ parameter [17:0] start_a = 18'b0_0000_0000_0000_0001;
+ parameter [17:0] start_b = 18'b0_0000_0000_0000_0010;
+ parameter [17:0] start_c = 18'b0_0000_0000_0000_0100;
+ parameter [17:0] start_d = 18'b0_0000_0000_0000_1000;
+ parameter [17:0] start_e = 18'b0_0000_0000_0001_0000;
+ parameter [17:0] stop_a = 18'b0_0000_0000_0010_0000;
+ parameter [17:0] stop_b = 18'b0_0000_0000_0100_0000;
+ parameter [17:0] stop_c = 18'b0_0000_0000_1000_0000;
+ parameter [17:0] stop_d = 18'b0_0000_0001_0000_0000;
+ parameter [17:0] rd_a = 18'b0_0000_0010_0000_0000;
+ parameter [17:0] rd_b = 18'b0_0000_0100_0000_0000;
+ parameter [17:0] rd_c = 18'b0_0000_1000_0000_0000;
+ parameter [17:0] rd_d = 18'b0_0001_0000_0000_0000;
+ parameter [17:0] wr_a = 18'b0_0010_0000_0000_0000;
+ parameter [17:0] wr_b = 18'b0_0100_0000_0000_0000;
+ parameter [17:0] wr_c = 18'b0_1000_0000_0000_0000;
+ parameter [17:0] wr_d = 18'b1_0000_0000_0000_0000;
+
+ always @(posedge clk or negedge nReset)
+ if (!nReset)
+ begin
+ c_state <= idle;
+ cmd_ack <= 1'b0;
+ scl_oen <= 1'b1;
+ sda_oen <= 1'b1;
+ sda_chk <= 1'b0;
+ end
+ else if (rst | al)
+ begin
+ c_state <= idle;
+ cmd_ack <= 1'b0;
+ scl_oen <= 1'b1;
+ sda_oen <= 1'b1;
+ sda_chk <= 1'b0;
+ end
+ else
+ begin
+ cmd_ack <= 1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle
+
+ if (clk_en)
+ case (c_state) // synopsys full_case parallel_case
+ // idle state
+ idle:
+ begin
+ case (cmd) // synopsys full_case parallel_case
+ `I2C_CMD_START: c_state <= start_a;
+ `I2C_CMD_STOP: c_state <= stop_a;
+ `I2C_CMD_WRITE: c_state <= wr_a;
+ `I2C_CMD_READ: c_state <= rd_a;
+ default: c_state <= idle;
+ endcase
+
+ scl_oen <= scl_oen; // keep SCL in same state
+ sda_oen <= sda_oen; // keep SDA in same state
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ // start
+ start_a:
+ begin
+ c_state <= start_b;
+ scl_oen <= scl_oen; // keep SCL in same state
+ sda_oen <= 1'b1; // set SDA high
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ start_b:
+ begin
+ c_state <= start_c;
+ scl_oen <= 1'b1; // set SCL high
+ sda_oen <= 1'b1; // keep SDA high
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ start_c:
+ begin
+ c_state <= start_d;
+ scl_oen <= 1'b1; // keep SCL high
+ sda_oen <= 1'b0; // set SDA low
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ start_d:
+ begin
+ c_state <= start_e;
+ scl_oen <= 1'b1; // keep SCL high
+ sda_oen <= 1'b0; // keep SDA low
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ start_e:
+ begin
+ c_state <= idle;
+ cmd_ack <= 1'b1;
+ scl_oen <= 1'b0; // set SCL low
+ sda_oen <= 1'b0; // keep SDA low
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ // stop
+ stop_a:
+ begin
+ c_state <= stop_b;
+ scl_oen <= 1'b0; // keep SCL low
+ sda_oen <= 1'b0; // set SDA low
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ stop_b:
+ begin
+ c_state <= stop_c;
+ scl_oen <= 1'b1; // set SCL high
+ sda_oen <= 1'b0; // keep SDA low
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ stop_c:
+ begin
+ c_state <= stop_d;
+ scl_oen <= 1'b1; // keep SCL high
+ sda_oen <= 1'b0; // keep SDA low
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ stop_d:
+ begin
+ c_state <= idle;
+ cmd_ack <= 1'b1;
+ scl_oen <= 1'b1; // keep SCL high
+ sda_oen <= 1'b1; // set SDA high
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ // read
+ rd_a:
+ begin
+ c_state <= rd_b;
+ scl_oen <= 1'b0; // keep SCL low
+ sda_oen <= 1'b1; // tri-state SDA
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ rd_b:
+ begin
+ c_state <= rd_c;
+ scl_oen <= 1'b1; // set SCL high
+ sda_oen <= 1'b1; // keep SDA tri-stated
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ rd_c:
+ begin
+ c_state <= rd_d;
+ scl_oen <= 1'b1; // keep SCL high
+ sda_oen <= 1'b1; // keep SDA tri-stated
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ rd_d:
+ begin
+ c_state <= idle;
+ cmd_ack <= 1'b1;
+ scl_oen <= 1'b0; // set SCL low
+ sda_oen <= 1'b1; // keep SDA tri-stated
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ // write
+ wr_a:
+ begin
+ c_state <= wr_b;
+ scl_oen <= 1'b0; // keep SCL low
+ sda_oen <= din; // set SDA
+ sda_chk <= 1'b0; // don't check SDA output (SCL low)
+ end
+
+ wr_b:
+ begin
+ c_state <= wr_c;
+ scl_oen <= 1'b1; // set SCL high
+ sda_oen <= din; // keep SDA
+ sda_chk <= 1'b0; // don't check SDA output yet
+ // allow some time for SDA and SCL to settle
+ end
+
+ wr_c:
+ begin
+ c_state <= wr_d;
+ scl_oen <= 1'b1; // keep SCL high
+ sda_oen <= din;
+ sda_chk <= 1'b1; // check SDA output
+ end
+
+ wr_d:
+ begin
+ c_state <= idle;
+ cmd_ack <= 1'b1;
+ scl_oen <= 1'b0; // set SCL low
+ sda_oen <= din;
+ sda_chk <= 1'b0; // don't check SDA output (SCL low)
+ end
+
+ endcase
+ end
+
+
+ // assign scl and sda output (always gnd)
+ assign scl_o = 1'b0;
+ assign sda_o = 1'b0;
+
+endmodule
diff --git a/tests/i2c_bench/i2c_master_byte_ctrl.v b/tests/i2c_bench/i2c_master_byte_ctrl.v
new file mode 100644
index 000000000..513953a82
--- /dev/null
+++ b/tests/i2c_bench/i2c_master_byte_ctrl.v
@@ -0,0 +1,344 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// WISHBONE rev.B2 compliant I2C Master byte-controller ////
+//// ////
+//// ////
+//// Author: Richard Herveille ////
+//// richard@asics.ws ////
+//// www.asics.ws ////
+//// ////
+//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 Richard Herveille ////
+//// richard@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: i2c_master_byte_ctrl.v,v 1.8 2009-01-19 20:29:26 rherveille Exp $
+//
+// $Date: 2009-01-19 20:29:26 $
+// $Revision: 1.8 $
+// $Author: rherveille $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: not supported by cvs2svn $
+// Revision 1.7 2004/02/18 11:40:46 rherveille
+// Fixed a potential bug in the statemachine. During a 'stop' 2 cmd_ack signals were generated. Possibly canceling a new start command.
+//
+// Revision 1.6 2003/08/09 07:01:33 rherveille
+// Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
+// Fixed a potential bug in the byte controller's host-acknowledge generation.
+//
+// Revision 1.5 2002/12/26 15:02:32 rherveille
+// Core is now a Multimaster I2C controller
+//
+// Revision 1.4 2002/11/30 22:24:40 rherveille
+// Cleaned up code
+//
+// Revision 1.3 2001/11/05 11:59:25 rherveille
+// Fixed wb_ack_o generation bug.
+// Fixed bug in the byte_controller statemachine.
+// Added headers.
+//
+
+// synopsys translate_off
+`include "timescale.v"
+// synopsys translate_on
+
+`include "i2c_master_defines.v"
+
+module i2c_master_byte_ctrl (
+ clk, rst, nReset, ena, clk_cnt, start, stop, read, write, ack_in, din,
+ cmd_ack, ack_out, dout, i2c_busy, i2c_al, scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen );
+
+ //
+ // inputs & outputs
+ //
+ input clk; // master clock
+ input rst; // synchronous active high reset
+ input nReset; // asynchronous active low reset
+ input ena; // core enable signal
+
+ input [15:0] clk_cnt; // 4x SCL
+
+ // control inputs
+ input start;
+ input stop;
+ input read;
+ input write;
+ input ack_in;
+ input [7:0] din;
+
+ // status outputs
+ output cmd_ack;
+ reg cmd_ack;
+ output ack_out;
+ reg ack_out;
+ output i2c_busy;
+ output i2c_al;
+ output [7:0] dout;
+
+ // I2C signals
+ input scl_i;
+ output scl_o;
+ output scl_oen;
+ input sda_i;
+ output sda_o;
+ output sda_oen;
+
+
+ //
+ // Variable declarations
+ //
+
+ // statemachine
+ parameter [4:0] ST_IDLE = 5'b0_0000;
+ parameter [4:0] ST_START = 5'b0_0001;
+ parameter [4:0] ST_READ = 5'b0_0010;
+ parameter [4:0] ST_WRITE = 5'b0_0100;
+ parameter [4:0] ST_ACK = 5'b0_1000;
+ parameter [4:0] ST_STOP = 5'b1_0000;
+
+ // signals for bit_controller
+ reg [3:0] core_cmd;
+ reg core_txd;
+ wire core_ack, core_rxd;
+
+ // signals for shift register
+ reg [7:0] sr; //8bit shift register
+ reg shift, ld;
+
+ // signals for state machine
+ wire go;
+ reg [2:0] dcnt;
+ wire cnt_done;
+
+ //
+ // Module body
+ //
+
+ // hookup bit_controller
+ i2c_master_bit_ctrl bit_controller (
+ .clk ( clk ),
+ .rst ( rst ),
+ .nReset ( nReset ),
+ .ena ( ena ),
+ .clk_cnt ( clk_cnt ),
+ .cmd ( core_cmd ),
+ .cmd_ack ( core_ack ),
+ .busy ( i2c_busy ),
+ .al ( i2c_al ),
+ .din ( core_txd ),
+ .dout ( core_rxd ),
+ .scl_i ( scl_i ),
+ .scl_o ( scl_o ),
+ .scl_oen ( scl_oen ),
+ .sda_i ( sda_i ),
+ .sda_o ( sda_o ),
+ .sda_oen ( sda_oen )
+ );
+
+ // generate go-signal
+ assign go = (read | write | stop) & ~cmd_ack;
+
+ // assign dout output to shift-register
+ assign dout = sr;
+
+ // generate shift register
+ always @(posedge clk or negedge nReset)
+ if (!nReset)
+ sr <= 8'h0;
+ else if (rst)
+ sr <= 8'h0;
+ else if (ld)
+ sr <= din;
+ else if (shift)
+ sr <= {sr[6:0], core_rxd};
+
+ // generate counter
+ always @(posedge clk or negedge nReset)
+ if (!nReset)
+ dcnt <= 3'h0;
+ else if (rst)
+ dcnt <= 3'h0;
+ else if (ld)
+ dcnt <= 3'h7;
+ else if (shift)
+ dcnt <= dcnt - 3'h1;
+
+ assign cnt_done = ~(|dcnt);
+
+ //
+ // state machine
+ //
+ reg [4:0] c_state; // synopsys enum_state
+
+ always @(posedge clk or negedge nReset)
+ if (!nReset)
+ begin
+ core_cmd <= `I2C_CMD_NOP;
+ core_txd <= 1'b0;
+ shift <= 1'b0;
+ ld <= 1'b0;
+ cmd_ack <= 1'b0;
+ c_state <= ST_IDLE;
+ ack_out <= 1'b0;
+ end
+ else if (rst | i2c_al)
+ begin
+ core_cmd <= `I2C_CMD_NOP;
+ core_txd <= 1'b0;
+ shift <= 1'b0;
+ ld <= 1'b0;
+ cmd_ack <= 1'b0;
+ c_state <= ST_IDLE;
+ ack_out <= 1'b0;
+ end
+ else
+ begin
+ // initially reset all signals
+ core_txd <= sr[7];
+ shift <= 1'b0;
+ ld <= 1'b0;
+ cmd_ack <= 1'b0;
+
+ case (c_state) // synopsys full_case parallel_case
+ ST_IDLE:
+ if (go)
+ begin
+ if (start)
+ begin
+ c_state <= ST_START;
+ core_cmd <= `I2C_CMD_START;
+ end
+ else if (read)
+ begin
+ c_state <= ST_READ;
+ core_cmd <= `I2C_CMD_READ;
+ end
+ else if (write)
+ begin
+ c_state <= ST_WRITE;
+ core_cmd <= `I2C_CMD_WRITE;
+ end
+ else // stop
+ begin
+ c_state <= ST_STOP;
+ core_cmd <= `I2C_CMD_STOP;
+ end
+
+ ld <= 1'b1;
+ end
+
+ ST_START:
+ if (core_ack)
+ begin
+ if (read)
+ begin
+ c_state <= ST_READ;
+ core_cmd <= `I2C_CMD_READ;
+ end
+ else
+ begin
+ c_state <= ST_WRITE;
+ core_cmd <= `I2C_CMD_WRITE;
+ end
+
+ ld <= 1'b1;
+ end
+
+ ST_WRITE:
+ if (core_ack)
+ if (cnt_done)
+ begin
+ c_state <= ST_ACK;
+ core_cmd <= `I2C_CMD_READ;
+ end
+ else
+ begin
+ c_state <= ST_WRITE; // stay in same state
+ core_cmd <= `I2C_CMD_WRITE; // write next bit
+ shift <= 1'b1;
+ end
+
+ ST_READ:
+ if (core_ack)
+ begin
+ if (cnt_done)
+ begin
+ c_state <= ST_ACK;
+ core_cmd <= `I2C_CMD_WRITE;
+ end
+ else
+ begin
+ c_state <= ST_READ; // stay in same state
+ core_cmd <= `I2C_CMD_READ; // read next bit
+ end
+
+ shift <= 1'b1;
+ core_txd <= ack_in;
+ end
+
+ ST_ACK:
+ if (core_ack)
+ begin
+ if (stop)
+ begin
+ c_state <= ST_STOP;
+ core_cmd <= `I2C_CMD_STOP;
+ end
+ else
+ begin
+ c_state <= ST_IDLE;
+ core_cmd <= `I2C_CMD_NOP;
+
+ // generate command acknowledge signal
+ cmd_ack <= 1'b1;
+ end
+
+ // assign ack_out output to bit_controller_rxd (contains last received bit)
+ ack_out <= core_rxd;
+
+ core_txd <= 1'b1;
+ end
+ else
+ core_txd <= ack_in;
+
+ ST_STOP:
+ if (core_ack)
+ begin
+ c_state <= ST_IDLE;
+ core_cmd <= `I2C_CMD_NOP;
+
+ // generate command acknowledge signal
+ cmd_ack <= 1'b1;
+ end
+
+ endcase
+ end
+endmodule
diff --git a/tests/i2c_bench/i2c_master_defines.v b/tests/i2c_bench/i2c_master_defines.v
new file mode 100644
index 000000000..e81c546a6
--- /dev/null
+++ b/tests/i2c_bench/i2c_master_defines.v
@@ -0,0 +1,59 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// WISHBONE rev.B2 compliant I2C Master controller defines ////
+//// ////
+//// ////
+//// Author: Richard Herveille ////
+//// richard@asics.ws ////
+//// www.asics.ws ////
+//// ////
+//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 Richard Herveille ////
+//// richard@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: i2c_master_defines.v,v 1.3 2001-11-05 11:59:25 rherveille Exp $
+//
+// $Date: 2001-11-05 11:59:25 $
+// $Revision: 1.3 $
+// $Author: rherveille $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: not supported by cvs2svn $
+
+
+// I2C registers wishbone addresses
+
+// bitcontroller states
+`define I2C_CMD_NOP 4'b0000
+`define I2C_CMD_START 4'b0001
+`define I2C_CMD_STOP 4'b0010
+`define I2C_CMD_WRITE 4'b0100
+`define I2C_CMD_READ 4'b1000
diff --git a/tests/i2c_bench/i2c_master_top.v b/tests/i2c_bench/i2c_master_top.v
new file mode 100644
index 000000000..5e9cde7e0
--- /dev/null
+++ b/tests/i2c_bench/i2c_master_top.v
@@ -0,0 +1,301 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// WISHBONE revB.2 compliant I2C Master controller Top-level ////
+//// ////
+//// ////
+//// Author: Richard Herveille ////
+//// richard@asics.ws ////
+//// www.asics.ws ////
+//// ////
+//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 Richard Herveille ////
+//// richard@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: i2c_master_top.v,v 1.12 2009-01-19 20:29:26 rherveille Exp $
+//
+// $Date: 2009-01-19 20:29:26 $
+// $Revision: 1.12 $
+// $Author: rherveille $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// Revision 1.11 2005/02/27 09:26:24 rherveille
+// Fixed register overwrite issue.
+// Removed full_case pragma, replaced it by a default statement.
+//
+// Revision 1.10 2003/09/01 10:34:38 rherveille
+// Fix a blocking vs. non-blocking error in the wb_dat output mux.
+//
+// Revision 1.9 2003/01/09 16:44:45 rherveille
+// Fixed a bug in the Command Register declaration.
+//
+// Revision 1.8 2002/12/26 16:05:12 rherveille
+// Small code simplifications
+//
+// Revision 1.7 2002/12/26 15:02:32 rherveille
+// Core is now a Multimaster I2C controller
+//
+// Revision 1.6 2002/11/30 22:24:40 rherveille
+// Cleaned up code
+//
+// Revision 1.5 2001/11/10 10:52:55 rherveille
+// Changed PRER reset value from 0x0000 to 0xffff, conform specs.
+//
+
+// synopsys translate_off
+`include "timescale.v"
+// synopsys translate_on
+
+`include "i2c_master_defines.v"
+
+module i2c_master_top(
+ wb_clk_i, wb_rst_i, arst_i, wb_adr_i, wb_dat_i, wb_dat_o,
+ wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_inta_o,
+ scl_pad_i, scl_pad_o, scl_padoen_o, sda_pad_i, sda_pad_o, sda_padoen_o );
+
+ // parameters
+ parameter ARST_LVL = 1'b0; // asynchronous reset level
+
+ //
+ // inputs & outputs
+ //
+
+ // wishbone signals
+ input wb_clk_i; // master clock input
+ input wb_rst_i; // synchronous active high reset
+ input arst_i; // asynchronous reset
+ input [2:0] wb_adr_i; // lower address bits
+ input [7:0] wb_dat_i; // databus input
+ output [7:0] wb_dat_o; // databus output
+ input wb_we_i; // write enable input
+ input wb_stb_i; // stobe/core select signal
+ input wb_cyc_i; // valid bus cycle input
+ output wb_ack_o; // bus cycle acknowledge output
+ output wb_inta_o; // interrupt request signal output
+
+ reg [7:0] wb_dat_o;
+ reg wb_ack_o;
+ reg wb_inta_o;
+
+ // I2C signals
+ // i2c clock line
+ input scl_pad_i; // SCL-line input
+ output scl_pad_o; // SCL-line output (always 1'b0)
+ output scl_padoen_o; // SCL-line output enable (active low)
+
+ // i2c data line
+ input sda_pad_i; // SDA-line input
+ output sda_pad_o; // SDA-line output (always 1'b0)
+ output sda_padoen_o; // SDA-line output enable (active low)
+
+
+ //
+ // variable declarations
+ //
+
+ // registers
+ reg [15:0] prer; // clock prescale register
+ reg [ 7:0] ctr; // control register
+ reg [ 7:0] txr; // transmit register
+ wire [ 7:0] rxr; // receive register
+ reg [ 7:0] cr; // command register
+ wire [ 7:0] sr; // status register
+
+ // done signal: command completed, clear command register
+ wire done;
+
+ // core enable signal
+ wire core_en;
+ wire ien;
+
+ // status register signals
+ wire irxack;
+ reg rxack; // received aknowledge from slave
+ reg tip; // transfer in progress
+ reg irq_flag; // interrupt pending flag
+ wire i2c_busy; // bus busy (start signal detected)
+ wire i2c_al; // i2c bus arbitration lost
+ reg al; // status register arbitration lost bit
+
+ //
+ // module body
+ //
+
+ // generate internal reset
+ wire rst_i = arst_i ^ ARST_LVL;
+
+ // generate wishbone signals
+ wire wb_wacc = wb_we_i & wb_ack_o;
+
+ // generate acknowledge output signal
+ always @(posedge wb_clk_i)
+ wb_ack_o <= wb_cyc_i & wb_stb_i & ~wb_ack_o; // because timing is always honored
+
+ // assign DAT_O
+ always @(posedge wb_clk_i)
+ begin
+ case (wb_adr_i) // synopsys parallel_case
+ 3'b000: wb_dat_o <= prer[ 7:0];
+ 3'b001: wb_dat_o <= prer[15:8];
+ 3'b010: wb_dat_o <= ctr;
+ 3'b011: wb_dat_o <= rxr; // write is transmit register (txr)
+ 3'b100: wb_dat_o <= sr; // write is command register (cr)
+ 3'b101: wb_dat_o <= txr;
+ 3'b110: wb_dat_o <= cr;
+ 3'b111: wb_dat_o <= 0; // reserved
+ default: wb_dat_o <= 16'bx;
+ endcase
+ end
+
+ // generate registers
+ always @(posedge wb_clk_i or negedge rst_i)
+ if (!rst_i)
+ begin
+ prer <= 16'hffff;
+ ctr <= 8'h0;
+ txr <= 8'h0;
+ end
+ else if (wb_rst_i)
+ begin
+ prer <= 16'hffff;
+ ctr <= 8'h0;
+ txr <= 8'h0;
+ end
+ else
+ if (wb_wacc)
+ case (wb_adr_i) // synopsys parallel_case
+ 3'b000 : prer [ 7:0] <= wb_dat_i;
+ 3'b001 : prer [15:8] <= wb_dat_i;
+ 3'b010 : ctr <= wb_dat_i;
+ 3'b011 : txr <= wb_dat_i;
+ default: ;
+ endcase
+
+ // generate command register (special case)
+ always @(posedge wb_clk_i or negedge rst_i)
+ if (!rst_i)
+ cr <= 8'h0;
+ else if (wb_rst_i)
+ cr <= 8'h0;
+ else if (wb_wacc)
+ begin
+ if (core_en & (wb_adr_i == 3'b100) )
+ cr <= wb_dat_i;
+ end
+ else
+ begin
+ if (done | i2c_al)
+ cr[7:4] <= 4'h0; // clear command bits when done
+ // or when aribitration lost
+ cr[2:1] <= 2'b0; // reserved bits
+ cr[0] <= 1'b0; // clear IRQ_ACK bit
+ end
+
+
+ // decode command register
+ wire sta = cr[7];
+ wire sto = cr[6];
+ wire rd = cr[5];
+ wire wr = cr[4];
+ wire ack = cr[3];
+ wire iack = cr[0];
+
+ // decode control register
+ assign core_en = ctr[7];
+ assign ien = ctr[6];
+
+ // hookup byte controller block
+ i2c_master_byte_ctrl byte_controller (
+ .clk ( wb_clk_i ),
+ .rst ( wb_rst_i ),
+ .nReset ( rst_i ),
+ .ena ( core_en ),
+ .clk_cnt ( prer ),
+ .start ( sta ),
+ .stop ( sto ),
+ .read ( rd ),
+ .write ( wr ),
+ .ack_in ( ack ),
+ .din ( txr ),
+ .cmd_ack ( done ),
+ .ack_out ( irxack ),
+ .dout ( rxr ),
+ .i2c_busy ( i2c_busy ),
+ .i2c_al ( i2c_al ),
+ .scl_i ( scl_pad_i ),
+ .scl_o ( scl_pad_o ),
+ .scl_oen ( scl_padoen_o ),
+ .sda_i ( sda_pad_i ),
+ .sda_o ( sda_pad_o ),
+ .sda_oen ( sda_padoen_o )
+ );
+
+ // status register block + interrupt request signal
+ always @(posedge wb_clk_i or negedge rst_i)
+ if (!rst_i)
+ begin
+ al <= 1'b0;
+ rxack <= 1'b0;
+ tip <= 1'b0;
+ irq_flag <= 1'b0;
+ end
+ else if (wb_rst_i)
+ begin
+ al <= 1'b0;
+ rxack <= 1'b0;
+ tip <= 1'b0;
+ irq_flag <= 1'b0;
+ end
+ else
+ begin
+ al <= i2c_al | (al & ~sta);
+ rxack <= irxack;
+ tip <= (rd | wr);
+ irq_flag <= (done | i2c_al | irq_flag) & ~iack; // interrupt request flag is always generated
+ end
+
+ // generate interrupt request signals
+ always @(posedge wb_clk_i or negedge rst_i)
+ if (!rst_i)
+ wb_inta_o <= 1'b0;
+ else if (wb_rst_i)
+ wb_inta_o <= 1'b0;
+ else
+ wb_inta_o <= irq_flag && ien; // interrupt signal is only generated when IEN (interrupt enable bit is set)
+
+ // assign status register bits
+ assign sr[7] = rxack;
+ assign sr[6] = i2c_busy;
+ assign sr[5] = al;
+ assign sr[4:2] = 3'h0; // reserved
+ assign sr[1] = tip;
+ assign sr[0] = irq_flag;
+
+endmodule
diff --git a/tests/i2c_bench/i2c_slave_model.v b/tests/i2c_bench/i2c_slave_model.v
new file mode 100644
index 000000000..02b7572cf
--- /dev/null
+++ b/tests/i2c_bench/i2c_slave_model.v
@@ -0,0 +1,361 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// WISHBONE rev.B2 compliant synthesizable I2C Slave model ////
+//// ////
+//// ////
+//// Authors: Richard Herveille (richard@asics.ws) www.asics.ws ////
+//// John Sheahan (jrsheahan@optushome.com.au) ////
+//// ////
+//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001,2002 Richard Herveille ////
+//// richard@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: i2c_slave_model.v,v 1.7 2006-09-04 09:08:51 rherveille Exp $
+//
+// $Date: 2006-09-04 09:08:51 $
+// $Revision: 1.7 $
+// $Author: rherveille $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: not supported by cvs2svn $
+// Revision 1.6 2005/02/28 11:33:48 rherveille
+// Fixed Tsu:sta timing check.
+// Added Thd:sta timing check.
+//
+// Revision 1.5 2003/12/05 11:05:19 rherveille
+// Fixed slave address MSB='1' bug
+//
+// Revision 1.4 2003/09/11 08:25:37 rherveille
+// Fixed a bug in the timing section. Changed 'tst_scl' into 'tst_sto'.
+//
+// Revision 1.3 2002/10/30 18:11:06 rherveille
+// Added timing tests to i2c_model.
+// Updated testbench.
+//
+// Revision 1.2 2002/03/17 10:26:38 rherveille
+// Fixed some race conditions in the i2c-slave model.
+// Added debug information.
+// Added headers.
+//
+
+`include "timescale.v"
+
+module i2c_slave_model (scl, sda);
+
+ //
+ // parameters
+ //
+ parameter I2C_ADR = 7'b001_0000;
+
+ //
+ // input && outpus
+ //
+ input scl;
+ inout sda;
+
+ //
+ // Variable declaration
+ //
+ wire debug = 1'b1;
+
+ reg [7:0] mem [3:0]; // initiate memory
+ reg [7:0] mem_adr; // memory address
+ reg [7:0] mem_do; // memory data output
+
+ reg sta, d_sta;
+ reg sto, d_sto;
+
+ reg [7:0] sr; // 8bit shift register
+ reg rw; // read/write direction
+
+ wire my_adr; // my address called ??
+ wire i2c_reset; // i2c-statemachine reset
+ reg [2:0] bit_cnt; // 3bit downcounter
+ wire acc_done; // 8bits transfered
+ reg ld; // load downcounter
+
+ reg sda_o; // sda-drive level
+ wire sda_dly; // delayed version of sda
+
+ // statemachine declaration
+ parameter idle = 3'b000;
+ parameter slave_ack = 3'b001;
+ parameter get_mem_adr = 3'b010;
+ parameter gma_ack = 3'b011;
+ parameter data = 3'b100;
+ parameter data_ack = 3'b101;
+
+ reg [2:0] state; // synopsys enum_state
+
+ //
+ // module body
+ //
+
+ initial
+ begin
+ sda_o = 1'b1;
+ state = idle;
+ mem[0] = 0;
+ mem[1] = 0;
+ mem[2] = 0;
+ mem[3] = 0;
+ end
+
+ // generate shift register
+ always @(posedge scl)
+ sr <= #1 {sr[6:0],sda};
+
+ //detect my_address
+ assign my_adr = (sr[7:1] == I2C_ADR);
+ // FIXME: This should not be a generic assign, but rather
+ // qualified on address transfer phase and probably reset by stop
+
+ //generate bit-counter
+ always @(posedge scl)
+ if(ld)
+ bit_cnt <= #1 3'b111;
+ else
+ bit_cnt <= #1 bit_cnt - 3'h1;
+
+ //generate access done signal
+ assign acc_done = !(|bit_cnt);
+
+ // generate delayed version of sda
+ // this model assumes a hold time for sda after the falling edge of scl.
+ // According to the Phillips i2c spec, there s/b a 0 ns hold time for sda
+ // with regards to scl. If the data changes coincident with the clock, the
+ // acknowledge is missed
+ // Fix by Michael Sosnoski
+ assign #1 sda_dly = sda;
+
+
+ //detect start condition
+ always @(negedge sda)
+ if(scl)
+ begin
+ sta <= #1 1'b1;
+ d_sta <= #1 1'b0;
+ sto <= #1 1'b0;
+
+ if(debug)
+ $display("DEBUG i2c_slave; start condition detected at %t", $time);
+ end
+ else
+ sta <= #1 1'b0;
+
+ always @(posedge scl)
+ d_sta <= #1 sta;
+
+ // detect stop condition
+ always @(posedge sda)
+ if(scl)
+ begin
+ sta <= #1 1'b0;
+ sto <= #1 1'b1;
+
+ if(debug)
+ $display("DEBUG i2c_slave; stop condition detected at %t", $time);
+ end
+ else
+ sto <= #1 1'b0;
+
+ //generate i2c_reset signal
+ assign i2c_reset = sta || sto;
+
+ // generate statemachine
+ always @(negedge scl or posedge sto)
+ if (sto || (sta && !d_sta) )
+ begin
+ state <= #1 idle; // reset statemachine
+
+ sda_o <= #1 1'b1;
+ ld <= #1 1'b1;
+ end
+ else
+ begin
+ // initial settings
+ sda_o <= #1 1'b1;
+ ld <= #1 1'b0;
+
+ case(state) // synopsys full_case parallel_case
+ idle: // idle state
+ if (acc_done && my_adr)
+ begin
+ state <= #1 slave_ack;
+ rw <= #1 sr[0];
+ sda_o <= #1 1'b0; // generate i2c_ack
+
+ #2;
+ if(debug && rw)
+ $display("DEBUG i2c_slave; command byte received (read) at %t", $time);
+ if(debug && !rw)
+ $display("DEBUG i2c_slave; command byte received (write) at %t", $time);
+
+ if(rw)
+ begin
+ mem_do <= #1 mem[mem_adr % 4];
+
+ if(debug)
+ begin
+ #2 $display("DEBUG i2c_slave; data block read %x from address %x (1)", mem_do, mem_adr);
+ #2 $display("DEBUG i2c_slave; memcheck [0]=%x, [1]=%x, [2]=%x", mem[4'h0], mem[4'h1], mem[4'h2]);
+ end
+ end
+ end
+
+ slave_ack:
+ begin
+ if(rw)
+ begin
+ state <= #1 data;
+ sda_o <= #1 mem_do[7];
+ end
+ else
+ state <= #1 get_mem_adr;
+
+ ld <= #1 1'b1;
+ end
+
+ get_mem_adr: // wait for memory address
+ if(acc_done)
+ begin
+ state <= #1 gma_ack;
+ mem_adr <= #1 sr; // store memory address
+ sda_o <= #1 !(sr <= 15); // generate i2c_ack, for valid address
+
+ if(debug)
+ #1 $display("DEBUG i2c_slave; address received. adr=%x, ack=%b", sr, sda_o);
+ end
+
+ gma_ack:
+ begin
+ state <= #1 data;
+ ld <= #1 1'b1;
+ end
+
+ data: // receive or drive data
+ begin
+ if(rw)
+ sda_o <= #1 mem_do[7];
+
+ if(acc_done)
+ begin
+ state <= #1 data_ack;
+ mem_adr <= #2 mem_adr + 8'h1;
+ sda_o <= #1 (rw && (mem_adr <= 15) ); // send ack on write, receive ack on read
+
+ if(rw)
+ begin
+ #3 mem_do <= mem[mem_adr % 4];
+
+ if(debug)
+ #5 $display("DEBUG i2c_slave; data block read %x from address %x (2)", mem_do, mem_adr);
+ end
+
+ if(!rw)
+ begin
+ mem[ mem_adr[3:0] ] <= #1 sr; // store data in memory
+
+ if(debug)
+ #2 $display("DEBUG i2c_slave; data block write %x to address %x", sr, mem_adr);
+ end
+ end
+ end
+
+ data_ack:
+ begin
+ ld <= #1 1'b1;
+
+ if(rw)
+ if(sr[0]) // read operation && master send NACK
+ begin
+ state <= #1 idle;
+ sda_o <= #1 1'b1;
+ end
+ else
+ begin
+ state <= #1 data;
+ sda_o <= #1 mem_do[7];
+ end
+ else
+ begin
+ state <= #1 data;
+ sda_o <= #1 1'b1;
+ end
+ end
+
+ endcase
+ end
+
+ // read data from memory
+ always @(posedge scl)
+ if(!acc_done && rw)
+ mem_do <= #1 {mem_do[6:0], 1'b1}; // insert 1'b1 for host ack generation
+
+ // generate tri-states
+ assign sda = sda_o ? 1'bz : 1'b0;
+
+
+ //
+ // Timing checks
+ //
+
+ wire tst_sto = sto;
+ wire tst_sta = sta;
+
+ specify
+ specparam normal_scl_low = 4700,
+ normal_scl_high = 4000,
+ normal_tsu_sta = 4700,
+ normal_thd_sta = 4000,
+ normal_tsu_sto = 4000,
+ normal_tbuf = 4700,
+
+ fast_scl_low = 1300,
+ fast_scl_high = 600,
+ fast_tsu_sta = 1300,
+ fast_thd_sta = 600,
+ fast_tsu_sto = 600,
+ fast_tbuf = 1300;
+
+ $width(negedge scl, normal_scl_low); // scl low time
+ $width(posedge scl, normal_scl_high); // scl high time
+
+ $setup(posedge scl, negedge sda &&& scl, normal_tsu_sta); // setup start
+ $setup(negedge sda &&& scl, negedge scl, normal_thd_sta); // hold start
+ $setup(posedge scl, posedge sda &&& scl, normal_tsu_sto); // setup stop
+
+ $setup(posedge tst_sta, posedge tst_sto, normal_tbuf); // stop to start time
+ endspecify
+
+endmodule
+
+
diff --git a/tests/i2c_bench/run-test.sh b/tests/i2c_bench/run-test.sh
new file mode 100755
index 000000000..5fdbb0594
--- /dev/null
+++ b/tests/i2c_bench/run-test.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+
+set -e
+make -C ../..
+../../yosys -l i2c_master_syn.log -o i2c_master_syn.v \
+ -p hierarchy -p proc -p memory -p techmap -p opt -p abc -p opt \
+ i2c_master_top.v i2c_master_bit_ctrl.v i2c_master_byte_ctrl.v
+. /opt/Xilinx/13.4/ISE_DS/settings64.sh
+
+vlogcomp --work ref i2c_master_bit_ctrl.v
+vlogcomp --work ref i2c_master_byte_ctrl.v
+vlogcomp --work ref i2c_master_top.v
+vlogcomp --work ref i2c_slave_model.v
+vlogcomp --work ref spi_slave_model.v
+vlogcomp --work ref tst_bench_top.v
+vlogcomp --work ref wb_master_model.v
+fuse --work ref -o testbench_ref --top tst_bench_top
+
+cat > testbench_ref.tcl << EOT
+vcd dumpfile testbench_ref.vcd
+vcd dumpvars -m tst_bench_top -l 0
+vcd dumpon
+run 2 ms
+exit
+EOT
+
+./testbench_ref -tclbatch testbench_ref.tcl
+
+vlogcomp --work syn i2c_master_syn.v
+vlogcomp --work syn ../../techlibs/simlib.v
+vlogcomp --work syn ../../techlibs/stdcells_sim.v
+vlogcomp --work syn i2c_slave_model.v
+vlogcomp --work syn spi_slave_model.v
+vlogcomp --work syn tst_bench_top.v
+vlogcomp --work syn wb_master_model.v
+fuse --work syn -o testbench_syn --top tst_bench_top
+
+cat > testbench_syn.tcl << EOT
+vcd dumpfile testbench_syn.vcd
+vcd dumpvars -m tst_bench_top -l 0
+vcd dumpon
+run 2 ms
+exit
+EOT
+
+./testbench_syn -tclbatch testbench_syn.tcl
+
+perl ../tools/vcdcd.pl testbench_ref.vcd testbench_syn.vcd | tee testbench_diff.txt
+echo READY.
+
diff --git a/tests/i2c_bench/spi_slave_model.v b/tests/i2c_bench/spi_slave_model.v
new file mode 100644
index 000000000..d49347b0c
--- /dev/null
+++ b/tests/i2c_bench/spi_slave_model.v
@@ -0,0 +1,125 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// SPI Slave Model ////
+//// ////
+//// ////
+//// Authors: Richard Herveille (richard@asics.ws) www.asics.ws ////
+//// ////
+//// http://www.opencores.org/projects/simple_spi/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2004 Richard Herveille ////
+//// richard@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: spi_slave_model.v,v 1.1 2004-02-28 15:32:54 rherveille Exp $
+//
+// $Date: 2004-02-28 15:32:54 $
+// $Revision: 1.1 $
+// $Author: rherveille $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: not supported by cvs2svn $
+//
+//
+
+
+// Requires: Verilog2001
+
+`include "timescale.v"
+
+module spi_slave_model (
+ input wire csn,
+ input wire sc,
+ input wire di,
+ output wire do
+);
+
+ //
+ // Variable declaration
+ //
+ wire debug = 1'b1;
+
+ wire cpol = 1'b0;
+ wire cpha = 1'b0;
+
+ reg [7:0] mem [7:0]; // initiate memory
+ reg [2:0] mem_adr; // memory address
+ reg [7:0] mem_do; // memory data output
+
+ reg [7:0] sri, sro; // 8bit shift register
+
+ reg [2:0] bit_cnt;
+ reg ld;
+
+ wire clk;
+
+ //
+ // module body
+ //
+
+ assign clk = cpol ^ cpha ^ sc;
+
+ // generate shift registers
+ always @(posedge clk)
+ sri <= #1 {sri[6:0],di};
+
+ always @(posedge clk)
+ if (&bit_cnt)
+ sro <= #1 mem[mem_adr];
+ else
+ sro <= #1 {sro[6:0],1'bx};
+
+ assign do = sro[7];
+
+ //generate bit-counter
+ always @(posedge clk, posedge csn)
+ if(csn)
+ bit_cnt <= #1 3'b111;
+ else
+ bit_cnt <= #1 bit_cnt - 3'h1;
+
+ //generate access done signal
+ always @(posedge clk)
+ ld <= #1 ~(|bit_cnt);
+
+ always @(negedge clk)
+ if (ld) begin
+ mem[mem_adr] <= #1 sri;
+ mem_adr <= #1 mem_adr + 1'b1;
+ end
+
+ initial
+ begin
+ bit_cnt=3'b111;
+ mem_adr = 0;
+ sro = mem[mem_adr];
+ end
+endmodule
+
+
diff --git a/tests/i2c_bench/timescale.v b/tests/i2c_bench/timescale.v
new file mode 100644
index 000000000..60d4ecbd1
--- /dev/null
+++ b/tests/i2c_bench/timescale.v
@@ -0,0 +1,2 @@
+`timescale 1ns / 10ps
+
diff --git a/tests/i2c_bench/tst_bench_top.v b/tests/i2c_bench/tst_bench_top.v
new file mode 100644
index 000000000..9458de054
--- /dev/null
+++ b/tests/i2c_bench/tst_bench_top.v
@@ -0,0 +1,468 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// WISHBONE rev.B2 compliant I2C Master controller Testbench ////
+//// ////
+//// ////
+//// Author: Richard Herveille ////
+//// richard@asics.ws ////
+//// www.asics.ws ////
+//// ////
+//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 Richard Herveille ////
+//// richard@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: tst_bench_top.v,v 1.8 2006-09-04 09:08:51 rherveille Exp $
+//
+// $Date: 2006-09-04 09:08:51 $
+// $Revision: 1.8 $
+// $Author: rherveille $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: not supported by cvs2svn $
+// Revision 1.7 2005/02/27 09:24:18 rherveille
+// Fixed scl, sda delay.
+//
+// Revision 1.6 2004/02/28 15:40:42 rherveille
+// *** empty log message ***
+//
+// Revision 1.4 2003/12/05 11:04:38 rherveille
+// Added slave address configurability
+//
+// Revision 1.3 2002/10/30 18:11:06 rherveille
+// Added timing tests to i2c_model.
+// Updated testbench.
+//
+// Revision 1.2 2002/03/17 10:26:38 rherveille
+// Fixed some race conditions in the i2c-slave model.
+// Added debug information.
+// Added headers.
+//
+
+`include "timescale.v"
+
+module tst_bench_top();
+
+ //
+ // wires && regs
+ //
+ reg clk;
+ reg rstn;
+
+ wire [31:0] adr;
+ wire [ 7:0] dat_i, dat_o, dat0_i, dat1_i;
+ wire we;
+ wire stb;
+ wire cyc;
+ wire ack0, ack1;
+ wire inta;
+
+ reg [7:0] q, qq;
+
+ wire scl, scl0_o, scl0_oen, scl1_o, scl1_oen;
+ wire sda, sda0_o, sda0_oen, sda1_o, sda1_oen;
+
+ parameter PRER_LO = 3'b000;
+ parameter PRER_HI = 3'b001;
+ parameter CTR = 3'b010;
+ parameter RXR = 3'b011;
+ parameter TXR = 3'b011;
+ parameter CR = 3'b100;
+ parameter SR = 3'b100;
+
+ parameter TXR_R = 3'b101; // undocumented / reserved output
+ parameter CR_R = 3'b110; // undocumented / reserved output
+
+ parameter RD = 1'b1;
+ parameter WR = 1'b0;
+ parameter SADR = 7'b0010_000;
+
+ //
+ // Module body
+ //
+
+ // generate clock
+ always #5 clk = ~clk;
+
+ // hookup wishbone master model
+ wb_master_model #(8, 32) u0 (
+ .clk(clk),
+ .rst(rstn),
+ .adr(adr),
+ .din(dat_i),
+ .dout(dat_o),
+ .cyc(cyc),
+ .stb(stb),
+ .we(we),
+ .sel(),
+ .ack(ack0 || ack1),
+ .err(1'b0),
+ .rty(1'b0)
+ );
+
+ wire stb0 = stb & ~adr[3];
+ wire stb1 = stb & adr[3];
+
+ assign dat_i = ({{8'd8}{stb0}} & dat0_i) | ({{8'd8}{stb1}} & dat1_i);
+
+ // hookup wishbone_i2c_master core
+ i2c_master_top i2c_top (
+
+ // wishbone interface
+ .wb_clk_i(clk),
+ .wb_rst_i(1'b0),
+ .arst_i(rstn),
+ .wb_adr_i(adr[2:0]),
+ .wb_dat_i(dat_o),
+ .wb_dat_o(dat0_i),
+ .wb_we_i(we),
+ .wb_stb_i(stb0),
+ .wb_cyc_i(cyc),
+ .wb_ack_o(ack0),
+ .wb_inta_o(inta),
+
+ // i2c signals
+ .scl_pad_i(scl),
+ .scl_pad_o(scl0_o),
+ .scl_padoen_o(scl0_oen),
+ .sda_pad_i(sda),
+ .sda_pad_o(sda0_o),
+ .sda_padoen_o(sda0_oen)
+ ),
+ i2c_top2 (
+
+ // wishbone interface
+ .wb_clk_i(clk),
+ .wb_rst_i(1'b0),
+ .arst_i(rstn),
+ .wb_adr_i(adr[2:0]),
+ .wb_dat_i(dat_o),
+ .wb_dat_o(dat1_i),
+ .wb_we_i(we),
+ .wb_stb_i(stb1),
+ .wb_cyc_i(cyc),
+ .wb_ack_o(ack1),
+ .wb_inta_o(inta),
+
+ // i2c signals
+ .scl_pad_i(scl),
+ .scl_pad_o(scl1_o),
+ .scl_padoen_o(scl1_oen),
+ .sda_pad_i(sda),
+ .sda_pad_o(sda1_o),
+ .sda_padoen_o(sda1_oen)
+ );
+
+
+ // hookup i2c slave model
+ i2c_slave_model #(SADR) i2c_slave (
+ .scl(scl),
+ .sda(sda)
+ );
+
+ //assign scl = ~((!scl0_oen && !scl0_o) || (!scl1_oen && !scl1_o));
+ //assign sda = ~((!sda0_oen && !sda0_o) || (!sda1_oen && !sda1_o));
+
+ // create i2c lines
+ delay m0_scl (scl0_oen ? 1'bz : scl0_o, scl),
+ m1_scl (scl1_oen ? 1'bz : scl1_o, scl),
+ m0_sda (sda0_oen ? 1'bz : sda0_o, sda),
+ m1_sda (sda1_oen ? 1'bz : sda1_o, sda);
+
+ pullup p1(scl); // pullup scl line
+ pullup p2(sda); // pullup sda line
+
+ initial
+ begin
+ `ifdef WAVES
+ $shm_open("waves");
+ $shm_probe("AS",tst_bench_top,"AS");
+ $display("INFO: Signal dump enabled ...\n\n");
+ `endif
+
+// force i2c_slave.debug = 1'b1; // enable i2c_slave debug information
+ force i2c_slave.debug = 1'b0; // disable i2c_slave debug information
+
+ $display("\nstatus: %t Testbench started\n\n", $time);
+
+// $dumpfile("bench.vcd");
+// $dumpvars(1, tst_bench_top);
+// $dumpvars(1, tst_bench_top.i2c_slave);
+
+ // initially values
+ clk = 0;
+
+ // reset system
+ rstn = 1'b1; // negate reset
+ #2;
+ rstn = 1'b0; // assert reset
+ #1000;
+ repeat(1) @(posedge clk);
+ rstn = 1'b1; // negate reset
+
+ $display("status: %t done reset", $time);
+
+ @(posedge clk);
+
+ //
+ // program core
+ //
+
+ // program internal registers
+ u0.wb_write(1, PRER_LO, 8'hfa); // load prescaler lo-byte
+ u0.wb_write(1, PRER_LO, 8'hc8); // load prescaler lo-byte
+ u0.wb_write(1, PRER_HI, 8'h00); // load prescaler hi-byte
+ $display("status: %t programmed registers", $time);
+
+ u0.wb_cmp(0, PRER_LO, 8'hc8); // verify prescaler lo-byte
+ u0.wb_cmp(0, PRER_HI, 8'h00); // verify prescaler hi-byte
+ $display("status: %t verified registers", $time);
+
+ u0.wb_write(1, CTR, 8'h80); // enable core
+ $display("status: %t core enabled", $time);
+
+ //
+ // access slave (write)
+ //
+
+ // drive slave address
+ u0.wb_write(1, TXR, {SADR,WR} ); // present slave address, set write-bit
+ u0.wb_write(0, CR, 8'h90 ); // set command (start, write)
+ $display("status: %t generate 'start', write cmd %0h (slave address+write)", $time, {SADR,WR} );
+
+ // check tip bit
+ u0.wb_read(1, SR, q);
+ while(q[1])
+ u0.wb_read(0, SR, q); // poll it until it is zero
+ $display("status: %t tip==0", $time);
+
+ // send memory address
+ u0.wb_write(1, TXR, 8'h01); // present slave's memory address
+ u0.wb_write(0, CR, 8'h10); // set command (write)
+ $display("status: %t write slave memory address 01", $time);
+
+ // check tip bit
+ u0.wb_read(1, SR, q);
+ while(q[1])
+ u0.wb_read(0, SR, q); // poll it until it is zero
+ $display("status: %t tip==0", $time);
+
+ // send memory contents
+ u0.wb_write(1, TXR, 8'ha5); // present data
+ u0.wb_write(0, CR, 8'h10); // set command (write)
+ $display("status: %t write data a5", $time);
+
+while (scl) #1;
+force scl= 1'b0;
+#100000;
+release scl;
+
+ // check tip bit
+ u0.wb_read(1, SR, q);
+ while(q[1])
+ u0.wb_read(1, SR, q); // poll it until it is zero
+ $display("status: %t tip==0", $time);
+
+ // send memory contents for next memory address (auto_inc)
+ u0.wb_write(1, TXR, 8'h5a); // present data
+ u0.wb_write(0, CR, 8'h50); // set command (stop, write)
+ $display("status: %t write next data 5a, generate 'stop'", $time);
+
+ // check tip bit
+ u0.wb_read(1, SR, q);
+ while(q[1])
+ u0.wb_read(1, SR, q); // poll it until it is zero
+ $display("status: %t tip==0", $time);
+
+ //
+ // delay
+ //
+// #100000; // wait for 100us.
+// $display("status: %t wait 100us", $time);
+
+ //
+ // access slave (read)
+ //
+
+ // drive slave address
+ u0.wb_write(1, TXR,{SADR,WR} ); // present slave address, set write-bit
+ u0.wb_write(0, CR, 8'h90 ); // set command (start, write)
+ $display("status: %t generate 'start', write cmd %0h (slave address+write)", $time, {SADR,WR} );
+
+ // check tip bit
+ u0.wb_read(1, SR, q);
+ while(q[1])
+ u0.wb_read(1, SR, q); // poll it until it is zero
+ $display("status: %t tip==0", $time);
+
+ // send memory address
+ u0.wb_write(1, TXR, 8'h01); // present slave's memory address
+ u0.wb_write(0, CR, 8'h10); // set command (write)
+ $display("status: %t write slave address 01", $time);
+
+ // check tip bit
+ u0.wb_read(1, SR, q);
+ while(q[1])
+ u0.wb_read(1, SR, q); // poll it until it is zero
+ $display("status: %t tip==0", $time);
+
+ // drive slave address
+ u0.wb_write(1, TXR, {SADR,RD} ); // present slave's address, set read-bit
+ u0.wb_write(0, CR, 8'h90 ); // set command (start, write)
+ $display("status: %t generate 'repeated start', write cmd %0h (slave address+read)", $time, {SADR,RD} );
+
+ // check tip bit
+ u0.wb_read(1, SR, q);
+ while(q[1])
+ u0.wb_read(1, SR, q); // poll it until it is zero
+ $display("status: %t tip==0", $time);
+
+ // read data from slave
+ u0.wb_write(1, CR, 8'h20); // set command (read, ack_read)
+ $display("status: %t read + ack", $time);
+
+ // check tip bit
+ u0.wb_read(1, SR, q);
+ while(q[1])
+ u0.wb_read(1, SR, q); // poll it until it is zero
+ $display("status: %t tip==0", $time);
+
+ // check data just received
+ u0.wb_read(1, RXR, qq);
+ if(qq !== 8'ha5)
+ $display("\nERROR: Expected a5, received %x at time %t", qq, $time);
+ else
+ $display("status: %t received %x", $time, qq);
+
+ // read data from slave
+ u0.wb_write(1, CR, 8'h20); // set command (read, ack_read)
+ $display("status: %t read + ack", $time);
+
+ // check tip bit
+ u0.wb_read(1, SR, q);
+ while(q[1])
+ u0.wb_read(1, SR, q); // poll it until it is zero
+ $display("status: %t tip==0", $time);
+
+ // check data just received
+ u0.wb_read(1, RXR, qq);
+ if(qq !== 8'h5a)
+ $display("\nERROR: Expected 5a, received %x at time %t", qq, $time);
+ else
+ $display("status: %t received %x", $time, qq);
+
+ // read data from slave
+ u0.wb_write(1, CR, 8'h20); // set command (read, ack_read)
+ $display("status: %t read + ack", $time);
+
+ // check tip bit
+ u0.wb_read(1, SR, q);
+ while(q[1])
+ u0.wb_read(1, SR, q); // poll it until it is zero
+ $display("status: %t tip==0", $time);
+
+ // check data just received
+ u0.wb_read(1, RXR, qq);
+ $display("status: %t received %x from 3rd read address", $time, qq);
+
+ // read data from slave
+ u0.wb_write(1, CR, 8'h28); // set command (read, nack_read)
+ $display("status: %t read + nack", $time);
+
+ // check tip bit
+ u0.wb_read(1, SR, q);
+ while(q[1])
+ u0.wb_read(1, SR, q); // poll it until it is zero
+ $display("status: %t tip==0", $time);
+
+ // check data just received
+ u0.wb_read(1, RXR, qq);
+ $display("status: %t received %x from 4th read address", $time, qq);
+
+ //
+ // check invalid slave memory address
+ //
+
+ // drive slave address
+ u0.wb_write(1, TXR, {SADR,WR} ); // present slave address, set write-bit
+ u0.wb_write(0, CR, 8'h90 ); // set command (start, write)
+ $display("status: %t generate 'start', write cmd %0h (slave address+write). Check invalid address", $time, {SADR,WR} );
+
+ // check tip bit
+ u0.wb_read(1, SR, q);
+ while(q[1])
+ u0.wb_read(1, SR, q); // poll it until it is zero
+ $display("status: %t tip==0", $time);
+
+ // send memory address
+ u0.wb_write(1, TXR, 8'h10); // present slave's memory address
+ u0.wb_write(0, CR, 8'h10); // set command (write)
+ $display("status: %t write slave memory address 10", $time);
+
+ // check tip bit
+ u0.wb_read(1, SR, q);
+ while(q[1])
+ u0.wb_read(1, SR, q); // poll it until it is zero
+ $display("status: %t tip==0", $time);
+
+ // slave should have send NACK
+ $display("status: %t Check for nack", $time);
+ if(!q[7])
+ $display("\nERROR: Expected NACK, received ACK\n");
+
+ // read data from slave
+ u0.wb_write(1, CR, 8'h40); // set command (stop)
+ $display("status: %t generate 'stop'", $time);
+
+ // check tip bit
+ u0.wb_read(1, SR, q);
+ while(q[1])
+ u0.wb_read(1, SR, q); // poll it until it is zero
+ $display("status: %t tip==0", $time);
+
+ #250000; // wait 250us
+ $display("\n\nstatus: %t Testbench done", $time);
+ $finish;
+ end
+
+endmodule
+
+module delay (in, out);
+ input in;
+ output out;
+
+ assign out = in;
+
+ specify
+ (in => out) = (599,599);
+ endspecify
+endmodule
+
+
diff --git a/tests/i2c_bench/wb_master_model.v b/tests/i2c_bench/wb_master_model.v
new file mode 100644
index 000000000..65a9b7988
--- /dev/null
+++ b/tests/i2c_bench/wb_master_model.v
@@ -0,0 +1,205 @@
+///////////////////////////////////////////////////////////////////////
+//// ////
+//// WISHBONE rev.B2 Wishbone Master model ////
+//// ////
+//// ////
+//// Author: Richard Herveille ////
+//// richard@asics.ws ////
+//// www.asics.ws ////
+//// ////
+//// Downloaded from: http://www.opencores.org/projects/mem_ctrl ////
+//// ////
+///////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 Richard Herveille ////
+//// richard@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+///////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: wb_master_model.v,v 1.4 2004-02-28 15:40:42 rherveille Exp $
+//
+// $Date: 2004-02-28 15:40:42 $
+// $Revision: 1.4 $
+// $Author: rherveille $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+//
+`include "timescale.v"
+
+module wb_master_model(clk, rst, adr, din, dout, cyc, stb, we, sel, ack, err, rty);
+
+parameter dwidth = 32;
+parameter awidth = 32;
+
+input clk, rst;
+output [awidth -1:0] adr;
+input [dwidth -1:0] din;
+output [dwidth -1:0] dout;
+output cyc, stb;
+output we;
+output [dwidth/8 -1:0] sel;
+input ack, err, rty;
+
+////////////////////////////////////////////////////////////////////
+//
+// Local Wires
+//
+
+reg [awidth -1:0] adr;
+reg [dwidth -1:0] dout;
+reg cyc, stb;
+reg we;
+reg [dwidth/8 -1:0] sel;
+
+reg [dwidth -1:0] q;
+
+////////////////////////////////////////////////////////////////////
+//
+// Memory Logic
+//
+
+initial
+ begin
+ //adr = 32'hxxxx_xxxx;
+ //adr = 0;
+ adr = {awidth{1'bx}};
+ dout = {dwidth{1'bx}};
+ cyc = 1'b0;
+ stb = 1'bx;
+ we = 1'hx;
+ sel = {dwidth/8{1'bx}};
+ #1;
+ $display("\nINFO: WISHBONE MASTER MODEL INSTANTIATED (%m)\n");
+ end
+
+////////////////////////////////////////////////////////////////////
+//
+// Wishbone write cycle
+//
+
+task wb_write;
+ input delay;
+ integer delay;
+
+ input [awidth -1:0] a;
+ input [dwidth -1:0] d;
+
+ begin
+
+ // wait initial delay
+ repeat(delay) @(posedge clk);
+
+ // assert wishbone signal
+ #1;
+ adr = a;
+ dout = d;
+ cyc = 1'b1;
+ stb = 1'b1;
+ we = 1'b1;
+ sel = {dwidth/8{1'b1}};
+ @(posedge clk);
+
+ // wait for acknowledge from slave
+ while(~ack) @(posedge clk);
+
+ // negate wishbone signals
+ #1;
+ cyc = 1'b0;
+ stb = 1'bx;
+ adr = {awidth{1'bx}};
+ dout = {dwidth{1'bx}};
+ we = 1'hx;
+ sel = {dwidth/8{1'bx}};
+
+ end
+endtask
+
+////////////////////////////////////////////////////////////////////
+//
+// Wishbone read cycle
+//
+
+task wb_read;
+ input delay;
+ integer delay;
+
+ input [awidth -1:0] a;
+ output [dwidth -1:0] d;
+
+ begin
+
+ // wait initial delay
+ repeat(delay) @(posedge clk);
+
+ // assert wishbone signals
+ #1;
+ adr = a;
+ dout = {dwidth{1'bx}};
+ cyc = 1'b1;
+ stb = 1'b1;
+ we = 1'b0;
+ sel = {dwidth/8{1'b1}};
+ @(posedge clk);
+
+ // wait for acknowledge from slave
+ while(~ack) @(posedge clk);
+
+ // negate wishbone signals
+ #1;
+ cyc = 1'b0;
+ stb = 1'bx;
+ adr = {awidth{1'bx}};
+ dout = {dwidth{1'bx}};
+ we = 1'hx;
+ sel = {dwidth/8{1'bx}};
+ d = din;
+
+ end
+endtask
+
+////////////////////////////////////////////////////////////////////
+//
+// Wishbone compare cycle (read data from location and compare with expected data)
+//
+
+task wb_cmp;
+ input delay;
+ integer delay;
+
+ input [awidth -1:0] a;
+ input [dwidth -1:0] d_exp;
+
+ begin
+ wb_read (delay, a, q);
+
+ if (d_exp !== q)
+ $display("Data compare error. Received %h, expected %h at time %t", q, d_exp, $time);
+ end
+endtask
+
+endmodule
+
+
diff --git a/tests/iwls2005/README b/tests/iwls2005/README
new file mode 100644
index 000000000..f44a89d93
--- /dev/null
+++ b/tests/iwls2005/README
@@ -0,0 +1,7 @@
+
+A collection of smaller rtl examples from the IWLS 2005 benchmark [1].
+We have no testbenches for these but we can check if we can
+parse and synthesize them.
+
+[1] http://iwls.org/iwls2005/benchmarks.html
+
diff --git a/tests/iwls2005/aes_core/aes_cipher_top.v b/tests/iwls2005/aes_core/aes_cipher_top.v
new file mode 100644
index 000000000..a0acaeb48
--- /dev/null
+++ b/tests/iwls2005/aes_core/aes_cipher_top.v
@@ -0,0 +1,256 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// AES Cipher Top Level ////
+//// ////
+//// ////
+//// Author: Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+//// ////
+//// Downloaded from: http://www.opencores.org/cores/aes_core/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000-2002 Rudolf Usselmann ////
+//// www.asics.ws ////
+//// rudi@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: aes_cipher_top.v,v 1.1.1.1 2002/11/09 11:22:48 rudi Exp $
+//
+// $Date: 2002/11/09 11:22:48 $
+// $Revision: 1.1.1.1 $
+// $Author: rudi $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: aes_cipher_top.v,v $
+// Revision 1.1.1.1 2002/11/09 11:22:48 rudi
+// Initial Checkin
+//
+//
+//
+//
+//
+//
+
+`include "timescale.v"
+
+module aes_cipher_top(clk, rst, ld, done, key, text_in, text_out );
+input clk, rst;
+input ld;
+output done;
+input [127:0] key;
+input [127:0] text_in;
+output [127:0] text_out;
+
+////////////////////////////////////////////////////////////////////
+//
+// Local Wires
+//
+
+wire [31:0] w0, w1, w2, w3;
+reg [127:0] text_in_r;
+reg [127:0] text_out;
+reg [7:0] sa00, sa01, sa02, sa03;
+reg [7:0] sa10, sa11, sa12, sa13;
+reg [7:0] sa20, sa21, sa22, sa23;
+reg [7:0] sa30, sa31, sa32, sa33;
+wire [7:0] sa00_next, sa01_next, sa02_next, sa03_next;
+wire [7:0] sa10_next, sa11_next, sa12_next, sa13_next;
+wire [7:0] sa20_next, sa21_next, sa22_next, sa23_next;
+wire [7:0] sa30_next, sa31_next, sa32_next, sa33_next;
+wire [7:0] sa00_sub, sa01_sub, sa02_sub, sa03_sub;
+wire [7:0] sa10_sub, sa11_sub, sa12_sub, sa13_sub;
+wire [7:0] sa20_sub, sa21_sub, sa22_sub, sa23_sub;
+wire [7:0] sa30_sub, sa31_sub, sa32_sub, sa33_sub;
+wire [7:0] sa00_sr, sa01_sr, sa02_sr, sa03_sr;
+wire [7:0] sa10_sr, sa11_sr, sa12_sr, sa13_sr;
+wire [7:0] sa20_sr, sa21_sr, sa22_sr, sa23_sr;
+wire [7:0] sa30_sr, sa31_sr, sa32_sr, sa33_sr;
+wire [7:0] sa00_mc, sa01_mc, sa02_mc, sa03_mc;
+wire [7:0] sa10_mc, sa11_mc, sa12_mc, sa13_mc;
+wire [7:0] sa20_mc, sa21_mc, sa22_mc, sa23_mc;
+wire [7:0] sa30_mc, sa31_mc, sa32_mc, sa33_mc;
+reg done, ld_r;
+reg [3:0] dcnt;
+
+////////////////////////////////////////////////////////////////////
+//
+// Misc Logic
+//
+
+always @(posedge clk)
+ if(!rst) dcnt <= #1 4'h0;
+ else
+ if(ld) dcnt <= #1 4'hb;
+ else
+ if(|dcnt) dcnt <= #1 dcnt - 4'h1;
+
+always @(posedge clk) done <= #1 !(|dcnt[3:1]) & dcnt[0] & !ld;
+always @(posedge clk) if(ld) text_in_r <= #1 text_in;
+always @(posedge clk) ld_r <= #1 ld;
+
+////////////////////////////////////////////////////////////////////
+//
+// Initial Permutation (AddRoundKey)
+//
+
+always @(posedge clk) sa33 <= #1 ld_r ? text_in_r[007:000] ^ w3[07:00] : sa33_next;
+always @(posedge clk) sa23 <= #1 ld_r ? text_in_r[015:008] ^ w3[15:08] : sa23_next;
+always @(posedge clk) sa13 <= #1 ld_r ? text_in_r[023:016] ^ w3[23:16] : sa13_next;
+always @(posedge clk) sa03 <= #1 ld_r ? text_in_r[031:024] ^ w3[31:24] : sa03_next;
+always @(posedge clk) sa32 <= #1 ld_r ? text_in_r[039:032] ^ w2[07:00] : sa32_next;
+always @(posedge clk) sa22 <= #1 ld_r ? text_in_r[047:040] ^ w2[15:08] : sa22_next;
+always @(posedge clk) sa12 <= #1 ld_r ? text_in_r[055:048] ^ w2[23:16] : sa12_next;
+always @(posedge clk) sa02 <= #1 ld_r ? text_in_r[063:056] ^ w2[31:24] : sa02_next;
+always @(posedge clk) sa31 <= #1 ld_r ? text_in_r[071:064] ^ w1[07:00] : sa31_next;
+always @(posedge clk) sa21 <= #1 ld_r ? text_in_r[079:072] ^ w1[15:08] : sa21_next;
+always @(posedge clk) sa11 <= #1 ld_r ? text_in_r[087:080] ^ w1[23:16] : sa11_next;
+always @(posedge clk) sa01 <= #1 ld_r ? text_in_r[095:088] ^ w1[31:24] : sa01_next;
+always @(posedge clk) sa30 <= #1 ld_r ? text_in_r[103:096] ^ w0[07:00] : sa30_next;
+always @(posedge clk) sa20 <= #1 ld_r ? text_in_r[111:104] ^ w0[15:08] : sa20_next;
+always @(posedge clk) sa10 <= #1 ld_r ? text_in_r[119:112] ^ w0[23:16] : sa10_next;
+always @(posedge clk) sa00 <= #1 ld_r ? text_in_r[127:120] ^ w0[31:24] : sa00_next;
+
+////////////////////////////////////////////////////////////////////
+//
+// Round Permutations
+//
+
+assign sa00_sr = sa00_sub;
+assign sa01_sr = sa01_sub;
+assign sa02_sr = sa02_sub;
+assign sa03_sr = sa03_sub;
+assign sa10_sr = sa11_sub;
+assign sa11_sr = sa12_sub;
+assign sa12_sr = sa13_sub;
+assign sa13_sr = sa10_sub;
+assign sa20_sr = sa22_sub;
+assign sa21_sr = sa23_sub;
+assign sa22_sr = sa20_sub;
+assign sa23_sr = sa21_sub;
+assign sa30_sr = sa33_sub;
+assign sa31_sr = sa30_sub;
+assign sa32_sr = sa31_sub;
+assign sa33_sr = sa32_sub;
+assign {sa00_mc, sa10_mc, sa20_mc, sa30_mc} = mix_col(sa00_sr,sa10_sr,sa20_sr,sa30_sr);
+assign {sa01_mc, sa11_mc, sa21_mc, sa31_mc} = mix_col(sa01_sr,sa11_sr,sa21_sr,sa31_sr);
+assign {sa02_mc, sa12_mc, sa22_mc, sa32_mc} = mix_col(sa02_sr,sa12_sr,sa22_sr,sa32_sr);
+assign {sa03_mc, sa13_mc, sa23_mc, sa33_mc} = mix_col(sa03_sr,sa13_sr,sa23_sr,sa33_sr);
+assign sa00_next = sa00_mc ^ w0[31:24];
+assign sa01_next = sa01_mc ^ w1[31:24];
+assign sa02_next = sa02_mc ^ w2[31:24];
+assign sa03_next = sa03_mc ^ w3[31:24];
+assign sa10_next = sa10_mc ^ w0[23:16];
+assign sa11_next = sa11_mc ^ w1[23:16];
+assign sa12_next = sa12_mc ^ w2[23:16];
+assign sa13_next = sa13_mc ^ w3[23:16];
+assign sa20_next = sa20_mc ^ w0[15:08];
+assign sa21_next = sa21_mc ^ w1[15:08];
+assign sa22_next = sa22_mc ^ w2[15:08];
+assign sa23_next = sa23_mc ^ w3[15:08];
+assign sa30_next = sa30_mc ^ w0[07:00];
+assign sa31_next = sa31_mc ^ w1[07:00];
+assign sa32_next = sa32_mc ^ w2[07:00];
+assign sa33_next = sa33_mc ^ w3[07:00];
+
+////////////////////////////////////////////////////////////////////
+//
+// Final text output
+//
+
+always @(posedge clk) text_out[127:120] <= #1 sa00_sr ^ w0[31:24];
+always @(posedge clk) text_out[095:088] <= #1 sa01_sr ^ w1[31:24];
+always @(posedge clk) text_out[063:056] <= #1 sa02_sr ^ w2[31:24];
+always @(posedge clk) text_out[031:024] <= #1 sa03_sr ^ w3[31:24];
+always @(posedge clk) text_out[119:112] <= #1 sa10_sr ^ w0[23:16];
+always @(posedge clk) text_out[087:080] <= #1 sa11_sr ^ w1[23:16];
+always @(posedge clk) text_out[055:048] <= #1 sa12_sr ^ w2[23:16];
+always @(posedge clk) text_out[023:016] <= #1 sa13_sr ^ w3[23:16];
+always @(posedge clk) text_out[111:104] <= #1 sa20_sr ^ w0[15:08];
+always @(posedge clk) text_out[079:072] <= #1 sa21_sr ^ w1[15:08];
+always @(posedge clk) text_out[047:040] <= #1 sa22_sr ^ w2[15:08];
+always @(posedge clk) text_out[015:008] <= #1 sa23_sr ^ w3[15:08];
+always @(posedge clk) text_out[103:096] <= #1 sa30_sr ^ w0[07:00];
+always @(posedge clk) text_out[071:064] <= #1 sa31_sr ^ w1[07:00];
+always @(posedge clk) text_out[039:032] <= #1 sa32_sr ^ w2[07:00];
+always @(posedge clk) text_out[007:000] <= #1 sa33_sr ^ w3[07:00];
+
+////////////////////////////////////////////////////////////////////
+//
+// Generic Functions
+//
+
+function [31:0] mix_col;
+input [7:0] s0,s1,s2,s3;
+reg [7:0] s0_o,s1_o,s2_o,s3_o;
+begin
+mix_col[31:24]=xtime(s0)^xtime(s1)^s1^s2^s3;
+mix_col[23:16]=s0^xtime(s1)^xtime(s2)^s2^s3;
+mix_col[15:08]=s0^s1^xtime(s2)^xtime(s3)^s3;
+mix_col[07:00]=xtime(s0)^s0^s1^s2^xtime(s3);
+end
+endfunction
+
+function [7:0] xtime;
+input [7:0] b; xtime={b[6:0],1'b0}^(8'h1b&{8{b[7]}});
+endfunction
+
+////////////////////////////////////////////////////////////////////
+//
+// Modules
+//
+
+aes_key_expand_128 u0(
+ .clk( clk ),
+ .kld( ld ),
+ .key( key ),
+ .wo_0( w0 ),
+ .wo_1( w1 ),
+ .wo_2( w2 ),
+ .wo_3( w3 ));
+
+aes_sbox us00( .a( sa00 ), .d( sa00_sub ));
+aes_sbox us01( .a( sa01 ), .d( sa01_sub ));
+aes_sbox us02( .a( sa02 ), .d( sa02_sub ));
+aes_sbox us03( .a( sa03 ), .d( sa03_sub ));
+aes_sbox us10( .a( sa10 ), .d( sa10_sub ));
+aes_sbox us11( .a( sa11 ), .d( sa11_sub ));
+aes_sbox us12( .a( sa12 ), .d( sa12_sub ));
+aes_sbox us13( .a( sa13 ), .d( sa13_sub ));
+aes_sbox us20( .a( sa20 ), .d( sa20_sub ));
+aes_sbox us21( .a( sa21 ), .d( sa21_sub ));
+aes_sbox us22( .a( sa22 ), .d( sa22_sub ));
+aes_sbox us23( .a( sa23 ), .d( sa23_sub ));
+aes_sbox us30( .a( sa30 ), .d( sa30_sub ));
+aes_sbox us31( .a( sa31 ), .d( sa31_sub ));
+aes_sbox us32( .a( sa32 ), .d( sa32_sub ));
+aes_sbox us33( .a( sa33 ), .d( sa33_sub ));
+
+endmodule
+
+
diff --git a/tests/iwls2005/aes_core/aes_inv_cipher_top.v b/tests/iwls2005/aes_core/aes_inv_cipher_top.v
new file mode 100644
index 000000000..51b3525ac
--- /dev/null
+++ b/tests/iwls2005/aes_core/aes_inv_cipher_top.v
@@ -0,0 +1,327 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// AES Inverse Cipher Top Level ////
+//// ////
+//// ////
+//// Author: Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+//// ////
+//// Downloaded from: http://www.opencores.org/cores/aes_core/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000-2002 Rudolf Usselmann ////
+//// www.asics.ws ////
+//// rudi@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: aes_inv_cipher_top.v,v 1.1.1.1 2002/11/09 11:22:53 rudi Exp $
+//
+// $Date: 2002/11/09 11:22:53 $
+// $Revision: 1.1.1.1 $
+// $Author: rudi $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: aes_inv_cipher_top.v,v $
+// Revision 1.1.1.1 2002/11/09 11:22:53 rudi
+// Initial Checkin
+//
+//
+//
+//
+//
+//
+
+`include "timescale.v"
+
+module aes_inv_cipher_top(clk, rst, kld, ld, done, key, text_in, text_out );
+input clk, rst;
+input kld, ld;
+output done;
+input [127:0] key;
+input [127:0] text_in;
+output [127:0] text_out;
+
+////////////////////////////////////////////////////////////////////
+//
+// Local Wires
+//
+
+wire [31:0] wk0, wk1, wk2, wk3;
+reg [31:0] w0, w1, w2, w3;
+reg [127:0] text_in_r;
+reg [127:0] text_out;
+reg [7:0] sa00, sa01, sa02, sa03;
+reg [7:0] sa10, sa11, sa12, sa13;
+reg [7:0] sa20, sa21, sa22, sa23;
+reg [7:0] sa30, sa31, sa32, sa33;
+wire [7:0] sa00_next, sa01_next, sa02_next, sa03_next;
+wire [7:0] sa10_next, sa11_next, sa12_next, sa13_next;
+wire [7:0] sa20_next, sa21_next, sa22_next, sa23_next;
+wire [7:0] sa30_next, sa31_next, sa32_next, sa33_next;
+wire [7:0] sa00_sub, sa01_sub, sa02_sub, sa03_sub;
+wire [7:0] sa10_sub, sa11_sub, sa12_sub, sa13_sub;
+wire [7:0] sa20_sub, sa21_sub, sa22_sub, sa23_sub;
+wire [7:0] sa30_sub, sa31_sub, sa32_sub, sa33_sub;
+wire [7:0] sa00_sr, sa01_sr, sa02_sr, sa03_sr;
+wire [7:0] sa10_sr, sa11_sr, sa12_sr, sa13_sr;
+wire [7:0] sa20_sr, sa21_sr, sa22_sr, sa23_sr;
+wire [7:0] sa30_sr, sa31_sr, sa32_sr, sa33_sr;
+wire [7:0] sa00_ark, sa01_ark, sa02_ark, sa03_ark;
+wire [7:0] sa10_ark, sa11_ark, sa12_ark, sa13_ark;
+wire [7:0] sa20_ark, sa21_ark, sa22_ark, sa23_ark;
+wire [7:0] sa30_ark, sa31_ark, sa32_ark, sa33_ark;
+reg ld_r, go, done;
+reg [3:0] dcnt;
+
+////////////////////////////////////////////////////////////////////
+//
+// Misc Logic
+//
+
+always @(posedge clk)
+ if(!rst) dcnt <= #1 4'h0;
+ else
+ if(done) dcnt <= #1 4'h0;
+ else
+ if(ld) dcnt <= #1 4'h1;
+ else
+ if(go) dcnt <= #1 dcnt + 4'h1;
+
+always @(posedge clk) done <= #1 (dcnt==4'hb) & !ld;
+
+always @(posedge clk)
+ if(!rst) go <= #1 1'b0;
+ else
+ if(ld) go <= #1 1'b1;
+ else
+ if(done) go <= #1 1'b0;
+
+always @(posedge clk) if(ld) text_in_r <= #1 text_in;
+
+always @(posedge clk) ld_r <= #1 ld;
+
+////////////////////////////////////////////////////////////////////
+//
+// Initial Permutation
+//
+
+always @(posedge clk) sa33 <= #1 ld_r ? text_in_r[007:000] ^ w3[07:00] : sa33_next;
+always @(posedge clk) sa23 <= #1 ld_r ? text_in_r[015:008] ^ w3[15:08] : sa23_next;
+always @(posedge clk) sa13 <= #1 ld_r ? text_in_r[023:016] ^ w3[23:16] : sa13_next;
+always @(posedge clk) sa03 <= #1 ld_r ? text_in_r[031:024] ^ w3[31:24] : sa03_next;
+always @(posedge clk) sa32 <= #1 ld_r ? text_in_r[039:032] ^ w2[07:00] : sa32_next;
+always @(posedge clk) sa22 <= #1 ld_r ? text_in_r[047:040] ^ w2[15:08] : sa22_next;
+always @(posedge clk) sa12 <= #1 ld_r ? text_in_r[055:048] ^ w2[23:16] : sa12_next;
+always @(posedge clk) sa02 <= #1 ld_r ? text_in_r[063:056] ^ w2[31:24] : sa02_next;
+always @(posedge clk) sa31 <= #1 ld_r ? text_in_r[071:064] ^ w1[07:00] : sa31_next;
+always @(posedge clk) sa21 <= #1 ld_r ? text_in_r[079:072] ^ w1[15:08] : sa21_next;
+always @(posedge clk) sa11 <= #1 ld_r ? text_in_r[087:080] ^ w1[23:16] : sa11_next;
+always @(posedge clk) sa01 <= #1 ld_r ? text_in_r[095:088] ^ w1[31:24] : sa01_next;
+always @(posedge clk) sa30 <= #1 ld_r ? text_in_r[103:096] ^ w0[07:00] : sa30_next;
+always @(posedge clk) sa20 <= #1 ld_r ? text_in_r[111:104] ^ w0[15:08] : sa20_next;
+always @(posedge clk) sa10 <= #1 ld_r ? text_in_r[119:112] ^ w0[23:16] : sa10_next;
+always @(posedge clk) sa00 <= #1 ld_r ? text_in_r[127:120] ^ w0[31:24] : sa00_next;
+
+////////////////////////////////////////////////////////////////////
+//
+// Round Permutations
+//
+
+assign sa00_sr = sa00;
+assign sa01_sr = sa01;
+assign sa02_sr = sa02;
+assign sa03_sr = sa03;
+assign sa10_sr = sa13;
+assign sa11_sr = sa10;
+assign sa12_sr = sa11;
+assign sa13_sr = sa12;
+assign sa20_sr = sa22;
+assign sa21_sr = sa23;
+assign sa22_sr = sa20;
+assign sa23_sr = sa21;
+assign sa30_sr = sa31;
+assign sa31_sr = sa32;
+assign sa32_sr = sa33;
+assign sa33_sr = sa30;
+assign sa00_ark = sa00_sub ^ w0[31:24];
+assign sa01_ark = sa01_sub ^ w1[31:24];
+assign sa02_ark = sa02_sub ^ w2[31:24];
+assign sa03_ark = sa03_sub ^ w3[31:24];
+assign sa10_ark = sa10_sub ^ w0[23:16];
+assign sa11_ark = sa11_sub ^ w1[23:16];
+assign sa12_ark = sa12_sub ^ w2[23:16];
+assign sa13_ark = sa13_sub ^ w3[23:16];
+assign sa20_ark = sa20_sub ^ w0[15:08];
+assign sa21_ark = sa21_sub ^ w1[15:08];
+assign sa22_ark = sa22_sub ^ w2[15:08];
+assign sa23_ark = sa23_sub ^ w3[15:08];
+assign sa30_ark = sa30_sub ^ w0[07:00];
+assign sa31_ark = sa31_sub ^ w1[07:00];
+assign sa32_ark = sa32_sub ^ w2[07:00];
+assign sa33_ark = sa33_sub ^ w3[07:00];
+assign {sa00_next, sa10_next, sa20_next, sa30_next} = inv_mix_col(sa00_ark,sa10_ark,sa20_ark,sa30_ark);
+assign {sa01_next, sa11_next, sa21_next, sa31_next} = inv_mix_col(sa01_ark,sa11_ark,sa21_ark,sa31_ark);
+assign {sa02_next, sa12_next, sa22_next, sa32_next} = inv_mix_col(sa02_ark,sa12_ark,sa22_ark,sa32_ark);
+assign {sa03_next, sa13_next, sa23_next, sa33_next} = inv_mix_col(sa03_ark,sa13_ark,sa23_ark,sa33_ark);
+
+////////////////////////////////////////////////////////////////////
+//
+// Final Text Output
+//
+
+always @(posedge clk) text_out[127:120] <= #1 sa00_ark;
+always @(posedge clk) text_out[095:088] <= #1 sa01_ark;
+always @(posedge clk) text_out[063:056] <= #1 sa02_ark;
+always @(posedge clk) text_out[031:024] <= #1 sa03_ark;
+always @(posedge clk) text_out[119:112] <= #1 sa10_ark;
+always @(posedge clk) text_out[087:080] <= #1 sa11_ark;
+always @(posedge clk) text_out[055:048] <= #1 sa12_ark;
+always @(posedge clk) text_out[023:016] <= #1 sa13_ark;
+always @(posedge clk) text_out[111:104] <= #1 sa20_ark;
+always @(posedge clk) text_out[079:072] <= #1 sa21_ark;
+always @(posedge clk) text_out[047:040] <= #1 sa22_ark;
+always @(posedge clk) text_out[015:008] <= #1 sa23_ark;
+always @(posedge clk) text_out[103:096] <= #1 sa30_ark;
+always @(posedge clk) text_out[071:064] <= #1 sa31_ark;
+always @(posedge clk) text_out[039:032] <= #1 sa32_ark;
+always @(posedge clk) text_out[007:000] <= #1 sa33_ark;
+
+////////////////////////////////////////////////////////////////////
+//
+// Generic Functions
+//
+
+function [31:0] inv_mix_col;
+input [7:0] s0,s1,s2,s3;
+begin
+inv_mix_col[31:24]=pmul_e(s0)^pmul_b(s1)^pmul_d(s2)^pmul_9(s3);
+inv_mix_col[23:16]=pmul_9(s0)^pmul_e(s1)^pmul_b(s2)^pmul_d(s3);
+inv_mix_col[15:08]=pmul_d(s0)^pmul_9(s1)^pmul_e(s2)^pmul_b(s3);
+inv_mix_col[07:00]=pmul_b(s0)^pmul_d(s1)^pmul_9(s2)^pmul_e(s3);
+end
+endfunction
+
+// Some synthesis tools don't like xtime being called recursevly ...
+function [7:0] pmul_e;
+input [7:0] b;
+reg [7:0] two,four,eight;
+begin
+two=xtime(b);four=xtime(two);eight=xtime(four);pmul_e=eight^four^two;
+end
+endfunction
+
+function [7:0] pmul_9;
+input [7:0] b;
+reg [7:0] two,four,eight;
+begin
+two=xtime(b);four=xtime(two);eight=xtime(four);pmul_9=eight^b;
+end
+endfunction
+
+function [7:0] pmul_d;
+input [7:0] b;
+reg [7:0] two,four,eight;
+begin
+two=xtime(b);four=xtime(two);eight=xtime(four);pmul_d=eight^four^b;
+end
+endfunction
+
+function [7:0] pmul_b;
+input [7:0] b;
+reg [7:0] two,four,eight;
+begin
+two=xtime(b);four=xtime(two);eight=xtime(four);pmul_b=eight^two^b;
+end
+endfunction
+
+function [7:0] xtime;
+input [7:0] b;xtime={b[6:0],1'b0}^(8'h1b&{8{b[7]}});
+endfunction
+
+////////////////////////////////////////////////////////////////////
+//
+// Key Buffer
+//
+
+reg [127:0] kb[10:0];
+reg [3:0] kcnt;
+reg kdone;
+reg kb_ld;
+
+always @(posedge clk)
+ if(!rst) kcnt <= #1 4'ha;
+ else
+ if(kld) kcnt <= #1 4'ha;
+ else
+ if(kb_ld) kcnt <= #1 kcnt - 4'h1;
+
+always @(posedge clk)
+ if(!rst) kb_ld <= #1 1'b0;
+ else
+ if(kld) kb_ld <= #1 1'b1;
+ else
+ if(kcnt==4'h0) kb_ld <= #1 1'b0;
+
+always @(posedge clk) kdone <= #1 (kcnt==4'h0) & !kld;
+always @(posedge clk) if(kb_ld) kb[kcnt] <= #1 {wk3, wk2, wk1, wk0};
+always @(posedge clk) {w3, w2, w1, w0} <= #1 kb[dcnt];
+
+////////////////////////////////////////////////////////////////////
+//
+// Modules
+//
+
+aes_key_expand_128 u0(
+ .clk( clk ),
+ .kld( kld ),
+ .key( key ),
+ .wo_0( wk0 ),
+ .wo_1( wk1 ),
+ .wo_2( wk2 ),
+ .wo_3( wk3 ));
+
+aes_inv_sbox us00( .a( sa00_sr ), .d( sa00_sub ));
+aes_inv_sbox us01( .a( sa01_sr ), .d( sa01_sub ));
+aes_inv_sbox us02( .a( sa02_sr ), .d( sa02_sub ));
+aes_inv_sbox us03( .a( sa03_sr ), .d( sa03_sub ));
+aes_inv_sbox us10( .a( sa10_sr ), .d( sa10_sub ));
+aes_inv_sbox us11( .a( sa11_sr ), .d( sa11_sub ));
+aes_inv_sbox us12( .a( sa12_sr ), .d( sa12_sub ));
+aes_inv_sbox us13( .a( sa13_sr ), .d( sa13_sub ));
+aes_inv_sbox us20( .a( sa20_sr ), .d( sa20_sub ));
+aes_inv_sbox us21( .a( sa21_sr ), .d( sa21_sub ));
+aes_inv_sbox us22( .a( sa22_sr ), .d( sa22_sub ));
+aes_inv_sbox us23( .a( sa23_sr ), .d( sa23_sub ));
+aes_inv_sbox us30( .a( sa30_sr ), .d( sa30_sub ));
+aes_inv_sbox us31( .a( sa31_sr ), .d( sa31_sub ));
+aes_inv_sbox us32( .a( sa32_sr ), .d( sa32_sub ));
+aes_inv_sbox us33( .a( sa33_sr ), .d( sa33_sub ));
+
+endmodule
+
diff --git a/tests/iwls2005/aes_core/aes_inv_sbox.v b/tests/iwls2005/aes_core/aes_inv_sbox.v
new file mode 100644
index 000000000..323181eba
--- /dev/null
+++ b/tests/iwls2005/aes_core/aes_inv_sbox.v
@@ -0,0 +1,328 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// AES Inverse SBOX (ROM) ////
+//// ////
+//// ////
+//// Author: Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+//// ////
+//// Downloaded from: http://www.opencores.org/cores/aes_core/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000-2002 Rudolf Usselmann ////
+//// www.asics.ws ////
+//// rudi@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: aes_inv_sbox.v,v 1.1.1.1 2002/11/09 11:22:55 rudi Exp $
+//
+// $Date: 2002/11/09 11:22:55 $
+// $Revision: 1.1.1.1 $
+// $Author: rudi $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: aes_inv_sbox.v,v $
+// Revision 1.1.1.1 2002/11/09 11:22:55 rudi
+// Initial Checkin
+//
+//
+//
+//
+//
+//
+
+`include "timescale.v"
+
+module aes_inv_sbox(a,d);
+input [7:0] a;
+output [7:0] d;
+reg [7:0] d;
+
+always @(a)
+ case(a) // synopsys full_case parallel_case
+ 8'h00: d=8'h52;
+ 8'h01: d=8'h09;
+ 8'h02: d=8'h6a;
+ 8'h03: d=8'hd5;
+ 8'h04: d=8'h30;
+ 8'h05: d=8'h36;
+ 8'h06: d=8'ha5;
+ 8'h07: d=8'h38;
+ 8'h08: d=8'hbf;
+ 8'h09: d=8'h40;
+ 8'h0a: d=8'ha3;
+ 8'h0b: d=8'h9e;
+ 8'h0c: d=8'h81;
+ 8'h0d: d=8'hf3;
+ 8'h0e: d=8'hd7;
+ 8'h0f: d=8'hfb;
+ 8'h10: d=8'h7c;
+ 8'h11: d=8'he3;
+ 8'h12: d=8'h39;
+ 8'h13: d=8'h82;
+ 8'h14: d=8'h9b;
+ 8'h15: d=8'h2f;
+ 8'h16: d=8'hff;
+ 8'h17: d=8'h87;
+ 8'h18: d=8'h34;
+ 8'h19: d=8'h8e;
+ 8'h1a: d=8'h43;
+ 8'h1b: d=8'h44;
+ 8'h1c: d=8'hc4;
+ 8'h1d: d=8'hde;
+ 8'h1e: d=8'he9;
+ 8'h1f: d=8'hcb;
+ 8'h20: d=8'h54;
+ 8'h21: d=8'h7b;
+ 8'h22: d=8'h94;
+ 8'h23: d=8'h32;
+ 8'h24: d=8'ha6;
+ 8'h25: d=8'hc2;
+ 8'h26: d=8'h23;
+ 8'h27: d=8'h3d;
+ 8'h28: d=8'hee;
+ 8'h29: d=8'h4c;
+ 8'h2a: d=8'h95;
+ 8'h2b: d=8'h0b;
+ 8'h2c: d=8'h42;
+ 8'h2d: d=8'hfa;
+ 8'h2e: d=8'hc3;
+ 8'h2f: d=8'h4e;
+ 8'h30: d=8'h08;
+ 8'h31: d=8'h2e;
+ 8'h32: d=8'ha1;
+ 8'h33: d=8'h66;
+ 8'h34: d=8'h28;
+ 8'h35: d=8'hd9;
+ 8'h36: d=8'h24;
+ 8'h37: d=8'hb2;
+ 8'h38: d=8'h76;
+ 8'h39: d=8'h5b;
+ 8'h3a: d=8'ha2;
+ 8'h3b: d=8'h49;
+ 8'h3c: d=8'h6d;
+ 8'h3d: d=8'h8b;
+ 8'h3e: d=8'hd1;
+ 8'h3f: d=8'h25;
+ 8'h40: d=8'h72;
+ 8'h41: d=8'hf8;
+ 8'h42: d=8'hf6;
+ 8'h43: d=8'h64;
+ 8'h44: d=8'h86;
+ 8'h45: d=8'h68;
+ 8'h46: d=8'h98;
+ 8'h47: d=8'h16;
+ 8'h48: d=8'hd4;
+ 8'h49: d=8'ha4;
+ 8'h4a: d=8'h5c;
+ 8'h4b: d=8'hcc;
+ 8'h4c: d=8'h5d;
+ 8'h4d: d=8'h65;
+ 8'h4e: d=8'hb6;
+ 8'h4f: d=8'h92;
+ 8'h50: d=8'h6c;
+ 8'h51: d=8'h70;
+ 8'h52: d=8'h48;
+ 8'h53: d=8'h50;
+ 8'h54: d=8'hfd;
+ 8'h55: d=8'hed;
+ 8'h56: d=8'hb9;
+ 8'h57: d=8'hda;
+ 8'h58: d=8'h5e;
+ 8'h59: d=8'h15;
+ 8'h5a: d=8'h46;
+ 8'h5b: d=8'h57;
+ 8'h5c: d=8'ha7;
+ 8'h5d: d=8'h8d;
+ 8'h5e: d=8'h9d;
+ 8'h5f: d=8'h84;
+ 8'h60: d=8'h90;
+ 8'h61: d=8'hd8;
+ 8'h62: d=8'hab;
+ 8'h63: d=8'h00;
+ 8'h64: d=8'h8c;
+ 8'h65: d=8'hbc;
+ 8'h66: d=8'hd3;
+ 8'h67: d=8'h0a;
+ 8'h68: d=8'hf7;
+ 8'h69: d=8'he4;
+ 8'h6a: d=8'h58;
+ 8'h6b: d=8'h05;
+ 8'h6c: d=8'hb8;
+ 8'h6d: d=8'hb3;
+ 8'h6e: d=8'h45;
+ 8'h6f: d=8'h06;
+ 8'h70: d=8'hd0;
+ 8'h71: d=8'h2c;
+ 8'h72: d=8'h1e;
+ 8'h73: d=8'h8f;
+ 8'h74: d=8'hca;
+ 8'h75: d=8'h3f;
+ 8'h76: d=8'h0f;
+ 8'h77: d=8'h02;
+ 8'h78: d=8'hc1;
+ 8'h79: d=8'haf;
+ 8'h7a: d=8'hbd;
+ 8'h7b: d=8'h03;
+ 8'h7c: d=8'h01;
+ 8'h7d: d=8'h13;
+ 8'h7e: d=8'h8a;
+ 8'h7f: d=8'h6b;
+ 8'h80: d=8'h3a;
+ 8'h81: d=8'h91;
+ 8'h82: d=8'h11;
+ 8'h83: d=8'h41;
+ 8'h84: d=8'h4f;
+ 8'h85: d=8'h67;
+ 8'h86: d=8'hdc;
+ 8'h87: d=8'hea;
+ 8'h88: d=8'h97;
+ 8'h89: d=8'hf2;
+ 8'h8a: d=8'hcf;
+ 8'h8b: d=8'hce;
+ 8'h8c: d=8'hf0;
+ 8'h8d: d=8'hb4;
+ 8'h8e: d=8'he6;
+ 8'h8f: d=8'h73;
+ 8'h90: d=8'h96;
+ 8'h91: d=8'hac;
+ 8'h92: d=8'h74;
+ 8'h93: d=8'h22;
+ 8'h94: d=8'he7;
+ 8'h95: d=8'had;
+ 8'h96: d=8'h35;
+ 8'h97: d=8'h85;
+ 8'h98: d=8'he2;
+ 8'h99: d=8'hf9;
+ 8'h9a: d=8'h37;
+ 8'h9b: d=8'he8;
+ 8'h9c: d=8'h1c;
+ 8'h9d: d=8'h75;
+ 8'h9e: d=8'hdf;
+ 8'h9f: d=8'h6e;
+ 8'ha0: d=8'h47;
+ 8'ha1: d=8'hf1;
+ 8'ha2: d=8'h1a;
+ 8'ha3: d=8'h71;
+ 8'ha4: d=8'h1d;
+ 8'ha5: d=8'h29;
+ 8'ha6: d=8'hc5;
+ 8'ha7: d=8'h89;
+ 8'ha8: d=8'h6f;
+ 8'ha9: d=8'hb7;
+ 8'haa: d=8'h62;
+ 8'hab: d=8'h0e;
+ 8'hac: d=8'haa;
+ 8'had: d=8'h18;
+ 8'hae: d=8'hbe;
+ 8'haf: d=8'h1b;
+ 8'hb0: d=8'hfc;
+ 8'hb1: d=8'h56;
+ 8'hb2: d=8'h3e;
+ 8'hb3: d=8'h4b;
+ 8'hb4: d=8'hc6;
+ 8'hb5: d=8'hd2;
+ 8'hb6: d=8'h79;
+ 8'hb7: d=8'h20;
+ 8'hb8: d=8'h9a;
+ 8'hb9: d=8'hdb;
+ 8'hba: d=8'hc0;
+ 8'hbb: d=8'hfe;
+ 8'hbc: d=8'h78;
+ 8'hbd: d=8'hcd;
+ 8'hbe: d=8'h5a;
+ 8'hbf: d=8'hf4;
+ 8'hc0: d=8'h1f;
+ 8'hc1: d=8'hdd;
+ 8'hc2: d=8'ha8;
+ 8'hc3: d=8'h33;
+ 8'hc4: d=8'h88;
+ 8'hc5: d=8'h07;
+ 8'hc6: d=8'hc7;
+ 8'hc7: d=8'h31;
+ 8'hc8: d=8'hb1;
+ 8'hc9: d=8'h12;
+ 8'hca: d=8'h10;
+ 8'hcb: d=8'h59;
+ 8'hcc: d=8'h27;
+ 8'hcd: d=8'h80;
+ 8'hce: d=8'hec;
+ 8'hcf: d=8'h5f;
+ 8'hd0: d=8'h60;
+ 8'hd1: d=8'h51;
+ 8'hd2: d=8'h7f;
+ 8'hd3: d=8'ha9;
+ 8'hd4: d=8'h19;
+ 8'hd5: d=8'hb5;
+ 8'hd6: d=8'h4a;
+ 8'hd7: d=8'h0d;
+ 8'hd8: d=8'h2d;
+ 8'hd9: d=8'he5;
+ 8'hda: d=8'h7a;
+ 8'hdb: d=8'h9f;
+ 8'hdc: d=8'h93;
+ 8'hdd: d=8'hc9;
+ 8'hde: d=8'h9c;
+ 8'hdf: d=8'hef;
+ 8'he0: d=8'ha0;
+ 8'he1: d=8'he0;
+ 8'he2: d=8'h3b;
+ 8'he3: d=8'h4d;
+ 8'he4: d=8'hae;
+ 8'he5: d=8'h2a;
+ 8'he6: d=8'hf5;
+ 8'he7: d=8'hb0;
+ 8'he8: d=8'hc8;
+ 8'he9: d=8'heb;
+ 8'hea: d=8'hbb;
+ 8'heb: d=8'h3c;
+ 8'hec: d=8'h83;
+ 8'hed: d=8'h53;
+ 8'hee: d=8'h99;
+ 8'hef: d=8'h61;
+ 8'hf0: d=8'h17;
+ 8'hf1: d=8'h2b;
+ 8'hf2: d=8'h04;
+ 8'hf3: d=8'h7e;
+ 8'hf4: d=8'hba;
+ 8'hf5: d=8'h77;
+ 8'hf6: d=8'hd6;
+ 8'hf7: d=8'h26;
+ 8'hf8: d=8'he1;
+ 8'hf9: d=8'h69;
+ 8'hfa: d=8'h14;
+ 8'hfb: d=8'h63;
+ 8'hfc: d=8'h55;
+ 8'hfd: d=8'h21;
+ 8'hfe: d=8'h0c;
+ 8'hff: d=8'h7d;
+ endcase
+endmodule
+
+
diff --git a/tests/iwls2005/aes_core/aes_key_expand_128.v b/tests/iwls2005/aes_core/aes_key_expand_128.v
new file mode 100644
index 000000000..ddc74b732
--- /dev/null
+++ b/tests/iwls2005/aes_core/aes_key_expand_128.v
@@ -0,0 +1,87 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// AES Key Expand Block (for 128 bit keys) ////
+//// ////
+//// ////
+//// Author: Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+//// ////
+//// Downloaded from: http://www.opencores.org/cores/aes_core/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000-2002 Rudolf Usselmann ////
+//// www.asics.ws ////
+//// rudi@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: aes_key_expand_128.v,v 1.1.1.1 2002/11/09 11:22:38 rudi Exp $
+//
+// $Date: 2002/11/09 11:22:38 $
+// $Revision: 1.1.1.1 $
+// $Author: rudi $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: aes_key_expand_128.v,v $
+// Revision 1.1.1.1 2002/11/09 11:22:38 rudi
+// Initial Checkin
+//
+//
+//
+//
+//
+//
+
+`include "timescale.v"
+
+module aes_key_expand_128(clk, kld, key, wo_0, wo_1, wo_2, wo_3);
+input clk;
+input kld;
+input [127:0] key;
+output [31:0] wo_0, wo_1, wo_2, wo_3;
+reg [31:0] w[3:0];
+wire [31:0] tmp_w;
+wire [31:0] subword;
+wire [31:0] rcon;
+
+assign wo_0 = w[0];
+assign wo_1 = w[1];
+assign wo_2 = w[2];
+assign wo_3 = w[3];
+always @(posedge clk) w[0] <= #1 kld ? key[127:096] : w[0]^subword^rcon;
+always @(posedge clk) w[1] <= #1 kld ? key[095:064] : w[0]^w[1]^subword^rcon;
+always @(posedge clk) w[2] <= #1 kld ? key[063:032] : w[0]^w[2]^w[1]^subword^rcon;
+always @(posedge clk) w[3] <= #1 kld ? key[031:000] : w[0]^w[3]^w[2]^w[1]^subword^rcon;
+assign tmp_w = w[3];
+aes_sbox u0( .a(tmp_w[23:16]), .d(subword[31:24]));
+aes_sbox u1( .a(tmp_w[15:08]), .d(subword[23:16]));
+aes_sbox u2( .a(tmp_w[07:00]), .d(subword[15:08]));
+aes_sbox u3( .a(tmp_w[31:24]), .d(subword[07:00]));
+aes_rcon r0( .clk(clk), .kld(kld), .out(rcon));
+endmodule
+
diff --git a/tests/iwls2005/aes_core/aes_rcon.v b/tests/iwls2005/aes_core/aes_rcon.v
new file mode 100644
index 000000000..c2c0a1242
--- /dev/null
+++ b/tests/iwls2005/aes_core/aes_rcon.v
@@ -0,0 +1,96 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// AES RCON Block ////
+//// ////
+//// ////
+//// Author: Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+//// ////
+//// Downloaded from: http://www.opencores.org/cores/aes_core/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000-2002 Rudolf Usselmann ////
+//// www.asics.ws ////
+//// rudi@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: aes_rcon.v,v 1.1.1.1 2002/11/09 11:22:38 rudi Exp $
+//
+// $Date: 2002/11/09 11:22:38 $
+// $Revision: 1.1.1.1 $
+// $Author: rudi $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: aes_rcon.v,v $
+// Revision 1.1.1.1 2002/11/09 11:22:38 rudi
+// Initial Checkin
+//
+//
+//
+//
+//
+//
+
+`include "timescale.v"
+
+module aes_rcon(clk, kld, out);
+input clk;
+input kld;
+output [31:0] out;
+reg [31:0] out;
+reg [3:0] rcnt;
+wire [3:0] rcnt_next;
+
+always @(posedge clk)
+ if(kld) out <= #1 32'h01_00_00_00;
+ else out <= #1 frcon(rcnt_next);
+
+assign rcnt_next = rcnt + 4'h1;
+always @(posedge clk)
+ if(kld) rcnt <= #1 4'h0;
+ else rcnt <= #1 rcnt_next;
+
+function [31:0] frcon;
+input [3:0] i;
+case(i) // synopsys parallel_case
+ 4'h0: frcon=32'h01_00_00_00;
+ 4'h1: frcon=32'h02_00_00_00;
+ 4'h2: frcon=32'h04_00_00_00;
+ 4'h3: frcon=32'h08_00_00_00;
+ 4'h4: frcon=32'h10_00_00_00;
+ 4'h5: frcon=32'h20_00_00_00;
+ 4'h6: frcon=32'h40_00_00_00;
+ 4'h7: frcon=32'h80_00_00_00;
+ 4'h8: frcon=32'h1b_00_00_00;
+ 4'h9: frcon=32'h36_00_00_00;
+ default: frcon=32'h00_00_00_00;
+endcase
+endfunction
+
+endmodule
diff --git a/tests/iwls2005/aes_core/aes_sbox.v b/tests/iwls2005/aes_core/aes_sbox.v
new file mode 100644
index 000000000..e01d75ef8
--- /dev/null
+++ b/tests/iwls2005/aes_core/aes_sbox.v
@@ -0,0 +1,329 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// AES SBOX (ROM) ////
+//// ////
+//// ////
+//// Author: Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+//// ////
+//// Downloaded from: http://www.opencores.org/cores/aes_core/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000-2002 Rudolf Usselmann ////
+//// www.asics.ws ////
+//// rudi@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: aes_sbox.v,v 1.1.1.1 2002/11/09 11:22:38 rudi Exp $
+//
+// $Date: 2002/11/09 11:22:38 $
+// $Revision: 1.1.1.1 $
+// $Author: rudi $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: aes_sbox.v,v $
+// Revision 1.1.1.1 2002/11/09 11:22:38 rudi
+// Initial Checkin
+//
+//
+//
+//
+//
+//
+
+`include "timescale.v"
+
+module aes_sbox(a,d);
+input [7:0] a;
+output [7:0] d;
+reg [7:0] d;
+
+always @(a)
+ case(a) // synopsys full_case parallel_case
+ 8'h00: d=8'h63;
+ 8'h01: d=8'h7c;
+ 8'h02: d=8'h77;
+ 8'h03: d=8'h7b;
+ 8'h04: d=8'hf2;
+ 8'h05: d=8'h6b;
+ 8'h06: d=8'h6f;
+ 8'h07: d=8'hc5;
+ 8'h08: d=8'h30;
+ 8'h09: d=8'h01;
+ 8'h0a: d=8'h67;
+ 8'h0b: d=8'h2b;
+ 8'h0c: d=8'hfe;
+ 8'h0d: d=8'hd7;
+ 8'h0e: d=8'hab;
+ 8'h0f: d=8'h76;
+ 8'h10: d=8'hca;
+ 8'h11: d=8'h82;
+ 8'h12: d=8'hc9;
+ 8'h13: d=8'h7d;
+ 8'h14: d=8'hfa;
+ 8'h15: d=8'h59;
+ 8'h16: d=8'h47;
+ 8'h17: d=8'hf0;
+ 8'h18: d=8'had;
+ 8'h19: d=8'hd4;
+ 8'h1a: d=8'ha2;
+ 8'h1b: d=8'haf;
+ 8'h1c: d=8'h9c;
+ 8'h1d: d=8'ha4;
+ 8'h1e: d=8'h72;
+ 8'h1f: d=8'hc0;
+ 8'h20: d=8'hb7;
+ 8'h21: d=8'hfd;
+ 8'h22: d=8'h93;
+ 8'h23: d=8'h26;
+ 8'h24: d=8'h36;
+ 8'h25: d=8'h3f;
+ 8'h26: d=8'hf7;
+ 8'h27: d=8'hcc;
+ 8'h28: d=8'h34;
+ 8'h29: d=8'ha5;
+ 8'h2a: d=8'he5;
+ 8'h2b: d=8'hf1;
+ 8'h2c: d=8'h71;
+ 8'h2d: d=8'hd8;
+ 8'h2e: d=8'h31;
+ 8'h2f: d=8'h15;
+ 8'h30: d=8'h04;
+ 8'h31: d=8'hc7;
+ 8'h32: d=8'h23;
+ 8'h33: d=8'hc3;
+ 8'h34: d=8'h18;
+ 8'h35: d=8'h96;
+ 8'h36: d=8'h05;
+ 8'h37: d=8'h9a;
+ 8'h38: d=8'h07;
+ 8'h39: d=8'h12;
+ 8'h3a: d=8'h80;
+ 8'h3b: d=8'he2;
+ 8'h3c: d=8'heb;
+ 8'h3d: d=8'h27;
+ 8'h3e: d=8'hb2;
+ 8'h3f: d=8'h75;
+ 8'h40: d=8'h09;
+ 8'h41: d=8'h83;
+ 8'h42: d=8'h2c;
+ 8'h43: d=8'h1a;
+ 8'h44: d=8'h1b;
+ 8'h45: d=8'h6e;
+ 8'h46: d=8'h5a;
+ 8'h47: d=8'ha0;
+ 8'h48: d=8'h52;
+ 8'h49: d=8'h3b;
+ 8'h4a: d=8'hd6;
+ 8'h4b: d=8'hb3;
+ 8'h4c: d=8'h29;
+ 8'h4d: d=8'he3;
+ 8'h4e: d=8'h2f;
+ 8'h4f: d=8'h84;
+ 8'h50: d=8'h53;
+ 8'h51: d=8'hd1;
+ 8'h52: d=8'h00;
+ 8'h53: d=8'hed;
+ 8'h54: d=8'h20;
+ 8'h55: d=8'hfc;
+ 8'h56: d=8'hb1;
+ 8'h57: d=8'h5b;
+ 8'h58: d=8'h6a;
+ 8'h59: d=8'hcb;
+ 8'h5a: d=8'hbe;
+ 8'h5b: d=8'h39;
+ 8'h5c: d=8'h4a;
+ 8'h5d: d=8'h4c;
+ 8'h5e: d=8'h58;
+ 8'h5f: d=8'hcf;
+ 8'h60: d=8'hd0;
+ 8'h61: d=8'hef;
+ 8'h62: d=8'haa;
+ 8'h63: d=8'hfb;
+ 8'h64: d=8'h43;
+ 8'h65: d=8'h4d;
+ 8'h66: d=8'h33;
+ 8'h67: d=8'h85;
+ 8'h68: d=8'h45;
+ 8'h69: d=8'hf9;
+ 8'h6a: d=8'h02;
+ 8'h6b: d=8'h7f;
+ 8'h6c: d=8'h50;
+ 8'h6d: d=8'h3c;
+ 8'h6e: d=8'h9f;
+ 8'h6f: d=8'ha8;
+ 8'h70: d=8'h51;
+ 8'h71: d=8'ha3;
+ 8'h72: d=8'h40;
+ 8'h73: d=8'h8f;
+ 8'h74: d=8'h92;
+ 8'h75: d=8'h9d;
+ 8'h76: d=8'h38;
+ 8'h77: d=8'hf5;
+ 8'h78: d=8'hbc;
+ 8'h79: d=8'hb6;
+ 8'h7a: d=8'hda;
+ 8'h7b: d=8'h21;
+ 8'h7c: d=8'h10;
+ 8'h7d: d=8'hff;
+ 8'h7e: d=8'hf3;
+ 8'h7f: d=8'hd2;
+ 8'h80: d=8'hcd;
+ 8'h81: d=8'h0c;
+ 8'h82: d=8'h13;
+ 8'h83: d=8'hec;
+ 8'h84: d=8'h5f;
+ 8'h85: d=8'h97;
+ 8'h86: d=8'h44;
+ 8'h87: d=8'h17;
+ 8'h88: d=8'hc4;
+ 8'h89: d=8'ha7;
+ 8'h8a: d=8'h7e;
+ 8'h8b: d=8'h3d;
+ 8'h8c: d=8'h64;
+ 8'h8d: d=8'h5d;
+ 8'h8e: d=8'h19;
+ 8'h8f: d=8'h73;
+ 8'h90: d=8'h60;
+ 8'h91: d=8'h81;
+ 8'h92: d=8'h4f;
+ 8'h93: d=8'hdc;
+ 8'h94: d=8'h22;
+ 8'h95: d=8'h2a;
+ 8'h96: d=8'h90;
+ 8'h97: d=8'h88;
+ 8'h98: d=8'h46;
+ 8'h99: d=8'hee;
+ 8'h9a: d=8'hb8;
+ 8'h9b: d=8'h14;
+ 8'h9c: d=8'hde;
+ 8'h9d: d=8'h5e;
+ 8'h9e: d=8'h0b;
+ 8'h9f: d=8'hdb;
+ 8'ha0: d=8'he0;
+ 8'ha1: d=8'h32;
+ 8'ha2: d=8'h3a;
+ 8'ha3: d=8'h0a;
+ 8'ha4: d=8'h49;
+ 8'ha5: d=8'h06;
+ 8'ha6: d=8'h24;
+ 8'ha7: d=8'h5c;
+ 8'ha8: d=8'hc2;
+ 8'ha9: d=8'hd3;
+ 8'haa: d=8'hac;
+ 8'hab: d=8'h62;
+ 8'hac: d=8'h91;
+ 8'had: d=8'h95;
+ 8'hae: d=8'he4;
+ 8'haf: d=8'h79;
+ 8'hb0: d=8'he7;
+ 8'hb1: d=8'hc8;
+ 8'hb2: d=8'h37;
+ 8'hb3: d=8'h6d;
+ 8'hb4: d=8'h8d;
+ 8'hb5: d=8'hd5;
+ 8'hb6: d=8'h4e;
+ 8'hb7: d=8'ha9;
+ 8'hb8: d=8'h6c;
+ 8'hb9: d=8'h56;
+ 8'hba: d=8'hf4;
+ 8'hbb: d=8'hea;
+ 8'hbc: d=8'h65;
+ 8'hbd: d=8'h7a;
+ 8'hbe: d=8'hae;
+ 8'hbf: d=8'h08;
+ 8'hc0: d=8'hba;
+ 8'hc1: d=8'h78;
+ 8'hc2: d=8'h25;
+ 8'hc3: d=8'h2e;
+ 8'hc4: d=8'h1c;
+ 8'hc5: d=8'ha6;
+ 8'hc6: d=8'hb4;
+ 8'hc7: d=8'hc6;
+ 8'hc8: d=8'he8;
+ 8'hc9: d=8'hdd;
+ 8'hca: d=8'h74;
+ 8'hcb: d=8'h1f;
+ 8'hcc: d=8'h4b;
+ 8'hcd: d=8'hbd;
+ 8'hce: d=8'h8b;
+ 8'hcf: d=8'h8a;
+ 8'hd0: d=8'h70;
+ 8'hd1: d=8'h3e;
+ 8'hd2: d=8'hb5;
+ 8'hd3: d=8'h66;
+ 8'hd4: d=8'h48;
+ 8'hd5: d=8'h03;
+ 8'hd6: d=8'hf6;
+ 8'hd7: d=8'h0e;
+ 8'hd8: d=8'h61;
+ 8'hd9: d=8'h35;
+ 8'hda: d=8'h57;
+ 8'hdb: d=8'hb9;
+ 8'hdc: d=8'h86;
+ 8'hdd: d=8'hc1;
+ 8'hde: d=8'h1d;
+ 8'hdf: d=8'h9e;
+ 8'he0: d=8'he1;
+ 8'he1: d=8'hf8;
+ 8'he2: d=8'h98;
+ 8'he3: d=8'h11;
+ 8'he4: d=8'h69;
+ 8'he5: d=8'hd9;
+ 8'he6: d=8'h8e;
+ 8'he7: d=8'h94;
+ 8'he8: d=8'h9b;
+ 8'he9: d=8'h1e;
+ 8'hea: d=8'h87;
+ 8'heb: d=8'he9;
+ 8'hec: d=8'hce;
+ 8'hed: d=8'h55;
+ 8'hee: d=8'h28;
+ 8'hef: d=8'hdf;
+ 8'hf0: d=8'h8c;
+ 8'hf1: d=8'ha1;
+ 8'hf2: d=8'h89;
+ 8'hf3: d=8'h0d;
+ 8'hf4: d=8'hbf;
+ 8'hf5: d=8'he6;
+ 8'hf6: d=8'h42;
+ 8'hf7: d=8'h68;
+ 8'hf8: d=8'h41;
+ 8'hf9: d=8'h99;
+ 8'hfa: d=8'h2d;
+ 8'hfb: d=8'h0f;
+ 8'hfc: d=8'hb0;
+ 8'hfd: d=8'h54;
+ 8'hfe: d=8'hbb;
+ 8'hff: d=8'h16;
+ endcase
+
+endmodule
+
+
diff --git a/tests/iwls2005/aes_core/timescale.v b/tests/iwls2005/aes_core/timescale.v
new file mode 100644
index 000000000..ff9e265a8
--- /dev/null
+++ b/tests/iwls2005/aes_core/timescale.v
@@ -0,0 +1 @@
+`timescale 1ns / 10ps
diff --git a/tests/iwls2005/fpu/except.v b/tests/iwls2005/fpu/except.v
new file mode 100644
index 000000000..007099fe1
--- /dev/null
+++ b/tests/iwls2005/fpu/except.v
@@ -0,0 +1,153 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// EXCEPT ////
+//// Floating Point Exception/Special Numbers Unit ////
+//// ////
+//// Author: Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+
+`timescale 1ns / 100ps
+
+
+module except( clk, opa, opb, inf, ind, qnan, snan, opa_nan, opb_nan,
+ opa_00, opb_00, opa_inf, opb_inf, opa_dn, opb_dn);
+input clk;
+input [31:0] opa, opb;
+output inf, ind, qnan, snan, opa_nan, opb_nan;
+output opa_00, opb_00;
+output opa_inf, opb_inf;
+output opa_dn;
+output opb_dn;
+
+////////////////////////////////////////////////////////////////////////
+//
+// Local Wires and registers
+//
+
+wire [7:0] expa, expb; // alias to opX exponent
+wire [22:0] fracta, fractb; // alias to opX fraction
+reg expa_ff, infa_f_r, qnan_r_a, snan_r_a;
+reg expb_ff, infb_f_r, qnan_r_b, snan_r_b;
+reg inf, ind, qnan, snan; // Output registers
+reg opa_nan, opb_nan;
+reg expa_00, expb_00, fracta_00, fractb_00;
+reg opa_00, opb_00;
+reg opa_inf, opb_inf;
+reg opa_dn, opb_dn;
+
+////////////////////////////////////////////////////////////////////////
+//
+// Aliases
+//
+
+assign expa = opa[30:23];
+assign expb = opb[30:23];
+assign fracta = opa[22:0];
+assign fractb = opb[22:0];
+
+////////////////////////////////////////////////////////////////////////
+//
+// Determine if any of the input operators is a INF or NAN or any other special number
+//
+
+always @(posedge clk)
+ expa_ff <= #1 &expa;
+
+always @(posedge clk)
+ expb_ff <= #1 &expb;
+
+always @(posedge clk)
+ infa_f_r <= #1 !(|fracta);
+
+always @(posedge clk)
+ infb_f_r <= #1 !(|fractb);
+
+always @(posedge clk)
+ qnan_r_a <= #1 fracta[22];
+
+always @(posedge clk)
+ snan_r_a <= #1 !fracta[22] & |fracta[21:0];
+
+always @(posedge clk)
+ qnan_r_b <= #1 fractb[22];
+
+always @(posedge clk)
+ snan_r_b <= #1 !fractb[22] & |fractb[21:0];
+
+always @(posedge clk)
+ ind <= #1 (expa_ff & infa_f_r) & (expb_ff & infb_f_r);
+
+always @(posedge clk)
+ inf <= #1 (expa_ff & infa_f_r) | (expb_ff & infb_f_r);
+
+always @(posedge clk)
+ qnan <= #1 (expa_ff & qnan_r_a) | (expb_ff & qnan_r_b);
+
+always @(posedge clk)
+ snan <= #1 (expa_ff & snan_r_a) | (expb_ff & snan_r_b);
+
+always @(posedge clk)
+ opa_nan <= #1 &expa & (|fracta[22:0]);
+
+always @(posedge clk)
+ opb_nan <= #1 &expb & (|fractb[22:0]);
+
+always @(posedge clk)
+ opa_inf <= #1 (expa_ff & infa_f_r);
+
+always @(posedge clk)
+ opb_inf <= #1 (expb_ff & infb_f_r);
+
+always @(posedge clk)
+ expa_00 <= #1 !(|expa);
+
+always @(posedge clk)
+ expb_00 <= #1 !(|expb);
+
+always @(posedge clk)
+ fracta_00 <= #1 !(|fracta);
+
+always @(posedge clk)
+ fractb_00 <= #1 !(|fractb);
+
+always @(posedge clk)
+ opa_00 <= #1 expa_00 & fracta_00;
+
+always @(posedge clk)
+ opb_00 <= #1 expb_00 & fractb_00;
+
+always @(posedge clk)
+ opa_dn <= #1 expa_00;
+
+always @(posedge clk)
+ opb_dn <= #1 expb_00;
+
+endmodule
+
diff --git a/tests/iwls2005/fpu/fpu.v b/tests/iwls2005/fpu/fpu.v
new file mode 100644
index 000000000..165a1d246
--- /dev/null
+++ b/tests/iwls2005/fpu/fpu.v
@@ -0,0 +1,560 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// FPU ////
+//// Floating Point Unit (Single precision) ////
+//// ////
+//// Author: Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+`timescale 1ns / 100ps
+
+/*
+
+FPU Operations (fpu_op):
+========================
+
+0 = add
+1 = sub
+2 = mul
+3 = div
+4 =
+5 =
+6 =
+7 =
+
+Rounding Modes (rmode):
+=======================
+
+0 = round_nearest_even
+1 = round_to_zero
+2 = round_up
+3 = round_down
+
+*/
+
+
+module fpu( clk, rmode, fpu_op, opa, opb, out, inf, snan, qnan, ine, overflow, underflow, zero, div_by_zero);
+input clk;
+input [1:0] rmode;
+input [2:0] fpu_op;
+input [31:0] opa, opb;
+output [31:0] out;
+output inf, snan, qnan;
+output ine;
+output overflow, underflow;
+output zero;
+output div_by_zero;
+
+parameter INF = 31'h7f800000,
+ QNAN = 31'h7fc00001,
+ SNAN = 31'h7f800001;
+
+////////////////////////////////////////////////////////////////////////
+//
+// Local Wires
+//
+reg zero;
+reg [31:0] opa_r, opb_r; // Input operand registers
+reg [31:0] out; // Output register
+reg div_by_zero; // Divide by zero output register
+wire signa, signb; // alias to opX sign
+wire sign_fasu; // sign output
+wire [26:0] fracta, fractb; // Fraction Outputs from EQU block
+wire [7:0] exp_fasu; // Exponent output from EQU block
+reg [7:0] exp_r; // Exponent output (registerd)
+wire [26:0] fract_out_d; // fraction output
+wire co; // carry output
+reg [27:0] fract_out_q; // fraction output (registerd)
+wire [30:0] out_d; // Intermediate final result output
+wire overflow_d, underflow_d;// Overflow/Underflow Indicators
+reg overflow, underflow; // Output registers for Overflow & Underflow
+reg inf, snan, qnan; // Output Registers for INF, SNAN and QNAN
+reg ine; // Output Registers for INE
+reg [1:0] rmode_r1, rmode_r2, // Pipeline registers for rounding mode
+ rmode_r3;
+reg [2:0] fpu_op_r1, fpu_op_r2, // Pipeline registers for fp opration
+ fpu_op_r3;
+wire mul_inf, div_inf;
+wire mul_00, div_00;
+
+////////////////////////////////////////////////////////////////////////
+//
+// Input Registers
+//
+
+always @(posedge clk)
+ opa_r <= #1 opa;
+
+always @(posedge clk)
+ opb_r <= #1 opb;
+
+always @(posedge clk)
+ rmode_r1 <= #1 rmode;
+
+always @(posedge clk)
+ rmode_r2 <= #1 rmode_r1;
+
+always @(posedge clk)
+ rmode_r3 <= #1 rmode_r2;
+
+always @(posedge clk)
+ fpu_op_r1 <= #1 fpu_op;
+
+always @(posedge clk)
+ fpu_op_r2 <= #1 fpu_op_r1;
+
+always @(posedge clk)
+ fpu_op_r3 <= #1 fpu_op_r2;
+
+////////////////////////////////////////////////////////////////////////
+//
+// Exceptions block
+//
+wire inf_d, ind_d, qnan_d, snan_d, opa_nan, opb_nan;
+wire opa_00, opb_00;
+wire opa_inf, opb_inf;
+wire opa_dn, opb_dn;
+
+except u0( .clk(clk),
+ .opa(opa_r), .opb(opb_r),
+ .inf(inf_d), .ind(ind_d),
+ .qnan(qnan_d), .snan(snan_d),
+ .opa_nan(opa_nan), .opb_nan(opb_nan),
+ .opa_00(opa_00), .opb_00(opb_00),
+ .opa_inf(opa_inf), .opb_inf(opb_inf),
+ .opa_dn(opa_dn), .opb_dn(opb_dn)
+ );
+
+////////////////////////////////////////////////////////////////////////
+//
+// Pre-Normalize block
+// - Adjusts the numbers to equal exponents and sorts them
+// - determine result sign
+// - determine actual operation to perform (add or sub)
+//
+
+wire nan_sign_d, result_zero_sign_d;
+reg sign_fasu_r;
+wire [7:0] exp_mul;
+wire sign_mul;
+reg sign_mul_r;
+wire [23:0] fracta_mul, fractb_mul;
+wire inf_mul;
+reg inf_mul_r;
+wire [1:0] exp_ovf;
+reg [1:0] exp_ovf_r;
+wire sign_exe;
+reg sign_exe_r;
+wire [2:0] underflow_fmul_d;
+
+
+pre_norm u1(.clk(clk), // System Clock
+ .rmode(rmode_r2), // Roundin Mode
+ .add(!fpu_op_r1[0]), // Add/Sub Input
+ .opa(opa_r), .opb(opb_r), // Registered OP Inputs
+ .opa_nan(opa_nan), // OpA is a NAN indicator
+ .opb_nan(opb_nan), // OpB is a NAN indicator
+ .fracta_out(fracta), // Equalized and sorted fraction
+ .fractb_out(fractb), // outputs (Registered)
+ .exp_dn_out(exp_fasu), // Selected exponent output (registered);
+ .sign(sign_fasu), // Encoded output Sign (registered)
+ .nan_sign(nan_sign_d), // Output Sign for NANs (registered)
+ .result_zero_sign(result_zero_sign_d), // Output Sign for zero result (registered)
+ .fasu_op(fasu_op) // Actual fasu operation output (registered)
+ );
+
+always @(posedge clk)
+ sign_fasu_r <= #1 sign_fasu;
+
+pre_norm_fmul u2(
+ .clk(clk),
+ .fpu_op(fpu_op_r1),
+ .opa(opa_r), .opb(opb_r),
+ .fracta(fracta_mul),
+ .fractb(fractb_mul),
+ .exp_out(exp_mul), // FMUL exponent output (registered)
+ .sign(sign_mul), // FMUL sign output (registered)
+ .sign_exe(sign_exe), // FMUL exception sign output (registered)
+ .inf(inf_mul), // FMUL inf output (registered)
+ .exp_ovf(exp_ovf), // FMUL exponnent overflow output (registered)
+ .underflow(underflow_fmul_d)
+ );
+
+
+always @(posedge clk)
+ sign_mul_r <= #1 sign_mul;
+
+always @(posedge clk)
+ sign_exe_r <= #1 sign_exe;
+
+always @(posedge clk)
+ inf_mul_r <= #1 inf_mul;
+
+always @(posedge clk)
+ exp_ovf_r <= #1 exp_ovf;
+
+
+////////////////////////////////////////////////////////////////////////
+//
+// Add/Sub
+//
+
+add_sub27 u3(
+ .add(fasu_op), // Add/Sub
+ .opa(fracta), // Fraction A input
+ .opb(fractb), // Fraction B Input
+ .sum(fract_out_d), // SUM output
+ .co(co_d) ); // Carry Output
+
+always @(posedge clk)
+ fract_out_q <= #1 {co_d, fract_out_d};
+
+////////////////////////////////////////////////////////////////////////
+//
+// Mul
+//
+wire [47:0] prod;
+
+mul_r2 u5(.clk(clk), .opa(fracta_mul), .opb(fractb_mul), .prod(prod));
+
+////////////////////////////////////////////////////////////////////////
+//
+// Divide
+//
+wire [49:0] quo;
+wire [49:0] fdiv_opa;
+wire [49:0] remainder;
+wire remainder_00;
+reg [4:0] div_opa_ldz_d, div_opa_ldz_r1, div_opa_ldz_r2;
+
+always @(fracta_mul)
+ casex(fracta_mul[22:0])
+ 23'b1??????????????????????: div_opa_ldz_d = 1;
+ 23'b01?????????????????????: div_opa_ldz_d = 2;
+ 23'b001????????????????????: div_opa_ldz_d = 3;
+ 23'b0001???????????????????: div_opa_ldz_d = 4;
+ 23'b00001??????????????????: div_opa_ldz_d = 5;
+ 23'b000001?????????????????: div_opa_ldz_d = 6;
+ 23'b0000001????????????????: div_opa_ldz_d = 7;
+ 23'b00000001???????????????: div_opa_ldz_d = 8;
+ 23'b000000001??????????????: div_opa_ldz_d = 9;
+ 23'b0000000001?????????????: div_opa_ldz_d = 10;
+ 23'b00000000001????????????: div_opa_ldz_d = 11;
+ 23'b000000000001???????????: div_opa_ldz_d = 12;
+ 23'b0000000000001??????????: div_opa_ldz_d = 13;
+ 23'b00000000000001?????????: div_opa_ldz_d = 14;
+ 23'b000000000000001????????: div_opa_ldz_d = 15;
+ 23'b0000000000000001???????: div_opa_ldz_d = 16;
+ 23'b00000000000000001??????: div_opa_ldz_d = 17;
+ 23'b000000000000000001?????: div_opa_ldz_d = 18;
+ 23'b0000000000000000001????: div_opa_ldz_d = 19;
+ 23'b00000000000000000001???: div_opa_ldz_d = 20;
+ 23'b000000000000000000001??: div_opa_ldz_d = 21;
+ 23'b0000000000000000000001?: div_opa_ldz_d = 22;
+ 23'b0000000000000000000000?: div_opa_ldz_d = 23;
+ endcase
+
+assign fdiv_opa = !(|opa_r[30:23]) ? {(fracta_mul<<div_opa_ldz_d), 26'h0} : {fracta_mul, 26'h0};
+
+
+div_r2 u6(.clk(clk), .opa(fdiv_opa), .opb(fractb_mul), .quo(quo), .rem(remainder));
+
+assign remainder_00 = !(|remainder);
+
+always @(posedge clk)
+ div_opa_ldz_r1 <= #1 div_opa_ldz_d;
+
+always @(posedge clk)
+ div_opa_ldz_r2 <= #1 div_opa_ldz_r1;
+
+
+////////////////////////////////////////////////////////////////////////
+//
+// Normalize Result
+//
+wire ine_d;
+reg [47:0] fract_denorm;
+wire [47:0] fract_div;
+wire sign_d;
+reg sign;
+reg [30:0] opa_r1;
+reg [47:0] fract_i2f;
+reg opas_r1, opas_r2;
+wire f2i_out_sign;
+
+always @(posedge clk) // Exponent must be once cycle delayed
+ case(fpu_op_r2)
+ 0,1: exp_r <= #1 exp_fasu;
+ 2,3: exp_r <= #1 exp_mul;
+ 4: exp_r <= #1 0;
+ 5: exp_r <= #1 opa_r1[30:23];
+ endcase
+
+assign fract_div = (opb_dn ? quo[49:2] : {quo[26:0], 21'h0});
+
+always @(posedge clk)
+ opa_r1 <= #1 opa_r[30:0];
+
+always @(posedge clk)
+ fract_i2f <= #1 (fpu_op_r2==5) ?
+ (sign_d ? 1-{24'h00, (|opa_r1[30:23]), opa_r1[22:0]}-1 : {24'h0, (|opa_r1[30:23]), opa_r1[22:0]}) :
+ (sign_d ? 1 - {opa_r1, 17'h01} : {opa_r1, 17'h0});
+
+always @(fpu_op_r3 or fract_out_q or prod or fract_div or fract_i2f)
+ case(fpu_op_r3)
+ 0,1: fract_denorm = {fract_out_q, 20'h0};
+ 2: fract_denorm = prod;
+ 3: fract_denorm = fract_div;
+ 4,5: fract_denorm = fract_i2f;
+ endcase
+
+
+always @(posedge clk)
+ opas_r1 <= #1 opa_r[31];
+
+always @(posedge clk)
+ opas_r2 <= #1 opas_r1;
+
+assign sign_d = fpu_op_r2[1] ? sign_mul : sign_fasu;
+
+always @(posedge clk)
+ sign <= #1 (rmode_r2==2'h3) ? !sign_d : sign_d;
+
+post_norm u4(.clk(clk), // System Clock
+ .fpu_op(fpu_op_r3), // Floating Point Operation
+ .opas(opas_r2), // OPA Sign
+ .sign(sign), // Sign of the result
+ .rmode(rmode_r3), // Rounding mode
+ .fract_in(fract_denorm), // Fraction Input
+ .exp_ovf(exp_ovf_r), // Exponent Overflow
+ .exp_in(exp_r), // Exponent Input
+ .opa_dn(opa_dn), // Operand A Denormalized
+ .opb_dn(opb_dn), // Operand A Denormalized
+ .rem_00(remainder_00), // Diveide Remainder is zero
+ .div_opa_ldz(div_opa_ldz_r2), // Divide opa leading zeros count
+ .output_zero(mul_00 | div_00), // Force output to Zero
+ .out(out_d), // Normalized output (un-registered)
+ .ine(ine_d), // Result Inexact output (un-registered)
+ .overflow(overflow_d), // Overflow output (un-registered)
+ .underflow(underflow_d), // Underflow output (un-registered)
+ .f2i_out_sign(f2i_out_sign) // F2I Output Sign
+ );
+
+////////////////////////////////////////////////////////////////////////
+//
+// FPU Outputs
+//
+reg fasu_op_r1, fasu_op_r2;
+wire [30:0] out_fixed;
+wire output_zero_fasu;
+wire output_zero_fdiv;
+wire output_zero_fmul;
+reg inf_mul2;
+wire overflow_fasu;
+wire overflow_fmul;
+wire overflow_fdiv;
+wire inf_fmul;
+wire sign_mul_final;
+wire out_d_00;
+wire sign_div_final;
+wire ine_mul, ine_mula, ine_div, ine_fasu;
+wire underflow_fasu, underflow_fmul, underflow_fdiv;
+wire underflow_fmul1;
+reg [2:0] underflow_fmul_r;
+reg opa_nan_r;
+
+
+always @(posedge clk)
+ fasu_op_r1 <= #1 fasu_op;
+
+always @(posedge clk)
+ fasu_op_r2 <= #1 fasu_op_r1;
+
+always @(posedge clk)
+ inf_mul2 <= #1 exp_mul == 8'hff;
+
+
+// Force pre-set values for non numerical output
+assign mul_inf = (fpu_op_r3==3'b010) & (inf_mul_r | inf_mul2) & (rmode_r3==2'h0);
+assign div_inf = (fpu_op_r3==3'b011) & (opb_00 | opa_inf);
+
+assign mul_00 = (fpu_op_r3==3'b010) & (opa_00 | opb_00);
+assign div_00 = (fpu_op_r3==3'b011) & (opa_00 | opb_inf);
+
+assign out_fixed = ( (qnan_d | snan_d) |
+ (ind_d & !fasu_op_r2) |
+ ((fpu_op_r3==3'b011) & opb_00 & opa_00) |
+ (((opa_inf & opb_00) | (opb_inf & opa_00 )) & fpu_op_r3==3'b010)
+ ) ? QNAN : INF;
+
+always @(posedge clk)
+ out[30:0] <= #1 (mul_inf | div_inf | (inf_d & (fpu_op_r3!=3'b011) & (fpu_op_r3!=3'b101)) | snan_d | qnan_d) & fpu_op_r3!=3'b100 ? out_fixed :
+ out_d;
+
+assign out_d_00 = !(|out_d);
+
+assign sign_mul_final = (sign_exe_r & ((opa_00 & opb_inf) | (opb_00 & opa_inf))) ? !sign_mul_r : sign_mul_r;
+assign sign_div_final = (sign_exe_r & (opa_inf & opb_inf)) ? !sign_mul_r : sign_mul_r | (opa_00 & opb_00);
+
+always @(posedge clk)
+ out[31] <= #1 ((fpu_op_r3==3'b101) & out_d_00) ? (f2i_out_sign & !(qnan_d | snan_d) ) :
+ ((fpu_op_r3==3'b010) & !(snan_d | qnan_d)) ? sign_mul_final :
+ ((fpu_op_r3==3'b011) & !(snan_d | qnan_d)) ? sign_div_final :
+ (snan_d | qnan_d | ind_d) ? nan_sign_d :
+ output_zero_fasu ? result_zero_sign_d :
+ sign_fasu_r;
+
+// Exception Outputs
+assign ine_mula = ((inf_mul_r | inf_mul2 | opa_inf | opb_inf) & (rmode_r3==2'h1) &
+ !((opa_inf & opb_00) | (opb_inf & opa_00 )) & fpu_op_r3[1]);
+
+assign ine_mul = (ine_mula | ine_d | inf_fmul | out_d_00 | overflow_d | underflow_d) &
+ !opa_00 & !opb_00 & !(snan_d | qnan_d | inf_d);
+assign ine_div = (ine_d | overflow_d | underflow_d) & !(opb_00 | snan_d | qnan_d | inf_d);
+assign ine_fasu = (ine_d | overflow_d | underflow_d) & !(snan_d | qnan_d | inf_d);
+
+always @(posedge clk)
+ ine <= #1 fpu_op_r3[2] ? ine_d :
+ !fpu_op_r3[1] ? ine_fasu :
+ fpu_op_r3[0] ? ine_div : ine_mul;
+
+
+assign overflow_fasu = overflow_d & !(snan_d | qnan_d | inf_d);
+assign overflow_fmul = !inf_d & (inf_mul_r | inf_mul2 | overflow_d) & !(snan_d | qnan_d);
+assign overflow_fdiv = (overflow_d & !(opb_00 | inf_d | snan_d | qnan_d));
+
+always @(posedge clk)
+ overflow <= #1 fpu_op_r3[2] ? 0 :
+ !fpu_op_r3[1] ? overflow_fasu :
+ fpu_op_r3[0] ? overflow_fdiv : overflow_fmul;
+
+always @(posedge clk)
+ underflow_fmul_r <= #1 underflow_fmul_d;
+
+
+assign underflow_fmul1 = underflow_fmul_r[0] |
+ (underflow_fmul_r[1] & underflow_d ) |
+ ((opa_dn | opb_dn) & out_d_00 & (prod!=0) & sign) |
+ (underflow_fmul_r[2] & ((out_d[30:23]==0) | (out_d[22:0]==0)));
+
+assign underflow_fasu = underflow_d & !(inf_d | snan_d | qnan_d);
+assign underflow_fmul = underflow_fmul1 & !(snan_d | qnan_d | inf_mul_r);
+assign underflow_fdiv = underflow_fasu & !opb_00;
+
+always @(posedge clk)
+ underflow <= #1 fpu_op_r3[2] ? 0 :
+ !fpu_op_r3[1] ? underflow_fasu :
+ fpu_op_r3[0] ? underflow_fdiv : underflow_fmul;
+
+always @(posedge clk)
+ snan <= #1 snan_d;
+
+// synopsys translate_off
+wire mul_uf_del;
+wire uf2_del, ufb2_del, ufc2_del, underflow_d_del;
+wire co_del;
+wire [30:0] out_d_del;
+wire ov_fasu_del, ov_fmul_del;
+wire [2:0] fop;
+wire [4:0] ldza_del;
+wire [49:0] quo_del;
+
+delay1 #0 ud000(clk, underflow_fmul1, mul_uf_del);
+delay1 #0 ud001(clk, underflow_fmul_r[0], uf2_del);
+delay1 #0 ud002(clk, underflow_fmul_r[1], ufb2_del);
+delay1 #0 ud003(clk, underflow_d, underflow_d_del);
+delay1 #0 ud004(clk, test.u0.u4.exp_out1_co, co_del);
+delay1 #0 ud005(clk, underflow_fmul_r[2], ufc2_del);
+delay1 #30 ud006(clk, out_d, out_d_del);
+
+delay1 #0 ud007(clk, overflow_fasu, ov_fasu_del);
+delay1 #0 ud008(clk, overflow_fmul, ov_fmul_del);
+
+delay1 #2 ud009(clk, fpu_op_r3, fop);
+
+delay3 #4 ud010(clk, div_opa_ldz_d, ldza_del);
+
+delay1 #49 ud012(clk, quo, quo_del);
+
+always @(test.error_event)
+ begin
+ #0.2
+ $display("muf: %b uf0: %b uf1: %b uf2: %b, tx0: %b, co: %b, out_d: %h (%h %h), ov_fasu: %b, ov_fmul: %b, fop: %h",
+ mul_uf_del, uf2_del, ufb2_del, ufc2_del, underflow_d_del, co_del, out_d_del, out_d_del[30:23], out_d_del[22:0],
+ ov_fasu_del, ov_fmul_del, fop );
+ $display("ldza: %h, quo: %b",
+ ldza_del, quo_del);
+ end
+// synopsys translate_on
+
+
+
+// Status Outputs
+always @(posedge clk)
+ qnan <= #1 fpu_op_r3[2] ? 0 : (
+ snan_d | qnan_d | (ind_d & !fasu_op_r2) |
+ (opa_00 & opb_00 & fpu_op_r3==3'b011) |
+ (((opa_inf & opb_00) | (opb_inf & opa_00 )) & fpu_op_r3==3'b010)
+ );
+
+assign inf_fmul = (((inf_mul_r | inf_mul2) & (rmode_r3==2'h0)) | opa_inf | opb_inf) &
+ !((opa_inf & opb_00) | (opb_inf & opa_00 )) &
+ fpu_op_r3==3'b010;
+
+always @(posedge clk)
+ inf <= #1 fpu_op_r3[2] ? 0 :
+ (!(qnan_d | snan_d) & (
+ ((&out_d[30:23]) & !(|out_d[22:0]) & !(opb_00 & fpu_op_r3==3'b011)) |
+ (inf_d & !(ind_d & !fasu_op_r2) & !fpu_op_r3[1]) |
+ inf_fmul |
+ (!opa_00 & opb_00 & fpu_op_r3==3'b011) |
+ (fpu_op_r3==3'b011 & opa_inf & !opb_inf)
+ )
+ );
+
+assign output_zero_fasu = out_d_00 & !(inf_d | snan_d | qnan_d);
+assign output_zero_fdiv = (div_00 | (out_d_00 & !opb_00)) & !(opa_inf & opb_inf) &
+ !(opa_00 & opb_00) & !(qnan_d | snan_d);
+assign output_zero_fmul = (out_d_00 | opa_00 | opb_00) &
+ !(inf_mul_r | inf_mul2 | opa_inf | opb_inf | snan_d | qnan_d) &
+ !(opa_inf & opb_00) & !(opb_inf & opa_00);
+
+always @(posedge clk)
+ zero <= #1 fpu_op_r3==3'b101 ? out_d_00 & !(snan_d | qnan_d):
+ fpu_op_r3==3'b011 ? output_zero_fdiv :
+ fpu_op_r3==3'b010 ? output_zero_fmul :
+ output_zero_fasu ;
+
+always @(posedge clk)
+ opa_nan_r <= #1 !opa_nan & fpu_op_r2==3'b011;
+
+always @(posedge clk)
+ div_by_zero <= #1 opa_nan_r & !opa_00 & !opa_inf & opb_00;
+
+endmodule
diff --git a/tests/iwls2005/fpu/post_norm.v b/tests/iwls2005/fpu/post_norm.v
new file mode 100644
index 000000000..ff9cf6fbd
--- /dev/null
+++ b/tests/iwls2005/fpu/post_norm.v
@@ -0,0 +1,676 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Post Norm ////
+//// Floating Point Post Normalisation Unit ////
+//// ////
+//// Author: Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+
+`timescale 1ns / 100ps
+
+module post_norm( clk, fpu_op, opas, sign, rmode, fract_in, exp_in, exp_ovf,
+ opa_dn, opb_dn, rem_00, div_opa_ldz, output_zero, out,
+ ine, overflow, underflow, f2i_out_sign);
+input clk;
+input [2:0] fpu_op;
+input opas;
+input sign;
+input [1:0] rmode;
+input [47:0] fract_in;
+input [1:0] exp_ovf;
+input [7:0] exp_in;
+input opa_dn, opb_dn;
+input rem_00;
+input [4:0] div_opa_ldz;
+input output_zero;
+output [30:0] out;
+output ine;
+output overflow, underflow;
+output f2i_out_sign;
+
+////////////////////////////////////////////////////////////////////////
+//
+// Local Wires and registers
+//
+
+wire [22:0] fract_out;
+wire [7:0] exp_out;
+wire [30:0] out;
+wire exp_out1_co, overflow, underflow;
+wire [22:0] fract_out_final;
+reg [22:0] fract_out_rnd;
+wire [8:0] exp_next_mi;
+wire dn;
+wire exp_rnd_adj;
+wire [7:0] exp_out_final;
+reg [7:0] exp_out_rnd;
+wire op_dn = opa_dn | opb_dn;
+wire op_mul = fpu_op[2:0]==3'b010;
+wire op_div = fpu_op[2:0]==3'b011;
+wire op_i2f = fpu_op[2:0]==3'b100;
+wire op_f2i = fpu_op[2:0]==3'b101;
+reg [5:0] fi_ldz;
+
+wire g, r, s;
+wire round, round2, round2a, round2_fasu, round2_fmul;
+wire [7:0] exp_out_rnd0, exp_out_rnd1, exp_out_rnd2, exp_out_rnd2a;
+wire [22:0] fract_out_rnd0, fract_out_rnd1, fract_out_rnd2, fract_out_rnd2a;
+wire exp_rnd_adj0, exp_rnd_adj2a;
+wire r_sign;
+wire ovf0, ovf1;
+wire [23:0] fract_out_pl1;
+wire [7:0] exp_out_pl1, exp_out_mi1;
+wire exp_out_00, exp_out_fe, exp_out_ff, exp_in_00, exp_in_ff;
+wire exp_out_final_ff, fract_out_7fffff;
+wire [24:0] fract_trunc;
+wire [7:0] exp_out1;
+wire grs_sel;
+wire fract_out_00, fract_in_00;
+wire shft_co;
+wire [8:0] exp_in_pl1, exp_in_mi1;
+wire [47:0] fract_in_shftr;
+wire [47:0] fract_in_shftl;
+
+wire [7:0] exp_div;
+wire [7:0] shft2;
+wire [7:0] exp_out1_mi1;
+wire div_dn;
+wire div_nr;
+wire grs_sel_div;
+
+wire div_inf;
+wire [6:0] fi_ldz_2a;
+wire [7:0] fi_ldz_2;
+wire [7:0] div_shft1, div_shft2, div_shft3, div_shft4;
+wire div_shft1_co;
+wire [8:0] div_exp1;
+wire [7:0] div_exp2, div_exp3;
+wire left_right, lr_mul, lr_div;
+wire [7:0] shift_right, shftr_mul, shftr_div;
+wire [7:0] shift_left, shftl_mul, shftl_div;
+wire [7:0] fasu_shift;
+wire [7:0] exp_fix_div;
+
+wire [7:0] exp_fix_diva, exp_fix_divb;
+wire [5:0] fi_ldz_mi1;
+wire [5:0] fi_ldz_mi22;
+wire exp_zero;
+wire [6:0] ldz_all;
+wire [7:0] ldz_dif;
+
+wire [8:0] div_scht1a;
+wire [7:0] f2i_shft;
+wire [55:0] exp_f2i_1;
+wire f2i_zero, f2i_max;
+wire [7:0] f2i_emin;
+wire [7:0] conv_shft;
+wire [7:0] exp_i2f, exp_f2i, conv_exp;
+wire round2_f2i;
+
+////////////////////////////////////////////////////////////////////////
+//
+// Normalize and Round Logic
+//
+
+// ---------------------------------------------------------------------
+// Count Leading zeros in fraction
+
+always @(fract_in)
+ casex(fract_in) // synopsys full_case parallel_case
+ 48'b1???????????????????????????????????????????????: fi_ldz = 1;
+ 48'b01??????????????????????????????????????????????: fi_ldz = 2;
+ 48'b001?????????????????????????????????????????????: fi_ldz = 3;
+ 48'b0001????????????????????????????????????????????: fi_ldz = 4;
+ 48'b00001???????????????????????????????????????????: fi_ldz = 5;
+ 48'b000001??????????????????????????????????????????: fi_ldz = 6;
+ 48'b0000001?????????????????????????????????????????: fi_ldz = 7;
+ 48'b00000001????????????????????????????????????????: fi_ldz = 8;
+ 48'b000000001???????????????????????????????????????: fi_ldz = 9;
+ 48'b0000000001??????????????????????????????????????: fi_ldz = 10;
+ 48'b00000000001?????????????????????????????????????: fi_ldz = 11;
+ 48'b000000000001????????????????????????????????????: fi_ldz = 12;
+ 48'b0000000000001???????????????????????????????????: fi_ldz = 13;
+ 48'b00000000000001??????????????????????????????????: fi_ldz = 14;
+ 48'b000000000000001?????????????????????????????????: fi_ldz = 15;
+ 48'b0000000000000001????????????????????????????????: fi_ldz = 16;
+ 48'b00000000000000001???????????????????????????????: fi_ldz = 17;
+ 48'b000000000000000001??????????????????????????????: fi_ldz = 18;
+ 48'b0000000000000000001?????????????????????????????: fi_ldz = 19;
+ 48'b00000000000000000001????????????????????????????: fi_ldz = 20;
+ 48'b000000000000000000001???????????????????????????: fi_ldz = 21;
+ 48'b0000000000000000000001??????????????????????????: fi_ldz = 22;
+ 48'b00000000000000000000001?????????????????????????: fi_ldz = 23;
+ 48'b000000000000000000000001????????????????????????: fi_ldz = 24;
+ 48'b0000000000000000000000001???????????????????????: fi_ldz = 25;
+ 48'b00000000000000000000000001??????????????????????: fi_ldz = 26;
+ 48'b000000000000000000000000001?????????????????????: fi_ldz = 27;
+ 48'b0000000000000000000000000001????????????????????: fi_ldz = 28;
+ 48'b00000000000000000000000000001???????????????????: fi_ldz = 29;
+ 48'b000000000000000000000000000001??????????????????: fi_ldz = 30;
+ 48'b0000000000000000000000000000001?????????????????: fi_ldz = 31;
+ 48'b00000000000000000000000000000001????????????????: fi_ldz = 32;
+ 48'b000000000000000000000000000000001???????????????: fi_ldz = 33;
+ 48'b0000000000000000000000000000000001??????????????: fi_ldz = 34;
+ 48'b00000000000000000000000000000000001?????????????: fi_ldz = 35;
+ 48'b000000000000000000000000000000000001????????????: fi_ldz = 36;
+ 48'b0000000000000000000000000000000000001???????????: fi_ldz = 37;
+ 48'b00000000000000000000000000000000000001??????????: fi_ldz = 38;
+ 48'b000000000000000000000000000000000000001?????????: fi_ldz = 39;
+ 48'b0000000000000000000000000000000000000001????????: fi_ldz = 40;
+ 48'b00000000000000000000000000000000000000001???????: fi_ldz = 41;
+ 48'b000000000000000000000000000000000000000001??????: fi_ldz = 42;
+ 48'b0000000000000000000000000000000000000000001?????: fi_ldz = 43;
+ 48'b00000000000000000000000000000000000000000001????: fi_ldz = 44;
+ 48'b000000000000000000000000000000000000000000001???: fi_ldz = 45;
+ 48'b0000000000000000000000000000000000000000000001??: fi_ldz = 46;
+ 48'b00000000000000000000000000000000000000000000001?: fi_ldz = 47;
+ 48'b00000000000000000000000000000000000000000000000?: fi_ldz = 48;
+ endcase
+
+
+// ---------------------------------------------------------------------
+// Normalize
+
+wire exp_in_80;
+wire rmode_00, rmode_01, rmode_10, rmode_11;
+
+// Misc common signals
+assign exp_in_ff = &exp_in;
+assign exp_in_00 = !(|exp_in);
+assign exp_in_80 = exp_in[7] & !(|exp_in[6:0]);
+assign exp_out_ff = &exp_out;
+assign exp_out_00 = !(|exp_out);
+assign exp_out_fe = &exp_out[7:1] & !exp_out[0];
+assign exp_out_final_ff = &exp_out_final;
+
+assign fract_out_7fffff = &fract_out;
+assign fract_out_00 = !(|fract_out);
+assign fract_in_00 = !(|fract_in);
+
+assign rmode_00 = (rmode==2'b00);
+assign rmode_01 = (rmode==2'b01);
+assign rmode_10 = (rmode==2'b10);
+assign rmode_11 = (rmode==2'b11);
+
+// Fasu Output will be denormalized ...
+assign dn = !op_mul & !op_div & (exp_in_00 | (exp_next_mi[8] & !fract_in[47]) );
+
+// ---------------------------------------------------------------------
+// Fraction Normalization
+parameter f2i_emax = 8'h9d;
+
+// Incremented fraction for rounding
+assign fract_out_pl1 = fract_out + 1;
+
+// Special Signals for f2i
+assign f2i_emin = rmode_00 ? 8'h7e : 8'h7f;
+assign f2i_zero = (!opas & (exp_in<f2i_emin)) | (opas & (exp_in>f2i_emax)) | (opas & (exp_in<f2i_emin) & (fract_in_00 | !rmode_11));
+assign f2i_max = (!opas & (exp_in>f2i_emax)) | (opas & (exp_in<f2i_emin) & !fract_in_00 & rmode_11);
+
+// Claculate various shifting options
+
+assign {shft_co,shftr_mul} = (!exp_ovf[1] & exp_in_00) ? {1'b0, exp_out} : exp_in_mi1 ;
+assign {div_shft1_co, div_shft1} = exp_in_00 ? {1'b0, div_opa_ldz} : div_scht1a;
+
+assign div_scht1a = exp_in-div_opa_ldz; // 9 bits - includes carry out
+assign div_shft2 = exp_in+2;
+assign div_shft3 = div_opa_ldz+exp_in;
+assign div_shft4 = div_opa_ldz-exp_in;
+
+assign div_dn = op_dn & div_shft1_co;
+assign div_nr = op_dn & exp_ovf[1] & !(|fract_in[46:23]) & (div_shft3>8'h16);
+
+assign f2i_shft = exp_in-8'h7d;
+
+// Select shifting direction
+assign left_right = op_div ? lr_div : op_mul ? lr_mul : 1;
+
+assign lr_div = (op_dn & !exp_ovf[1] & exp_ovf[0]) ? 1 :
+ (op_dn & exp_ovf[1]) ? 0 :
+ (op_dn & div_shft1_co) ? 0 :
+ (op_dn & exp_out_00) ? 1 :
+ (!op_dn & exp_out_00 & !exp_ovf[1]) ? 1 :
+ exp_ovf[1] ? 0 :
+ 1;
+assign lr_mul = (shft_co | (!exp_ovf[1] & exp_in_00) |
+ (!exp_ovf[1] & !exp_in_00 & (exp_out1_co | exp_out_00) )) ? 1 :
+ ( exp_ovf[1] | exp_in_00 ) ? 0 :
+ 1;
+
+// Select Left and Right shift value
+assign fasu_shift = (dn | exp_out_00) ? (exp_in_00 ? 8'h2 : exp_in_pl1[7:0]) : {2'h0, fi_ldz};
+assign shift_right = op_div ? shftr_div : shftr_mul;
+
+assign conv_shft = op_f2i ? f2i_shft : {2'h0, fi_ldz};
+
+assign shift_left = op_div ? shftl_div : op_mul ? shftl_mul : (op_f2i | op_i2f) ? conv_shft : fasu_shift;
+
+assign shftl_mul = (shft_co |
+ (!exp_ovf[1] & exp_in_00) |
+ (!exp_ovf[1] & !exp_in_00 & (exp_out1_co | exp_out_00))) ? exp_in_pl1[7:0] : {2'h0, fi_ldz};
+
+assign shftl_div = ( op_dn & exp_out_00 & !(!exp_ovf[1] & exp_ovf[0])) ? div_shft1[7:0] :
+ (!op_dn & exp_out_00 & !exp_ovf[1]) ? exp_in[7:0] :
+ {2'h0, fi_ldz};
+assign shftr_div = (op_dn & exp_ovf[1]) ? div_shft3 :
+ (op_dn & div_shft1_co) ? div_shft4 :
+ div_shft2;
+// Do the actual shifting
+assign fract_in_shftr = (|shift_right[7:6]) ? 0 : fract_in>>shift_right[5:0];
+assign fract_in_shftl = (|shift_left[7:6] | (f2i_zero & op_f2i)) ? 0 : fract_in<<shift_left[5:0];
+
+// Chose final fraction output
+assign {fract_out,fract_trunc} = left_right ? fract_in_shftl : fract_in_shftr;
+
+// ---------------------------------------------------------------------
+// Exponent Normalization
+
+assign fi_ldz_mi1 = fi_ldz - 1;
+assign fi_ldz_mi22 = fi_ldz - 22;
+assign exp_out_pl1 = exp_out + 1;
+assign exp_out_mi1 = exp_out - 1;
+assign exp_in_pl1 = exp_in + 1; // 9 bits - includes carry out
+assign exp_in_mi1 = exp_in - 1; // 9 bits - includes carry out
+assign exp_out1_mi1 = exp_out1 - 1;
+
+assign exp_next_mi = exp_in_pl1 - fi_ldz_mi1; // 9 bits - includes carry out
+
+assign exp_fix_diva = exp_in - fi_ldz_mi22;
+assign exp_fix_divb = exp_in - fi_ldz_mi1;
+
+assign exp_zero = (exp_ovf[1] & !exp_ovf[0] & op_mul & (!exp_rnd_adj2a | !rmode[1])) | (op_mul & exp_out1_co);
+assign {exp_out1_co, exp_out1} = fract_in[47] ? exp_in_pl1 : exp_next_mi;
+
+assign f2i_out_sign = !opas ? ((exp_in<f2i_emin) ? 0 : (exp_in>f2i_emax) ? 0 : opas) :
+ ((exp_in<f2i_emin) ? 0 : (exp_in>f2i_emax) ? 1 : opas);
+
+assign exp_i2f = fract_in_00 ? (opas ? 8'h9e : 0) : (8'h9e-fi_ldz);
+assign exp_f2i_1 = {{8{fract_in[47]}}, fract_in }<<f2i_shft;
+assign exp_f2i = f2i_zero ? 0 : f2i_max ? 8'hff : exp_f2i_1[55:48];
+assign conv_exp = op_f2i ? exp_f2i : exp_i2f;
+
+assign exp_out = op_div ? exp_div : (op_f2i | op_i2f) ? conv_exp : exp_zero ? 8'h0 : dn ? {6'h0, fract_in[47:46]} : exp_out1;
+
+assign ldz_all = div_opa_ldz + fi_ldz;
+assign ldz_dif = fi_ldz_2 - div_opa_ldz;
+assign fi_ldz_2a = 6'd23 - fi_ldz;
+assign fi_ldz_2 = {fi_ldz_2a[6], fi_ldz_2a[6:0]};
+
+assign div_exp1 = exp_in_mi1 + fi_ldz_2; // 9 bits - includes carry out
+
+assign div_exp2 = exp_in_pl1 - ldz_all;
+assign div_exp3 = exp_in + ldz_dif;
+
+assign exp_div =(opa_dn & opb_dn) ? div_exp3 :
+ opb_dn ? div_exp1[7:0] :
+ (opa_dn & !( (exp_in<div_opa_ldz) | (div_exp2>9'hfe) )) ? div_exp2 :
+ (opa_dn | (exp_in_00 & !exp_ovf[1]) ) ? 0 :
+ exp_out1_mi1;
+
+assign div_inf = opb_dn & !opa_dn & (div_exp1[7:0] < 8'h7f);
+
+// ---------------------------------------------------------------------
+// Round
+
+// Extract rounding (GRS) bits
+assign grs_sel_div = op_div & (exp_ovf[1] | div_dn | exp_out1_co | exp_out_00);
+
+assign g = grs_sel_div ? fract_out[0] : fract_out[0];
+assign r = grs_sel_div ? (fract_trunc[24] & !div_nr) : fract_trunc[24];
+assign s = grs_sel_div ? |fract_trunc[24:0] : (|fract_trunc[23:0] | (fract_trunc[24] & op_div));
+
+// Round to nearest even
+assign round = (g & r) | (r & s) ;
+assign {exp_rnd_adj0, fract_out_rnd0} = round ? fract_out_pl1 : {1'b0, fract_out};
+assign exp_out_rnd0 = exp_rnd_adj0 ? exp_out_pl1 : exp_out;
+assign ovf0 = exp_out_final_ff & !rmode_01 & !op_f2i;
+
+// round to zero
+assign fract_out_rnd1 = (exp_out_ff & !op_div & !dn & !op_f2i) ? 23'h7fffff : fract_out;
+assign exp_fix_div = (fi_ldz>22) ? exp_fix_diva : exp_fix_divb;
+assign exp_out_rnd1 = (g & r & s & exp_in_ff) ? (op_div ? exp_fix_div : exp_next_mi[7:0]) :
+ (exp_out_ff & !op_f2i) ? exp_in : exp_out;
+assign ovf1 = exp_out_ff & !dn;
+
+// round to +inf (UP) and -inf (DOWN)
+assign r_sign = sign;
+
+assign round2a = !exp_out_fe | !fract_out_7fffff | (exp_out_fe & fract_out_7fffff);
+assign round2_fasu = ((r | s) & !r_sign) & (!exp_out[7] | (exp_out[7] & round2a));
+
+assign round2_fmul = !r_sign &
+ (
+ (exp_ovf[1] & !fract_in_00 &
+ ( ((!exp_out1_co | op_dn) & (r | s | (!rem_00 & op_div) )) | fract_out_00 | (!op_dn & !op_div))
+ ) |
+ (
+ (r | s | (!rem_00 & op_div)) & (
+ (!exp_ovf[1] & (exp_in_80 | !exp_ovf[0])) | op_div |
+ ( exp_ovf[1] & !exp_ovf[0] & exp_out1_co)
+ )
+ )
+ );
+
+assign round2_f2i = rmode_10 & (( |fract_in[23:0] & !opas & (exp_in<8'h80 )) | (|fract_trunc));
+assign round2 = (op_mul | op_div) ? round2_fmul : op_f2i ? round2_f2i : round2_fasu;
+
+assign {exp_rnd_adj2a, fract_out_rnd2a} = round2 ? fract_out_pl1 : {1'b0, fract_out};
+assign exp_out_rnd2a = exp_rnd_adj2a ? ((exp_ovf[1] & op_mul) ? exp_out_mi1 : exp_out_pl1) : exp_out;
+
+assign fract_out_rnd2 = (r_sign & exp_out_ff & !op_div & !dn & !op_f2i) ? 23'h7fffff : fract_out_rnd2a;
+assign exp_out_rnd2 = (r_sign & exp_out_ff & !op_f2i) ? 8'hfe : exp_out_rnd2a;
+
+
+// Choose rounding mode
+always @(rmode or exp_out_rnd0 or exp_out_rnd1 or exp_out_rnd2)
+ case(rmode) // synopsys full_case parallel_case
+ 0: exp_out_rnd = exp_out_rnd0;
+ 1: exp_out_rnd = exp_out_rnd1;
+ 2,3: exp_out_rnd = exp_out_rnd2;
+ endcase
+
+always @(rmode or fract_out_rnd0 or fract_out_rnd1 or fract_out_rnd2)
+ case(rmode) // synopsys full_case parallel_case
+ 0: fract_out_rnd = fract_out_rnd0;
+ 1: fract_out_rnd = fract_out_rnd1;
+ 2,3: fract_out_rnd = fract_out_rnd2;
+ endcase
+
+// ---------------------------------------------------------------------
+// Final Output Mux
+// Fix Output for denormalized and special numbers
+wire max_num, inf_out;
+
+assign max_num = ( !rmode_00 & (op_mul | op_div ) & (
+ ( exp_ovf[1] & exp_ovf[0]) |
+ (!exp_ovf[1] & !exp_ovf[0] & exp_in_ff & (fi_ldz_2<24) & (exp_out!=8'hfe) )
+ )
+ ) |
+
+ ( op_div & (
+ ( rmode_01 & ( div_inf |
+ (exp_out_ff & !exp_ovf[1] ) |
+ (exp_ovf[1] & exp_ovf[0] )
+ )
+ ) |
+
+ ( rmode[1] & !exp_ovf[1] & (
+ ( exp_ovf[0] & exp_in_ff & r_sign & fract_in[47]
+ ) |
+
+ ( r_sign & (
+ (fract_in[47] & div_inf) |
+ (exp_in[7] & !exp_out_rnd[7] & !exp_in_80 & exp_out!=8'h7f ) |
+ (exp_in[7] & exp_out_rnd[7] & r_sign & exp_out_ff & op_dn &
+ div_exp1>9'h0fe )
+ )
+ ) |
+
+ ( exp_in_00 & r_sign & (
+ div_inf |
+ (r_sign & exp_out_ff & fi_ldz_2<24)
+ )
+ )
+ )
+ )
+ )
+ );
+
+
+assign inf_out = (rmode[1] & (op_mul | op_div) & !r_sign & ( (exp_in_ff & !op_div) |
+ (exp_ovf[1] & exp_ovf[0] & (exp_in_00 | exp_in[7]) )
+ )
+ ) | (div_inf & op_div & (
+ rmode_00 |
+ (rmode[1] & !exp_in_ff & !exp_ovf[1] & !exp_ovf[0] & !r_sign ) |
+ (rmode[1] & !exp_ovf[1] & exp_ovf[0] & exp_in_00 & !r_sign)
+ )
+ ) | (op_div & rmode[1] & exp_in_ff & op_dn & !r_sign & (fi_ldz_2 < 24) & (exp_out_rnd!=8'hfe) );
+
+assign fract_out_final = (inf_out | ovf0 | output_zero ) ? 23'h0 :
+ (max_num | (f2i_max & op_f2i) ) ? 23'h7fffff :
+ fract_out_rnd;
+
+assign exp_out_final = ((op_div & exp_ovf[1] & !exp_ovf[0]) | output_zero ) ? 8'h00 :
+ ((op_div & exp_ovf[1] & exp_ovf[0] & rmode_00) | inf_out | (f2i_max & op_f2i) ) ? 8'hff :
+ max_num ? 8'hfe :
+ exp_out_rnd;
+
+
+// ---------------------------------------------------------------------
+// Pack Result
+
+assign out = {exp_out_final, fract_out_final};
+
+// ---------------------------------------------------------------------
+// Exceptions
+wire underflow_fmul;
+wire overflow_fdiv;
+wire undeflow_div;
+
+wire z = shft_co | ( exp_ovf[1] | exp_in_00) |
+ (!exp_ovf[1] & !exp_in_00 & (exp_out1_co | exp_out_00));
+
+assign underflow_fmul = ( (|fract_trunc) & z & !exp_in_ff ) |
+ (fract_out_00 & !fract_in_00 & exp_ovf[1]);
+
+assign undeflow_div = !(exp_ovf[1] & exp_ovf[0] & rmode_00) & !inf_out & !max_num & exp_out_final!=8'hff & (
+
+ ((|fract_trunc) & !opb_dn & (
+ ( op_dn & !exp_ovf[1] & exp_ovf[0]) |
+ ( op_dn & exp_ovf[1]) |
+ ( op_dn & div_shft1_co) |
+ exp_out_00 |
+ exp_ovf[1]
+ )
+
+ ) |
+
+ ( exp_ovf[1] & !exp_ovf[0] & (
+ ( op_dn & exp_in>8'h16 & fi_ldz<23) |
+ ( op_dn & exp_in<23 & fi_ldz<23 & !rem_00) |
+ ( !op_dn & (exp_in[7]==exp_div[7]) & !rem_00) |
+ ( !op_dn & exp_in_00 & (exp_div[7:1]==7'h7f) ) |
+ ( !op_dn & exp_in<8'h7f & exp_in>8'h20 )
+ )
+ ) |
+
+ (!exp_ovf[1] & !exp_ovf[0] & (
+ ( op_dn & fi_ldz<23 & exp_out_00) |
+ ( exp_in_00 & !rem_00) |
+ ( !op_dn & ldz_all<23 & exp_in==1 & exp_out_00 & !rem_00)
+ )
+ )
+
+ );
+
+assign underflow = op_div ? undeflow_div : op_mul ? underflow_fmul : (!fract_in[47] & exp_out1_co) & !dn;
+
+assign overflow_fdiv = inf_out |
+ (!rmode_00 & max_num) |
+ (exp_in[7] & op_dn & exp_out_ff) |
+ (exp_ovf[0] & (exp_ovf[1] | exp_out_ff) );
+
+assign overflow = op_div ? overflow_fdiv : (ovf0 | ovf1);
+
+wire f2i_ine;
+
+assign f2i_ine = (f2i_zero & !fract_in_00 & !opas) |
+ (|fract_trunc) |
+ (f2i_zero & (exp_in<8'h80) & opas & !fract_in_00) |
+ (f2i_max & rmode_11 & (exp_in<8'h80));
+
+
+
+assign ine = op_f2i ? f2i_ine :
+ op_i2f ? (|fract_trunc) :
+ ((r & !dn) | (s & !dn) | max_num | (op_div & !rem_00));
+
+// ---------------------------------------------------------------------
+// Debugging Stuff
+
+// synopsys translate_off
+
+wire [26:0] fracta_del, fractb_del;
+wire [2:0] grs_del;
+wire dn_del;
+wire [7:0] exp_in_del;
+wire [7:0] exp_out_del;
+wire [22:0] fract_out_del;
+wire [47:0] fract_in_del;
+wire overflow_del;
+wire [1:0] exp_ovf_del;
+wire [22:0] fract_out_x_del, fract_out_rnd2a_del;
+wire [24:0] trunc_xx_del;
+wire exp_rnd_adj2a_del;
+wire [22:0] fract_dn_del;
+wire [4:0] div_opa_ldz_del;
+wire [23:0] fracta_div_del;
+wire [23:0] fractb_div_del;
+wire div_inf_del;
+wire [7:0] fi_ldz_2_del;
+wire inf_out_del, max_out_del;
+wire [5:0] fi_ldz_del;
+wire rx_del;
+wire ez_del;
+wire lr;
+wire [7:0] shr, shl, exp_div_del;
+
+delay2 #26 ud000(clk, test.u0.fracta, fracta_del);
+delay2 #26 ud001(clk, test.u0.fractb, fractb_del);
+delay1 #2 ud002(clk, {g,r,s}, grs_del);
+delay1 #0 ud004(clk, dn, dn_del);
+delay1 #7 ud005(clk, exp_in, exp_in_del);
+delay1 #7 ud007(clk, exp_out_rnd, exp_out_del);
+delay1 #47 ud009(clk, fract_in, fract_in_del);
+delay1 #0 ud010(clk, overflow, overflow_del);
+delay1 #1 ud011(clk, exp_ovf, exp_ovf_del);
+delay1 #22 ud014(clk, fract_out, fract_out_x_del);
+delay1 #24 ud015(clk, fract_trunc, trunc_xx_del);
+delay1 #0 ud017(clk, exp_rnd_adj2a, exp_rnd_adj2a_del);
+delay1 #4 ud019(clk, div_opa_ldz, div_opa_ldz_del);
+delay3 #23 ud020(clk, test.u0.fdiv_opa[49:26], fracta_div_del);
+delay3 #23 ud021(clk, test.u0.fractb_mul, fractb_div_del);
+delay1 #0 ud023(clk, div_inf, div_inf_del);
+delay1 #7 ud024(clk, fi_ldz_2, fi_ldz_2_del);
+delay1 #0 ud025(clk, inf_out, inf_out_del);
+delay1 #0 ud026(clk, max_num, max_num_del);
+delay1 #5 ud027(clk, fi_ldz, fi_ldz_del);
+delay1 #0 ud028(clk, rem_00, rx_del);
+
+delay1 #0 ud029(clk, left_right, lr);
+delay1 #7 ud030(clk, shift_right, shr);
+delay1 #7 ud031(clk, shift_left, shl);
+delay1 #22 ud032(clk, fract_out_rnd2a, fract_out_rnd2a_del);
+
+delay1 #7 ud033(clk, exp_div, exp_div_del);
+
+always @(test.error_event)
+ begin
+
+ $display("\n----------------------------------------------");
+
+ $display("ERROR: GRS: %b exp_ovf: %b dn: %h exp_in: %h exp_out: %h, exp_rnd_adj2a: %b",
+ grs_del, exp_ovf_del, dn_del, exp_in_del, exp_out_del, exp_rnd_adj2a_del);
+
+ $display(" div_opa: %b, div_opb: %b, rem_00: %b, exp_div: %h",
+ fracta_div_del, fractb_div_del, rx_del, exp_div_del);
+
+ $display(" lr: %b, shl: %h, shr: %h",
+ lr, shl, shr);
+
+
+ $display(" overflow: %b, fract_in=%b fa:%h fb:%h",
+ overflow_del, fract_in_del, fracta_del, fractb_del);
+
+ $display(" div_opa_ldz: %h, div_inf: %b, inf_out: %b, max_num: %b, fi_ldz: %h, fi_ldz_2: %h",
+ div_opa_ldz_del, div_inf_del, inf_out_del, max_num_del, fi_ldz_del, fi_ldz_2_del);
+
+ $display(" fract_out_x: %b, fract_out_rnd2a_del: %h, fract_trunc: %b\n",
+ fract_out_x_del, fract_out_rnd2a_del, trunc_xx_del);
+ end
+
+
+// synopsys translate_on
+
+endmodule
+
+// synopsys translate_off
+
+module delay1(clk, in, out);
+parameter N = 1;
+input [N:0] in;
+output [N:0] out;
+input clk;
+
+reg [N:0] out;
+
+always @(posedge clk)
+ out <= #1 in;
+
+endmodule
+
+
+module delay2(clk, in, out);
+parameter N = 1;
+input [N:0] in;
+output [N:0] out;
+input clk;
+
+reg [N:0] out, r1;
+
+always @(posedge clk)
+ r1 <= #1 in;
+
+always @(posedge clk)
+ out <= #1 r1;
+
+endmodule
+
+module delay3(clk, in, out);
+parameter N = 1;
+input [N:0] in;
+output [N:0] out;
+input clk;
+
+reg [N:0] out, r1, r2;
+
+always @(posedge clk)
+ r1 <= #1 in;
+
+always @(posedge clk)
+ r2 <= #1 r1;
+
+always @(posedge clk)
+ out <= #1 r2;
+
+endmodule
+
+// synopsys translate_on \ No newline at end of file
diff --git a/tests/iwls2005/fpu/pre_norm.v b/tests/iwls2005/fpu/pre_norm.v
new file mode 100644
index 000000000..c54c71fa2
--- /dev/null
+++ b/tests/iwls2005/fpu/pre_norm.v
@@ -0,0 +1,270 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Pre Normalize ////
+//// Pre Normalization Unit for Add/Sub Operations ////
+//// ////
+//// Author: Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+`timescale 1ns / 100ps
+
+
+module pre_norm(clk, rmode, add, opa, opb, opa_nan, opb_nan, fracta_out,
+ fractb_out, exp_dn_out, sign, nan_sign, result_zero_sign,
+ fasu_op);
+input clk;
+input [1:0] rmode;
+input add;
+input [31:0] opa, opb;
+input opa_nan, opb_nan;
+output [26:0] fracta_out, fractb_out;
+output [7:0] exp_dn_out;
+output sign;
+output nan_sign, result_zero_sign;
+output fasu_op; // Operation Output
+
+////////////////////////////////////////////////////////////////////////
+//
+// Local Wires and registers
+//
+
+wire signa, signb; // alias to opX sign
+wire [7:0] expa, expb; // alias to opX exponent
+wire [22:0] fracta, fractb; // alias to opX fraction
+wire expa_lt_expb; // expa is larger than expb indicator
+wire fractb_lt_fracta; // fractb is larger than fracta indicator
+reg [7:0] exp_dn_out; // de normalized exponent output
+wire [7:0] exp_small, exp_large;
+wire [7:0] exp_diff; // Numeric difference of the two exponents
+wire [22:0] adj_op; // Fraction adjustment: input
+wire [26:0] adj_op_tmp;
+wire [26:0] adj_op_out; // Fraction adjustment: output
+wire [26:0] fracta_n, fractb_n; // Fraction selection after normalizing
+wire [26:0] fracta_s, fractb_s; // Fraction Sorting out
+reg [26:0] fracta_out, fractb_out; // Fraction Output
+reg sign, sign_d; // Sign Output
+reg add_d; // operation (add/sub)
+reg fasu_op; // operation (add/sub) register
+wire expa_dn, expb_dn;
+reg sticky;
+reg result_zero_sign;
+reg add_r, signa_r, signb_r;
+wire [4:0] exp_diff_sft;
+wire exp_lt_27;
+wire op_dn;
+wire [26:0] adj_op_out_sft;
+reg fracta_lt_fractb, fracta_eq_fractb;
+wire nan_sign1;
+reg nan_sign;
+
+////////////////////////////////////////////////////////////////////////
+//
+// Aliases
+//
+
+assign signa = opa[31];
+assign signb = opb[31];
+assign expa = opa[30:23];
+assign expb = opb[30:23];
+assign fracta = opa[22:0];
+assign fractb = opb[22:0];
+
+////////////////////////////////////////////////////////////////////////
+//
+// Pre-Normalize exponents (and fractions)
+//
+
+assign expa_lt_expb = expa > expb; // expa is larger than expb
+
+// ---------------------------------------------------------------------
+// Normalize
+
+assign expa_dn = !(|expa); // opa denormalized
+assign expb_dn = !(|expb); // opb denormalized
+
+// ---------------------------------------------------------------------
+// Calculate the difference between the smaller and larger exponent
+
+wire [7:0] exp_diff1, exp_diff1a, exp_diff2;
+
+assign exp_small = expa_lt_expb ? expb : expa;
+assign exp_large = expa_lt_expb ? expa : expb;
+assign exp_diff1 = exp_large - exp_small;
+assign exp_diff1a = exp_diff1-1;
+assign exp_diff2 = (expa_dn | expb_dn) ? exp_diff1a : exp_diff1;
+assign exp_diff = (expa_dn & expb_dn) ? 8'h0 : exp_diff2;
+
+always @(posedge clk) // If numbers are equal we should return zero
+ exp_dn_out <= #1 (!add_d & expa==expb & fracta==fractb) ? 8'h0 : exp_large;
+
+// ---------------------------------------------------------------------
+// Adjust the smaller fraction
+
+
+assign op_dn = expa_lt_expb ? expb_dn : expa_dn;
+assign adj_op = expa_lt_expb ? fractb : fracta;
+assign adj_op_tmp = { ~op_dn, adj_op, 3'b0 }; // recover hidden bit (op_dn)
+
+// adj_op_out is 27 bits wide, so can only be shifted 27 bits to the right
+assign exp_lt_27 = exp_diff > 8'd27;
+assign exp_diff_sft = exp_lt_27 ? 5'd27 : exp_diff[4:0];
+assign adj_op_out_sft = adj_op_tmp >> exp_diff_sft;
+assign adj_op_out = {adj_op_out_sft[26:1], adj_op_out_sft[0] | sticky };
+
+// ---------------------------------------------------------------------
+// Get truncated portion (sticky bit)
+
+always @(exp_diff_sft or adj_op_tmp)
+ case(exp_diff_sft) // synopsys full_case parallel_case
+ 00: sticky = 1'h0;
+ 01: sticky = adj_op_tmp[0];
+ 02: sticky = |adj_op_tmp[01:0];
+ 03: sticky = |adj_op_tmp[02:0];
+ 04: sticky = |adj_op_tmp[03:0];
+ 05: sticky = |adj_op_tmp[04:0];
+ 06: sticky = |adj_op_tmp[05:0];
+ 07: sticky = |adj_op_tmp[06:0];
+ 08: sticky = |adj_op_tmp[07:0];
+ 09: sticky = |adj_op_tmp[08:0];
+ 10: sticky = |adj_op_tmp[09:0];
+ 11: sticky = |adj_op_tmp[10:0];
+ 12: sticky = |adj_op_tmp[11:0];
+ 13: sticky = |adj_op_tmp[12:0];
+ 14: sticky = |adj_op_tmp[13:0];
+ 15: sticky = |adj_op_tmp[14:0];
+ 16: sticky = |adj_op_tmp[15:0];
+ 17: sticky = |adj_op_tmp[16:0];
+ 18: sticky = |adj_op_tmp[17:0];
+ 19: sticky = |adj_op_tmp[18:0];
+ 20: sticky = |adj_op_tmp[19:0];
+ 21: sticky = |adj_op_tmp[20:0];
+ 22: sticky = |adj_op_tmp[21:0];
+ 23: sticky = |adj_op_tmp[22:0];
+ 24: sticky = |adj_op_tmp[23:0];
+ 25: sticky = |adj_op_tmp[24:0];
+ 26: sticky = |adj_op_tmp[25:0];
+ 27: sticky = |adj_op_tmp[26:0];
+ endcase
+
+// ---------------------------------------------------------------------
+// Select operands for add/sub (recover hidden bit)
+
+assign fracta_n = expa_lt_expb ? {~expa_dn, fracta, 3'b0} : adj_op_out;
+assign fractb_n = expa_lt_expb ? adj_op_out : {~expb_dn, fractb, 3'b0};
+
+// ---------------------------------------------------------------------
+// Sort operands (for sub only)
+
+assign fractb_lt_fracta = fractb_n > fracta_n; // fractb is larger than fracta
+assign fracta_s = fractb_lt_fracta ? fractb_n : fracta_n;
+assign fractb_s = fractb_lt_fracta ? fracta_n : fractb_n;
+
+always @(posedge clk)
+ fracta_out <= #1 fracta_s;
+
+always @(posedge clk)
+ fractb_out <= #1 fractb_s;
+
+// ---------------------------------------------------------------------
+// Determine sign for the output
+
+// sign: 0=Positive Number; 1=Negative Number
+always @(signa or signb or add or fractb_lt_fracta)
+ case({signa, signb, add}) // synopsys full_case parallel_case
+
+ // Add
+ 3'b0_0_1: sign_d = 0;
+ 3'b0_1_1: sign_d = fractb_lt_fracta;
+ 3'b1_0_1: sign_d = !fractb_lt_fracta;
+ 3'b1_1_1: sign_d = 1;
+
+ // Sub
+ 3'b0_0_0: sign_d = fractb_lt_fracta;
+ 3'b0_1_0: sign_d = 0;
+ 3'b1_0_0: sign_d = 1;
+ 3'b1_1_0: sign_d = !fractb_lt_fracta;
+ endcase
+
+always @(posedge clk)
+ sign <= #1 sign_d;
+
+// Fix sign for ZERO result
+always @(posedge clk)
+ signa_r <= #1 signa;
+
+always @(posedge clk)
+ signb_r <= #1 signb;
+
+always @(posedge clk)
+ add_r <= #1 add;
+
+always @(posedge clk)
+ result_zero_sign <= #1 ( add_r & signa_r & signb_r) |
+ (!add_r & signa_r & !signb_r) |
+ ( add_r & (signa_r | signb_r) & (rmode==3)) |
+ (!add_r & (signa_r == signb_r) & (rmode==3));
+
+// Fix sign for NAN result
+always @(posedge clk)
+ fracta_lt_fractb <= #1 fracta < fractb;
+
+always @(posedge clk)
+ fracta_eq_fractb <= #1 fracta == fractb;
+
+assign nan_sign1 = fracta_eq_fractb ? (signa_r & signb_r) : fracta_lt_fractb ? signb_r : signa_r;
+
+always @(posedge clk)
+ nan_sign <= #1 (opa_nan & opb_nan) ? nan_sign1 : opb_nan ? signb_r : signa_r;
+
+////////////////////////////////////////////////////////////////////////
+//
+// Decode Add/Sub operation
+//
+
+// add: 1=Add; 0=Subtract
+always @(signa or signb or add)
+ case({signa, signb, add}) // synopsys full_case parallel_case
+
+ // Add
+ 3'b0_0_1: add_d = 1;
+ 3'b0_1_1: add_d = 0;
+ 3'b1_0_1: add_d = 0;
+ 3'b1_1_1: add_d = 1;
+
+ // Sub
+ 3'b0_0_0: add_d = 0;
+ 3'b0_1_0: add_d = 1;
+ 3'b1_0_0: add_d = 1;
+ 3'b1_1_0: add_d = 0;
+ endcase
+
+always @(posedge clk)
+ fasu_op <= #1 add_d;
+
+endmodule
diff --git a/tests/iwls2005/fpu/pre_norm_fmul.v b/tests/iwls2005/fpu/pre_norm_fmul.v
new file mode 100644
index 000000000..26ddfeb75
--- /dev/null
+++ b/tests/iwls2005/fpu/pre_norm_fmul.v
@@ -0,0 +1,150 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Pre Normalize ////
+//// Floating Point Pre Normalization Unit for FMUL ////
+//// ////
+//// Author: Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+`timescale 1ns / 100ps
+
+module pre_norm_fmul(clk, fpu_op, opa, opb, fracta, fractb, exp_out, sign,
+ sign_exe, inf, exp_ovf, underflow);
+input clk;
+input [2:0] fpu_op;
+input [31:0] opa, opb;
+output [23:0] fracta, fractb;
+output [7:0] exp_out;
+output sign, sign_exe;
+output inf;
+output [1:0] exp_ovf;
+output [2:0] underflow;
+
+////////////////////////////////////////////////////////////////////////
+//
+// Local Wires and registers
+//
+
+reg [7:0] exp_out;
+wire signa, signb;
+reg sign, sign_d;
+reg sign_exe;
+reg inf;
+wire [1:0] exp_ovf_d;
+reg [1:0] exp_ovf;
+wire [7:0] expa, expb;
+wire [7:0] exp_tmp1, exp_tmp2;
+wire co1, co2;
+wire expa_dn, expb_dn;
+wire [7:0] exp_out_a;
+wire opa_00, opb_00, fracta_00, fractb_00;
+wire [7:0] exp_tmp3, exp_tmp4, exp_tmp5;
+wire [2:0] underflow_d;
+reg [2:0] underflow;
+wire op_div = (fpu_op == 3'b011);
+wire [7:0] exp_out_mul, exp_out_div;
+
+////////////////////////////////////////////////////////////////////////
+//
+// Aliases
+//
+
+assign signa = opa[31];
+assign signb = opb[31];
+assign expa = opa[30:23];
+assign expb = opb[30:23];
+
+////////////////////////////////////////////////////////////////////////
+//
+// Calculate Exponenet
+//
+
+assign expa_dn = !(|expa);
+assign expb_dn = !(|expb);
+assign opa_00 = !(|opa[30:0]);
+assign opb_00 = !(|opb[30:0]);
+assign fracta_00 = !(|opa[22:0]);
+assign fractb_00 = !(|opb[22:0]);
+
+assign fracta = {!expa_dn,opa[22:0]}; // Recover hidden bit
+assign fractb = {!expb_dn,opb[22:0]}; // Recover hidden bit
+
+assign {co1,exp_tmp1} = op_div ? (expa - expb) : (expa + expb);
+assign {co2,exp_tmp2} = op_div ? ({co1,exp_tmp1} + 8'h7f) : ({co1,exp_tmp1} - 8'h7f);
+
+assign exp_tmp3 = exp_tmp2 + 1;
+assign exp_tmp4 = 8'h7f - exp_tmp1;
+assign exp_tmp5 = op_div ? (exp_tmp4+1) : (exp_tmp4-1);
+
+
+always@(posedge clk)
+ exp_out <= #1 op_div ? exp_out_div : exp_out_mul;
+
+assign exp_out_div = (expa_dn | expb_dn) ? (co2 ? exp_tmp5 : exp_tmp3 ) : co2 ? exp_tmp4 : exp_tmp2;
+assign exp_out_mul = exp_ovf_d[1] ? exp_out_a : (expa_dn | expb_dn) ? exp_tmp3 : exp_tmp2;
+assign exp_out_a = (expa_dn | expb_dn) ? exp_tmp5 : exp_tmp4;
+assign exp_ovf_d[0] = op_div ? (expa[7] & !expb[7]) : (co2 & expa[7] & expb[7]);
+assign exp_ovf_d[1] = op_div ? co2 : ((!expa[7] & !expb[7] & exp_tmp2[7]) | co2);
+
+always @(posedge clk)
+ exp_ovf <= #1 exp_ovf_d;
+
+assign underflow_d[0] = (exp_tmp1 < 8'h7f) & !co1 & !(opa_00 | opb_00 | expa_dn | expb_dn);
+assign underflow_d[1] = ((expa[7] | expb[7]) & !opa_00 & !opb_00) |
+ (expa_dn & !fracta_00) | (expb_dn & !fractb_00);
+assign underflow_d[2] = !opa_00 & !opb_00 & (exp_tmp1 == 8'h7f);
+
+always @(posedge clk)
+ underflow <= #1 underflow_d;
+
+always @(posedge clk)
+ inf <= #1 op_div ? (expb_dn & !expa[7]) : ({co1,exp_tmp1} > 9'h17e) ;
+
+
+////////////////////////////////////////////////////////////////////////
+//
+// Determine sign for the output
+//
+
+// sign: 0=Posetive Number; 1=Negative Number
+always @(signa or signb)
+ case({signa, signb}) // synopsys full_case parallel_case
+ 2'b0_0: sign_d = 0;
+ 2'b0_1: sign_d = 1;
+ 2'b1_0: sign_d = 1;
+ 2'b1_1: sign_d = 0;
+ endcase
+
+always @(posedge clk)
+ sign <= #1 sign_d;
+
+always @(posedge clk)
+ sign_exe <= #1 signa & signb;
+
+endmodule \ No newline at end of file
diff --git a/tests/iwls2005/fpu/primitives.v b/tests/iwls2005/fpu/primitives.v
new file mode 100644
index 000000000..2e7f050e5
--- /dev/null
+++ b/tests/iwls2005/fpu/primitives.v
@@ -0,0 +1,103 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Primitives ////
+//// FPU Primitives ////
+//// ////
+//// Author: Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+
+`timescale 1ns / 100ps
+
+
+////////////////////////////////////////////////////////////////////////
+//
+// Add/Sub
+//
+
+module add_sub27(add, opa, opb, sum, co);
+input add;
+input [26:0] opa, opb;
+output [26:0] sum;
+output co;
+
+
+
+assign {co, sum} = add ? (opa + opb) : (opa - opb);
+
+endmodule
+
+////////////////////////////////////////////////////////////////////////
+//
+// Multiply
+//
+
+module mul_r2(clk, opa, opb, prod);
+input clk;
+input [23:0] opa, opb;
+output [47:0] prod;
+
+reg [47:0] prod1, prod;
+
+always @(posedge clk)
+ prod1 <= #1 opa * opb;
+
+always @(posedge clk)
+ prod <= #1 prod1;
+
+endmodule
+
+////////////////////////////////////////////////////////////////////////
+//
+// Divide
+//
+
+module div_r2(clk, opa, opb, quo, rem);
+input clk;
+input [49:0] opa;
+input [23:0] opb;
+output [49:0] quo, rem;
+
+reg [49:0] quo, rem, quo1, remainder;
+
+always @(posedge clk)
+ quo1 <= #1 opa / opb;
+
+always @(posedge clk)
+ quo <= #1 quo1;
+
+always @(posedge clk)
+ remainder <= #1 opa % opb;
+
+always @(posedge clk)
+ rem <= #1 remainder;
+
+endmodule
+
+
diff --git a/tests/iwls2005/i2c/i2c_master_bit_ctrl.v b/tests/iwls2005/i2c/i2c_master_bit_ctrl.v
new file mode 100644
index 000000000..17b2c8b1f
--- /dev/null
+++ b/tests/iwls2005/i2c/i2c_master_bit_ctrl.v
@@ -0,0 +1,535 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// WISHBONE rev.B2 compliant I2C Master bit-controller ////
+//// ////
+//// ////
+//// Author: Richard Herveille ////
+//// richard@asics.ws ////
+//// www.asics.ws ////
+//// ////
+//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 Richard Herveille ////
+//// richard@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: i2c_master_bit_ctrl.v,v 1.11 2004/05/07 11:02:26 rherveille Exp $
+//
+// $Date: 2004/05/07 11:02:26 $
+// $Revision: 1.11 $
+// $Author: rherveille $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: i2c_master_bit_ctrl.v,v $
+// Revision 1.11 2004/05/07 11:02:26 rherveille
+// Fixed a bug where the core would signal an arbitration lost (AL bit set), when another master controls the bus and the other master generates a STOP bit.
+//
+// Revision 1.10 2003/08/09 07:01:33 rherveille
+// Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
+// Fixed a potential bug in the byte controller's host-acknowledge generation.
+//
+// Revision 1.9 2003/03/10 14:26:37 rherveille
+// Fixed cmd_ack generation item (no bug).
+//
+// Revision 1.8 2003/02/05 00:06:10 rherveille
+// Fixed a bug where the core would trigger an erroneous 'arbitration lost' interrupt after being reset, when the reset pulse width < 3 clk cycles.
+//
+// Revision 1.7 2002/12/26 16:05:12 rherveille
+// Small code simplifications
+//
+// Revision 1.6 2002/12/26 15:02:32 rherveille
+// Core is now a Multimaster I2C controller
+//
+// Revision 1.5 2002/11/30 22:24:40 rherveille
+// Cleaned up code
+//
+// Revision 1.4 2002/10/30 18:10:07 rherveille
+// Fixed some reported minor start/stop generation timing issuess.
+//
+// Revision 1.3 2002/06/15 07:37:03 rherveille
+// Fixed a small timing bug in the bit controller.\nAdded verilog simulation environment.
+//
+// Revision 1.2 2001/11/05 11:59:25 rherveille
+// Fixed wb_ack_o generation bug.
+// Fixed bug in the byte_controller statemachine.
+// Added headers.
+//
+
+//
+/////////////////////////////////////
+// Bit controller section
+/////////////////////////////////////
+//
+// Translate simple commands into SCL/SDA transitions
+// Each command has 5 states, A/B/C/D/idle
+//
+// start: SCL ~~~~~~~~~~\____
+// SDA ~~~~~~~~\______
+// x | A | B | C | D | i
+//
+// repstart SCL ____/~~~~\___
+// SDA __/~~~\______
+// x | A | B | C | D | i
+//
+// stop SCL ____/~~~~~~~~
+// SDA ==\____/~~~~~
+// x | A | B | C | D | i
+//
+//- write SCL ____/~~~~\____
+// SDA ==X=========X=
+// x | A | B | C | D | i
+//
+//- read SCL ____/~~~~\____
+// SDA XXXX=====XXXX
+// x | A | B | C | D | i
+//
+
+// Timing: Normal mode Fast mode
+///////////////////////////////////////////////////////////////////////
+// Fscl 100KHz 400KHz
+// Th_scl 4.0us 0.6us High period of SCL
+// Tl_scl 4.7us 1.3us Low period of SCL
+// Tsu:sta 4.7us 0.6us setup time for a repeated start condition
+// Tsu:sto 4.0us 0.6us setup time for a stop conditon
+// Tbuf 4.7us 1.3us Bus free time between a stop and start condition
+//
+
+// synopsys translate_off
+`include "timescale.v"
+// synopsys translate_on
+
+`include "i2c_master_defines.v"
+
+module i2c_master_bit_ctrl(
+ clk, rst, nReset,
+ clk_cnt, ena, cmd, cmd_ack, busy, al, din, dout,
+ scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen
+ );
+
+ //
+ // inputs & outputs
+ //
+ input clk;
+ input rst;
+ input nReset;
+ input ena; // core enable signal
+
+ input [15:0] clk_cnt; // clock prescale value
+
+ input [3:0] cmd;
+ output cmd_ack; // command complete acknowledge
+ reg cmd_ack;
+ output busy; // i2c bus busy
+ reg busy;
+ output al; // i2c bus arbitration lost
+ reg al;
+
+ input din;
+ output dout;
+ reg dout;
+
+ // I2C lines
+ input scl_i; // i2c clock line input
+ output scl_o; // i2c clock line output
+ output scl_oen; // i2c clock line output enable (active low)
+ reg scl_oen;
+ input sda_i; // i2c data line input
+ output sda_o; // i2c data line output
+ output sda_oen; // i2c data line output enable (active low)
+ reg sda_oen;
+
+
+ //
+ // variable declarations
+ //
+
+ reg sSCL, sSDA; // synchronized SCL and SDA inputs
+ reg dscl_oen; // delayed scl_oen
+ reg sda_chk; // check SDA output (Multi-master arbitration)
+ reg clk_en; // clock generation signals
+ wire slave_wait;
+// reg [15:0] cnt = clk_cnt; // clock divider counter (simulation)
+ reg [15:0] cnt; // clock divider counter (synthesis)
+
+ // state machine variable
+ reg [16:0] c_state; // synopsys enum_state
+
+ //
+ // module body
+ //
+
+ // whenever the slave is not ready it can delay the cycle by pulling SCL low
+ // delay scl_oen
+ always @(posedge clk)
+ dscl_oen <= #1 scl_oen;
+
+ assign slave_wait = dscl_oen && !sSCL;
+
+
+ // generate clk enable signal
+ always @(posedge clk or negedge nReset)
+ if(~nReset)
+ begin
+ cnt <= #1 16'h0;
+ clk_en <= #1 1'b1;
+ end
+ else if (rst)
+ begin
+ cnt <= #1 16'h0;
+ clk_en <= #1 1'b1;
+ end
+ else if ( ~|cnt || ~ena)
+ if (~slave_wait)
+ begin
+ cnt <= #1 clk_cnt;
+ clk_en <= #1 1'b1;
+ end
+ else
+ begin
+ cnt <= #1 cnt;
+ clk_en <= #1 1'b0;
+ end
+ else
+ begin
+ cnt <= #1 cnt - 16'h1;
+ clk_en <= #1 1'b0;
+ end
+
+
+ // generate bus status controller
+ reg dSCL, dSDA;
+ reg sta_condition;
+ reg sto_condition;
+
+ // synchronize SCL and SDA inputs
+ // reduce metastability risc
+ always @(posedge clk or negedge nReset)
+ if (~nReset)
+ begin
+ sSCL <= #1 1'b1;
+ sSDA <= #1 1'b1;
+
+ dSCL <= #1 1'b1;
+ dSDA <= #1 1'b1;
+ end
+ else if (rst)
+ begin
+ sSCL <= #1 1'b1;
+ sSDA <= #1 1'b1;
+
+ dSCL <= #1 1'b1;
+ dSDA <= #1 1'b1;
+ end
+ else
+ begin
+ sSCL <= #1 scl_i;
+ sSDA <= #1 sda_i;
+
+ dSCL <= #1 sSCL;
+ dSDA <= #1 sSDA;
+ end
+
+ // detect start condition => detect falling edge on SDA while SCL is high
+ // detect stop condition => detect rising edge on SDA while SCL is high
+ always @(posedge clk or negedge nReset)
+ if (~nReset)
+ begin
+ sta_condition <= #1 1'b0;
+ sto_condition <= #1 1'b0;
+ end
+ else if (rst)
+ begin
+ sta_condition <= #1 1'b0;
+ sto_condition <= #1 1'b0;
+ end
+ else
+ begin
+ sta_condition <= #1 ~sSDA & dSDA & sSCL;
+ sto_condition <= #1 sSDA & ~dSDA & sSCL;
+ end
+
+ // generate i2c bus busy signal
+ always @(posedge clk or negedge nReset)
+ if(!nReset)
+ busy <= #1 1'b0;
+ else if (rst)
+ busy <= #1 1'b0;
+ else
+ busy <= #1 (sta_condition | busy) & ~sto_condition;
+
+ // generate arbitration lost signal
+ // aribitration lost when:
+ // 1) master drives SDA high, but the i2c bus is low
+ // 2) stop detected while not requested
+ reg cmd_stop;
+ always @(posedge clk or negedge nReset)
+ if (~nReset)
+ cmd_stop <= #1 1'b0;
+ else if (rst)
+ cmd_stop <= #1 1'b0;
+ else if (clk_en)
+ cmd_stop <= #1 cmd == `I2C_CMD_STOP;
+
+ always @(posedge clk or negedge nReset)
+ if (~nReset)
+ al <= #1 1'b0;
+ else if (rst)
+ al <= #1 1'b0;
+ else
+ al <= #1 (sda_chk & ~sSDA & sda_oen) | (|c_state & sto_condition & ~cmd_stop);
+
+
+ // generate dout signal (store SDA on rising edge of SCL)
+ always @(posedge clk)
+ if(sSCL & ~dSCL)
+ dout <= #1 sSDA;
+
+ // generate statemachine
+
+ // nxt_state decoder
+ parameter [16:0] idle = 17'b0_0000_0000_0000_0000;
+ parameter [16:0] start_a = 17'b0_0000_0000_0000_0001;
+ parameter [16:0] start_b = 17'b0_0000_0000_0000_0010;
+ parameter [16:0] start_c = 17'b0_0000_0000_0000_0100;
+ parameter [16:0] start_d = 17'b0_0000_0000_0000_1000;
+ parameter [16:0] start_e = 17'b0_0000_0000_0001_0000;
+ parameter [16:0] stop_a = 17'b0_0000_0000_0010_0000;
+ parameter [16:0] stop_b = 17'b0_0000_0000_0100_0000;
+ parameter [16:0] stop_c = 17'b0_0000_0000_1000_0000;
+ parameter [16:0] stop_d = 17'b0_0000_0001_0000_0000;
+ parameter [16:0] rd_a = 17'b0_0000_0010_0000_0000;
+ parameter [16:0] rd_b = 17'b0_0000_0100_0000_0000;
+ parameter [16:0] rd_c = 17'b0_0000_1000_0000_0000;
+ parameter [16:0] rd_d = 17'b0_0001_0000_0000_0000;
+ parameter [16:0] wr_a = 17'b0_0010_0000_0000_0000;
+ parameter [16:0] wr_b = 17'b0_0100_0000_0000_0000;
+ parameter [16:0] wr_c = 17'b0_1000_0000_0000_0000;
+ parameter [16:0] wr_d = 17'b1_0000_0000_0000_0000;
+
+ always @(posedge clk or negedge nReset)
+ if (!nReset)
+ begin
+ c_state <= #1 idle;
+ cmd_ack <= #1 1'b0;
+ scl_oen <= #1 1'b1;
+ sda_oen <= #1 1'b1;
+ sda_chk <= #1 1'b0;
+ end
+ else if (rst | al)
+ begin
+ c_state <= #1 idle;
+ cmd_ack <= #1 1'b0;
+ scl_oen <= #1 1'b1;
+ sda_oen <= #1 1'b1;
+ sda_chk <= #1 1'b0;
+ end
+ else
+ begin
+ cmd_ack <= #1 1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle
+
+ if (clk_en)
+ case (c_state) // synopsys full_case parallel_case
+ // idle state
+ idle:
+ begin
+ case (cmd) // synopsys full_case parallel_case
+ `I2C_CMD_START:
+ c_state <= #1 start_a;
+
+ `I2C_CMD_STOP:
+ c_state <= #1 stop_a;
+
+ `I2C_CMD_WRITE:
+ c_state <= #1 wr_a;
+
+ `I2C_CMD_READ:
+ c_state <= #1 rd_a;
+
+ default:
+ c_state <= #1 idle;
+ endcase
+
+ scl_oen <= #1 scl_oen; // keep SCL in same state
+ sda_oen <= #1 sda_oen; // keep SDA in same state
+ sda_chk <= #1 1'b0; // don't check SDA output
+ end
+
+ // start
+ start_a:
+ begin
+ c_state <= #1 start_b;
+ scl_oen <= #1 scl_oen; // keep SCL in same state
+ sda_oen <= #1 1'b1; // set SDA high
+ sda_chk <= #1 1'b0; // don't check SDA output
+ end
+
+ start_b:
+ begin
+ c_state <= #1 start_c;
+ scl_oen <= #1 1'b1; // set SCL high
+ sda_oen <= #1 1'b1; // keep SDA high
+ sda_chk <= #1 1'b0; // don't check SDA output
+ end
+
+ start_c:
+ begin
+ c_state <= #1 start_d;
+ scl_oen <= #1 1'b1; // keep SCL high
+ sda_oen <= #1 1'b0; // set SDA low
+ sda_chk <= #1 1'b0; // don't check SDA output
+ end
+
+ start_d:
+ begin
+ c_state <= #1 start_e;
+ scl_oen <= #1 1'b1; // keep SCL high
+ sda_oen <= #1 1'b0; // keep SDA low
+ sda_chk <= #1 1'b0; // don't check SDA output
+ end
+
+ start_e:
+ begin
+ c_state <= #1 idle;
+ cmd_ack <= #1 1'b1;
+ scl_oen <= #1 1'b0; // set SCL low
+ sda_oen <= #1 1'b0; // keep SDA low
+ sda_chk <= #1 1'b0; // don't check SDA output
+ end
+
+ // stop
+ stop_a:
+ begin
+ c_state <= #1 stop_b;
+ scl_oen <= #1 1'b0; // keep SCL low
+ sda_oen <= #1 1'b0; // set SDA low
+ sda_chk <= #1 1'b0; // don't check SDA output
+ end
+
+ stop_b:
+ begin
+ c_state <= #1 stop_c;
+ scl_oen <= #1 1'b1; // set SCL high
+ sda_oen <= #1 1'b0; // keep SDA low
+ sda_chk <= #1 1'b0; // don't check SDA output
+ end
+
+ stop_c:
+ begin
+ c_state <= #1 stop_d;
+ scl_oen <= #1 1'b1; // keep SCL high
+ sda_oen <= #1 1'b0; // keep SDA low
+ sda_chk <= #1 1'b0; // don't check SDA output
+ end
+
+ stop_d:
+ begin
+ c_state <= #1 idle;
+ cmd_ack <= #1 1'b1;
+ scl_oen <= #1 1'b1; // keep SCL high
+ sda_oen <= #1 1'b1; // set SDA high
+ sda_chk <= #1 1'b0; // don't check SDA output
+ end
+
+ // read
+ rd_a:
+ begin
+ c_state <= #1 rd_b;
+ scl_oen <= #1 1'b0; // keep SCL low
+ sda_oen <= #1 1'b1; // tri-state SDA
+ sda_chk <= #1 1'b0; // don't check SDA output
+ end
+
+ rd_b:
+ begin
+ c_state <= #1 rd_c;
+ scl_oen <= #1 1'b1; // set SCL high
+ sda_oen <= #1 1'b1; // keep SDA tri-stated
+ sda_chk <= #1 1'b0; // don't check SDA output
+ end
+
+ rd_c:
+ begin
+ c_state <= #1 rd_d;
+ scl_oen <= #1 1'b1; // keep SCL high
+ sda_oen <= #1 1'b1; // keep SDA tri-stated
+ sda_chk <= #1 1'b0; // don't check SDA output
+ end
+
+ rd_d:
+ begin
+ c_state <= #1 idle;
+ cmd_ack <= #1 1'b1;
+ scl_oen <= #1 1'b0; // set SCL low
+ sda_oen <= #1 1'b1; // keep SDA tri-stated
+ sda_chk <= #1 1'b0; // don't check SDA output
+ end
+
+ // write
+ wr_a:
+ begin
+ c_state <= #1 wr_b;
+ scl_oen <= #1 1'b0; // keep SCL low
+ sda_oen <= #1 din; // set SDA
+ sda_chk <= #1 1'b0; // don't check SDA output (SCL low)
+ end
+
+ wr_b:
+ begin
+ c_state <= #1 wr_c;
+ scl_oen <= #1 1'b1; // set SCL high
+ sda_oen <= #1 din; // keep SDA
+ sda_chk <= #1 1'b1; // check SDA output
+ end
+
+ wr_c:
+ begin
+ c_state <= #1 wr_d;
+ scl_oen <= #1 1'b1; // keep SCL high
+ sda_oen <= #1 din;
+ sda_chk <= #1 1'b1; // check SDA output
+ end
+
+ wr_d:
+ begin
+ c_state <= #1 idle;
+ cmd_ack <= #1 1'b1;
+ scl_oen <= #1 1'b0; // set SCL low
+ sda_oen <= #1 din;
+ sda_chk <= #1 1'b0; // don't check SDA output (SCL low)
+ end
+
+ endcase
+ end
+
+
+ // assign scl and sda output (always gnd)
+ assign scl_o = 1'b0;
+ assign sda_o = 1'b0;
+
+endmodule
diff --git a/tests/iwls2005/i2c/i2c_master_byte_ctrl.v b/tests/iwls2005/i2c/i2c_master_byte_ctrl.v
new file mode 100644
index 000000000..d091d1e36
--- /dev/null
+++ b/tests/iwls2005/i2c/i2c_master_byte_ctrl.v
@@ -0,0 +1,344 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// WISHBONE rev.B2 compliant I2C Master byte-controller ////
+//// ////
+//// ////
+//// Author: Richard Herveille ////
+//// richard@asics.ws ////
+//// www.asics.ws ////
+//// ////
+//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 Richard Herveille ////
+//// richard@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: i2c_master_byte_ctrl.v,v 1.7 2004/02/18 11:40:46 rherveille Exp $
+//
+// $Date: 2004/02/18 11:40:46 $
+// $Revision: 1.7 $
+// $Author: rherveille $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: i2c_master_byte_ctrl.v,v $
+// Revision 1.7 2004/02/18 11:40:46 rherveille
+// Fixed a potential bug in the statemachine. During a 'stop' 2 cmd_ack signals were generated. Possibly canceling a new start command.
+//
+// Revision 1.6 2003/08/09 07:01:33 rherveille
+// Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
+// Fixed a potential bug in the byte controller's host-acknowledge generation.
+//
+// Revision 1.5 2002/12/26 15:02:32 rherveille
+// Core is now a Multimaster I2C controller
+//
+// Revision 1.4 2002/11/30 22:24:40 rherveille
+// Cleaned up code
+//
+// Revision 1.3 2001/11/05 11:59:25 rherveille
+// Fixed wb_ack_o generation bug.
+// Fixed bug in the byte_controller statemachine.
+// Added headers.
+//
+
+// synopsys translate_off
+`include "timescale.v"
+// synopsys translate_on
+
+`include "i2c_master_defines.v"
+
+module i2c_master_byte_ctrl (
+ clk, rst, nReset, ena, clk_cnt, start, stop, read, write, ack_in, din,
+ cmd_ack, ack_out, dout, i2c_busy, i2c_al, scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen );
+
+ //
+ // inputs & outputs
+ //
+ input clk; // master clock
+ input rst; // synchronous active high reset
+ input nReset; // asynchronous active low reset
+ input ena; // core enable signal
+
+ input [15:0] clk_cnt; // 4x SCL
+
+ // control inputs
+ input start;
+ input stop;
+ input read;
+ input write;
+ input ack_in;
+ input [7:0] din;
+
+ // status outputs
+ output cmd_ack;
+ reg cmd_ack;
+ output ack_out;
+ reg ack_out;
+ output i2c_busy;
+ output i2c_al;
+ output [7:0] dout;
+
+ // I2C signals
+ input scl_i;
+ output scl_o;
+ output scl_oen;
+ input sda_i;
+ output sda_o;
+ output sda_oen;
+
+
+ //
+ // Variable declarations
+ //
+
+ // statemachine
+ parameter [4:0] ST_IDLE = 5'b0_0000;
+ parameter [4:0] ST_START = 5'b0_0001;
+ parameter [4:0] ST_READ = 5'b0_0010;
+ parameter [4:0] ST_WRITE = 5'b0_0100;
+ parameter [4:0] ST_ACK = 5'b0_1000;
+ parameter [4:0] ST_STOP = 5'b1_0000;
+
+ // signals for bit_controller
+ reg [3:0] core_cmd;
+ reg core_txd;
+ wire core_ack, core_rxd;
+
+ // signals for shift register
+ reg [7:0] sr; //8bit shift register
+ reg shift, ld;
+
+ // signals for state machine
+ wire go;
+ reg [2:0] dcnt;
+ wire cnt_done;
+
+ //
+ // Module body
+ //
+
+ // hookup bit_controller
+ i2c_master_bit_ctrl bit_controller (
+ .clk ( clk ),
+ .rst ( rst ),
+ .nReset ( nReset ),
+ .ena ( ena ),
+ .clk_cnt ( clk_cnt ),
+ .cmd ( core_cmd ),
+ .cmd_ack ( core_ack ),
+ .busy ( i2c_busy ),
+ .al ( i2c_al ),
+ .din ( core_txd ),
+ .dout ( core_rxd ),
+ .scl_i ( scl_i ),
+ .scl_o ( scl_o ),
+ .scl_oen ( scl_oen ),
+ .sda_i ( sda_i ),
+ .sda_o ( sda_o ),
+ .sda_oen ( sda_oen )
+ );
+
+ // generate go-signal
+ assign go = (read | write | stop) & ~cmd_ack;
+
+ // assign dout output to shift-register
+ assign dout = sr;
+
+ // generate shift register
+ always @(posedge clk or negedge nReset)
+ if (!nReset)
+ sr <= #1 8'h0;
+ else if (rst)
+ sr <= #1 8'h0;
+ else if (ld)
+ sr <= #1 din;
+ else if (shift)
+ sr <= #1 {sr[6:0], core_rxd};
+
+ // generate counter
+ always @(posedge clk or negedge nReset)
+ if (!nReset)
+ dcnt <= #1 3'h0;
+ else if (rst)
+ dcnt <= #1 3'h0;
+ else if (ld)
+ dcnt <= #1 3'h7;
+ else if (shift)
+ dcnt <= #1 dcnt - 3'h1;
+
+ assign cnt_done = ~(|dcnt);
+
+ //
+ // state machine
+ //
+ reg [4:0] c_state; // synopsis enum_state
+
+ always @(posedge clk or negedge nReset)
+ if (!nReset)
+ begin
+ core_cmd <= #1 `I2C_CMD_NOP;
+ core_txd <= #1 1'b0;
+ shift <= #1 1'b0;
+ ld <= #1 1'b0;
+ cmd_ack <= #1 1'b0;
+ c_state <= #1 ST_IDLE;
+ ack_out <= #1 1'b0;
+ end
+ else if (rst | i2c_al)
+ begin
+ core_cmd <= #1 `I2C_CMD_NOP;
+ core_txd <= #1 1'b0;
+ shift <= #1 1'b0;
+ ld <= #1 1'b0;
+ cmd_ack <= #1 1'b0;
+ c_state <= #1 ST_IDLE;
+ ack_out <= #1 1'b0;
+ end
+ else
+ begin
+ // initially reset all signals
+ core_txd <= #1 sr[7];
+ shift <= #1 1'b0;
+ ld <= #1 1'b0;
+ cmd_ack <= #1 1'b0;
+
+ case (c_state) // synopsys full_case parallel_case
+ ST_IDLE:
+ if (go)
+ begin
+ if (start)
+ begin
+ c_state <= #1 ST_START;
+ core_cmd <= #1 `I2C_CMD_START;
+ end
+ else if (read)
+ begin
+ c_state <= #1 ST_READ;
+ core_cmd <= #1 `I2C_CMD_READ;
+ end
+ else if (write)
+ begin
+ c_state <= #1 ST_WRITE;
+ core_cmd <= #1 `I2C_CMD_WRITE;
+ end
+ else // stop
+ begin
+ c_state <= #1 ST_STOP;
+ core_cmd <= #1 `I2C_CMD_STOP;
+ end
+
+ ld <= #1 1'b1;
+ end
+
+ ST_START:
+ if (core_ack)
+ begin
+ if (read)
+ begin
+ c_state <= #1 ST_READ;
+ core_cmd <= #1 `I2C_CMD_READ;
+ end
+ else
+ begin
+ c_state <= #1 ST_WRITE;
+ core_cmd <= #1 `I2C_CMD_WRITE;
+ end
+
+ ld <= #1 1'b1;
+ end
+
+ ST_WRITE:
+ if (core_ack)
+ if (cnt_done)
+ begin
+ c_state <= #1 ST_ACK;
+ core_cmd <= #1 `I2C_CMD_READ;
+ end
+ else
+ begin
+ c_state <= #1 ST_WRITE; // stay in same state
+ core_cmd <= #1 `I2C_CMD_WRITE; // write next bit
+ shift <= #1 1'b1;
+ end
+
+ ST_READ:
+ if (core_ack)
+ begin
+ if (cnt_done)
+ begin
+ c_state <= #1 ST_ACK;
+ core_cmd <= #1 `I2C_CMD_WRITE;
+ end
+ else
+ begin
+ c_state <= #1 ST_READ; // stay in same state
+ core_cmd <= #1 `I2C_CMD_READ; // read next bit
+ end
+
+ shift <= #1 1'b1;
+ core_txd <= #1 ack_in;
+ end
+
+ ST_ACK:
+ if (core_ack)
+ begin
+ if (stop)
+ begin
+ c_state <= #1 ST_STOP;
+ core_cmd <= #1 `I2C_CMD_STOP;
+ end
+ else
+ begin
+ c_state <= #1 ST_IDLE;
+ core_cmd <= #1 `I2C_CMD_NOP;
+
+ // generate command acknowledge signal
+ cmd_ack <= #1 1'b1;
+ end
+
+ // assign ack_out output to bit_controller_rxd (contains last received bit)
+ ack_out <= #1 core_rxd;
+
+ core_txd <= #1 1'b1;
+ end
+ else
+ core_txd <= #1 ack_in;
+
+ ST_STOP:
+ if (core_ack)
+ begin
+ c_state <= #1 ST_IDLE;
+ core_cmd <= #1 `I2C_CMD_NOP;
+
+ // generate command acknowledge signal
+ cmd_ack <= #1 1'b1;
+ end
+
+ endcase
+ end
+endmodule
diff --git a/tests/iwls2005/i2c/i2c_master_defines.v b/tests/iwls2005/i2c/i2c_master_defines.v
new file mode 100644
index 000000000..ee3b694fa
--- /dev/null
+++ b/tests/iwls2005/i2c/i2c_master_defines.v
@@ -0,0 +1,64 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// WISHBONE rev.B2 compliant I2C Master controller defines ////
+//// ////
+//// ////
+//// Author: Richard Herveille ////
+//// richard@asics.ws ////
+//// www.asics.ws ////
+//// ////
+//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 Richard Herveille ////
+//// richard@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: i2c_master_defines.v,v 1.3 2001/11/05 11:59:25 rherveille Exp $
+//
+// $Date: 2001/11/05 11:59:25 $
+// $Revision: 1.3 $
+// $Author: rherveille $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: i2c_master_defines.v,v $
+// Revision 1.3 2001/11/05 11:59:25 rherveille
+// Fixed wb_ack_o generation bug.
+// Fixed bug in the byte_controller statemachine.
+// Added headers.
+//
+
+
+// I2C registers wishbone addresses
+
+// bitcontroller states
+`define I2C_CMD_NOP 4'b0000
+`define I2C_CMD_START 4'b0001
+`define I2C_CMD_STOP 4'b0010
+`define I2C_CMD_WRITE 4'b0100
+`define I2C_CMD_READ 4'b1000
diff --git a/tests/iwls2005/i2c/i2c_master_top.v b/tests/iwls2005/i2c/i2c_master_top.v
new file mode 100644
index 000000000..30689bd70
--- /dev/null
+++ b/tests/iwls2005/i2c/i2c_master_top.v
@@ -0,0 +1,301 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// WISHBONE revB.2 compliant I2C Master controller Top-level ////
+//// ////
+//// ////
+//// Author: Richard Herveille ////
+//// richard@asics.ws ////
+//// www.asics.ws ////
+//// ////
+//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 Richard Herveille ////
+//// richard@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: i2c_master_top.v,v 1.11 2005/02/27 09:26:24 rherveille Exp $
+//
+// $Date: 2005/02/27 09:26:24 $
+// $Revision: 1.11 $
+// $Author: rherveille $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: i2c_master_top.v,v $
+// Revision 1.11 2005/02/27 09:26:24 rherveille
+// Fixed register overwrite issue.
+// Removed full_case pragma, replaced it by a default statement.
+//
+// Revision 1.10 2003/09/01 10:34:38 rherveille
+// Fix a blocking vs. non-blocking error in the wb_dat output mux.
+//
+// Revision 1.9 2003/01/09 16:44:45 rherveille
+// Fixed a bug in the Command Register declaration.
+//
+// Revision 1.8 2002/12/26 16:05:12 rherveille
+// Small code simplifications
+//
+// Revision 1.7 2002/12/26 15:02:32 rherveille
+// Core is now a Multimaster I2C controller
+//
+// Revision 1.6 2002/11/30 22:24:40 rherveille
+// Cleaned up code
+//
+// Revision 1.5 2001/11/10 10:52:55 rherveille
+// Changed PRER reset value from 0x0000 to 0xffff, conform specs.
+//
+
+// synopsys translate_off
+`include "timescale.v"
+// synopsys translate_on
+
+`include "i2c_master_defines.v"
+
+module i2c_master_top(
+ wb_clk_i, wb_rst_i, arst_i, wb_adr_i, wb_dat_i, wb_dat_o,
+ wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_inta_o,
+ scl_pad_i, scl_pad_o, scl_padoen_o, sda_pad_i, sda_pad_o, sda_padoen_o );
+
+ // parameters
+ parameter ARST_LVL = 1'b0; // asynchronous reset level
+
+ //
+ // inputs & outputs
+ //
+
+ // wishbone signals
+ input wb_clk_i; // master clock input
+ input wb_rst_i; // synchronous active high reset
+ input arst_i; // asynchronous reset
+ input [2:0] wb_adr_i; // lower address bits
+ input [7:0] wb_dat_i; // databus input
+ output [7:0] wb_dat_o; // databus output
+ input wb_we_i; // write enable input
+ input wb_stb_i; // stobe/core select signal
+ input wb_cyc_i; // valid bus cycle input
+ output wb_ack_o; // bus cycle acknowledge output
+ output wb_inta_o; // interrupt request signal output
+
+ reg [7:0] wb_dat_o;
+ reg wb_ack_o;
+ reg wb_inta_o;
+
+ // I2C signals
+ // i2c clock line
+ input scl_pad_i; // SCL-line input
+ output scl_pad_o; // SCL-line output (always 1'b0)
+ output scl_padoen_o; // SCL-line output enable (active low)
+
+ // i2c data line
+ input sda_pad_i; // SDA-line input
+ output sda_pad_o; // SDA-line output (always 1'b0)
+ output sda_padoen_o; // SDA-line output enable (active low)
+
+
+ //
+ // variable declarations
+ //
+
+ // registers
+ reg [15:0] prer; // clock prescale register
+ reg [ 7:0] ctr; // control register
+ reg [ 7:0] txr; // transmit register
+ wire [ 7:0] rxr; // receive register
+ reg [ 7:0] cr; // command register
+ wire [ 7:0] sr; // status register
+
+ // done signal: command completed, clear command register
+ wire done;
+
+ // core enable signal
+ wire core_en;
+ wire ien;
+
+ // status register signals
+ wire irxack;
+ reg rxack; // received aknowledge from slave
+ reg tip; // transfer in progress
+ reg irq_flag; // interrupt pending flag
+ wire i2c_busy; // bus busy (start signal detected)
+ wire i2c_al; // i2c bus arbitration lost
+ reg al; // status register arbitration lost bit
+
+ //
+ // module body
+ //
+
+ // generate internal reset
+ wire rst_i = arst_i ^ ARST_LVL;
+
+ // generate wishbone signals
+ wire wb_wacc = wb_cyc_i & wb_stb_i & wb_we_i;
+
+ // generate acknowledge output signal
+ always @(posedge wb_clk_i)
+ wb_ack_o <= #1 wb_cyc_i & wb_stb_i & ~wb_ack_o; // because timing is always honored
+
+ // assign DAT_O
+ always @(posedge wb_clk_i)
+ begin
+ case (wb_adr_i) // synopsis parallel_case
+ 3'b000: wb_dat_o <= #1 prer[ 7:0];
+ 3'b001: wb_dat_o <= #1 prer[15:8];
+ 3'b010: wb_dat_o <= #1 ctr;
+ 3'b011: wb_dat_o <= #1 rxr; // write is transmit register (txr)
+ 3'b100: wb_dat_o <= #1 sr; // write is command register (cr)
+ 3'b101: wb_dat_o <= #1 txr;
+ 3'b110: wb_dat_o <= #1 cr;
+ 3'b111: wb_dat_o <= #1 0; // reserved
+ endcase
+ end
+
+ // generate registers
+ always @(posedge wb_clk_i or negedge rst_i)
+ if (!rst_i)
+ begin
+ prer <= #1 16'hffff;
+ ctr <= #1 8'h0;
+ txr <= #1 8'h0;
+ end
+ else if (wb_rst_i)
+ begin
+ prer <= #1 16'hffff;
+ ctr <= #1 8'h0;
+ txr <= #1 8'h0;
+ end
+ else
+ if (wb_wacc)
+ case (wb_adr_i) // synopsis parallel_case
+ 3'b000 : prer [ 7:0] <= #1 wb_dat_i;
+ 3'b001 : prer [15:8] <= #1 wb_dat_i;
+ 3'b010 : ctr <= #1 wb_dat_i;
+ 3'b011 : txr <= #1 wb_dat_i;
+ default: ;
+ endcase
+
+ // generate command register (special case)
+ always @(posedge wb_clk_i or negedge rst_i)
+ if (~rst_i)
+ cr <= #1 8'h0;
+ else if (wb_rst_i)
+ cr <= #1 8'h0;
+ else if (wb_wacc)
+ begin
+ if (core_en & (wb_adr_i == 3'b100) )
+ cr <= #1 wb_dat_i;
+ end
+ else
+ begin
+ if (done | i2c_al)
+ cr[7:4] <= #1 4'h0; // clear command bits when done
+ // or when aribitration lost
+ cr[2:1] <= #1 2'b0; // reserved bits
+ cr[0] <= #1 2'b0; // clear IRQ_ACK bit
+ end
+
+
+ // decode command register
+ wire sta = cr[7];
+ wire sto = cr[6];
+ wire rd = cr[5];
+ wire wr = cr[4];
+ wire ack = cr[3];
+ wire iack = cr[0];
+
+ // decode control register
+ assign core_en = ctr[7];
+ assign ien = ctr[6];
+
+ // hookup byte controller block
+ i2c_master_byte_ctrl byte_controller (
+ .clk ( wb_clk_i ),
+ .rst ( wb_rst_i ),
+ .nReset ( rst_i ),
+ .ena ( core_en ),
+ .clk_cnt ( prer ),
+ .start ( sta ),
+ .stop ( sto ),
+ .read ( rd ),
+ .write ( wr ),
+ .ack_in ( ack ),
+ .din ( txr ),
+ .cmd_ack ( done ),
+ .ack_out ( irxack ),
+ .dout ( rxr ),
+ .i2c_busy ( i2c_busy ),
+ .i2c_al ( i2c_al ),
+ .scl_i ( scl_pad_i ),
+ .scl_o ( scl_pad_o ),
+ .scl_oen ( scl_padoen_o ),
+ .sda_i ( sda_pad_i ),
+ .sda_o ( sda_pad_o ),
+ .sda_oen ( sda_padoen_o )
+ );
+
+ // status register block + interrupt request signal
+ always @(posedge wb_clk_i or negedge rst_i)
+ if (!rst_i)
+ begin
+ al <= #1 1'b0;
+ rxack <= #1 1'b0;
+ tip <= #1 1'b0;
+ irq_flag <= #1 1'b0;
+ end
+ else if (wb_rst_i)
+ begin
+ al <= #1 1'b0;
+ rxack <= #1 1'b0;
+ tip <= #1 1'b0;
+ irq_flag <= #1 1'b0;
+ end
+ else
+ begin
+ al <= #1 i2c_al | (al & ~sta);
+ rxack <= #1 irxack;
+ tip <= #1 (rd | wr);
+ irq_flag <= #1 (done | i2c_al | irq_flag) & ~iack; // interrupt request flag is always generated
+ end
+
+ // generate interrupt request signals
+ always @(posedge wb_clk_i or negedge rst_i)
+ if (!rst_i)
+ wb_inta_o <= #1 1'b0;
+ else if (wb_rst_i)
+ wb_inta_o <= #1 1'b0;
+ else
+ wb_inta_o <= #1 irq_flag && ien; // interrupt signal is only generated when IEN (interrupt enable bit is set)
+
+ // assign status register bits
+ assign sr[7] = rxack;
+ assign sr[6] = i2c_busy;
+ assign sr[5] = al;
+ assign sr[4:2] = 3'h0; // reserved
+ assign sr[1] = tip;
+ assign sr[0] = irq_flag;
+
+endmodule
diff --git a/tests/iwls2005/i2c/timescale.v b/tests/iwls2005/i2c/timescale.v
new file mode 100644
index 000000000..60d4ecbd1
--- /dev/null
+++ b/tests/iwls2005/i2c/timescale.v
@@ -0,0 +1,2 @@
+`timescale 1ns / 10ps
+
diff --git a/tests/iwls2005/run-fm.sh b/tests/iwls2005/run-fm.sh
new file mode 100755
index 000000000..14bb4e82c
--- /dev/null
+++ b/tests/iwls2005/run-fm.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+if [ -n "$REMOTE_YOSYS_ROOT" ]; then
+ rsync --exclude=".svn" --exclude="synth.log" --exclude="run-fm.sh" -rv -e "${REMOTE_YOSYS_SSH:-ssh}" "$REMOTE_YOSYS_ROOT"/tests/iwls2005/. .
+fi
+
+exec_fm()
+{
+ dir=$1; top=$2; shift; shift
+ cat > $dir/fm.do <<- EOT
+ set hdlin_ignore_full_case false
+ set hdlin_warn_on_mismatch_message "FMR_ELAB-115 FMR_ELAB-146 FMR_ELAB-147"
+ read_verilog -container r -libname WORK -01 { $* }
+ set_top r:/WORK/$top
+ read_verilog -container i -libname WORK -01 synth.v
+ # read_verilog -container i -technology_library -libname TECH_WORK -01 ../../../techlibs/stdcells_sim.v
+ set_top i:/WORK/$top
+ if ![verify] start_gui exit
+ EOT
+ ( cd $dir; fm_shell -64 -file fm.do 2>&1 | tee fm.log; )
+}
+
+# cores that validated
+exec_fm aes_core aes_cipher_top aes_cipher_top.v aes_inv_cipher_top.v aes_inv_sbox.v aes_key_expand_128.v aes_rcon.v aes_sbox.v
+exec_fm i2c i2c_master_top i2c_master_top.v i2c_master_bit_ctrl.v i2c_master_byte_ctrl.v
+exec_fm sasc sasc_top sasc_top.v sasc_brg.v sasc_fifo4.v
+exec_fm simple_spi simple_spi_top simple_spi_top.v fifo4.v
+exec_fm spi spi_top spi_top.v spi_clgen.v spi_shift.v
+exec_fm ss_pcm pcm_slv_top pcm_slv_top.v
+exec_fm systemcaes aes aes.v byte_mixcolum.v keysched.v mixcolum.v sbox.v subbytes.v word_mixcolum.v
+exec_fm usb_phy usb_phy usb_phy.v usb_rx_phy.v usb_tx_phy.v
+
+# cores with known problems (the fpu core unfortunately was designed with logic loops)
+#exec_fm fpu fpu fpu.v except.v post_norm.v pre_norm_fmul.v pre_norm.v primitives.v
+
+# summary
+echo; echo
+for x in */fm.log; do
+ echo -e "${x%/*}\\t$( egrep '^Verification (SUCCEEDED|FAILED)' $x; )"
+done | expand -t15
+echo; echo
+
diff --git a/tests/iwls2005/run-synth.sh b/tests/iwls2005/run-synth.sh
new file mode 100755
index 000000000..2f1e30661
--- /dev/null
+++ b/tests/iwls2005/run-synth.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+make -C ../..
+set -x
+
+vg=""
+# vg="valgrind --leak-check=full --show-reachable=yes --log-file=valgrind.log"
+
+cd aes_core
+time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \
+ aes_cipher_top.v aes_inv_cipher_top.v aes_inv_sbox.v \
+ aes_key_expand_128.v aes_rcon.v aes_sbox.v
+
+cd ../fpu
+time $vg ../../../yosys -qt -l synth.log -o synth.v -f "verilog -nolatches" -s ../run-synth.ys \
+ fpu.v except.v post_norm.v pre_norm_fmul.v pre_norm.v primitives.v
+
+cd ../i2c
+time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \
+ i2c_master_top.v i2c_master_bit_ctrl.v i2c_master_byte_ctrl.v
+
+cd ../sasc
+time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \
+ sasc_top.v sasc_brg.v sasc_fifo4.v
+
+cd ../simple_spi
+time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \
+ simple_spi_top.v fifo4.v
+
+cd ../spi
+time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \
+ spi_top.v spi_clgen.v spi_shift.v
+
+cd ../ss_pcm
+time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \
+ pcm_slv_top.v
+
+cd ../systemcaes
+time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \
+ aes.v byte_mixcolum.v keysched.v mixcolum.v sbox.v subbytes.v word_mixcolum.v
+
+cd ../usb_phy
+time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \
+ usb_phy.v usb_rx_phy.v usb_tx_phy.v
+
diff --git a/tests/iwls2005/run-synth.ys b/tests/iwls2005/run-synth.ys
new file mode 100644
index 000000000..f3253d5f9
--- /dev/null
+++ b/tests/iwls2005/run-synth.ys
@@ -0,0 +1,11 @@
+hierarchy
+proc
+opt
+memory
+opt
+# fsm -norecode
+# opt
+techmap
+opt
+abc
+opt
diff --git a/tests/iwls2005/sasc/sasc_brg.v b/tests/iwls2005/sasc/sasc_brg.v
new file mode 100644
index 000000000..74a7cc5b6
--- /dev/null
+++ b/tests/iwls2005/sasc/sasc_brg.v
@@ -0,0 +1,160 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Simple Baud Rate Generator ////
+//// ////
+//// ////
+//// Author: Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+//// ////
+//// Downloaded from: http://www.opencores.org/cores/sasc/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000-2002 Rudolf Usselmann ////
+//// www.asics.ws ////
+//// rudi@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: sasc_brg.v,v 1.2 2002/11/08 15:22:49 rudi Exp $
+//
+// $Date: 2002/11/08 15:22:49 $
+// $Revision: 1.2 $
+// $Author: rudi $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: sasc_brg.v,v $
+// Revision 1.2 2002/11/08 15:22:49 rudi
+//
+// Fixed a typo in brg
+//
+// Revision 1.1.1.1 2002/09/16 16:16:40 rudi
+// Initial Checkin
+//
+//
+//
+//
+//
+//
+//
+//
+
+`include "timescale.v"
+
+/*
+ Baud rate Generator
+ ==================
+
+ div0 - is the first stage divider
+ Set this to the desired number of cycles less two
+ div1 - is the second stage divider
+ Set this to the actual number of cycles
+
+ Remember you have to generate a baud rate that is 4 higher than what
+ you really want. This is because of the DPLL in the RX section ...
+
+ Example:
+ If your system clock is 50MHz and you want to generate a 9.6 Kbps baud rate:
+ 9600*4 = 38400KHz
+ 50MHz/38400KHz=1302 or 6*217
+ set div0=4 (6-2) and set div1=217
+
+*/
+
+module sasc_brg(clk, rst, div0, div1, sio_ce, sio_ce_x4);
+input clk;
+input rst;
+input [7:0] div0, div1;
+output sio_ce, sio_ce_x4;
+
+///////////////////////////////////////////////////////////////////
+//
+// Local Wires and Registers
+//
+
+reg [7:0] ps;
+reg ps_clr;
+reg [7:0] br_cnt;
+reg br_clr;
+reg sio_ce_x4_r;
+reg [1:0] cnt;
+reg sio_ce, sio_ce_x4;
+reg sio_ce_r ;
+reg sio_ce_x4_t;
+
+///////////////////////////////////////////////////////////////////
+//
+// Boud Rate Generator
+//
+
+// -----------------------------------------------------
+// Prescaler
+always @(posedge clk)
+ if(!rst) ps <= #1 8'h0;
+ else
+ if(ps_clr) ps <= #1 8'h0;
+ else ps <= #1 ps + 8'h1;
+
+always @(posedge clk)
+ ps_clr <= #1 (ps == div0); // Desired number of cycles less 2
+
+// -----------------------------------------------------
+// Oversampled Boud Rate (x4)
+always @(posedge clk)
+ if(!rst) br_cnt <= #1 8'h0;
+ else
+ if(br_clr) br_cnt <= #1 8'h0;
+ else
+ if(ps_clr) br_cnt <= #1 br_cnt + 8'h1;
+
+always @(posedge clk)
+ br_clr <= #1 (br_cnt == div1); // Prciese number of PS cycles
+
+always @(posedge clk)
+ sio_ce_x4_r <= #1 br_clr;
+
+always @(posedge clk)
+ sio_ce_x4_t <= #1 !sio_ce_x4_r & br_clr;
+
+always @(posedge clk)
+ sio_ce_x4 <= #1 sio_ce_x4_t;
+
+// -----------------------------------------------------
+// Actual Boud rate
+always @(posedge clk)
+ if(!rst) cnt <= #1 2'h0;
+ else
+ if(!sio_ce_x4_r & br_clr) cnt <= #1 cnt + 2'h1;
+
+always @(posedge clk)
+ sio_ce_r <= #1 (cnt == 2'h0);
+
+always @(posedge clk)
+ sio_ce <= #1 !sio_ce_r & (cnt == 2'h0);
+
+endmodule
+
diff --git a/tests/iwls2005/sasc/sasc_fifo4.v b/tests/iwls2005/sasc/sasc_fifo4.v
new file mode 100644
index 000000000..ab9b9fefe
--- /dev/null
+++ b/tests/iwls2005/sasc/sasc_fifo4.v
@@ -0,0 +1,135 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// FIFO 4 entries deep ////
+//// ////
+//// ////
+//// Author: Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+//// ////
+//// Downloaded from: http://www.opencores.org/cores/sasc/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000-2002 Rudolf Usselmann ////
+//// www.asics.ws ////
+//// rudi@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: sasc_fifo4.v,v 1.1.1.1 2002/09/16 16:16:41 rudi Exp $
+//
+// $Date: 2002/09/16 16:16:41 $
+// $Revision: 1.1.1.1 $
+// $Author: rudi $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: sasc_fifo4.v,v $
+// Revision 1.1.1.1 2002/09/16 16:16:41 rudi
+// Initial Checkin
+//
+//
+//
+//
+//
+//
+
+`include "timescale.v"
+
+// 4 entry deep fast fifo
+module sasc_fifo4(clk, rst, clr, din, we, dout, re, full, empty);
+
+input clk, rst;
+input clr;
+input [7:0] din;
+input we;
+output [7:0] dout;
+input re;
+output full, empty;
+
+
+////////////////////////////////////////////////////////////////////
+//
+// Local Wires
+//
+
+reg [7:0] mem[0:3];
+reg [1:0] wp;
+reg [1:0] rp;
+wire [1:0] wp_p1;
+wire [1:0] wp_p2;
+wire [1:0] rp_p1;
+wire full, empty;
+reg gb;
+
+////////////////////////////////////////////////////////////////////
+//
+// Misc Logic
+//
+
+always @(posedge clk or negedge rst)
+ if(!rst) wp <= #1 2'h0;
+ else
+ if(clr) wp <= #1 2'h0;
+ else
+ if(we) wp <= #1 wp_p1;
+
+assign wp_p1 = wp + 2'h1;
+assign wp_p2 = wp + 2'h2;
+
+always @(posedge clk or negedge rst)
+ if(!rst) rp <= #1 2'h0;
+ else
+ if(clr) rp <= #1 2'h0;
+ else
+ if(re) rp <= #1 rp_p1;
+
+assign rp_p1 = rp + 2'h1;
+
+// Fifo Output
+assign dout = mem[ rp ];
+
+// Fifo Input
+always @(posedge clk)
+ if(we) mem[ wp ] <= #1 din;
+
+// Status
+assign empty = (wp == rp) & !gb;
+assign full = (wp == rp) & gb;
+
+// Guard Bit ...
+always @(posedge clk)
+ if(!rst) gb <= #1 1'b0;
+ else
+ if(clr) gb <= #1 1'b0;
+ else
+ if((wp_p1 == rp) & we) gb <= #1 1'b1;
+ else
+ if(re) gb <= #1 1'b0;
+
+endmodule
+
+
diff --git a/tests/iwls2005/sasc/sasc_top.v b/tests/iwls2005/sasc/sasc_top.v
new file mode 100644
index 000000000..a59329add
--- /dev/null
+++ b/tests/iwls2005/sasc/sasc_top.v
@@ -0,0 +1,301 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Simple Asynchronous Serial Comm. Device ////
+//// ////
+//// ////
+//// Author: Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+//// ////
+//// Downloaded from: http://www.opencores.org/cores/sasc/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000-2002 Rudolf Usselmann ////
+//// www.asics.ws ////
+//// rudi@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: sasc_top.v,v 1.1.1.1 2002/09/16 16:16:42 rudi Exp $
+//
+// $Date: 2002/09/16 16:16:42 $
+// $Revision: 1.1.1.1 $
+// $Author: rudi $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: sasc_top.v,v $
+// Revision 1.1.1.1 2002/09/16 16:16:42 rudi
+// Initial Checkin
+//
+//
+//
+//
+//
+//
+//
+//
+
+`include "timescale.v"
+
+/*
+Serial IO Interface
+===============================
+RTS I Request To Send
+CTS O Clear to send
+TD I Transmit Data
+RD O Receive Data
+*/
+
+module sasc_top( clk, rst,
+
+ // SIO
+ rxd_i, txd_o, cts_i, rts_o,
+
+ // External Baud Rate Generator
+ sio_ce, sio_ce_x4,
+
+ // Internal Interface
+ din_i, dout_o, re_i, we_i, full_o, empty_o);
+
+input clk;
+input rst;
+input rxd_i;
+output txd_o;
+input cts_i;
+output rts_o;
+input sio_ce;
+input sio_ce_x4;
+input [7:0] din_i;
+output [7:0] dout_o;
+input re_i, we_i;
+output full_o, empty_o;
+
+///////////////////////////////////////////////////////////////////
+//
+// Local Wires and Registers
+//
+
+parameter START_BIT = 1'b0,
+ STOP_BIT = 1'b1,
+ IDLE_BIT = 1'b1;
+
+wire [7:0] txd_p;
+reg load;
+reg load_r;
+wire load_e;
+reg [9:0] hold_reg;
+wire txf_empty;
+reg txd_o;
+reg shift_en;
+reg [3:0] tx_bit_cnt;
+reg rxd_s, rxd_r;
+wire start;
+reg [3:0] rx_bit_cnt;
+reg rx_go;
+reg [9:0] rxr;
+reg rx_valid, rx_valid_r;
+wire rx_we;
+wire rxf_full;
+reg rts_o;
+reg txf_empty_r;
+reg shift_en_r;
+reg rxd_r1, rxd_r2;
+wire lock_en;
+reg change;
+reg rx_sio_ce_d, rx_sio_ce_r1, rx_sio_ce_r2, rx_sio_ce;
+reg [1:0] dpll_state, dpll_next_state;
+
+///////////////////////////////////////////////////////////////////
+//
+// IO Fifo's
+//
+
+sasc_fifo4 tx_fifo( .clk( clk ),
+ .rst( rst ),
+ .clr( 1'b0 ),
+ .din( din_i ),
+ .we( we_i ),
+ .dout( txd_p ),
+ .re( load_e ),
+ .full( full_o ),
+ .empty( txf_empty )
+ );
+
+sasc_fifo4 rx_fifo( .clk( clk ),
+ .rst( rst ),
+ .clr( 1'b0 ),
+ .din( rxr[9:2] ),
+ .we( rx_we ),
+ .dout( dout_o ),
+ .re( re_i ),
+ .full( rxf_full ),
+ .empty( empty_o )
+ );
+
+///////////////////////////////////////////////////////////////////
+//
+// Transmit Logic
+//
+always @(posedge clk)
+ if(!rst) txf_empty_r <= #1 1'b1;
+ else
+ if(sio_ce) txf_empty_r <= #1 txf_empty;
+
+always @(posedge clk)
+ load <= #1 !txf_empty_r & !shift_en & !cts_i;
+
+always @(posedge clk)
+ load_r <= #1 load;
+
+assign load_e = load & sio_ce;
+
+always @(posedge clk)
+ if(load_e) hold_reg <= #1 {STOP_BIT, txd_p, START_BIT};
+ else
+ if(shift_en & sio_ce) hold_reg <= #1 {IDLE_BIT, hold_reg[9:1]};
+
+always @(posedge clk)
+ if(!rst) txd_o <= #1 IDLE_BIT;
+ else
+ if(sio_ce)
+ if(shift_en | shift_en_r) txd_o <= #1 hold_reg[0];
+ else txd_o <= #1 IDLE_BIT;
+
+always @(posedge clk)
+ if(!rst) tx_bit_cnt <= #1 4'h9;
+ else
+ if(load_e) tx_bit_cnt <= #1 4'h0;
+ else
+ if(shift_en & sio_ce) tx_bit_cnt <= #1 tx_bit_cnt + 4'h1;
+
+always @(posedge clk)
+ shift_en <= #1 (tx_bit_cnt != 4'h9);
+
+always @(posedge clk)
+ if(!rst) shift_en_r <= #1 1'b0;
+ else
+ if(sio_ce) shift_en_r <= #1 shift_en;
+
+///////////////////////////////////////////////////////////////////
+//
+// Recieve Logic
+//
+
+always @(posedge clk)
+ rxd_s <= #1 rxd_i;
+
+always @(posedge clk)
+ rxd_r <= #1 rxd_s;
+
+assign start = (rxd_r == IDLE_BIT) & (rxd_s == START_BIT);
+
+always @(posedge clk)
+ if(!rst) rx_bit_cnt <= #1 4'ha;
+ else
+ if(!rx_go & start) rx_bit_cnt <= #1 4'h0;
+ else
+ if(rx_go & rx_sio_ce) rx_bit_cnt <= #1 rx_bit_cnt + 4'h1;
+
+always @(posedge clk)
+ rx_go <= #1 (rx_bit_cnt != 4'ha);
+
+always @(posedge clk)
+ rx_valid <= #1 (rx_bit_cnt == 4'h9);
+
+always @(posedge clk)
+ rx_valid_r <= #1 rx_valid;
+
+assign rx_we = !rx_valid_r & rx_valid & !rxf_full;
+
+always @(posedge clk)
+ if(rx_go & rx_sio_ce) rxr <= {rxd_s, rxr[9:1]};
+
+always @(posedge clk)
+ rts_o <= #1 rxf_full;
+
+///////////////////////////////////////////////////////////////////
+//
+// Reciever DPLL
+//
+
+// Uses 4x baud clock to lock to incoming stream
+
+// Edge detector
+always @(posedge clk)
+ if(sio_ce_x4) rxd_r1 <= #1 rxd_s;
+
+always @(posedge clk)
+ if(sio_ce_x4) rxd_r2 <= #1 rxd_r1;
+
+always @(posedge clk)
+ if(!rst) change <= #1 1'b0;
+ else
+ if(rxd_r != rxd_s) change <= #1 1'b1;
+ else
+ if(sio_ce_x4) change <= #1 1'b0;
+
+// DPLL FSM
+always @(posedge clk or negedge rst)
+ if(!rst) dpll_state <= #1 2'h1;
+ else
+ if(sio_ce_x4) dpll_state <= #1 dpll_next_state;
+
+always @(dpll_state or change)
+ begin
+ rx_sio_ce_d = 1'b0;
+ case(dpll_state)
+ 2'h0:
+ if(change) dpll_next_state = 3'h0;
+ else dpll_next_state = 3'h1;
+ 2'h1:begin
+ rx_sio_ce_d = 1'b1;
+ if(change) dpll_next_state = 3'h3;
+ else dpll_next_state = 3'h2;
+ end
+ 2'h2:
+ if(change) dpll_next_state = 3'h0;
+ else dpll_next_state = 3'h3;
+ 2'h3:
+ if(change) dpll_next_state = 3'h0;
+ else dpll_next_state = 3'h0;
+ endcase
+ end
+
+// Compensate for sync registers at the input - allign sio
+// clock enable to be in the middle between two bit changes ...
+always @(posedge clk)
+ rx_sio_ce_r1 <= #1 rx_sio_ce_d;
+
+always @(posedge clk)
+ rx_sio_ce_r2 <= #1 rx_sio_ce_r1;
+
+always @(posedge clk)
+ rx_sio_ce <= #1 rx_sio_ce_r1 & !rx_sio_ce_r2;
+
+endmodule
+
+
diff --git a/tests/iwls2005/sasc/timescale.v b/tests/iwls2005/sasc/timescale.v
new file mode 100644
index 000000000..ff9e265a8
--- /dev/null
+++ b/tests/iwls2005/sasc/timescale.v
@@ -0,0 +1 @@
+`timescale 1ns / 10ps
diff --git a/tests/iwls2005/simple_spi/fifo4.v b/tests/iwls2005/simple_spi/fifo4.v
new file mode 100644
index 000000000..f041c7d2f
--- /dev/null
+++ b/tests/iwls2005/simple_spi/fifo4.v
@@ -0,0 +1,134 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// FIFO 4 entries deep ////
+//// ////
+//// Authors: Rudolf Usselmann, Richard Herveille ////
+//// rudi@asics.ws richard@asics.ws ////
+//// ////
+//// ////
+//// Download from: http://www.opencores.org/projects/sasc ////
+//// http://www.opencores.org/projects/simple_spi ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000-2002 Rudolf Usselmann, Richard Herveille ////
+//// www.asics.ws ////
+//// rudi@asics.ws, richard@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: fifo4.v,v 1.1.1.1 2002/12/22 16:07:14 rherveille Exp $
+//
+// $Date: 2002/12/22 16:07:14 $
+// $Revision: 1.1.1.1 $
+// $Author: rherveille $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: fifo4.v,v $
+// Revision 1.1.1.1 2002/12/22 16:07:14 rherveille
+// Initial release
+//
+//
+
+// synopsys translate_off
+`include "timescale.v"
+// synopsys translate_on
+
+
+// 4 entry deep fast fifo
+module fifo4(clk, rst, clr, din, we, dout, re, full, empty);
+
+parameter dw = 8;
+
+input clk, rst;
+input clr;
+input [dw:1] din;
+input we;
+output [dw:1] dout;
+input re;
+output full, empty;
+
+
+////////////////////////////////////////////////////////////////////
+//
+// Local Wires
+//
+
+reg [dw:1] mem[0:3];
+reg [1:0] wp;
+reg [1:0] rp;
+wire [1:0] wp_p1;
+wire [1:0] wp_p2;
+wire [1:0] rp_p1;
+wire full, empty;
+reg gb;
+
+////////////////////////////////////////////////////////////////////
+//
+// Misc Logic
+//
+
+always @(posedge clk or negedge rst)
+ if(!rst) wp <= #1 2'h0;
+ else
+ if(clr) wp <= #1 2'h0;
+ else
+ if(we) wp <= #1 wp_p1;
+
+assign wp_p1 = wp + 2'h1;
+assign wp_p2 = wp + 2'h2;
+
+always @(posedge clk or negedge rst)
+ if(!rst) rp <= #1 2'h0;
+ else
+ if(clr) rp <= #1 2'h0;
+ else
+ if(re) rp <= #1 rp_p1;
+
+assign rp_p1 = rp + 2'h1;
+
+// Fifo Output
+assign dout = mem[ rp ];
+
+// Fifo Input
+always @(posedge clk)
+ if(we) mem[ wp ] <= #1 din;
+
+// Status
+assign empty = (wp == rp) & !gb;
+assign full = (wp == rp) & gb;
+
+// Guard Bit ...
+always @(posedge clk)
+ if(!rst) gb <= #1 1'b0;
+ else
+ if(clr) gb <= #1 1'b0;
+ else
+ if((wp_p1 == rp) & we) gb <= #1 1'b1;
+ else
+ if(re) gb <= #1 1'b0;
+
+endmodule
diff --git a/tests/iwls2005/simple_spi/simple_spi_top.v b/tests/iwls2005/simple_spi/simple_spi_top.v
new file mode 100644
index 000000000..e952f4bef
--- /dev/null
+++ b/tests/iwls2005/simple_spi/simple_spi_top.v
@@ -0,0 +1,329 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// OpenCores MC68HC11E based SPI interface ////
+//// ////
+//// Author: Richard Herveille ////
+//// richard@asics.ws ////
+//// www.asics.ws ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2002 Richard Herveille ////
+//// richard@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: simple_spi_top.v,v 1.5 2004/02/28 15:59:50 rherveille Exp $
+//
+// $Date: 2004/02/28 15:59:50 $
+// $Revision: 1.5 $
+// $Author: rherveille $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: simple_spi_top.v,v $
+// Revision 1.5 2004/02/28 15:59:50 rherveille
+// Fixed SCK_O generation bug.
+// This resulted in a major rewrite of the serial interface engine.
+//
+// Revision 1.4 2003/08/01 11:41:54 rherveille
+// Fixed some timing bugs.
+//
+// Revision 1.3 2003/01/09 16:47:59 rherveille
+// Updated clkcnt size and decoding due to new SPR bit assignments.
+//
+// Revision 1.2 2003/01/07 13:29:52 rherveille
+// Changed SPR bits coding.
+//
+// Revision 1.1.1.1 2002/12/22 16:07:15 rherveille
+// Initial release
+//
+//
+
+
+
+//
+// Motorola MC68HC11E based SPI interface
+//
+// Currently only MASTER mode is supported
+//
+
+// synopsys translate_off
+`include "timescale.v"
+// synopsys translate_on
+
+module simple_spi_top(
+ // 8bit WISHBONE bus slave interface
+ input wire clk_i, // clock
+ input wire rst_i, // reset (asynchronous active low)
+ input wire cyc_i, // cycle
+ input wire stb_i, // strobe
+ input wire [1:0] adr_i, // address
+ input wire we_i, // write enable
+ input wire [7:0] dat_i, // data input
+ output reg [7:0] dat_o, // data output
+ output reg ack_o, // normal bus termination
+ output reg inta_o, // interrupt output
+
+ // SPI port
+ output reg sck_o, // serial clock output
+ output wire mosi_o, // MasterOut SlaveIN
+ input wire miso_i // MasterIn SlaveOut
+);
+
+ //
+ // Module body
+ //
+ reg [7:0] spcr; // Serial Peripheral Control Register ('HC11 naming)
+ wire [7:0] spsr; // Serial Peripheral Status register ('HC11 naming)
+ reg [7:0] sper; // Serial Peripheral Extension register
+ reg [7:0] treg, rreg; // Transmit/Receive register
+
+ // fifo signals
+ wire [7:0] rfdout;
+ reg wfre, rfwe;
+ wire rfre, rffull, rfempty;
+ wire [7:0] wfdout;
+ wire wfwe, wffull, wfempty;
+
+ // misc signals
+ wire tirq; // transfer interrupt (selected number of transfers done)
+ wire wfov; // write fifo overrun (writing while fifo full)
+ reg [1:0] state; // statemachine state
+ reg [2:0] bcnt;
+
+ //
+ // Wishbone interface
+ wire wb_acc = cyc_i & stb_i; // WISHBONE access
+ wire wb_wr = wb_acc & we_i; // WISHBONE write access
+
+ // dat_i
+ always @(posedge clk_i or negedge rst_i)
+ if (~rst_i)
+ begin
+ spcr <= #1 8'h10; // set master bit
+ sper <= #1 8'h00;
+ end
+ else if (wb_wr)
+ begin
+ if (adr_i == 2'b00)
+ spcr <= #1 dat_i | 8'h10; // always set master bit
+
+ if (adr_i == 2'b11)
+ sper <= #1 dat_i;
+ end
+
+ // write fifo
+ assign wfwe = wb_acc & (adr_i == 2'b10) & ack_o & we_i;
+ assign wfov = wfwe & wffull;
+
+ // dat_o
+ always @(posedge clk_i)
+ case(adr_i) // synopsys full_case parallel_case
+ 2'b00: dat_o <= #1 spcr;
+ 2'b01: dat_o <= #1 spsr;
+ 2'b10: dat_o <= #1 rfdout;
+ 2'b11: dat_o <= #1 sper;
+ endcase
+
+ // read fifo
+ assign rfre = wb_acc & (adr_i == 2'b10) & ack_o & ~we_i;
+
+ // ack_o
+ always @(posedge clk_i or negedge rst_i)
+ if (~rst_i)
+ ack_o <= #1 1'b0;
+ else
+ ack_o <= #1 wb_acc & !ack_o;
+
+ // decode Serial Peripheral Control Register
+ wire spie = spcr[7]; // Interrupt enable bit
+ wire spe = spcr[6]; // System Enable bit
+ wire dwom = spcr[5]; // Port D Wired-OR Mode Bit
+ wire mstr = spcr[4]; // Master Mode Select Bit
+ wire cpol = spcr[3]; // Clock Polarity Bit
+ wire cpha = spcr[2]; // Clock Phase Bit
+ wire [1:0] spr = spcr[1:0]; // Clock Rate Select Bits
+
+ // decode Serial Peripheral Extension Register
+ wire [1:0] icnt = sper[7:6]; // interrupt on transfer count
+ wire [1:0] spre = sper[1:0]; // extended clock rate select
+
+ wire [3:0] espr = {spre, spr};
+
+ // generate status register
+ wire wr_spsr = wb_wr & (adr_i == 2'b01);
+
+ reg spif;
+ always @(posedge clk_i)
+ if (~spe)
+ spif <= #1 1'b0;
+ else
+ spif <= #1 (tirq | spif) & ~(wr_spsr & dat_i[7]);
+
+ reg wcol;
+ always @(posedge clk_i)
+ if (~spe)
+ wcol <= #1 1'b0;
+ else
+ wcol <= #1 (wfov | wcol) & ~(wr_spsr & dat_i[6]);
+
+ assign spsr[7] = spif;
+ assign spsr[6] = wcol;
+ assign spsr[5:4] = 2'b00;
+ assign spsr[3] = wffull;
+ assign spsr[2] = wfempty;
+ assign spsr[1] = rffull;
+ assign spsr[0] = rfempty;
+
+
+ // generate IRQ output (inta_o)
+ always @(posedge clk_i)
+ inta_o <= #1 spif & spie;
+
+ //
+ // hookup read/write buffer fifo
+ fifo4 #(8)
+ rfifo(
+ .clk ( clk_i ),
+ .rst ( rst_i ),
+ .clr ( ~spe ),
+ .din ( treg ),
+ .we ( rfwe ),
+ .dout ( rfdout ),
+ .re ( rfre ),
+ .full ( rffull ),
+ .empty ( rfempty )
+ ),
+ wfifo(
+ .clk ( clk_i ),
+ .rst ( rst_i ),
+ .clr ( ~spe ),
+ .din ( dat_i ),
+ .we ( wfwe ),
+ .dout ( wfdout ),
+ .re ( wfre ),
+ .full ( wffull ),
+ .empty ( wfempty )
+ );
+
+ //
+ // generate clk divider
+ reg [11:0] clkcnt;
+ always @(posedge clk_i)
+ if(spe & (|clkcnt & |state))
+ clkcnt <= #1 clkcnt - 11'h1;
+ else
+ case (espr) // synopsys full_case parallel_case
+ 4'b0000: clkcnt <= #1 12'h0; // 2 -- original M68HC11 coding
+ 4'b0001: clkcnt <= #1 12'h1; // 4 -- original M68HC11 coding
+ 4'b0010: clkcnt <= #1 12'h3; // 16 -- original M68HC11 coding
+ 4'b0011: clkcnt <= #1 12'hf; // 32 -- original M68HC11 coding
+ 4'b0100: clkcnt <= #1 12'h1f; // 8
+ 4'b0101: clkcnt <= #1 12'h7; // 64
+ 4'b0110: clkcnt <= #1 12'h3f; // 128
+ 4'b0111: clkcnt <= #1 12'h7f; // 256
+ 4'b1000: clkcnt <= #1 12'hff; // 512
+ 4'b1001: clkcnt <= #1 12'h1ff; // 1024
+ 4'b1010: clkcnt <= #1 12'h3ff; // 2048
+ 4'b1011: clkcnt <= #1 12'h7ff; // 4096
+ endcase
+
+ // generate clock enable signal
+ wire ena = ~|clkcnt;
+
+ // transfer statemachine
+ always @(posedge clk_i)
+ if (~spe)
+ begin
+ state <= #1 2'b00; // idle
+ bcnt <= #1 3'h0;
+ treg <= #1 8'h00;
+ wfre <= #1 1'b0;
+ rfwe <= #1 1'b0;
+ sck_o <= #1 1'b0;
+ end
+ else
+ begin
+ wfre <= #1 1'b0;
+ rfwe <= #1 1'b0;
+
+ case (state) //synopsys full_case parallel_case
+ 2'b00: // idle state
+ begin
+ bcnt <= #1 3'h7; // set transfer counter
+ treg <= #1 wfdout; // load transfer register
+ sck_o <= #1 cpol; // set sck
+
+ if (~wfempty) begin
+ wfre <= #1 1'b1;
+ state <= #1 2'b01;
+ if (cpha) sck_o <= #1 ~sck_o;
+ end
+ end
+
+ 2'b01: // clock-phase2, next data
+ if (ena) begin
+ sck_o <= #1 ~sck_o;
+ state <= #1 2'b11;
+ end
+
+ 2'b11: // clock phase1
+ if (ena) begin
+ treg <= #1 {treg[6:0], miso_i};
+ bcnt <= #1 bcnt -3'h1;
+
+ if (~|bcnt) begin
+ state <= #1 2'b00;
+ sck_o <= #1 cpol;
+ rfwe <= #1 1'b1;
+ end else begin
+ state <= #1 2'b01;
+ sck_o <= #1 ~sck_o;
+ end
+ end
+
+ 2'b10: state <= #1 2'b00;
+ endcase
+ end
+
+ assign mosi_o = treg[7];
+
+
+ // count number of transfers (for interrupt generation)
+ reg [1:0] tcnt; // transfer count
+ always @(posedge clk_i)
+ if (~spe)
+ tcnt <= #1 icnt;
+ else if (rfwe) // rfwe gets asserted when all bits have been transfered
+ if (|tcnt)
+ tcnt <= #1 tcnt - 2'h1;
+ else
+ tcnt <= #1 icnt;
+
+ assign tirq = ~|tcnt & rfwe;
+
+endmodule
+
diff --git a/tests/iwls2005/spi/spi_clgen.v b/tests/iwls2005/spi/spi_clgen.v
new file mode 100644
index 000000000..7bc4f6e5e
--- /dev/null
+++ b/tests/iwls2005/spi/spi_clgen.v
@@ -0,0 +1,108 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// spi_clgen.v ////
+//// ////
+//// This file is part of the SPI IP core project ////
+//// http://www.opencores.org/projects/spi/ ////
+//// ////
+//// Author(s): ////
+//// - Simon Srot (simons@opencores.org) ////
+//// ////
+//// All additional information is avaliable in the Readme.txt ////
+//// file. ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2002 Authors ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`include "spi_defines.v"
+`include "timescale.v"
+
+module spi_clgen (clk_in, rst, go, enable, last_clk, divider, clk_out, pos_edge, neg_edge);
+
+ parameter Tp = 1;
+
+ input clk_in; // input clock (system clock)
+ input rst; // reset
+ input enable; // clock enable
+ input go; // start transfer
+ input last_clk; // last clock
+ input [`SPI_DIVIDER_LEN-1:0] divider; // clock divider (output clock is divided by this value)
+ output clk_out; // output clock
+ output pos_edge; // pulse marking positive edge of clk_out
+ output neg_edge; // pulse marking negative edge of clk_out
+
+ reg clk_out;
+ reg pos_edge;
+ reg neg_edge;
+
+ reg [`SPI_DIVIDER_LEN-1:0] cnt; // clock counter
+ wire cnt_zero; // conter is equal to zero
+ wire cnt_one; // conter is equal to one
+
+
+ assign cnt_zero = cnt == {`SPI_DIVIDER_LEN{1'b0}};
+ assign cnt_one = cnt == {{`SPI_DIVIDER_LEN-1{1'b0}}, 1'b1};
+
+ // Counter counts half period
+ always @(posedge clk_in or posedge rst)
+ begin
+ if(rst)
+ cnt <= #Tp {`SPI_DIVIDER_LEN{1'b1}};
+ else
+ begin
+ if(!enable || cnt_zero)
+ cnt <= #Tp divider;
+ else
+ cnt <= #Tp cnt - {{`SPI_DIVIDER_LEN-1{1'b0}}, 1'b1};
+ end
+ end
+
+ // clk_out is asserted every other half period
+ always @(posedge clk_in or posedge rst)
+ begin
+ if(rst)
+ clk_out <= #Tp 1'b0;
+ else
+ clk_out <= #Tp (enable && cnt_zero && (!last_clk || clk_out)) ? ~clk_out : clk_out;
+ end
+
+ // Pos and neg edge signals
+ always @(posedge clk_in or posedge rst)
+ begin
+ if(rst)
+ begin
+ pos_edge <= #Tp 1'b0;
+ neg_edge <= #Tp 1'b0;
+ end
+ else
+ begin
+ pos_edge <= #Tp (enable && !clk_out && cnt_one) || (!(|divider) && clk_out) || (!(|divider) && go && !enable);
+ neg_edge <= #Tp (enable && clk_out && cnt_one) || (!(|divider) && !clk_out && enable);
+ end
+ end
+endmodule
+
diff --git a/tests/iwls2005/spi/spi_defines.v b/tests/iwls2005/spi/spi_defines.v
new file mode 100644
index 000000000..a6925918e
--- /dev/null
+++ b/tests/iwls2005/spi/spi_defines.v
@@ -0,0 +1,159 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// spi_define.v ////
+//// ////
+//// This file is part of the SPI IP core project ////
+//// http://www.opencores.org/projects/spi/ ////
+//// ////
+//// Author(s): ////
+//// - Simon Srot (simons@opencores.org) ////
+//// ////
+//// All additional information is avaliable in the Readme.txt ////
+//// file. ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2002 Authors ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+//
+// Number of bits used for devider register. If used in system with
+// low frequency of system clock this can be reduced.
+// Use SPI_DIVIDER_LEN for fine tuning theexact number.
+//
+//`define SPI_DIVIDER_LEN_8
+`define SPI_DIVIDER_LEN_16
+//`define SPI_DIVIDER_LEN_24
+//`define SPI_DIVIDER_LEN_32
+
+`ifdef SPI_DIVIDER_LEN_8
+ `define SPI_DIVIDER_LEN 8 // Can be set from 1 to 8
+`endif
+`ifdef SPI_DIVIDER_LEN_16
+ `define SPI_DIVIDER_LEN 16 // Can be set from 9 to 16
+`endif
+`ifdef SPI_DIVIDER_LEN_24
+ `define SPI_DIVIDER_LEN 24 // Can be set from 17 to 24
+`endif
+`ifdef SPI_DIVIDER_LEN_32
+ `define SPI_DIVIDER_LEN 32 // Can be set from 25 to 32
+`endif
+
+//
+// Maximum nuber of bits that can be send/received at once.
+// Use SPI_MAX_CHAR for fine tuning the exact number, when using
+// SPI_MAX_CHAR_32, SPI_MAX_CHAR_24, SPI_MAX_CHAR_16, SPI_MAX_CHAR_8.
+//
+`define SPI_MAX_CHAR_128
+//`define SPI_MAX_CHAR_64
+//`define SPI_MAX_CHAR_32
+//`define SPI_MAX_CHAR_24
+//`define SPI_MAX_CHAR_16
+//`define SPI_MAX_CHAR_8
+
+`ifdef SPI_MAX_CHAR_128
+ `define SPI_MAX_CHAR 128 // Can only be set to 128
+ `define SPI_CHAR_LEN_BITS 7
+`endif
+`ifdef SPI_MAX_CHAR_64
+ `define SPI_MAX_CHAR 64 // Can only be set to 64
+ `define SPI_CHAR_LEN_BITS 6
+`endif
+`ifdef SPI_MAX_CHAR_32
+ `define SPI_MAX_CHAR 32 // Can be set from 25 to 32
+ `define SPI_CHAR_LEN_BITS 5
+`endif
+`ifdef SPI_MAX_CHAR_24
+ `define SPI_MAX_CHAR 24 // Can be set from 17 to 24
+ `define SPI_CHAR_LEN_BITS 5
+`endif
+`ifdef SPI_MAX_CHAR_16
+ `define SPI_MAX_CHAR 16 // Can be set from 9 to 16
+ `define SPI_CHAR_LEN_BITS 4
+`endif
+`ifdef SPI_MAX_CHAR_8
+ `define SPI_MAX_CHAR 8 // Can be set from 1 to 8
+ `define SPI_CHAR_LEN_BITS 3
+`endif
+
+//
+// Number of device select signals. Use SPI_SS_NB for fine tuning the
+// exact number.
+//
+`define SPI_SS_NB_8
+//`define SPI_SS_NB_16
+//`define SPI_SS_NB_24
+//`define SPI_SS_NB_32
+
+`ifdef SPI_SS_NB_8
+ `define SPI_SS_NB 8 // Can be set from 1 to 8
+`endif
+`ifdef SPI_SS_NB_16
+ `define SPI_SS_NB 16 // Can be set from 9 to 16
+`endif
+`ifdef SPI_SS_NB_24
+ `define SPI_SS_NB 24 // Can be set from 17 to 24
+`endif
+`ifdef SPI_SS_NB_32
+ `define SPI_SS_NB 32 // Can be set from 25 to 32
+`endif
+
+//
+// Bits of WISHBONE address used for partial decoding of SPI registers.
+//
+`define SPI_OFS_BITS 4:2
+
+//
+// Register offset
+//
+`define SPI_RX_0 0
+`define SPI_RX_1 1
+`define SPI_RX_2 2
+`define SPI_RX_3 3
+`define SPI_TX_0 0
+`define SPI_TX_1 1
+`define SPI_TX_2 2
+`define SPI_TX_3 3
+`define SPI_CTRL 4
+`define SPI_DEVIDE 5
+`define SPI_SS 6
+
+//
+// Number of bits in ctrl register
+//
+`define SPI_CTRL_BIT_NB 14
+
+//
+// Control register bit position
+//
+`define SPI_CTRL_ASS 13
+`define SPI_CTRL_IE 12
+`define SPI_CTRL_LSB 11
+`define SPI_CTRL_TX_NEGEDGE 10
+`define SPI_CTRL_RX_NEGEDGE 9
+`define SPI_CTRL_GO 8
+`define SPI_CTRL_RES_1 7
+`define SPI_CTRL_CHAR_LEN 6:0
+
diff --git a/tests/iwls2005/spi/spi_shift.v b/tests/iwls2005/spi/spi_shift.v
new file mode 100644
index 000000000..b17ac8b1f
--- /dev/null
+++ b/tests/iwls2005/spi/spi_shift.v
@@ -0,0 +1,238 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// spi_shift.v ////
+//// ////
+//// This file is part of the SPI IP core project ////
+//// http://www.opencores.org/projects/spi/ ////
+//// ////
+//// Author(s): ////
+//// - Simon Srot (simons@opencores.org) ////
+//// ////
+//// All additional information is avaliable in the Readme.txt ////
+//// file. ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2002 Authors ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`include "spi_defines.v"
+`include "timescale.v"
+
+module spi_shift (clk, rst, latch, byte_sel, len, lsb, go,
+ pos_edge, neg_edge, rx_negedge, tx_negedge,
+ tip, last,
+ p_in, p_out, s_clk, s_in, s_out);
+
+ parameter Tp = 1;
+
+ input clk; // system clock
+ input rst; // reset
+ input [3:0] latch; // latch signal for storing the data in shift register
+ input [3:0] byte_sel; // byte select signals for storing the data in shift register
+ input [`SPI_CHAR_LEN_BITS-1:0] len; // data len in bits (minus one)
+ input lsb; // lbs first on the line
+ input go; // start stansfer
+ input pos_edge; // recognize posedge of sclk
+ input neg_edge; // recognize negedge of sclk
+ input rx_negedge; // s_in is sampled on negative edge
+ input tx_negedge; // s_out is driven on negative edge
+ output tip; // transfer in progress
+ output last; // last bit
+ input [31:0] p_in; // parallel in
+ output [`SPI_MAX_CHAR-1:0] p_out; // parallel out
+ input s_clk; // serial clock
+ input s_in; // serial in
+ output s_out; // serial out
+
+ reg s_out;
+ reg tip;
+
+ reg [`SPI_CHAR_LEN_BITS:0] cnt; // data bit count
+ reg [`SPI_MAX_CHAR-1:0] data; // shift register
+ wire [`SPI_CHAR_LEN_BITS:0] tx_bit_pos; // next bit position
+ wire [`SPI_CHAR_LEN_BITS:0] rx_bit_pos; // next bit position
+ wire rx_clk; // rx clock enable
+ wire tx_clk; // tx clock enable
+
+ assign p_out = data;
+
+ assign tx_bit_pos = lsb ? {!(|len), len} - cnt : cnt - {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1};
+ assign rx_bit_pos = lsb ? {!(|len), len} - (rx_negedge ? cnt + {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1} : cnt) :
+ (rx_negedge ? cnt : cnt - {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1});
+
+ assign last = !(|cnt);
+
+ assign rx_clk = (rx_negedge ? neg_edge : pos_edge) && (!last || s_clk);
+ assign tx_clk = (tx_negedge ? neg_edge : pos_edge) && !last;
+
+ // Character bit counter
+ always @(posedge clk or posedge rst)
+ begin
+ if(rst)
+ cnt <= #Tp {`SPI_CHAR_LEN_BITS+1{1'b0}};
+ else
+ begin
+ if(tip)
+ cnt <= #Tp pos_edge ? (cnt - {{`SPI_CHAR_LEN_BITS{1'b0}}, 1'b1}) : cnt;
+ else
+ cnt <= #Tp !(|len) ? {1'b1, {`SPI_CHAR_LEN_BITS{1'b0}}} : {1'b0, len};
+ end
+ end
+
+ // Transfer in progress
+ always @(posedge clk or posedge rst)
+ begin
+ if(rst)
+ tip <= #Tp 1'b0;
+ else if(go && ~tip)
+ tip <= #Tp 1'b1;
+ else if(tip && last && pos_edge)
+ tip <= #Tp 1'b0;
+ end
+
+ // Sending bits to the line
+ always @(posedge clk or posedge rst)
+ begin
+ if (rst)
+ s_out <= #Tp 1'b0;
+ else
+ s_out <= #Tp (tx_clk || !tip) ? data[tx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]] : s_out;
+ end
+
+ // Receiving bits from the line
+ always @(posedge clk or posedge rst)
+ begin
+ if (rst)
+ data <= #Tp {`SPI_MAX_CHAR{1'b0}};
+`ifdef SPI_MAX_CHAR_128
+ else if (latch[0] && !tip)
+ begin
+ if (byte_sel[3])
+ data[31:24] <= #Tp p_in[31:24];
+ if (byte_sel[2])
+ data[23:16] <= #Tp p_in[23:16];
+ if (byte_sel[1])
+ data[15:8] <= #Tp p_in[15:8];
+ if (byte_sel[0])
+ data[7:0] <= #Tp p_in[7:0];
+ end
+ else if (latch[1] && !tip)
+ begin
+ if (byte_sel[3])
+ data[63:56] <= #Tp p_in[31:24];
+ if (byte_sel[2])
+ data[55:48] <= #Tp p_in[23:16];
+ if (byte_sel[1])
+ data[47:40] <= #Tp p_in[15:8];
+ if (byte_sel[0])
+ data[39:32] <= #Tp p_in[7:0];
+ end
+ else if (latch[2] && !tip)
+ begin
+ if (byte_sel[3])
+ data[95:88] <= #Tp p_in[31:24];
+ if (byte_sel[2])
+ data[87:80] <= #Tp p_in[23:16];
+ if (byte_sel[1])
+ data[79:72] <= #Tp p_in[15:8];
+ if (byte_sel[0])
+ data[71:64] <= #Tp p_in[7:0];
+ end
+ else if (latch[3] && !tip)
+ begin
+ if (byte_sel[3])
+ data[127:120] <= #Tp p_in[31:24];
+ if (byte_sel[2])
+ data[119:112] <= #Tp p_in[23:16];
+ if (byte_sel[1])
+ data[111:104] <= #Tp p_in[15:8];
+ if (byte_sel[0])
+ data[103:96] <= #Tp p_in[7:0];
+ end
+`else
+`ifdef SPI_MAX_CHAR_64
+ else if (latch[0] && !tip)
+ begin
+ if (byte_sel[3])
+ data[31:24] <= #Tp p_in[31:24];
+ if (byte_sel[2])
+ data[23:16] <= #Tp p_in[23:16];
+ if (byte_sel[1])
+ data[15:8] <= #Tp p_in[15:8];
+ if (byte_sel[0])
+ data[7:0] <= #Tp p_in[7:0];
+ end
+ else if (latch[1] && !tip)
+ begin
+ if (byte_sel[3])
+ data[63:56] <= #Tp p_in[31:24];
+ if (byte_sel[2])
+ data[55:48] <= #Tp p_in[23:16];
+ if (byte_sel[1])
+ data[47:40] <= #Tp p_in[15:8];
+ if (byte_sel[0])
+ data[39:32] <= #Tp p_in[7:0];
+ end
+`else
+ else if (latch[0] && !tip)
+ begin
+ `ifdef SPI_MAX_CHAR_8
+ if (byte_sel[0])
+ data[`SPI_MAX_CHAR-1:0] <= #Tp p_in[`SPI_MAX_CHAR-1:0];
+ `endif
+ `ifdef SPI_MAX_CHAR_16
+ if (byte_sel[0])
+ data[7:0] <= #Tp p_in[7:0];
+ if (byte_sel[1])
+ data[`SPI_MAX_CHAR-1:8] <= #Tp p_in[`SPI_MAX_CHAR-1:8];
+ `endif
+ `ifdef SPI_MAX_CHAR_24
+ if (byte_sel[0])
+ data[7:0] <= #Tp p_in[7:0];
+ if (byte_sel[1])
+ data[15:8] <= #Tp p_in[15:8];
+ if (byte_sel[2])
+ data[`SPI_MAX_CHAR-1:16] <= #Tp p_in[`SPI_MAX_CHAR-1:16];
+ `endif
+ `ifdef SPI_MAX_CHAR_32
+ if (byte_sel[0])
+ data[7:0] <= #Tp p_in[7:0];
+ if (byte_sel[1])
+ data[15:8] <= #Tp p_in[15:8];
+ if (byte_sel[2])
+ data[23:16] <= #Tp p_in[23:16];
+ if (byte_sel[3])
+ data[`SPI_MAX_CHAR-1:24] <= #Tp p_in[`SPI_MAX_CHAR-1:24];
+ `endif
+ end
+`endif
+`endif
+ else
+ data[rx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]] <= #Tp rx_clk ? s_in : data[rx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]];
+ end
+
+endmodule
+
diff --git a/tests/iwls2005/spi/spi_top.v b/tests/iwls2005/spi/spi_top.v
new file mode 100644
index 000000000..09b2e50e1
--- /dev/null
+++ b/tests/iwls2005/spi/spi_top.v
@@ -0,0 +1,287 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// spi_top.v ////
+//// ////
+//// This file is part of the SPI IP core project ////
+//// http://www.opencores.org/projects/spi/ ////
+//// ////
+//// Author(s): ////
+//// - Simon Srot (simons@opencores.org) ////
+//// ////
+//// All additional information is avaliable in the Readme.txt ////
+//// file. ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2002 Authors ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+`include "spi_defines.v"
+`include "timescale.v"
+
+module spi_top
+(
+ // Wishbone signals
+ wb_clk_i, wb_rst_i, wb_adr_i, wb_dat_i, wb_dat_o, wb_sel_i,
+ wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_err_o, wb_int_o,
+
+ // SPI signals
+ ss_pad_o, sclk_pad_o, mosi_pad_o, miso_pad_i
+);
+
+ parameter Tp = 1;
+
+ // Wishbone signals
+ input wb_clk_i; // master clock input
+ input wb_rst_i; // synchronous active high reset
+ input [4:0] wb_adr_i; // lower address bits
+ input [32-1:0] wb_dat_i; // databus input
+ output [32-1:0] wb_dat_o; // databus output
+ input [3:0] wb_sel_i; // byte select inputs
+ input wb_we_i; // write enable input
+ input wb_stb_i; // stobe/core select signal
+ input wb_cyc_i; // valid bus cycle input
+ output wb_ack_o; // bus cycle acknowledge output
+ output wb_err_o; // termination w/ error
+ output wb_int_o; // interrupt request signal output
+
+ // SPI signals
+ output [`SPI_SS_NB-1:0] ss_pad_o; // slave select
+ output sclk_pad_o; // serial clock
+ output mosi_pad_o; // master out slave in
+ input miso_pad_i; // master in slave out
+
+ reg [32-1:0] wb_dat_o;
+ reg wb_ack_o;
+ reg wb_int_o;
+
+ // Internal signals
+ reg [`SPI_DIVIDER_LEN-1:0] divider; // Divider register
+ reg [`SPI_CTRL_BIT_NB-1:0] ctrl; // Control and status register
+ reg [`SPI_SS_NB-1:0] ss; // Slave select register
+ reg [32-1:0] wb_dat; // wb data out
+ wire [`SPI_MAX_CHAR-1:0] rx; // Rx register
+ wire rx_negedge; // miso is sampled on negative edge
+ wire tx_negedge; // mosi is driven on negative edge
+ wire [`SPI_CHAR_LEN_BITS-1:0] char_len; // char len
+ wire go; // go
+ wire lsb; // lsb first on line
+ wire ie; // interrupt enable
+ wire ass; // automatic slave select
+ wire spi_divider_sel; // divider register select
+ wire spi_ctrl_sel; // ctrl register select
+ wire [3:0] spi_tx_sel; // tx_l register select
+ wire spi_ss_sel; // ss register select
+ wire tip; // transfer in progress
+ wire pos_edge; // recognize posedge of sclk
+ wire neg_edge; // recognize negedge of sclk
+ wire last_bit; // marks last character bit
+
+ // Address decoder
+ assign spi_divider_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_DEVIDE);
+ assign spi_ctrl_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_CTRL);
+ assign spi_tx_sel[0] = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_0);
+ assign spi_tx_sel[1] = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_1);
+ assign spi_tx_sel[2] = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_2);
+ assign spi_tx_sel[3] = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_3);
+ assign spi_ss_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_SS);
+
+ // Read from registers
+ always @(wb_adr_i or rx or ctrl or divider or ss)
+ begin
+ case (wb_adr_i[`SPI_OFS_BITS])
+`ifdef SPI_MAX_CHAR_128
+ `SPI_RX_0: wb_dat = rx[31:0];
+ `SPI_RX_1: wb_dat = rx[63:32];
+ `SPI_RX_2: wb_dat = rx[95:64];
+ `SPI_RX_3: wb_dat = {{128-`SPI_MAX_CHAR{1'b0}}, rx[`SPI_MAX_CHAR-1:96]};
+`else
+`ifdef SPI_MAX_CHAR_64
+ `SPI_RX_0: wb_dat = rx[31:0];
+ `SPI_RX_1: wb_dat = {{64-`SPI_MAX_CHAR{1'b0}}, rx[`SPI_MAX_CHAR-1:32]};
+ `SPI_RX_2: wb_dat = 32'b0;
+ `SPI_RX_3: wb_dat = 32'b0;
+`else
+ `SPI_RX_0: wb_dat = {{32-`SPI_MAX_CHAR{1'b0}}, rx[`SPI_MAX_CHAR-1:0]};
+ `SPI_RX_1: wb_dat = 32'b0;
+ `SPI_RX_2: wb_dat = 32'b0;
+ `SPI_RX_3: wb_dat = 32'b0;
+`endif
+`endif
+ `SPI_CTRL: wb_dat = {{32-`SPI_CTRL_BIT_NB{1'b0}}, ctrl};
+ `SPI_DEVIDE: wb_dat = {{32-`SPI_DIVIDER_LEN{1'b0}}, divider};
+ `SPI_SS: wb_dat = {{32-`SPI_SS_NB{1'b0}}, ss};
+ default: wb_dat = 32'bx;
+ endcase
+ end
+
+ // Wb data out
+ always @(posedge wb_clk_i or posedge wb_rst_i)
+ begin
+ if (wb_rst_i)
+ wb_dat_o <= #Tp 32'b0;
+ else
+ wb_dat_o <= #Tp wb_dat;
+ end
+
+ // Wb acknowledge
+ always @(posedge wb_clk_i or posedge wb_rst_i)
+ begin
+ if (wb_rst_i)
+ wb_ack_o <= #Tp 1'b0;
+ else
+ wb_ack_o <= #Tp wb_cyc_i & wb_stb_i & ~wb_ack_o;
+ end
+
+ // Wb error
+ assign wb_err_o = 1'b0;
+
+ // Interrupt
+ always @(posedge wb_clk_i or posedge wb_rst_i)
+ begin
+ if (wb_rst_i)
+ wb_int_o <= #Tp 1'b0;
+ else if (ie && tip && last_bit && pos_edge)
+ wb_int_o <= #Tp 1'b1;
+ else if (wb_ack_o)
+ wb_int_o <= #Tp 1'b0;
+ end
+
+ // Divider register
+ always @(posedge wb_clk_i or posedge wb_rst_i)
+ begin
+ if (wb_rst_i)
+ divider <= #Tp {`SPI_DIVIDER_LEN{1'b0}};
+ else if (spi_divider_sel && wb_we_i && !tip)
+ begin
+ `ifdef SPI_DIVIDER_LEN_8
+ if (wb_sel_i[0])
+ divider <= #Tp wb_dat_i[`SPI_DIVIDER_LEN-1:0];
+ `endif
+ `ifdef SPI_DIVIDER_LEN_16
+ if (wb_sel_i[0])
+ divider[7:0] <= #Tp wb_dat_i[7:0];
+ if (wb_sel_i[1])
+ divider[`SPI_DIVIDER_LEN-1:8] <= #Tp wb_dat_i[`SPI_DIVIDER_LEN-1:8];
+ `endif
+ `ifdef SPI_DIVIDER_LEN_24
+ if (wb_sel_i[0])
+ divider[7:0] <= #Tp wb_dat_i[7:0];
+ if (wb_sel_i[1])
+ divider[15:8] <= #Tp wb_dat_i[15:8];
+ if (wb_sel_i[2])
+ divider[`SPI_DIVIDER_LEN-1:16] <= #Tp wb_dat_i[`SPI_DIVIDER_LEN-1:16];
+ `endif
+ `ifdef SPI_DIVIDER_LEN_32
+ if (wb_sel_i[0])
+ divider[7:0] <= #Tp wb_dat_i[7:0];
+ if (wb_sel_i[1])
+ divider[15:8] <= #Tp wb_dat_i[15:8];
+ if (wb_sel_i[2])
+ divider[23:16] <= #Tp wb_dat_i[23:16];
+ if (wb_sel_i[3])
+ divider[`SPI_DIVIDER_LEN-1:24] <= #Tp wb_dat_i[`SPI_DIVIDER_LEN-1:24];
+ `endif
+ end
+ end
+
+ // Ctrl register
+ always @(posedge wb_clk_i or posedge wb_rst_i)
+ begin
+ if (wb_rst_i)
+ ctrl <= #Tp {`SPI_CTRL_BIT_NB{1'b0}};
+ else if(spi_ctrl_sel && wb_we_i && !tip)
+ begin
+ if (wb_sel_i[0])
+ ctrl[7:0] <= #Tp wb_dat_i[7:0] | {7'b0, ctrl[0]};
+ if (wb_sel_i[1])
+ ctrl[`SPI_CTRL_BIT_NB-1:8] <= #Tp wb_dat_i[`SPI_CTRL_BIT_NB-1:8];
+ end
+ else if(tip && last_bit && pos_edge)
+ ctrl[`SPI_CTRL_GO] <= #Tp 1'b0;
+ end
+
+ assign rx_negedge = ctrl[`SPI_CTRL_RX_NEGEDGE];
+ assign tx_negedge = ctrl[`SPI_CTRL_TX_NEGEDGE];
+ assign go = ctrl[`SPI_CTRL_GO];
+ assign char_len = ctrl[`SPI_CTRL_CHAR_LEN];
+ assign lsb = ctrl[`SPI_CTRL_LSB];
+ assign ie = ctrl[`SPI_CTRL_IE];
+ assign ass = ctrl[`SPI_CTRL_ASS];
+
+ // Slave select register
+ always @(posedge wb_clk_i or posedge wb_rst_i)
+ begin
+ if (wb_rst_i)
+ ss <= #Tp {`SPI_SS_NB{1'b0}};
+ else if(spi_ss_sel && wb_we_i && !tip)
+ begin
+ `ifdef SPI_SS_NB_8
+ if (wb_sel_i[0])
+ ss <= #Tp wb_dat_i[`SPI_SS_NB-1:0];
+ `endif
+ `ifdef SPI_SS_NB_16
+ if (wb_sel_i[0])
+ ss[7:0] <= #Tp wb_dat_i[7:0];
+ if (wb_sel_i[1])
+ ss[`SPI_SS_NB-1:8] <= #Tp wb_dat_i[`SPI_SS_NB-1:8];
+ `endif
+ `ifdef SPI_SS_NB_24
+ if (wb_sel_i[0])
+ ss[7:0] <= #Tp wb_dat_i[7:0];
+ if (wb_sel_i[1])
+ ss[15:8] <= #Tp wb_dat_i[15:8];
+ if (wb_sel_i[2])
+ ss[`SPI_SS_NB-1:16] <= #Tp wb_dat_i[`SPI_SS_NB-1:16];
+ `endif
+ `ifdef SPI_SS_NB_32
+ if (wb_sel_i[0])
+ ss[7:0] <= #Tp wb_dat_i[7:0];
+ if (wb_sel_i[1])
+ ss[15:8] <= #Tp wb_dat_i[15:8];
+ if (wb_sel_i[2])
+ ss[23:16] <= #Tp wb_dat_i[23:16];
+ if (wb_sel_i[3])
+ ss[`SPI_SS_NB-1:24] <= #Tp wb_dat_i[`SPI_SS_NB-1:24];
+ `endif
+ end
+ end
+
+ assign ss_pad_o = ~((ss & {`SPI_SS_NB{tip & ass}}) | (ss & {`SPI_SS_NB{!ass}}));
+
+ spi_clgen clgen (.clk_in(wb_clk_i), .rst(wb_rst_i), .go(go), .enable(tip), .last_clk(last_bit),
+ .divider(divider), .clk_out(sclk_pad_o), .pos_edge(pos_edge),
+ .neg_edge(neg_edge));
+
+ spi_shift shift (.clk(wb_clk_i), .rst(wb_rst_i), .len(char_len[`SPI_CHAR_LEN_BITS-1:0]),
+ .latch(spi_tx_sel[3:0] & {4{wb_we_i}}), .byte_sel(wb_sel_i), .lsb(lsb),
+ .go(go), .pos_edge(pos_edge), .neg_edge(neg_edge),
+ .rx_negedge(rx_negedge), .tx_negedge(tx_negedge),
+ .tip(tip), .last(last_bit),
+ .p_in(wb_dat_i), .p_out(rx),
+ .s_clk(sclk_pad_o), .s_in(miso_pad_i), .s_out(mosi_pad_o));
+endmodule
+
diff --git a/tests/iwls2005/spi/timescale.v b/tests/iwls2005/spi/timescale.v
new file mode 100644
index 000000000..60d4ecbd1
--- /dev/null
+++ b/tests/iwls2005/spi/timescale.v
@@ -0,0 +1,2 @@
+`timescale 1ns / 10ps
+
diff --git a/tests/iwls2005/ss_pcm/pcm_slv_top.v b/tests/iwls2005/ss_pcm/pcm_slv_top.v
new file mode 100644
index 000000000..2548d35fa
--- /dev/null
+++ b/tests/iwls2005/ss_pcm/pcm_slv_top.v
@@ -0,0 +1,222 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// PCM IO Slave Module ////
+//// ////
+//// ////
+//// Author: Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+//// ////
+//// Downloaded from: http://www.opencores.org/cores/ss_pcm/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000-2002 Rudolf Usselmann ////
+//// www.asics.ws ////
+//// rudi@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: pcm_slv_top.v,v 1.2 2002/09/17 15:32:50 rudi Exp $
+//
+// $Date: 2002/09/17 15:32:50 $
+// $Revision: 1.2 $
+// $Author: rudi $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: pcm_slv_top.v,v $
+// Revision 1.2 2002/09/17 15:32:50 rudi
+// *** empty log message ***
+//
+// Revision 1.1.1.1 2002/09/17 15:17:25 rudi
+// Initial Checkin
+//
+//
+//
+//
+//
+//
+//
+//
+
+`include "timescale.v"
+
+/*
+PCM Interface
+===============================
+PCM_CLK
+PCM_SYNC
+PCM_DIN
+PCM_DOUT
+*/
+
+module pcm_slv_top( clk, rst,
+
+ ssel,
+
+ // PCM
+ pcm_clk_i, pcm_sync_i, pcm_din_i, pcm_dout_o,
+
+ // Internal Interface
+ din_i, dout_o, re_i, we_i);
+
+input clk, rst;
+input [2:0] ssel; // Number of bits to delay (0-7)
+input pcm_clk_i, pcm_sync_i, pcm_din_i;
+output pcm_dout_o;
+input [7:0] din_i;
+output [7:0] dout_o;
+input re_i;
+input [1:0] we_i;
+
+///////////////////////////////////////////////////////////////////
+//
+// Local Wires and Registers
+//
+
+reg pclk_t, pclk_s, pclk_r;
+wire pclk_ris, pclk_fal;
+reg psync;
+reg pcm_sync_r1, pcm_sync_r2, pcm_sync_r3;
+reg tx_go;
+wire tx_data_le;
+reg [15:0] tx_hold_reg;
+reg [7:0] tx_hold_byte_h, tx_hold_byte_l;
+reg [3:0] tx_cnt;
+wire tx_done;
+reg [15:0] rx_hold_reg, rx_reg;
+wire rx_data_le;
+reg rxd_t, rxd;
+reg tx_go_r1, tx_go_r2;
+reg [7:0] psa;
+
+///////////////////////////////////////////////////////////////////
+//
+// Misc Logic
+//
+
+always @(posedge clk)
+ pclk_t <= #1 pcm_clk_i;
+
+always @(posedge clk)
+ pclk_s <= #1 pclk_t;
+
+always @(posedge clk)
+ pclk_r <= #1 pclk_s;
+
+assign pclk_ris = !pclk_r & pclk_s;
+assign pclk_fal = pclk_r & !pclk_s;
+
+///////////////////////////////////////////////////////////////////
+//
+// Retrieve Sync Signal
+//
+
+always @(posedge clk) // Latch it at falling edge
+ if(pclk_fal) pcm_sync_r1 <= #1 pcm_sync_i;
+
+always @(posedge clk) // resync to rising edge
+ if(pclk_ris) psa <= #1 {psa[6:0], pcm_sync_r1};
+
+always @(posedge clk) //delay bit N
+ pcm_sync_r2 <= #1 psa[ssel];
+
+always @(posedge clk) // edge detector
+ pcm_sync_r3 <= #1 pcm_sync_r2;
+
+always @(posedge clk)
+ psync <= #1 !pcm_sync_r3 & pcm_sync_r2;
+
+///////////////////////////////////////////////////////////////////
+//
+// Transmit Logic
+//
+
+assign tx_data_le = tx_go & pclk_ris;
+
+always @(posedge clk)
+ if(we_i[1]) tx_hold_byte_h <= #1 din_i;
+
+always @(posedge clk)
+ if(we_i[0]) tx_hold_byte_l <= #1 din_i;
+
+always @(posedge clk)
+ if(!rst) tx_go <= #1 1'b0;
+ else
+ if(psync) tx_go <= #1 1'b1;
+ else
+ if(tx_done) tx_go <= #1 1'b0;
+
+always @(posedge clk)
+ if(!rst) tx_hold_reg <= #1 16'h0;
+ else
+ if(psync) tx_hold_reg <= #1 {tx_hold_byte_h, tx_hold_byte_l};
+ else
+ if(tx_data_le) tx_hold_reg <= #1 {tx_hold_reg[14:0],1'b0};
+
+assign pcm_dout_o = tx_hold_reg[15];
+
+always @(posedge clk)
+ if(!rst) tx_cnt <= #1 4'h0;
+ else
+ if(tx_data_le) tx_cnt <= tx_cnt + 4'h1;
+
+assign tx_done = (tx_cnt == 4'hf) & tx_data_le;
+
+///////////////////////////////////////////////////////////////////
+//
+// Recieve Logic
+//
+
+always @(posedge clk)
+ if(pclk_ris) tx_go_r1 <= #1 tx_go;
+
+always @(posedge clk)
+ if(pclk_ris) tx_go_r2 <= #1 tx_go_r1;
+
+// Receive is in sync with transmit ...
+always @(posedge clk)
+ if(pclk_fal) rxd_t <= #1 pcm_din_i;
+
+always @(posedge clk)
+ rxd <= #1 rxd_t;
+
+assign rx_data_le = (tx_go_r1 | tx_go) & pclk_fal;
+
+always @(posedge clk)
+ if(!rst) rx_hold_reg <= #1 16'h0;
+ else
+ if(rx_data_le) rx_hold_reg <= #1 {rx_hold_reg[14:0], rxd};
+
+always @(posedge clk)
+ if(!rst) rx_reg <= #1 16'h0;
+ else
+ if(tx_go_r1 & !tx_go & pclk_ris) rx_reg <= #1 rx_hold_reg;
+
+assign dout_o = re_i ? rx_reg[15:8] : rx_reg[7:0];
+
+endmodule
+
diff --git a/tests/iwls2005/ss_pcm/timescale.v b/tests/iwls2005/ss_pcm/timescale.v
new file mode 100644
index 000000000..ff9e265a8
--- /dev/null
+++ b/tests/iwls2005/ss_pcm/timescale.v
@@ -0,0 +1 @@
+`timescale 1ns / 10ps
diff --git a/tests/iwls2005/systemcaes/aes.v b/tests/iwls2005/systemcaes/aes.v
new file mode 100644
index 000000000..e5021ed16
--- /dev/null
+++ b/tests/iwls2005/systemcaes/aes.v
@@ -0,0 +1,358 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// AES top file ////
+//// ////
+//// This file is part of the SystemC AES ////
+//// ////
+//// Description: ////
+//// AES top ////
+//// ////
+//// Generated automatically using SystemC to Verilog translator ////
+//// ////
+//// To Do: ////
+//// - done ////
+//// ////
+//// Author(s): ////
+//// - Javier Castillo, jcastilo@opencores.org ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: aes.v,v $
+// Revision 1.1.1.1 2004/07/05 09:46:23 jcastillo
+// First import
+//
+
+module aes(clk,reset,load_i,decrypt_i,data_i,key_i,ready_o,data_o);
+input clk;
+input reset;
+input load_i;
+input decrypt_i;
+input [127:0] data_i;
+input [127:0] key_i;
+output ready_o;
+output [127:0] data_o;
+
+reg ready_o;
+reg [127:0] data_o;
+
+reg next_ready_o;
+reg keysched_start_i;
+reg [3:0] keysched_round_i;
+reg [127:0] keysched_last_key_i;
+wire [127:0] keysched_new_key_o;
+
+wire keysched_ready_o;
+
+wire keysched_sbox_access_o;
+
+wire [7:0] keysched_sbox_data_o;
+
+wire keysched_sbox_decrypt_o;
+
+reg mixcol_start_i;
+reg [127:0] mixcol_data_i;
+wire mixcol_ready_o;
+
+wire [127:0] mixcol_data_o;
+
+reg subbytes_start_i;
+reg [127:0] subbytes_data_i;
+wire subbytes_ready_o;
+
+wire [127:0] subbytes_data_o;
+
+wire [7:0] subbytes_sbox_data_o;
+
+wire subbytes_sbox_decrypt_o;
+
+wire [7:0] sbox_data_o;
+
+reg [7:0] sbox_data_i;
+reg sbox_decrypt_i;
+reg state;
+reg next_state;
+reg [3:0] round;
+reg [3:0] next_round;
+reg [127:0] addroundkey_data_o;
+reg [127:0] next_addroundkey_data_reg;
+reg [127:0] addroundkey_data_reg;
+reg [127:0] addroundkey_data_i;
+reg addroundkey_ready_o;
+reg next_addroundkey_ready_o;
+reg addroundkey_start_i;
+reg next_addroundkey_start_i;
+reg [3:0] addroundkey_round;
+reg [3:0] next_addroundkey_round;
+reg first_round_reg;
+reg next_first_round_reg;
+
+sbox sbox1 (.clk(clk), .reset(reset), .data_i(sbox_data_i), .decrypt_i(sbox_decrypt_i), .data_o(sbox_data_o));
+subbytes sub1 (.clk(clk), .reset(reset), .start_i(subbytes_start_i), .decrypt_i(decrypt_i), .data_i(subbytes_data_i), .ready_o(subbytes_ready_o), .data_o(subbytes_data_o), .sbox_data_o(subbytes_sbox_data_o), .sbox_data_i(sbox_data_o), .sbox_decrypt_o(subbytes_sbox_decrypt_o));
+mixcolum mix1 (.clk(clk), .reset(reset), .decrypt_i(decrypt_i), .start_i(mixcol_start_i), .data_i(mixcol_data_i), .ready_o(mixcol_ready_o), .data_o(mixcol_data_o));
+keysched ks1 (.clk(clk), .reset(reset), .start_i(keysched_start_i), .round_i(keysched_round_i), .last_key_i(keysched_last_key_i), .new_key_o(keysched_new_key_o), .ready_o(keysched_ready_o), .sbox_access_o(keysched_sbox_access_o), .sbox_data_o(keysched_sbox_data_o), .sbox_data_i(sbox_data_o), .sbox_decrypt_o(keysched_sbox_decrypt_o));
+
+//registers:
+always @(posedge clk or negedge reset)
+
+begin
+
+ if(!reset)
+begin
+
+ state = (0);
+ ready_o = (0);
+ round = (0);
+ addroundkey_round = (0);
+ addroundkey_data_reg = (0);
+ addroundkey_ready_o = (0);
+ addroundkey_start_i = (0);
+ first_round_reg = (0);
+
+end
+else
+begin
+
+ state = (next_state);
+ ready_o = (next_ready_o);
+ round = (next_round);
+ addroundkey_round = (next_addroundkey_round);
+ addroundkey_data_reg = (next_addroundkey_data_reg);
+ addroundkey_ready_o = (next_addroundkey_ready_o);
+ first_round_reg = (next_first_round_reg);
+ addroundkey_start_i = (next_addroundkey_start_i);
+
+end
+
+
+end
+//control:
+always @( state or round or addroundkey_data_o or data_i or load_i or decrypt_i or addroundkey_ready_o or mixcol_ready_o or subbytes_ready_o or subbytes_data_o or mixcol_data_o or first_round_reg)
+
+begin
+
+
+ next_state = (state);
+ next_round = (round);
+ data_o = (addroundkey_data_o);
+ next_ready_o = (0);
+
+ //Tokeyschedulemodule
+
+ next_first_round_reg = (0);
+
+
+ subbytes_data_i = (0);
+ mixcol_data_i = (0);
+ addroundkey_data_i = (0);
+ next_addroundkey_start_i = (first_round_reg);
+ mixcol_start_i = ((addroundkey_ready_o&decrypt_i&round!=10)|(subbytes_ready_o&!decrypt_i));
+ subbytes_start_i = ((addroundkey_ready_o&!decrypt_i)|(mixcol_ready_o&decrypt_i)|(addroundkey_ready_o&decrypt_i&round==10));
+
+ if(decrypt_i&&round!=10)
+ begin
+ addroundkey_data_i = (subbytes_data_o);
+ subbytes_data_i = (mixcol_data_o);
+ mixcol_data_i = (addroundkey_data_o);
+ end
+ else if(!decrypt_i&&round!=0)
+ begin
+ addroundkey_data_i = (mixcol_data_o);
+ subbytes_data_i = (addroundkey_data_o);
+ mixcol_data_i = (subbytes_data_o);
+ end
+ else
+ begin
+ mixcol_data_i = (subbytes_data_o);
+ subbytes_data_i = (addroundkey_data_o);
+ addroundkey_data_i = (data_i);
+ end
+
+
+ case(state)
+
+ 0:
+ begin
+ if(load_i)
+ begin
+ next_state = (1);
+ if(decrypt_i)
+ next_round = (10);
+ else
+ next_round = (0);
+ next_first_round_reg = (1);
+ end
+ end
+
+ 1:
+ begin
+
+ //Counter
+ if(!decrypt_i&&mixcol_ready_o)
+ begin
+ next_addroundkey_start_i = (1);
+ addroundkey_data_i = (mixcol_data_o);
+ next_round = (round+1);
+ end
+ else if(decrypt_i&&subbytes_ready_o)
+ begin
+ next_addroundkey_start_i = (1);
+ addroundkey_data_i = (subbytes_data_o);
+ next_round = (round-1);
+ end
+
+ //Output
+ if((round==9&&!decrypt_i)||(round==0&&decrypt_i))
+ begin
+ next_addroundkey_start_i = (0);
+ mixcol_start_i = (0);
+ if(subbytes_ready_o)
+ begin
+ addroundkey_data_i = (subbytes_data_o);
+ next_addroundkey_start_i = (1);
+ next_round = (round+1);
+ end
+ end
+
+ if((round==10&&!decrypt_i)||(round==0&&decrypt_i))
+ begin
+ addroundkey_data_i = (subbytes_data_o);
+ subbytes_start_i = (0);
+ if(addroundkey_ready_o)
+ begin
+ next_ready_o = (1);
+ next_state = (0);
+ next_addroundkey_start_i = (0);
+ next_round = (0);
+ end
+
+ end
+
+
+ end
+
+ default:
+begin
+ next_state = (0);
+ end
+ endcase
+
+
+end
+//addroundkey:
+reg[127:0] data_var,round_data_var,round_key_var;
+always @( addroundkey_data_i or addroundkey_start_i or addroundkey_data_reg or addroundkey_round or keysched_new_key_o or keysched_ready_o or key_i or round)
+
+begin
+
+
+
+ round_data_var=addroundkey_data_reg;
+ next_addroundkey_data_reg = (addroundkey_data_reg);
+next_addroundkey_ready_o = (0);
+ next_addroundkey_round = (addroundkey_round);
+ addroundkey_data_o = (addroundkey_data_reg);
+
+ if(addroundkey_round==1||addroundkey_round==0)
+ keysched_last_key_i = (key_i);
+else
+ keysched_last_key_i = (keysched_new_key_o);
+
+ keysched_start_i = (0);
+
+ keysched_round_i = (addroundkey_round);
+
+ if(round==0&&addroundkey_start_i)
+begin
+
+ //Taketheinputandxorthemwithdataifround==0;
+ data_var=addroundkey_data_i;
+ round_key_var=key_i;
+ round_data_var=round_key_var^data_var;
+ next_addroundkey_data_reg = (round_data_var);
+next_addroundkey_ready_o = (1);
+
+end
+else if(addroundkey_start_i&&round!=0)
+begin
+
+ keysched_last_key_i = (key_i);
+ keysched_start_i = (1);
+ keysched_round_i = (1);
+ next_addroundkey_round = (1);
+
+end
+else if(addroundkey_round!=round&&keysched_ready_o)
+begin
+
+next_addroundkey_round = (addroundkey_round+1);
+ keysched_last_key_i = (keysched_new_key_o);
+ keysched_start_i = (1);
+ keysched_round_i = (addroundkey_round+1);
+
+end
+else if(addroundkey_round==round&&keysched_ready_o)
+begin
+
+ data_var=addroundkey_data_i;
+ round_key_var=keysched_new_key_o;
+ round_data_var=round_key_var^data_var;
+ next_addroundkey_data_reg = (round_data_var);
+next_addroundkey_ready_o = (1);
+ next_addroundkey_round = (0);
+
+end
+
+
+end
+//sbox_muxes:
+always @( keysched_sbox_access_o or keysched_sbox_decrypt_o or keysched_sbox_data_o or subbytes_sbox_decrypt_o or subbytes_sbox_data_o)
+
+begin
+
+
+ if(keysched_sbox_access_o)
+begin
+
+ sbox_decrypt_i = (keysched_sbox_decrypt_o);
+ sbox_data_i = (keysched_sbox_data_o);
+
+end
+else
+begin
+
+ sbox_decrypt_i = (subbytes_sbox_decrypt_o);
+sbox_data_i = (subbytes_sbox_data_o);
+
+end
+
+
+end
+
+endmodule
diff --git a/tests/iwls2005/systemcaes/byte_mixcolum.v b/tests/iwls2005/systemcaes/byte_mixcolum.v
new file mode 100644
index 000000000..b248cc400
--- /dev/null
+++ b/tests/iwls2005/systemcaes/byte_mixcolum.v
@@ -0,0 +1,92 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Mixcolumns for 8 bit ////
+//// ////
+//// This file is part of the SystemC AES ////
+//// ////
+//// Description: ////
+//// Mixcolum for a byte ////
+//// ////
+//// Generated automatically using SystemC to Verilog translator ////
+//// ////
+//// To Do: ////
+//// - done ////
+//// ////
+//// Author(s): ////
+//// - Javier Castillo, jcastilo@opencores.org ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: byte_mixcolum.v,v $
+// Revision 1.1.1.1 2004/07/05 09:46:23 jcastillo
+// First import
+//
+
+module byte_mixcolum(a,b,c,d,outx,outy);
+
+input [7:0] a,b,c,d;
+output [7:0] outx, outy;
+
+reg [7:0] outx, outy;
+
+function [7:0] xtime;
+input [7:0] in;
+reg [3:0] xtime_t;
+
+begin
+xtime[7:5] = in[6:4];
+xtime_t[3] = in[7];
+xtime_t[2] = in[7];
+xtime_t[1] = 0;
+xtime_t[0] = in[7];
+xtime[4:1] =xtime_t^in[3:0];
+xtime[0] = in[7];
+end
+endfunction
+
+reg [7:0] w1,w2,w3,w4,w5,w6,w7,w8,outx_var;
+always @ (a, b, c, d)
+begin
+w1 = a ^b;
+w2 = a ^c;
+w3 = c ^d;
+w4 = xtime(w1);
+w5 = xtime(w3);
+w6 = w2 ^w4 ^w5;
+w7 = xtime(w6);
+w8 = xtime(w7);
+
+outx_var = b^w3^w4;
+outx=outx_var;
+outy=w8^outx_var;
+
+end
+
+endmodule
diff --git a/tests/iwls2005/systemcaes/keysched.v b/tests/iwls2005/systemcaes/keysched.v
new file mode 100644
index 000000000..f242c5675
--- /dev/null
+++ b/tests/iwls2005/systemcaes/keysched.v
@@ -0,0 +1,248 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Key schedule ////
+//// ////
+//// This file is part of the SystemC AES ////
+//// ////
+//// Description: ////
+//// Generate the next round key from the previous one ////
+//// ////
+//// Generated automatically using SystemC to Verilog translator ////
+//// ////
+//// To Do: ////
+//// - done ////
+//// ////
+//// Author(s): ////
+//// - Javier Castillo, jcastilo@opencores.org ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: keysched.v,v $
+// Revision 1.1.1.1 2004/07/05 09:46:23 jcastillo
+// First import
+//
+
+module keysched(clk,reset,start_i,round_i,last_key_i,new_key_o,ready_o,sbox_access_o,sbox_data_o,sbox_data_i,sbox_decrypt_o);
+input clk;
+input reset;
+input start_i;
+input [3:0] round_i;
+input [127:0] last_key_i;
+output [127:0] new_key_o;
+output ready_o;
+output sbox_access_o;
+output [7:0] sbox_data_o;
+input [7:0] sbox_data_i;
+output sbox_decrypt_o;
+
+reg [127:0] new_key_o;
+reg ready_o;
+reg sbox_access_o;
+reg [7:0] sbox_data_o;
+reg sbox_decrypt_o;
+
+reg [2:0] next_state;
+reg [2:0] state;
+reg [7:0] rcon_o;
+reg [31:0] next_col;
+reg [31:0] col;
+reg [127:0] key_reg;
+reg [127:0] next_key_reg;
+reg next_ready_o;
+
+
+//rcon:
+always @( round_i)
+
+begin
+
+
+ case(round_i)
+ 1:
+begin
+rcon_o = (1);
+end
+ 2:
+begin
+rcon_o = (2);
+end
+ 3:
+begin
+rcon_o = (4);
+end
+ 4:
+begin
+rcon_o = (8);
+end
+ 5:
+begin
+rcon_o = ('h10);
+end
+ 6:
+begin
+rcon_o = ('h20);
+end
+ 7:
+begin
+rcon_o = ('h40);
+end
+ 8:
+begin
+rcon_o = ('h80);
+end
+ 9:
+begin
+rcon_o = ('h1B);
+end
+ 10:
+begin
+rcon_o = ('h36);
+end
+default:
+begin
+ rcon_o = (0);
+end
+ endcase
+
+
+end
+//registers:
+always @(posedge clk or negedge reset)
+
+begin
+
+ if(!reset)
+ begin
+ state = (0);
+ col = (0);
+ key_reg = (0);
+ ready_o = (0);
+ end
+else
+ begin
+ state = (next_state);
+ col = (next_col);
+ key_reg = (next_key_reg);
+ ready_o = (next_ready_o);
+ end
+
+
+end
+//generate_key:
+reg[127:0] K_var,W_var;
+ reg[31:0] col_t;
+ reg[23:0] zero;
+
+always @( start_i or last_key_i or sbox_data_i or state or rcon_o or col or key_reg)
+
+begin
+
+
+ zero=0;
+
+ col_t=col;
+ W_var=0;
+
+ next_state = (state);
+ next_col = (col);
+
+ next_ready_o = (0);
+ next_key_reg = (key_reg);
+ new_key_o = (key_reg);
+
+sbox_decrypt_o = (0);
+ sbox_access_o = (0);
+ sbox_data_o = (0);
+ K_var=last_key_i;
+
+ case(state)
+ //Substitutethebyteswhilerotatingthem
+ //FouraccessestoSBoxareneeded
+ 0:
+begin
+ if(start_i)
+begin
+
+ col_t=0;
+ sbox_access_o = (1);
+ sbox_data_o = (K_var[31:24]);
+ next_state = (1);
+
+end
+
+ end
+ 1:
+begin
+ sbox_access_o = (1);
+ sbox_data_o = (K_var[23:16]);
+ col_t[7:0]=sbox_data_i;
+ next_col = (col_t);
+ next_state = (2);
+ end
+ 2:
+begin
+ sbox_access_o = (1);
+ sbox_data_o = (K_var[15:8]);
+ col_t[31:24]=sbox_data_i;
+ next_col = (col_t);
+ next_state = (3);
+ end
+ 3:
+begin
+ sbox_access_o = (1);
+ sbox_data_o = (K_var[7:0]);
+ col_t[23:16]=sbox_data_i;
+ next_col = (col_t);
+ next_state = (4);
+ end
+ 4:
+begin
+ sbox_access_o = (1);
+ col_t[15:8]=sbox_data_i;
+ next_col = (col_t);
+ W_var[127:96]=col_t^K_var[127:96]^{rcon_o,zero};
+ W_var[95:64]=W_var[127:96]^K_var[95:64];
+ W_var[63:32]=W_var[95:64]^K_var[63:32];
+ W_var[31:0]=W_var[63:32]^K_var[31:0];
+next_ready_o = (1);
+next_key_reg = (W_var);
+ next_state = (0);
+ end
+
+default:
+begin
+ next_state = (0);
+ end
+endcase
+
+
+end
+
+endmodule
diff --git a/tests/iwls2005/systemcaes/mixcolum.v b/tests/iwls2005/systemcaes/mixcolum.v
new file mode 100644
index 000000000..ab6dc1e67
--- /dev/null
+++ b/tests/iwls2005/systemcaes/mixcolum.v
@@ -0,0 +1,188 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Mixcolumns module implementation ////
+//// ////
+//// This file is part of the SystemC AES ////
+//// ////
+//// Description: ////
+//// Mixcolum module ////
+//// ////
+//// Generated automatically using SystemC to Verilog translator ////
+//// ////
+//// To Do: ////
+//// - done ////
+//// ////
+//// Author(s): ////
+//// - Javier Castillo, jcastilo@opencores.org ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: mixcolum.v,v $
+// Revision 1.1.1.1 2004/07/05 09:46:23 jcastillo
+// First import
+//
+
+
+module mixcolum(clk,reset,decrypt_i,start_i,data_i,ready_o,data_o);
+input clk;
+input reset;
+input decrypt_i;
+input start_i;
+input [127:0] data_i;
+output ready_o;
+output [127:0] data_o;
+
+reg ready_o;
+reg [127:0] data_o;
+
+reg [127:0] data_reg;
+reg [127:0] next_data_reg;
+reg [127:0] data_o_reg;
+reg [127:0] next_data_o;
+reg next_ready_o;
+reg [1:0] state;
+reg [1:0] next_state;
+wire [31:0] outx;
+
+wire [31:0] outy;
+
+reg [31:0] mix_word;
+reg [31:0] outmux;
+
+word_mixcolum w1 (.in(mix_word), .outx(outx), .outy(outy));
+
+//assign_data_o:
+always @( data_o_reg)
+
+begin
+
+ data_o = (data_o_reg);
+
+end
+//mux:
+always @( outx or outy or decrypt_i)
+
+begin
+
+ outmux = (decrypt_i?outy:outx);
+
+end
+//registers:
+always @(posedge clk or negedge reset)
+
+begin
+
+if(!reset)
+ begin
+ data_reg = (0);
+ state = (0);
+ ready_o = (0);
+ data_o_reg = (0);
+ end
+else
+ begin
+ data_reg = (next_data_reg);
+ state = (next_state);
+ ready_o = (next_ready_o);
+ data_o_reg = (next_data_o);
+ end
+
+
+end
+//mixcol:
+reg[127:0] data_i_var;
+ reg[31:0] aux;
+ reg[127:0] data_reg_var;
+
+always @( decrypt_i or start_i or state or data_reg or outmux or data_o_reg or data_i)
+
+begin
+
+
+ data_i_var=data_i;
+ data_reg_var=data_reg;
+ next_data_reg = (data_reg);
+ next_state = (state);
+
+ mix_word = (0);
+
+ next_ready_o = (0);
+ next_data_o = (data_o_reg);
+
+ case(state)
+
+ 0:
+begin
+ if(start_i)
+begin
+
+ aux=data_i_var[127:96];
+ mix_word = (aux);
+ data_reg_var[127:96]=outmux;
+ next_data_reg = (data_reg_var);
+ next_state = (1);
+
+end
+
+ end
+ 1:
+begin
+ aux=data_i_var[95:64];
+ mix_word = (aux);
+ data_reg_var[95:64]=outmux;
+ next_data_reg = (data_reg_var);
+ next_state = (2);
+ end
+ 2:
+begin
+ aux=data_i_var[63:32];
+ mix_word = (aux);
+ data_reg_var[63:32]=outmux;
+ next_data_reg = (data_reg_var);
+ next_state = (3);
+ end
+ 3:
+begin
+ aux=data_i_var[31:0];
+ mix_word = (aux);
+ data_reg_var[31:0]=outmux;
+ next_data_o = (data_reg_var);
+ next_ready_o = (1);
+ next_state = (0);
+ end
+ default:
+ begin
+ end
+ endcase
+
+
+end
+
+endmodule
diff --git a/tests/iwls2005/systemcaes/sbox.v b/tests/iwls2005/systemcaes/sbox.v
new file mode 100644
index 000000000..b5f741c30
--- /dev/null
+++ b/tests/iwls2005/systemcaes/sbox.v
@@ -0,0 +1,392 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// S-Box calculation ////
+//// ////
+//// This file is part of the SystemC AES ////
+//// ////
+//// Description: ////
+//// S-box calculation calculating inverse on gallois field ////
+//// ////
+//// Generated automatically using SystemC to Verilog translator ////
+//// ////
+//// To Do: ////
+//// - done ////
+//// ////
+//// Author(s): ////
+//// - Javier Castillo, jcastilo@opencores.org ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: sbox.v,v $
+// Revision 1.1.1.1 2004/07/05 09:46:23 jcastillo
+// First import
+//
+
+module sbox(clk,reset,data_i,decrypt_i,data_o);
+input clk;
+input reset;
+input [7:0] data_i;
+input decrypt_i;
+output [7:0] data_o;
+
+reg [7:0] data_o;
+
+reg [7:0] inva;
+reg [3:0] ah;
+reg [3:0] al;
+reg [3:0] ah2;
+reg [3:0] al2;
+reg [3:0] alxh;
+reg [3:0] alph;
+reg [3:0] d;
+reg [3:0] ahp;
+reg [3:0] alp;
+reg [3:0] to_invert;
+reg [3:0] next_to_invert;
+reg [3:0] ah_reg;
+reg [3:0] next_ah_reg;
+reg [3:0] next_alph;
+
+
+//registers:
+always @(posedge clk or negedge reset)
+
+begin
+
+if(!reset)
+begin
+
+to_invert = (0);
+ ah_reg = (0);
+alph = (0);
+
+end
+else
+begin
+
+ to_invert = (next_to_invert);
+ ah_reg = (next_ah_reg);
+alph = (next_alph);
+
+end
+
+
+end
+//first_mux:
+reg[7:0] first_mux_data_var;
+ reg[7:0] first_mux_InvInput;
+ reg[3:0] first_mux_ah_t,first_mux_al_t;
+ reg first_mux_aA,first_mux_aB,first_mux_aC,first_mux_aD;
+
+always @( data_i or decrypt_i)
+
+begin
+
+
+ first_mux_data_var=data_i;
+ first_mux_InvInput=first_mux_data_var;
+
+ case(decrypt_i)
+ 1:
+begin
+ //Applyinverseaffinetrasformation
+first_mux_aA=first_mux_data_var[0]^first_mux_data_var[5];first_mux_aB=first_mux_data_var[1]^first_mux_data_var[4];
+ first_mux_aC=first_mux_data_var[2]^first_mux_data_var[7];first_mux_aD=first_mux_data_var[3]^first_mux_data_var[6];
+ first_mux_InvInput[0]=(!first_mux_data_var[5])^first_mux_aC;
+ first_mux_InvInput[1]=first_mux_data_var[0]^first_mux_aD;
+ first_mux_InvInput[2]=(!first_mux_data_var[7])^first_mux_aB;
+ first_mux_InvInput[3]=first_mux_data_var[2]^first_mux_aA;
+ first_mux_InvInput[4]=first_mux_data_var[1]^first_mux_aD;
+ first_mux_InvInput[5]=first_mux_data_var[4]^first_mux_aC;
+ first_mux_InvInput[6]=first_mux_data_var[3]^first_mux_aA;
+ first_mux_InvInput[7]=first_mux_data_var[6]^first_mux_aB;
+ end
+ default:
+begin
+first_mux_InvInput=first_mux_data_var;
+ end
+ endcase
+
+
+ //ConvertelementsfromGF(2^8)intotwoelementsofGF(2^4^2)
+
+ first_mux_aA=first_mux_InvInput[1]^first_mux_InvInput[7];
+ first_mux_aB=first_mux_InvInput[5]^first_mux_InvInput[7];
+ first_mux_aC=first_mux_InvInput[4]^first_mux_InvInput[6];
+
+
+ first_mux_al_t[0]=first_mux_aC^first_mux_InvInput[0]^first_mux_InvInput[5];
+ first_mux_al_t[1]=first_mux_InvInput[1]^first_mux_InvInput[2];
+ first_mux_al_t[2]=first_mux_aA;
+ first_mux_al_t[3]=first_mux_InvInput[2]^first_mux_InvInput[4];
+
+ first_mux_ah_t[0]=first_mux_aC^first_mux_InvInput[5];
+ first_mux_ah_t[1]=first_mux_aA^first_mux_aC;
+ first_mux_ah_t[2]=first_mux_aB^first_mux_InvInput[2]^first_mux_InvInput[3];
+ first_mux_ah_t[3]=first_mux_aB;
+
+ al = (first_mux_al_t);
+ ah = (first_mux_ah_t);
+ next_ah_reg = (first_mux_ah_t);
+
+end
+//end_mux:
+reg[7:0] end_mux_data_var,end_mux_data_o_var;
+ reg end_mux_aA,end_mux_aB,end_mux_aC,end_mux_aD;
+
+always @( decrypt_i or inva)
+
+begin
+
+
+
+ //Taketheoutputoftheinverter
+ end_mux_data_var=inva;
+
+ case(decrypt_i)
+ 0:
+begin
+ //Applyaffinetrasformation
+end_mux_aA=end_mux_data_var[0]^end_mux_data_var[1];end_mux_aB=end_mux_data_var[2]^end_mux_data_var[3];
+ end_mux_aC=end_mux_data_var[4]^end_mux_data_var[5];end_mux_aD=end_mux_data_var[6]^end_mux_data_var[7];
+ end_mux_data_o_var[0]=(!end_mux_data_var[0])^end_mux_aC^end_mux_aD;
+ end_mux_data_o_var[1]=(!end_mux_data_var[5])^end_mux_aA^end_mux_aD;
+ end_mux_data_o_var[2]=end_mux_data_var[2]^end_mux_aA^end_mux_aD;
+ end_mux_data_o_var[3]=end_mux_data_var[7]^end_mux_aA^end_mux_aB;
+ end_mux_data_o_var[4]=end_mux_data_var[4]^end_mux_aA^end_mux_aB;
+ end_mux_data_o_var[5]=(!end_mux_data_var[1])^end_mux_aB^end_mux_aC;
+ end_mux_data_o_var[6]=(!end_mux_data_var[6])^end_mux_aB^end_mux_aC;
+ end_mux_data_o_var[7]=end_mux_data_var[3]^end_mux_aC^end_mux_aD;
+ data_o = (end_mux_data_o_var);
+ end
+ default:
+begin
+data_o = (end_mux_data_var);
+ end
+ endcase
+
+
+
+end
+//inversemap:
+reg[3:0] aA,aB;
+ reg[3:0] inversemap_alp_t,inversemap_ahp_t;
+ reg[7:0] inversemap_inva_t;
+
+always @( alp or ahp)
+begin
+
+
+ inversemap_alp_t=alp;
+ inversemap_ahp_t=ahp;
+
+ aA=inversemap_alp_t[1]^inversemap_ahp_t[3];
+ aB=inversemap_ahp_t[0]^inversemap_ahp_t[1];
+
+ inversemap_inva_t[0]=inversemap_alp_t[0]^inversemap_ahp_t[0];
+ inversemap_inva_t[1]=aB^inversemap_ahp_t[3];
+ inversemap_inva_t[2]=aA^aB;
+ inversemap_inva_t[3]=aB^inversemap_alp_t[1]^inversemap_ahp_t[2];
+ inversemap_inva_t[4]=aA^aB^inversemap_alp_t[3];
+ inversemap_inva_t[5]=aB^inversemap_alp_t[2];
+ inversemap_inva_t[6]=aA^inversemap_alp_t[2]^inversemap_alp_t[3]^inversemap_ahp_t[0];
+ inversemap_inva_t[7]=aB^inversemap_alp_t[2]^inversemap_ahp_t[3];
+
+ inva = (inversemap_inva_t);
+
+end
+//mul1:
+reg[3:0] mul1_alxh_t;
+ reg[3:0] mul1_aA,mul1_a;
+
+always @( ah or al)
+
+begin
+
+ //alxah
+
+ mul1_aA=al[0]^al[3];
+ mul1_a=al[2]^al[3];
+
+ mul1_alxh_t[0]=(al[0]&ah[0])^(al[3]&ah[1])^(al[2]&ah[2])^(al[1]&ah[3]);
+ mul1_alxh_t[1]=(al[1]&ah[0])^(mul1_aA&ah[1])^(mul1_a&ah[2])^((al[1]^al[2])&ah[3]);
+ mul1_alxh_t[2]=(al[2]&ah[0])^(al[1]&ah[1])^(mul1_aA&ah[2])^(mul1_a&ah[3]);
+ mul1_alxh_t[3]=(al[3]&ah[0])^(al[2]&ah[1])^(al[1]&ah[2])^(mul1_aA&ah[3]);
+
+ alxh = (mul1_alxh_t);
+
+end
+//mul2:
+reg[3:0] mul2_ahp_t;
+ reg[3:0] mul2_aA,mul2_aB;
+
+always @( d or ah_reg)
+
+begin
+
+ //ahxd
+
+ mul2_aA=ah_reg[0]^ah_reg[3];
+ mul2_aB=ah_reg[2]^ah_reg[3];
+
+ mul2_ahp_t[0]=(ah_reg[0]&d[0])^(ah_reg[3]&d[1])^(ah_reg[2]&d[2])^(ah_reg[1]&d[3]);
+ mul2_ahp_t[1]=(ah_reg[1]&d[0])^(mul2_aA&d[1])^(mul2_aB&d[2])^((ah_reg[1]^ah_reg[2])&d[3]);
+ mul2_ahp_t[2]=(ah_reg[2]&d[0])^(ah_reg[1]&d[1])^(mul2_aA&d[2])^(mul2_aB&d[3]);
+ mul2_ahp_t[3]=(ah_reg[3]&d[0])^(ah_reg[2]&d[1])^(ah_reg[1]&d[2])^(mul2_aA&d[3]);
+
+ ahp = (mul2_ahp_t);
+
+end
+//mul3:
+reg[3:0] mul3_alp_t;
+ reg[3:0] mul3_aA,mul3_aB;
+
+always @( d or alph)
+
+begin
+
+ //dxal
+
+ mul3_aA=d[0]^d[3];
+ mul3_aB=d[2]^d[3];
+
+ mul3_alp_t[0]=(d[0]&alph[0])^(d[3]&alph[1])^(d[2]&alph[2])^(d[1]&alph[3]);
+ mul3_alp_t[1]=(d[1]&alph[0])^(mul3_aA&alph[1])^(mul3_aB&alph[2])^((d[1]^d[2])&alph[3]);
+ mul3_alp_t[2]=(d[2]&alph[0])^(d[1]&alph[1])^(mul3_aA&alph[2])^(mul3_aB&alph[3]);
+ mul3_alp_t[3]=(d[3]&alph[0])^(d[2]&alph[1])^(d[1]&alph[2])^(mul3_aA&alph[3]);
+
+ alp = (mul3_alp_t);
+
+end
+//intermediate:
+reg[3:0] intermediate_aA,intermediate_aB;
+ reg[3:0] intermediate_ah2e,intermediate_ah2epl2,intermediate_to_invert_var;
+
+always @( ah2 or al2 or alxh)
+
+begin
+
+
+ //ahsquareismultipliedwithe
+ intermediate_aA=ah2[0]^ah2[1];
+ intermediate_aB=ah2[2]^ah2[3];
+ intermediate_ah2e[0]=ah2[1]^intermediate_aB;
+ intermediate_ah2e[1]=intermediate_aA;
+ intermediate_ah2e[2]=intermediate_aA^ah2[2];
+ intermediate_ah2e[3]=intermediate_aA^intermediate_aB;
+
+ //Additionofintermediate_ah2eplusal2
+ intermediate_ah2epl2[0]=intermediate_ah2e[0]^al2[0];
+ intermediate_ah2epl2[1]=intermediate_ah2e[1]^al2[1];
+ intermediate_ah2epl2[2]=intermediate_ah2e[2]^al2[2];
+ intermediate_ah2epl2[3]=intermediate_ah2e[3]^al2[3];
+
+ //Additionoflastresultwiththeresultof(alxah)
+ intermediate_to_invert_var[0]=intermediate_ah2epl2[0]^alxh[0];
+ intermediate_to_invert_var[1]=intermediate_ah2epl2[1]^alxh[1];
+ intermediate_to_invert_var[2]=intermediate_ah2epl2[2]^alxh[2];
+ intermediate_to_invert_var[3]=intermediate_ah2epl2[3]^alxh[3];
+
+//Registers
+ next_to_invert = (intermediate_to_invert_var);
+
+end
+//inversion:
+reg[3:0] inversion_to_invert_var;
+ reg[3:0] inversion_aA,inversion_d_t;
+
+always @( to_invert)
+
+begin
+
+
+ inversion_to_invert_var=to_invert;
+
+ //InverttheresultinGF(2^4)
+ inversion_aA=inversion_to_invert_var[1]^inversion_to_invert_var[2]^inversion_to_invert_var[3]^(inversion_to_invert_var[1]&inversion_to_invert_var[2]&inversion_to_invert_var[3]);
+ inversion_d_t[0]=inversion_aA^inversion_to_invert_var[0]^(inversion_to_invert_var[0]&inversion_to_invert_var[2])^(inversion_to_invert_var[1]&inversion_to_invert_var[2])^(inversion_to_invert_var[0]&inversion_to_invert_var[1]&inversion_to_invert_var[2]);
+ inversion_d_t[1]=(inversion_to_invert_var[0]&inversion_to_invert_var[1])^(inversion_to_invert_var[0]&inversion_to_invert_var[2])^(inversion_to_invert_var[1]&inversion_to_invert_var[2])^inversion_to_invert_var[3]^(inversion_to_invert_var[1]&inversion_to_invert_var[3])^(inversion_to_invert_var[0]&inversion_to_invert_var[1]&inversion_to_invert_var[3]);
+ inversion_d_t[2]=(inversion_to_invert_var[0]&inversion_to_invert_var[1])^inversion_to_invert_var[2]^(inversion_to_invert_var[0]&inversion_to_invert_var[2])^inversion_to_invert_var[3]^(inversion_to_invert_var[0]&inversion_to_invert_var[3])^(inversion_to_invert_var[0]&inversion_to_invert_var[2]&inversion_to_invert_var[3]);
+ inversion_d_t[3]=inversion_aA^(inversion_to_invert_var[0]&inversion_to_invert_var[3])^(inversion_to_invert_var[1]&inversion_to_invert_var[3])^(inversion_to_invert_var[2]&inversion_to_invert_var[3]);
+
+ d = (inversion_d_t);
+
+
+end
+//sum1:
+reg[3:0] sum1_alph_t;
+
+always @( ah or al)
+
+begin
+
+
+ sum1_alph_t[0]=al[0]^ah[0];
+ sum1_alph_t[1]=al[1]^ah[1];
+ sum1_alph_t[2]=al[2]^ah[2];
+ sum1_alph_t[3]=al[3]^ah[3];
+
+ next_alph = (sum1_alph_t);
+
+end
+//square1:
+reg[3:0] square1_ah_t;
+
+always @( ah)
+
+begin
+
+
+ square1_ah_t[0]=ah[0]^ah[2];
+ square1_ah_t[1]=ah[2];
+ square1_ah_t[2]=ah[1]^ah[3];
+ square1_ah_t[3]=ah[3];
+
+ ah2 = (square1_ah_t);
+
+end
+//square2:
+reg[3:0] square2_al_t;
+
+always @( al)
+
+begin
+
+
+ square2_al_t[0]=al[0]^al[2];
+ square2_al_t[1]=al[2];
+ square2_al_t[2]=al[1]^al[3];
+ square2_al_t[3]=al[3];
+
+ al2 = (square2_al_t);
+
+end
+
+endmodule
diff --git a/tests/iwls2005/systemcaes/subbytes.v b/tests/iwls2005/systemcaes/subbytes.v
new file mode 100644
index 000000000..6c6bd20c8
--- /dev/null
+++ b/tests/iwls2005/systemcaes/subbytes.v
@@ -0,0 +1,259 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Subbytes module implementation ////
+//// ////
+//// This file is part of the SystemC AES ////
+//// ////
+//// Description: ////
+//// Subbytes module implementation ////
+//// ////
+//// Generated automatically using SystemC to Verilog translator ////
+//// ////
+//// To Do: ////
+//// - done ////
+//// ////
+//// Author(s): ////
+//// - Javier Castillo, jcastilo@opencores.org ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: subbytes.v,v $
+// Revision 1.1.1.1 2004/07/05 09:46:23 jcastillo
+// First import
+//
+
+module subbytes(clk,reset,start_i,decrypt_i,data_i,ready_o,data_o,sbox_data_o,sbox_data_i,sbox_decrypt_o);
+input clk;
+input reset;
+input start_i;
+input decrypt_i;
+input [127:0] data_i;
+output ready_o;
+output [127:0] data_o;
+output [7:0] sbox_data_o;
+input [7:0] sbox_data_i;
+output sbox_decrypt_o;
+
+reg ready_o;
+reg [127:0] data_o;
+reg [7:0] sbox_data_o;
+reg sbox_decrypt_o;
+
+reg [4:0] state;
+reg [4:0] next_state;
+reg [127:0] data_reg;
+reg [127:0] next_data_reg;
+reg next_ready_o;
+
+`define assign_array_to_128 \
+ data_reg_128[127:120]=data_reg_var[0]; \
+ data_reg_128[119:112]=data_reg_var[1]; \
+ data_reg_128[111:104]=data_reg_var[2]; \
+ data_reg_128[103:96]=data_reg_var[3]; \
+ data_reg_128[95:88]=data_reg_var[4]; \
+ data_reg_128[87:80]=data_reg_var[5]; \
+ data_reg_128[79:72]=data_reg_var[6]; \
+ data_reg_128[71:64]=data_reg_var[7]; \
+ data_reg_128[63:56]=data_reg_var[8]; \
+ data_reg_128[55:48]=data_reg_var[9]; \
+ data_reg_128[47:40]=data_reg_var[10]; \
+ data_reg_128[39:32]=data_reg_var[11]; \
+ data_reg_128[31:24]=data_reg_var[12]; \
+ data_reg_128[23:16]=data_reg_var[13]; \
+ data_reg_128[15:8]=data_reg_var[14]; \
+ data_reg_128[7:0]=data_reg_var[15];
+
+`define shift_array_to_128 \
+ data_reg_128[127:120]=data_reg_var[0]; \
+ data_reg_128[119:112]=data_reg_var[5]; \
+ data_reg_128[111:104]=data_reg_var[10]; \
+ data_reg_128[103:96]=data_reg_var[15]; \
+ data_reg_128[95:88]=data_reg_var[4]; \
+ data_reg_128[87:80]=data_reg_var[9]; \
+ data_reg_128[79:72]=data_reg_var[14]; \
+ data_reg_128[71:64]=data_reg_var[3]; \
+ data_reg_128[63:56]=data_reg_var[8]; \
+ data_reg_128[55:48]=data_reg_var[13]; \
+ data_reg_128[47:40]=data_reg_var[2]; \
+ data_reg_128[39:32]=data_reg_var[7]; \
+ data_reg_128[31:24]=data_reg_var[12]; \
+ data_reg_128[23:16]=data_reg_var[1]; \
+ data_reg_128[15:8]=data_reg_var[6]; \
+ data_reg_128[7:0]=data_reg_var[11];
+
+`define invert_shift_array_to_128 \
+ data_reg_128[127:120]=data_reg_var[0]; \
+ data_reg_128[119:112]=data_reg_var[13]; \
+ data_reg_128[111:104]=data_reg_var[10]; \
+ data_reg_128[103:96]=data_reg_var[7]; \
+ data_reg_128[95:88]=data_reg_var[4]; \
+ data_reg_128[87:80]=data_reg_var[1]; \
+ data_reg_128[79:72]=data_reg_var[14]; \
+ data_reg_128[71:64]=data_reg_var[11]; \
+ data_reg_128[63:56]=data_reg_var[8]; \
+ data_reg_128[55:48]=data_reg_var[5]; \
+ data_reg_128[47:40]=data_reg_var[2]; \
+ data_reg_128[39:32]=data_reg_var[15]; \
+ data_reg_128[31:24]=data_reg_var[12]; \
+ data_reg_128[23:16]=data_reg_var[9]; \
+ data_reg_128[15:8]=data_reg_var[6]; \
+ data_reg_128[7:0]=data_reg_var[3];
+
+
+//registers:
+always @(posedge clk or negedge reset)
+
+begin
+
+if(!reset)
+begin
+
+ data_reg = (0);
+ state = (0);
+ ready_o = (0);
+
+end
+else
+begin
+
+ data_reg = (next_data_reg);
+ state = (next_state);
+ ready_o = (next_ready_o);
+
+end
+
+
+end
+//sub:
+reg[127:0] data_i_var,data_reg_128;
+reg[7:0] data_array[15:0],data_reg_var[15:0];
+
+always @( decrypt_i or start_i or state or data_i or sbox_data_i or data_reg)
+
+begin
+
+
+ data_i_var=data_i;
+
+ data_array[0]=data_i_var[127:120];
+ data_array[1]=data_i_var[119:112];
+ data_array[2]=data_i_var[111:104];
+ data_array[3]=data_i_var[103:96];
+ data_array[4]=data_i_var[95:88];
+ data_array[5]=data_i_var[87:80];
+ data_array[6]=data_i_var[79:72];
+ data_array[7]=data_i_var[71:64];
+ data_array[8]=data_i_var[63:56];
+ data_array[9]=data_i_var[55:48];
+ data_array[10]=data_i_var[47:40];
+ data_array[11]=data_i_var[39:32];
+ data_array[12]=data_i_var[31:24];
+ data_array[13]=data_i_var[23:16];
+ data_array[14]=data_i_var[15:8];
+ data_array[15]=data_i_var[7:0];
+
+ data_reg_var[0]=data_reg[127:120];
+ data_reg_var[1]=data_reg[119:112];
+ data_reg_var[2]=data_reg[111:104];
+ data_reg_var[3]=data_reg[103:96];
+ data_reg_var[4]=data_reg[95:88];
+ data_reg_var[5]=data_reg[87:80];
+ data_reg_var[6]=data_reg[79:72];
+ data_reg_var[7]=data_reg[71:64];
+ data_reg_var[8]=data_reg[63:56];
+ data_reg_var[9]=data_reg[55:48];
+ data_reg_var[10]=data_reg[47:40];
+ data_reg_var[11]=data_reg[39:32];
+ data_reg_var[12]=data_reg[31:24];
+ data_reg_var[13]=data_reg[23:16];
+ data_reg_var[14]=data_reg[15:8];
+ data_reg_var[15]=data_reg[7:0];
+
+
+ sbox_decrypt_o = (decrypt_i);
+ sbox_data_o = (0);
+ next_state = (state);
+ next_data_reg = (data_reg);
+
+ next_ready_o = (0);
+ data_o = (data_reg);
+
+ case(state)
+
+ 0:
+begin
+ if(start_i)
+begin
+
+sbox_data_o = (data_array[0]);
+ next_state = (1);
+
+end
+
+ end
+ 16:
+begin
+ data_reg_var[15]=sbox_data_i;
+ //Makeshiftrowsstage
+ case(decrypt_i)
+ 0:
+ begin
+ `shift_array_to_128
+ end
+ 1:
+ begin
+ `invert_shift_array_to_128
+ end
+ endcase
+
+ next_data_reg = (data_reg_128);
+ next_ready_o = (1);
+ next_state = (0);
+ end
+ default:
+ begin
+ /* original version (causing troubles with synopsys formality):
+ sbox_data_o = (data_array[state]);
+ data_reg_var[state-1]=sbox_data_i;
+ improved version: */
+ sbox_data_o = (data_array[state & 15]);
+ data_reg_var[(state-1) & 15]=sbox_data_i;
+ /* end of improved version */
+ `assign_array_to_128
+ next_data_reg = (data_reg_128);
+ next_state = (state+1);
+ end
+
+endcase
+
+
+end
+
+endmodule
diff --git a/tests/iwls2005/systemcaes/timescale.v b/tests/iwls2005/systemcaes/timescale.v
new file mode 100644
index 000000000..ff9e265a8
--- /dev/null
+++ b/tests/iwls2005/systemcaes/timescale.v
@@ -0,0 +1 @@
+`timescale 1ns / 10ps
diff --git a/tests/iwls2005/systemcaes/word_mixcolum.v b/tests/iwls2005/systemcaes/word_mixcolum.v
new file mode 100644
index 000000000..9308ccc9b
--- /dev/null
+++ b/tests/iwls2005/systemcaes/word_mixcolum.v
@@ -0,0 +1,124 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Mixcolumns for a 16 bit word module implementation ////
+//// ////
+//// This file is part of the SystemC AES ////
+//// ////
+//// Description: ////
+//// Mixcolum for a 16 bit word ////
+//// ////
+//// Generated automatically using SystemC to Verilog translator ////
+//// ////
+//// To Do: ////
+//// - done ////
+//// ////
+//// Author(s): ////
+//// - Javier Castillo, jcastilo@opencores.org ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: word_mixcolum.v,v $
+// Revision 1.1.1.1 2004/07/05 09:46:23 jcastillo
+// First import
+//
+
+module word_mixcolum(in,outx,outy);
+input [31:0] in;
+output [31:0] outx;
+output [31:0] outy;
+
+reg [31:0] outx;
+reg [31:0] outy;
+
+reg [7:0] a;
+reg [7:0] b;
+reg [7:0] c;
+reg [7:0] d;
+wire [7:0] x1;
+
+wire [7:0] x2;
+
+wire [7:0] x3;
+
+wire [7:0] x4;
+
+wire [7:0] y1;
+
+wire [7:0] y2;
+
+wire [7:0] y3;
+
+wire [7:0] y4;
+
+
+byte_mixcolum bm1 (.a(a), .b(b), .c(c), .d(d), .outx(x1), .outy(y1));
+byte_mixcolum bm2 (.a(b), .b(c), .c(d), .d(a), .outx(x2), .outy(y2));
+byte_mixcolum bm3 (.a(c), .b(d), .c(a), .d(b), .outx(x3), .outy(y3));
+byte_mixcolum bm4 (.a(d), .b(a), .c(b), .d(c), .outx(x4), .outy(y4));
+
+
+ reg[31:0] in_var;
+ reg[31:0] outx_var,outy_var;
+//split:
+always @( in)
+
+begin
+
+
+
+ in_var=in;
+ a = (in_var[31:24]);
+ b = (in_var[23:16]);
+ c = (in_var[15:8]);
+ d = (in_var[7:0]);
+
+end
+//mix:
+always @( x1 or x2 or x3 or x4 or y1 or y2 or y3 or y4)
+
+begin
+
+
+
+ outx_var[31:24]=x1;
+ outx_var[23:16]=x2;
+ outx_var[15:8]=x3;
+ outx_var[7:0]=x4;
+ outy_var[31:24]=y1;
+ outy_var[23:16]=y2;
+ outy_var[15:8]=y3;
+ outy_var[7:0]=y4;
+
+ outx = (outx_var);
+ outy = (outy_var);
+
+end
+
+endmodule
diff --git a/tests/iwls2005/usb_phy/timescale.v b/tests/iwls2005/usb_phy/timescale.v
new file mode 100644
index 000000000..ff9e265a8
--- /dev/null
+++ b/tests/iwls2005/usb_phy/timescale.v
@@ -0,0 +1 @@
+`timescale 1ns / 10ps
diff --git a/tests/iwls2005/usb_phy/usb_phy.v b/tests/iwls2005/usb_phy/usb_phy.v
new file mode 100644
index 000000000..4ee345add
--- /dev/null
+++ b/tests/iwls2005/usb_phy/usb_phy.v
@@ -0,0 +1,184 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// USB 1.1 PHY ////
+//// ////
+//// ////
+//// Author: Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+//// ////
+//// Downloaded from: http://www.opencores.org/cores/usb_phy/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000-2002 Rudolf Usselmann ////
+//// www.asics.ws ////
+//// rudi@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: usb_phy.v,v 1.4 2003/10/21 05:58:40 rudi Exp $
+//
+// $Date: 2003/10/21 05:58:40 $
+// $Revision: 1.4 $
+// $Author: rudi $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: usb_phy.v,v $
+// Revision 1.4 2003/10/21 05:58:40 rudi
+// usb_rst is no longer or'ed with the incomming reset internally.
+// Now usb_rst is simply an output, the application can decide how
+// to utilize it.
+//
+// Revision 1.3 2003/10/19 17:40:13 rudi
+// - Made core more robust against line noise
+// - Added Error Checking and Reporting
+// (See README.txt for more info)
+//
+// Revision 1.2 2002/09/16 16:06:37 rudi
+// Changed top level name to be consistent ...
+//
+// Revision 1.1.1.1 2002/09/16 14:26:59 rudi
+// Created Directory Structure
+//
+//
+//
+//
+//
+//
+//
+//
+
+`include "timescale.v"
+
+module usb_phy(clk, rst, phy_tx_mode, usb_rst,
+
+ // Transciever Interface
+ txdp, txdn, txoe,
+ rxd, rxdp, rxdn,
+
+ // UTMI Interface
+ DataOut_i, TxValid_i, TxReady_o, RxValid_o,
+ RxActive_o, RxError_o, DataIn_o, LineState_o
+ );
+
+input clk;
+input rst;
+input phy_tx_mode;
+output usb_rst;
+output txdp, txdn, txoe;
+input rxd, rxdp, rxdn;
+input [7:0] DataOut_i;
+input TxValid_i;
+output TxReady_o;
+output [7:0] DataIn_o;
+output RxValid_o;
+output RxActive_o;
+output RxError_o;
+output [1:0] LineState_o;
+
+///////////////////////////////////////////////////////////////////
+//
+// Local Wires and Registers
+//
+
+reg [4:0] rst_cnt;
+reg usb_rst;
+wire fs_ce;
+wire rst;
+
+///////////////////////////////////////////////////////////////////
+//
+// Misc Logic
+//
+
+///////////////////////////////////////////////////////////////////
+//
+// TX Phy
+//
+
+usb_tx_phy i_tx_phy(
+ .clk( clk ),
+ .rst( rst ),
+ .fs_ce( fs_ce ),
+ .phy_mode( phy_tx_mode ),
+
+ // Transciever Interface
+ .txdp( txdp ),
+ .txdn( txdn ),
+ .txoe( txoe ),
+
+ // UTMI Interface
+ .DataOut_i( DataOut_i ),
+ .TxValid_i( TxValid_i ),
+ .TxReady_o( TxReady_o )
+ );
+
+///////////////////////////////////////////////////////////////////
+//
+// RX Phy and DPLL
+//
+
+usb_rx_phy i_rx_phy(
+ .clk( clk ),
+ .rst( rst ),
+ .fs_ce( fs_ce ),
+
+ // Transciever Interface
+ .rxd( rxd ),
+ .rxdp( rxdp ),
+ .rxdn( rxdn ),
+
+ // UTMI Interface
+ .DataIn_o( DataIn_o ),
+ .RxValid_o( RxValid_o ),
+ .RxActive_o( RxActive_o ),
+ .RxError_o( RxError_o ),
+ .RxEn_i( txoe ),
+ .LineState( LineState_o )
+ );
+
+///////////////////////////////////////////////////////////////////
+//
+// Generate an USB Reset is we see SE0 for at least 2.5uS
+//
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) rst_cnt <= 5'h0;
+ else
+ if(LineState_o != 2'h0) rst_cnt <= 5'h0;
+ else
+ if(!usb_rst && fs_ce) rst_cnt <= rst_cnt + 5'h1;
+
+always @(posedge clk)
+ usb_rst <= (rst_cnt == 5'h1f);
+
+endmodule
+
diff --git a/tests/iwls2005/usb_phy/usb_rx_phy.v b/tests/iwls2005/usb_phy/usb_rx_phy.v
new file mode 100644
index 000000000..c0568fb7d
--- /dev/null
+++ b/tests/iwls2005/usb_phy/usb_rx_phy.v
@@ -0,0 +1,452 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// USB 1.1 PHY ////
+//// RX & DPLL ////
+//// ////
+//// ////
+//// Author: Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+//// ////
+//// Downloaded from: http://www.opencores.org/cores/usb_phy/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000-2002 Rudolf Usselmann ////
+//// www.asics.ws ////
+//// rudi@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: usb_rx_phy.v,v 1.5 2004/10/19 09:29:07 rudi Exp $
+//
+// $Date: 2004/10/19 09:29:07 $
+// $Revision: 1.5 $
+// $Author: rudi $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: usb_rx_phy.v,v $
+// Revision 1.5 2004/10/19 09:29:07 rudi
+// Fixed DPLL alignment in the rx_phy and bit stuffing errors in the tx_phy (if last bit bit was a stuff bit in a packet it was omitted).
+//
+// Revision 1.4 2003/12/02 04:56:00 rudi
+// Fixed a bug reported by Karl C. Posch from Graz University of Technology. Thanks Karl !
+//
+// Revision 1.3 2003/10/19 18:07:45 rudi
+// - Fixed Sync Error to be only checked/generated during the sync phase
+//
+// Revision 1.2 2003/10/19 17:40:13 rudi
+// - Made core more robust against line noise
+// - Added Error Checking and Reporting
+// (See README.txt for more info)
+//
+// Revision 1.1.1.1 2002/09/16 14:27:01 rudi
+// Created Directory Structure
+//
+//
+//
+//
+//
+//
+//
+//
+
+`include "timescale.v"
+
+module usb_rx_phy( clk, rst, fs_ce,
+
+ // Transciever Interface
+ rxd, rxdp, rxdn,
+
+ // UTMI Interface
+ RxValid_o, RxActive_o, RxError_o, DataIn_o,
+ RxEn_i, LineState);
+
+input clk;
+input rst;
+output fs_ce;
+input rxd, rxdp, rxdn;
+output [7:0] DataIn_o;
+output RxValid_o;
+output RxActive_o;
+output RxError_o;
+input RxEn_i;
+output [1:0] LineState;
+
+///////////////////////////////////////////////////////////////////
+//
+// Local Wires and Registers
+//
+
+reg rxd_s0, rxd_s1, rxd_s;
+reg rxdp_s0, rxdp_s1, rxdp_s, rxdp_s_r;
+reg rxdn_s0, rxdn_s1, rxdn_s, rxdn_s_r;
+reg synced_d;
+wire k, j, se0;
+reg rxd_r;
+reg rx_en;
+reg rx_active;
+reg [2:0] bit_cnt;
+reg rx_valid1, rx_valid;
+reg shift_en;
+reg sd_r;
+reg sd_nrzi;
+reg [7:0] hold_reg;
+wire drop_bit; // Indicates a stuffed bit
+reg [2:0] one_cnt;
+
+reg [1:0] dpll_state, dpll_next_state;
+reg fs_ce_d;
+reg fs_ce;
+wire change;
+wire lock_en;
+reg [2:0] fs_state, fs_next_state;
+reg rx_valid_r;
+reg sync_err_d, sync_err;
+reg bit_stuff_err;
+reg se0_r, byte_err;
+reg se0_s;
+
+///////////////////////////////////////////////////////////////////
+//
+// Misc Logic
+//
+
+assign RxActive_o = rx_active;
+assign RxValid_o = rx_valid;
+assign RxError_o = sync_err | bit_stuff_err | byte_err;
+assign DataIn_o = hold_reg;
+assign LineState = {rxdn_s1, rxdp_s1};
+
+always @(posedge clk) rx_en <= RxEn_i;
+always @(posedge clk) sync_err <= !rx_active & sync_err_d;
+
+///////////////////////////////////////////////////////////////////
+//
+// Synchronize Inputs
+//
+
+// First synchronize to the local system clock to
+// avoid metastability outside the sync block (*_s0).
+// Then make sure we see the signal for at least two
+// clock cycles stable to avoid glitches and noise
+
+always @(posedge clk) rxd_s0 <= rxd;
+always @(posedge clk) rxd_s1 <= rxd_s0;
+always @(posedge clk) // Avoid detecting Line Glitches and noise
+ if(rxd_s0 && rxd_s1) rxd_s <= 1'b1;
+ else
+ if(!rxd_s0 && !rxd_s1) rxd_s <= 1'b0;
+
+always @(posedge clk) rxdp_s0 <= rxdp;
+always @(posedge clk) rxdp_s1 <= rxdp_s0;
+always @(posedge clk) rxdp_s_r <= rxdp_s0 & rxdp_s1;
+always @(posedge clk) rxdp_s <= (rxdp_s0 & rxdp_s1) | rxdp_s_r; // Avoid detecting Line Glitches and noise
+
+always @(posedge clk) rxdn_s0 <= rxdn;
+always @(posedge clk) rxdn_s1 <= rxdn_s0;
+always @(posedge clk) rxdn_s_r <= rxdn_s0 & rxdn_s1;
+always @(posedge clk) rxdn_s <= (rxdn_s0 & rxdn_s1) | rxdn_s_r; // Avoid detecting Line Glitches and noise
+
+assign k = !rxdp_s & rxdn_s;
+assign j = rxdp_s & !rxdn_s;
+assign se0 = !rxdp_s & !rxdn_s;
+
+always @(posedge clk) if(fs_ce) se0_s <= se0;
+
+///////////////////////////////////////////////////////////////////
+//
+// DPLL
+//
+
+// This design uses a clock enable to do 12Mhz timing and not a
+// real 12Mhz clock. Everything always runs at 48Mhz. We want to
+// make sure however, that the clock enable is always exactly in
+// the middle between two virtual 12Mhz rising edges.
+// We monitor rxdp and rxdn for any changes and do the appropiate
+// adjustments.
+// In addition to the locking done in the dpll FSM, we adjust the
+// final latch enable to compensate for various sync registers ...
+
+// Allow lockinf only when we are receiving
+assign lock_en = rx_en;
+
+always @(posedge clk) rxd_r <= rxd_s;
+
+// Edge detector
+assign change = rxd_r != rxd_s;
+
+// DPLL FSM
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) dpll_state <= 2'h1;
+ else dpll_state <= dpll_next_state;
+
+always @(dpll_state or lock_en or change)
+ begin
+ fs_ce_d = 1'b0;
+ case(dpll_state) // synopsys full_case parallel_case
+ 2'h0:
+ if(lock_en && change) dpll_next_state = 2'h0;
+ else dpll_next_state = 2'h1;
+ 2'h1:begin
+ fs_ce_d = 1'b1;
+ if(lock_en && change) dpll_next_state = 2'h3;
+ else dpll_next_state = 2'h2;
+ end
+ 2'h2:
+ if(lock_en && change) dpll_next_state = 2'h0;
+ else dpll_next_state = 2'h3;
+ 2'h3:
+ if(lock_en && change) dpll_next_state = 2'h0;
+ else dpll_next_state = 2'h0;
+ endcase
+ end
+
+// Compensate for sync registers at the input - allign full speed
+// clock enable to be in the middle between two bit changes ...
+reg fs_ce_r1, fs_ce_r2;
+
+always @(posedge clk) fs_ce_r1 <= fs_ce_d;
+always @(posedge clk) fs_ce_r2 <= fs_ce_r1;
+always @(posedge clk) fs_ce <= fs_ce_r2;
+
+
+///////////////////////////////////////////////////////////////////
+//
+// Find Sync Pattern FSM
+//
+
+parameter FS_IDLE = 3'h0,
+ K1 = 3'h1,
+ J1 = 3'h2,
+ K2 = 3'h3,
+ J2 = 3'h4,
+ K3 = 3'h5,
+ J3 = 3'h6,
+ K4 = 3'h7;
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) fs_state <= FS_IDLE;
+ else fs_state <= fs_next_state;
+
+always @(fs_state or fs_ce or k or j or rx_en or rx_active or se0 or se0_s)
+ begin
+ synced_d = 1'b0;
+ sync_err_d = 1'b0;
+ fs_next_state = fs_state;
+ if(fs_ce && !rx_active && !se0 && !se0_s)
+ case(fs_state) // synopsys full_case parallel_case
+ FS_IDLE:
+ begin
+ if(k && rx_en) fs_next_state = K1;
+ end
+ K1:
+ begin
+ if(j && rx_en) fs_next_state = J1;
+ else
+ begin
+ sync_err_d = 1'b1;
+ fs_next_state = FS_IDLE;
+ end
+ end
+ J1:
+ begin
+ if(k && rx_en) fs_next_state = K2;
+ else
+ begin
+ sync_err_d = 1'b1;
+ fs_next_state = FS_IDLE;
+ end
+ end
+ K2:
+ begin
+ if(j && rx_en) fs_next_state = J2;
+ else
+ begin
+ sync_err_d = 1'b1;
+ fs_next_state = FS_IDLE;
+ end
+ end
+ J2:
+ begin
+ if(k && rx_en) fs_next_state = K3;
+ else
+ begin
+ sync_err_d = 1'b1;
+ fs_next_state = FS_IDLE;
+ end
+ end
+ K3:
+ begin
+ if(j && rx_en) fs_next_state = J3;
+ else
+ if(k && rx_en)
+ begin
+ fs_next_state = FS_IDLE; // Allow missing first K-J
+ synced_d = 1'b1;
+ end
+ else
+ begin
+ sync_err_d = 1'b1;
+ fs_next_state = FS_IDLE;
+ end
+ end
+ J3:
+ begin
+ if(k && rx_en) fs_next_state = K4;
+ else
+ begin
+ sync_err_d = 1'b1;
+ fs_next_state = FS_IDLE;
+ end
+ end
+ K4:
+ begin
+ if(k) synced_d = 1'b1;
+ fs_next_state = FS_IDLE;
+ end
+ endcase
+ end
+
+///////////////////////////////////////////////////////////////////
+//
+// Generate RxActive
+//
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) rx_active <= 1'b0;
+ else
+ if(synced_d && rx_en) rx_active <= 1'b1;
+ else
+ if(se0 && rx_valid_r) rx_active <= 1'b0;
+
+always @(posedge clk)
+ if(rx_valid) rx_valid_r <= 1'b1;
+ else
+ if(fs_ce) rx_valid_r <= 1'b0;
+
+///////////////////////////////////////////////////////////////////
+//
+// NRZI Decoder
+//
+
+always @(posedge clk)
+ if(fs_ce) sd_r <= rxd_s;
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) sd_nrzi <= 1'b0;
+ else
+ if(!rx_active) sd_nrzi <= 1'b1;
+ else
+ if(rx_active && fs_ce) sd_nrzi <= !(rxd_s ^ sd_r);
+
+///////////////////////////////////////////////////////////////////
+//
+// Bit Stuff Detect
+//
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) one_cnt <= 3'h0;
+ else
+ if(!shift_en) one_cnt <= 3'h0;
+ else
+ if(fs_ce)
+ begin
+ if(!sd_nrzi || drop_bit) one_cnt <= 3'h0;
+ else one_cnt <= one_cnt + 3'h1;
+ end
+
+assign drop_bit = (one_cnt==3'h6);
+
+always @(posedge clk) bit_stuff_err <= drop_bit & sd_nrzi & fs_ce & !se0 & rx_active; // Bit Stuff Error
+
+///////////////////////////////////////////////////////////////////
+//
+// Serial => Parallel converter
+//
+
+always @(posedge clk)
+ if(fs_ce) shift_en <= synced_d | rx_active;
+
+always @(posedge clk)
+ if(fs_ce && shift_en && !drop_bit)
+ hold_reg <= {sd_nrzi, hold_reg[7:1]};
+
+///////////////////////////////////////////////////////////////////
+//
+// Generate RxValid
+//
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) bit_cnt <= 3'b0;
+ else
+ if(!shift_en) bit_cnt <= 3'h0;
+ else
+ if(fs_ce && !drop_bit) bit_cnt <= bit_cnt + 3'h1;
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) rx_valid1 <= 1'b0;
+ else
+ if(fs_ce && !drop_bit && (bit_cnt==3'h7)) rx_valid1 <= 1'b1;
+ else
+ if(rx_valid1 && fs_ce && !drop_bit) rx_valid1 <= 1'b0;
+
+always @(posedge clk) rx_valid <= !drop_bit & rx_valid1 & fs_ce;
+
+always @(posedge clk) se0_r <= se0;
+
+always @(posedge clk) byte_err <= se0 & !se0_r & (|bit_cnt[2:1]) & rx_active;
+
+endmodule
+
diff --git a/tests/iwls2005/usb_phy/usb_tx_phy.v b/tests/iwls2005/usb_phy/usb_tx_phy.v
new file mode 100644
index 000000000..7f61ffd3b
--- /dev/null
+++ b/tests/iwls2005/usb_phy/usb_tx_phy.v
@@ -0,0 +1,465 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// USB 1.1 PHY ////
+//// TX ////
+//// ////
+//// ////
+//// Author: Rudolf Usselmann ////
+//// rudi@asics.ws ////
+//// ////
+//// ////
+//// Downloaded from: http://www.opencores.org/cores/usb_phy/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000-2002 Rudolf Usselmann ////
+//// www.asics.ws ////
+//// rudi@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+// CVS Log
+//
+// $Id: usb_tx_phy.v,v 1.4 2004/10/19 09:29:07 rudi Exp $
+//
+// $Date: 2004/10/19 09:29:07 $
+// $Revision: 1.4 $
+// $Author: rudi $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: usb_tx_phy.v,v $
+// Revision 1.4 2004/10/19 09:29:07 rudi
+// Fixed DPLL alignment in the rx_phy and bit stuffing errors in the tx_phy (if last bit bit was a stuff bit in a packet it was omitted).
+//
+// Revision 1.3 2003/10/21 05:58:41 rudi
+// usb_rst is no longer or'ed with the incomming reset internally.
+// Now usb_rst is simply an output, the application can decide how
+// to utilize it.
+//
+// Revision 1.2 2003/10/19 17:40:13 rudi
+// - Made core more robust against line noise
+// - Added Error Checking and Reporting
+// (See README.txt for more info)
+//
+// Revision 1.1.1.1 2002/09/16 14:27:02 rudi
+// Created Directory Structure
+//
+//
+//
+//
+//
+//
+//
+
+`include "timescale.v"
+
+module usb_tx_phy(
+ clk, rst, fs_ce, phy_mode,
+
+ // Transciever Interface
+ txdp, txdn, txoe,
+
+ // UTMI Interface
+ DataOut_i, TxValid_i, TxReady_o
+ );
+
+input clk;
+input rst;
+input fs_ce;
+input phy_mode;
+output txdp, txdn, txoe;
+input [7:0] DataOut_i;
+input TxValid_i;
+output TxReady_o;
+
+///////////////////////////////////////////////////////////////////
+//
+// Local Wires and Registers
+//
+
+parameter IDLE = 3'd0,
+ SOP = 3'h1,
+ DATA = 3'h2,
+ EOP1 = 3'h3,
+ EOP2 = 3'h4,
+ WAIT = 3'h5;
+
+reg TxReady_o;
+reg [2:0] state, next_state;
+reg tx_ready_d;
+reg ld_sop_d;
+reg ld_data_d;
+reg ld_eop_d;
+reg tx_ip;
+reg tx_ip_sync;
+reg [2:0] bit_cnt;
+reg [7:0] hold_reg;
+reg [7:0] hold_reg_d;
+
+reg sd_raw_o;
+wire hold;
+reg data_done;
+reg sft_done;
+reg sft_done_r;
+wire sft_done_e;
+reg ld_data;
+wire eop_done;
+reg [2:0] one_cnt;
+wire stuff;
+reg sd_bs_o;
+reg sd_nrzi_o;
+reg append_eop;
+reg append_eop_sync1;
+reg append_eop_sync2;
+reg append_eop_sync3;
+reg append_eop_sync4;
+reg txdp, txdn;
+reg txoe_r1, txoe_r2;
+reg txoe;
+
+///////////////////////////////////////////////////////////////////
+//
+// Misc Logic
+//
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) TxReady_o <= 1'b0;
+ else TxReady_o <= tx_ready_d & TxValid_i;
+
+always @(posedge clk) ld_data <= ld_data_d;
+
+///////////////////////////////////////////////////////////////////
+//
+// Transmit in progress indicator
+//
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) tx_ip <= 1'b0;
+ else
+ if(ld_sop_d) tx_ip <= 1'b1;
+ else
+ if(eop_done) tx_ip <= 1'b0;
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) tx_ip_sync <= 1'b0;
+ else
+ if(fs_ce) tx_ip_sync <= tx_ip;
+
+// data_done helps us to catch cases where TxValid drops due to
+// packet end and then gets re-asserted as a new packet starts.
+// We might not see this because we are still transmitting.
+// data_done should solve those cases ...
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) data_done <= 1'b0;
+ else
+ if(TxValid_i && ! tx_ip) data_done <= 1'b1;
+ else
+ if(!TxValid_i) data_done <= 1'b0;
+
+///////////////////////////////////////////////////////////////////
+//
+// Shift Register
+//
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) bit_cnt <= 3'h0;
+ else
+ if(!tx_ip_sync) bit_cnt <= 3'h0;
+ else
+ if(fs_ce && !hold) bit_cnt <= bit_cnt + 3'h1;
+
+assign hold = stuff;
+
+always @(posedge clk)
+ if(!tx_ip_sync) sd_raw_o <= 1'b0;
+ else
+ case(bit_cnt) // synopsys full_case parallel_case
+ 3'h0: sd_raw_o <= hold_reg_d[0];
+ 3'h1: sd_raw_o <= hold_reg_d[1];
+ 3'h2: sd_raw_o <= hold_reg_d[2];
+ 3'h3: sd_raw_o <= hold_reg_d[3];
+ 3'h4: sd_raw_o <= hold_reg_d[4];
+ 3'h5: sd_raw_o <= hold_reg_d[5];
+ 3'h6: sd_raw_o <= hold_reg_d[6];
+ 3'h7: sd_raw_o <= hold_reg_d[7];
+ endcase
+
+always @(posedge clk)
+ sft_done <= !hold & (bit_cnt == 3'h7);
+
+always @(posedge clk)
+ sft_done_r <= sft_done;
+
+assign sft_done_e = sft_done & !sft_done_r;
+
+// Out Data Hold Register
+always @(posedge clk)
+ if(ld_sop_d) hold_reg <= 8'h80;
+ else
+ if(ld_data) hold_reg <= DataOut_i;
+
+always @(posedge clk) hold_reg_d <= hold_reg;
+
+///////////////////////////////////////////////////////////////////
+//
+// Bit Stuffer
+//
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) one_cnt <= 3'h0;
+ else
+ if(!tx_ip_sync) one_cnt <= 3'h0;
+ else
+ if(fs_ce)
+ begin
+ if(!sd_raw_o || stuff) one_cnt <= 3'h0;
+ else one_cnt <= one_cnt + 3'h1;
+ end
+
+assign stuff = (one_cnt==3'h6);
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) sd_bs_o <= 1'h0;
+ else
+ if(fs_ce) sd_bs_o <= !tx_ip_sync ? 1'b0 : (stuff ? 1'b0 : sd_raw_o);
+
+///////////////////////////////////////////////////////////////////
+//
+// NRZI Encoder
+//
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) sd_nrzi_o <= 1'b1;
+ else
+ if(!tx_ip_sync || !txoe_r1) sd_nrzi_o <= 1'b1;
+ else
+ if(fs_ce) sd_nrzi_o <= sd_bs_o ? sd_nrzi_o : ~sd_nrzi_o;
+
+///////////////////////////////////////////////////////////////////
+//
+// EOP append logic
+//
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) append_eop <= 1'b0;
+ else
+ if(ld_eop_d) append_eop <= 1'b1;
+ else
+ if(append_eop_sync2) append_eop <= 1'b0;
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) append_eop_sync1 <= 1'b0;
+ else
+ if(fs_ce) append_eop_sync1 <= append_eop;
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) append_eop_sync2 <= 1'b0;
+ else
+ if(fs_ce) append_eop_sync2 <= append_eop_sync1;
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) append_eop_sync3 <= 1'b0;
+ else
+ if(fs_ce) append_eop_sync3 <= append_eop_sync2 |
+ (append_eop_sync3 & !append_eop_sync4); // Make sure always 2 bit wide
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) append_eop_sync4 <= 1'b0;
+ else
+ if(fs_ce) append_eop_sync4 <= append_eop_sync3;
+
+assign eop_done = append_eop_sync3;
+
+///////////////////////////////////////////////////////////////////
+//
+// Output Enable Logic
+//
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) txoe_r1 <= 1'b0;
+ else
+ if(fs_ce) txoe_r1 <= tx_ip_sync;
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) txoe_r2 <= 1'b0;
+ else
+ if(fs_ce) txoe_r2 <= txoe_r1;
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) txoe <= 1'b1;
+ else
+ if(fs_ce) txoe <= !(txoe_r1 | txoe_r2);
+
+///////////////////////////////////////////////////////////////////
+//
+// Output Registers
+//
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) txdp <= 1'b1;
+ else
+ if(fs_ce) txdp <= phy_mode ?
+ (!append_eop_sync3 & sd_nrzi_o) :
+ sd_nrzi_o;
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) txdn <= 1'b0;
+ else
+ if(fs_ce) txdn <= phy_mode ?
+ (!append_eop_sync3 & ~sd_nrzi_o) :
+ append_eop_sync3;
+
+///////////////////////////////////////////////////////////////////
+//
+// Tx Statemashine
+//
+
+`ifdef USB_ASYNC_REST
+always @(posedge clk or negedge rst)
+`else
+always @(posedge clk)
+`endif
+ if(!rst) state <= IDLE;
+ else state <= next_state;
+
+always @(state or TxValid_i or data_done or sft_done_e or eop_done or fs_ce)
+ begin
+ next_state = state;
+ tx_ready_d = 1'b0;
+
+ ld_sop_d = 1'b0;
+ ld_data_d = 1'b0;
+ ld_eop_d = 1'b0;
+
+ case(state) // synopsys full_case parallel_case
+ IDLE:
+ if(TxValid_i)
+ begin
+ ld_sop_d = 1'b1;
+ next_state = SOP;
+ end
+ SOP:
+ if(sft_done_e)
+ begin
+ tx_ready_d = 1'b1;
+ ld_data_d = 1'b1;
+ next_state = DATA;
+ end
+ DATA:
+ begin
+ if(!data_done && sft_done_e)
+ begin
+ ld_eop_d = 1'b1;
+ next_state = EOP1;
+ end
+
+ if(data_done && sft_done_e)
+ begin
+ tx_ready_d = 1'b1;
+ ld_data_d = 1'b1;
+ end
+ end
+ EOP1:
+ if(eop_done) next_state = EOP2;
+ EOP2:
+ if(!eop_done && fs_ce) next_state = WAIT;
+ WAIT:
+ if(fs_ce) next_state = IDLE;
+ endcase
+ end
+
+endmodule
+
diff --git a/tests/no-icarus/README b/tests/no-icarus/README
new file mode 100644
index 000000000..b43e7c02a
--- /dev/null
+++ b/tests/no-icarus/README
@@ -0,0 +1,2 @@
+This directory contains test cases that can't be tested using Icarus Verilog
+because they exceed the Verilog subset that is supported by Icarus Verilog.
diff --git a/tests/no-icarus/autowire.v b/tests/no-icarus/autowire.v
new file mode 100644
index 000000000..3633d4274
--- /dev/null
+++ b/tests/no-icarus/autowire.v
@@ -0,0 +1,25 @@
+
+module test01(a, b, y);
+
+input [3:0] a, b;
+output [3:0] y;
+
+assign temp1 = a + b;
+assign temp2 = ~temp1;
+assign y = temp2;
+
+endmodule
+
+// ------------------------------
+
+module test02(a, b, y);
+
+input [3:0] a, b;
+output [3:0] y;
+
+test01 test01_cell(A, B, Y);
+
+assign A = a, B = b, y = Y;
+
+endmodule
+
diff --git a/tests/no-icarus/var_range.v b/tests/no-icarus/var_range.v
new file mode 100644
index 000000000..431eacb86
--- /dev/null
+++ b/tests/no-icarus/var_range.v
@@ -0,0 +1,45 @@
+
+module test01(a, b, x, y, z);
+
+input [7:0] a;
+input [2:0] b;
+output [7:0] x, y;
+output z;
+
+assign x = a >> b;
+assign y = a[b+7:b];
+assign z = a[b];
+
+endmodule
+
+module test02(clk, a, b, x, y, z);
+
+input clk;
+input [7:0] a;
+input [2:0] b;
+output reg [7:0] x, y;
+output reg z;
+
+always @(posedge clk) begin
+ x <= a >> b;
+ y <= a[b+7:b];
+ z <= a[b];
+end
+
+endmodule
+
+module test03(clk, a, b, x, y);
+
+input clk;
+input [2:0] a, b;
+output reg [7:0] x;
+output reg [9:0] y;
+
+always @(posedge clk)
+ y[b] <= a;
+
+always @(posedge clk)
+ y[b+2:b] <= a;
+
+endmodule
+
diff --git a/tests/openmsp430/rtl/omsp_alu.v b/tests/openmsp430/rtl/omsp_alu.v
new file mode 100644
index 000000000..d1069973b
--- /dev/null
+++ b/tests/openmsp430/rtl/omsp_alu.v
@@ -0,0 +1,258 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2009 , Olivier Girard
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the authors nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE
+//
+//----------------------------------------------------------------------------
+//
+// *File Name: omsp_alu.v
+//
+// *Module Description:
+// openMSP430 ALU
+//
+// *Author(s):
+// - Olivier Girard, olgirard@gmail.com
+//
+//----------------------------------------------------------------------------
+// $Rev: 134 $
+// $LastChangedBy: olivier.girard $
+// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $
+//----------------------------------------------------------------------------
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_defines.v"
+`endif
+
+module omsp_alu (
+
+// OUTPUTs
+ alu_out, // ALU output value
+ alu_out_add, // ALU adder output value
+ alu_stat, // ALU Status {V,N,Z,C}
+ alu_stat_wr, // ALU Status write {V,N,Z,C}
+
+// INPUTs
+ dbg_halt_st, // Halt/Run status from CPU
+ exec_cycle, // Instruction execution cycle
+ inst_alu, // ALU control signals
+ inst_bw, // Decoded Inst: byte width
+ inst_jmp, // Decoded Inst: Conditional jump
+ inst_so, // Single-operand arithmetic
+ op_dst, // Destination operand
+ op_src, // Source operand
+ status // R2 Status {V,N,Z,C}
+);
+
+// OUTPUTs
+//=========
+output [15:0] alu_out; // ALU output value
+output [15:0] alu_out_add; // ALU adder output value
+output [3:0] alu_stat; // ALU Status {V,N,Z,C}
+output [3:0] alu_stat_wr; // ALU Status write {V,N,Z,C}
+
+// INPUTs
+//=========
+input dbg_halt_st; // Halt/Run status from CPU
+input exec_cycle; // Instruction execution cycle
+input [11:0] inst_alu; // ALU control signals
+input inst_bw; // Decoded Inst: byte width
+input [7:0] inst_jmp; // Decoded Inst: Conditional jump
+input [7:0] inst_so; // Single-operand arithmetic
+input [15:0] op_dst; // Destination operand
+input [15:0] op_src; // Source operand
+input [3:0] status; // R2 Status {V,N,Z,C}
+
+
+//=============================================================================
+// 1) FUNCTIONS
+//=============================================================================
+
+function [4:0] bcd_add;
+
+ input [3:0] X;
+ input [3:0] Y;
+ input C_;
+
+ reg [4:0] Z_;
+ begin
+ Z_ = {1'b0,X}+{1'b0,Y}+{4'b0,C_};
+ if (Z_<5'd10) bcd_add = Z_;
+ else bcd_add = Z_+5'd6;
+ end
+
+endfunction
+
+
+//=============================================================================
+// 2) INSTRUCTION FETCH/DECODE CONTROL STATE MACHINE
+//=============================================================================
+// SINGLE-OPERAND ARITHMETIC:
+//-----------------------------------------------------------------------------
+// Mnemonic S-Reg, Operation Status bits
+// D-Reg, V N Z C
+//
+// RRC dst C->MSB->...LSB->C * * * *
+// RRA dst MSB->MSB->...LSB->C 0 * * *
+// SWPB dst Swap bytes - - - -
+// SXT dst Bit7->Bit8...Bit15 0 * * *
+// PUSH src SP-2->SP, src->@SP - - - -
+// CALL dst SP-2->SP, PC+2->@SP, dst->PC - - - -
+// RETI TOS->SR, SP+2->SP, TOS->PC, SP+2->SP * * * *
+//
+//-----------------------------------------------------------------------------
+// TWO-OPERAND ARITHMETIC:
+//-----------------------------------------------------------------------------
+// Mnemonic S-Reg, Operation Status bits
+// D-Reg, V N Z C
+//
+// MOV src,dst src -> dst - - - -
+// ADD src,dst src + dst -> dst * * * *
+// ADDC src,dst src + dst + C -> dst * * * *
+// SUB src,dst dst + ~src + 1 -> dst * * * *
+// SUBC src,dst dst + ~src + C -> dst * * * *
+// CMP src,dst dst + ~src + 1 * * * *
+// DADD src,dst src + dst + C -> dst (decimaly) * * * *
+// BIT src,dst src & dst 0 * * *
+// BIC src,dst ~src & dst -> dst - - - -
+// BIS src,dst src | dst -> dst - - - -
+// XOR src,dst src ^ dst -> dst * * * *
+// AND src,dst src & dst -> dst 0 * * *
+//
+//-----------------------------------------------------------------------------
+// * the status bit is affected
+// - the status bit is not affected
+// 0 the status bit is cleared
+// 1 the status bit is set
+//-----------------------------------------------------------------------------
+
+// Invert source for substract and compare instructions.
+wire op_src_inv_cmd = exec_cycle & (inst_alu[`ALU_SRC_INV]);
+wire [15:0] op_src_inv = {16{op_src_inv_cmd}} ^ op_src;
+
+
+// Mask the bit 8 for the Byte instructions for correct flags generation
+wire op_bit8_msk = ~exec_cycle | ~inst_bw;
+wire [16:0] op_src_in = {1'b0, {op_src_inv[15:8] & {8{op_bit8_msk}}}, op_src_inv[7:0]};
+wire [16:0] op_dst_in = {1'b0, {op_dst[15:8] & {8{op_bit8_msk}}}, op_dst[7:0]};
+
+// Clear the source operand (= jump offset) for conditional jumps
+wire jmp_not_taken = (inst_jmp[`JL] & ~(status[3]^status[2])) |
+ (inst_jmp[`JGE] & (status[3]^status[2])) |
+ (inst_jmp[`JN] & ~status[2]) |
+ (inst_jmp[`JC] & ~status[0]) |
+ (inst_jmp[`JNC] & status[0]) |
+ (inst_jmp[`JEQ] & ~status[1]) |
+ (inst_jmp[`JNE] & status[1]);
+wire [16:0] op_src_in_jmp = op_src_in & {17{~jmp_not_taken}};
+
+// Adder / AND / OR / XOR
+wire [16:0] alu_add = op_src_in_jmp + op_dst_in;
+wire [16:0] alu_and = op_src_in & op_dst_in;
+wire [16:0] alu_or = op_src_in | op_dst_in;
+wire [16:0] alu_xor = op_src_in ^ op_dst_in;
+
+
+// Incrementer
+wire alu_inc = exec_cycle & ((inst_alu[`ALU_INC_C] & status[0]) |
+ inst_alu[`ALU_INC]);
+wire [16:0] alu_add_inc = alu_add + {16'h0000, alu_inc};
+
+
+
+// Decimal adder (DADD)
+wire [4:0] alu_dadd0 = bcd_add(op_src_in[3:0], op_dst_in[3:0], status[0]);
+wire [4:0] alu_dadd1 = bcd_add(op_src_in[7:4], op_dst_in[7:4], alu_dadd0[4]);
+wire [4:0] alu_dadd2 = bcd_add(op_src_in[11:8], op_dst_in[11:8], alu_dadd1[4]);
+wire [4:0] alu_dadd3 = bcd_add(op_src_in[15:12], op_dst_in[15:12],alu_dadd2[4]);
+wire [16:0] alu_dadd = {alu_dadd3, alu_dadd2[3:0], alu_dadd1[3:0], alu_dadd0[3:0]};
+
+
+// Shifter for rotate instructions (RRC & RRA)
+wire alu_shift_msb = inst_so[`RRC] ? status[0] :
+ inst_bw ? op_src[7] : op_src[15];
+wire alu_shift_7 = inst_bw ? alu_shift_msb : op_src[8];
+wire [16:0] alu_shift = {1'b0, alu_shift_msb, op_src[15:9], alu_shift_7, op_src[7:1]};
+
+
+// Swap bytes / Extend Sign
+wire [16:0] alu_swpb = {1'b0, op_src[7:0],op_src[15:8]};
+wire [16:0] alu_sxt = {1'b0, {8{op_src[7]}},op_src[7:0]};
+
+
+// Combine short paths toghether to simplify final ALU mux
+wire alu_short_thro = ~(inst_alu[`ALU_AND] |
+ inst_alu[`ALU_OR] |
+ inst_alu[`ALU_XOR] |
+ inst_alu[`ALU_SHIFT] |
+ inst_so[`SWPB] |
+ inst_so[`SXT]);
+
+wire [16:0] alu_short = ({17{inst_alu[`ALU_AND]}} & alu_and) |
+ ({17{inst_alu[`ALU_OR]}} & alu_or) |
+ ({17{inst_alu[`ALU_XOR]}} & alu_xor) |
+ ({17{inst_alu[`ALU_SHIFT]}} & alu_shift) |
+ ({17{inst_so[`SWPB]}} & alu_swpb) |
+ ({17{inst_so[`SXT]}} & alu_sxt) |
+ ({17{alu_short_thro}} & op_src_in);
+
+
+// ALU output mux
+wire [16:0] alu_out_nxt = (inst_so[`IRQ] | dbg_halt_st |
+ inst_alu[`ALU_ADD]) ? alu_add_inc :
+ inst_alu[`ALU_DADD] ? alu_dadd : alu_short;
+
+assign alu_out = alu_out_nxt[15:0];
+assign alu_out_add = alu_add[15:0];
+
+
+//-----------------------------------------------------------------------------
+// STATUS FLAG GENERATION
+//-----------------------------------------------------------------------------
+
+wire V_xor = inst_bw ? (op_src_in[7] & op_dst_in[7]) :
+ (op_src_in[15] & op_dst_in[15]);
+
+wire V = inst_bw ? ((~op_src_in[7] & ~op_dst_in[7] & alu_out[7]) |
+ ( op_src_in[7] & op_dst_in[7] & ~alu_out[7])) :
+ ((~op_src_in[15] & ~op_dst_in[15] & alu_out[15]) |
+ ( op_src_in[15] & op_dst_in[15] & ~alu_out[15]));
+
+wire N = inst_bw ? alu_out[7] : alu_out[15];
+wire Z = inst_bw ? (alu_out[7:0]==0) : (alu_out==0);
+wire C = inst_bw ? alu_out[8] : alu_out_nxt[16];
+
+assign alu_stat = inst_alu[`ALU_SHIFT] ? {1'b0, N,Z,op_src_in[0]} :
+ inst_alu[`ALU_STAT_7] ? {1'b0, N,Z,~Z} :
+ inst_alu[`ALU_XOR] ? {V_xor,N,Z,~Z} : {V,N,Z,C};
+
+assign alu_stat_wr = (inst_alu[`ALU_STAT_F] & exec_cycle) ? 4'b1111 : 4'b0000;
+
+
+endmodule // omsp_alu
+
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_undefines.v"
+`endif
diff --git a/tests/openmsp430/rtl/omsp_and_gate.v b/tests/openmsp430/rtl/omsp_and_gate.v
new file mode 100644
index 000000000..7ceeb8d97
--- /dev/null
+++ b/tests/openmsp430/rtl/omsp_and_gate.v
@@ -0,0 +1,89 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2009 , Olivier Girard
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the authors nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE
+//
+//----------------------------------------------------------------------------
+//
+// *File Name: omsp_and_gate.v
+//
+// *Module Description:
+// Generic AND gate cell for the openMSP430
+//
+// *Author(s):
+// - Olivier Girard, olgirard@gmail.com
+//
+//----------------------------------------------------------------------------
+// $Rev: 103 $
+// $LastChangedBy: olivier.girard $
+// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
+//----------------------------------------------------------------------------
+
+module omsp_and_gate (
+
+// OUTPUTs
+ y, // AND gate output
+
+// INPUTs
+ a, // AND gate input A
+ b // AND gate input B
+);
+
+// OUTPUTs
+//=========
+output y; // AND gate output
+
+// INPUTs
+//=========
+input a; // AND gate input A
+input b; // AND gate input B
+
+
+//=============================================================================
+// 1) SOME COMMENTS ON THIS MODULE
+//=============================================================================
+//
+// In its ASIC version, some combinatorial pathes of the openMSP430 are
+// sensitive to glitches, in particular the ones generating the wakeup
+// signals.
+// To prevent synthesis from optmizing combinatorial clouds into glitchy
+// logic, this AND gate module has been instanciated in the critical places.
+//
+// Make sure that synthesis doesn't ungroup this module. As an alternative,
+// a standard cell from the library could also be directly instanciated here
+// (don't forget the "dont_touch" attribute)
+//
+//
+//=============================================================================
+// 2) AND GATE
+//=============================================================================
+
+assign y = a & b;
+
+
+endmodule // omsp_and_gate
+
+
+
diff --git a/tests/openmsp430/rtl/omsp_clock_gate.v b/tests/openmsp430/rtl/omsp_clock_gate.v
new file mode 100644
index 000000000..8ffe8e0d4
--- /dev/null
+++ b/tests/openmsp430/rtl/omsp_clock_gate.v
@@ -0,0 +1,86 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2009 , Olivier Girard
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the authors nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE
+//
+//----------------------------------------------------------------------------
+//
+// *File Name: omsp_clock_gate.v
+//
+// *Module Description:
+// Generic clock gate cell for the openMSP430
+//
+// *Author(s):
+// - Olivier Girard, olgirard@gmail.com
+//
+//----------------------------------------------------------------------------
+// $Rev: 103 $
+// $LastChangedBy: olivier.girard $
+// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
+//----------------------------------------------------------------------------
+
+module omsp_clock_gate (
+
+// OUTPUTs
+ gclk, // Gated clock
+
+// INPUTs
+ clk, // Clock
+ enable, // Clock enable
+ scan_enable // Scan enable (active during scan shifting)
+);
+
+// OUTPUTs
+//=========
+output gclk; // Gated clock
+
+// INPUTs
+//=========
+input clk; // Clock
+input enable; // Clock enable
+input scan_enable; // Scan enable (active during scan shifting)
+
+
+//=============================================================================
+// CLOCK GATE: LATCH + AND
+//=============================================================================
+
+// Enable clock gate during scan shift
+// (the gate itself is checked with the scan capture cycle)
+wire enable_in = (enable | scan_enable);
+
+// LATCH the enable signal
+reg enable_latch;
+always @(clk or enable_in)
+ if (~clk)
+ enable_latch <= enable_in;
+
+// AND gate
+assign gclk = (clk & enable_latch);
+
+
+endmodule // omsp_clock_gate
+
+
diff --git a/tests/openmsp430/rtl/omsp_clock_module.v b/tests/openmsp430/rtl/omsp_clock_module.v
new file mode 100644
index 000000000..670c5e590
--- /dev/null
+++ b/tests/openmsp430/rtl/omsp_clock_module.v
@@ -0,0 +1,1058 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2009 , Olivier Girard
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the authors nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE
+//
+//----------------------------------------------------------------------------
+//
+// *File Name: omsp_clock_module.v
+//
+// *Module Description:
+// Basic clock module implementation.
+//
+// *Author(s):
+// - Olivier Girard, olgirard@gmail.com
+//
+//----------------------------------------------------------------------------
+// $Rev: 134 $
+// $LastChangedBy: olivier.girard $
+// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $
+//----------------------------------------------------------------------------
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_defines.v"
+`endif
+
+module omsp_clock_module (
+
+// OUTPUTs
+ aclk, // ACLK
+ aclk_en, // ACLK enable
+ cpu_en_s, // Enable CPU code execution (synchronous)
+ dbg_clk, // Debug unit clock
+ dbg_en_s, // Debug interface enable (synchronous)
+ dbg_rst, // Debug unit reset
+ dco_enable, // Fast oscillator enable
+ dco_wkup, // Fast oscillator wake-up (asynchronous)
+ lfxt_enable, // Low frequency oscillator enable
+ lfxt_wkup, // Low frequency oscillator wake-up (asynchronous)
+ mclk, // Main system clock
+ per_dout, // Peripheral data output
+ por, // Power-on reset
+ puc_pnd_set, // PUC pending set for the serial debug interface
+ puc_rst, // Main system reset
+ smclk, // SMCLK
+ smclk_en, // SMCLK enable
+
+// INPUTs
+ cpu_en, // Enable CPU code execution (asynchronous)
+ cpuoff, // Turns off the CPU
+ dbg_cpu_reset, // Reset CPU from debug interface
+ dbg_en, // Debug interface enable (asynchronous)
+ dco_clk, // Fast oscillator (fast clock)
+ lfxt_clk, // Low frequency oscillator (typ 32kHz)
+ mclk_enable, // Main System Clock enable
+ mclk_wkup, // Main System Clock wake-up (asynchronous)
+ oscoff, // Turns off LFXT1 clock input
+ per_addr, // Peripheral address
+ per_din, // Peripheral data input
+ per_en, // Peripheral enable (high active)
+ per_we, // Peripheral write enable (high active)
+ reset_n, // Reset Pin (low active, asynchronous)
+ scan_enable, // Scan enable (active during scan shifting)
+ scan_mode, // Scan mode
+ scg0, // System clock generator 1. Turns off the DCO
+ scg1, // System clock generator 1. Turns off the SMCLK
+ wdt_reset // Watchdog-timer reset
+);
+
+// OUTPUTs
+//=========
+output aclk; // ACLK
+output aclk_en; // ACLK enable
+output cpu_en_s; // Enable CPU code execution (synchronous)
+output dbg_clk; // Debug unit clock
+output dbg_en_s; // Debug unit enable (synchronous)
+output dbg_rst; // Debug unit reset
+output dco_enable; // Fast oscillator enable
+output dco_wkup; // Fast oscillator wake-up (asynchronous)
+output lfxt_enable; // Low frequency oscillator enable
+output lfxt_wkup; // Low frequency oscillator wake-up (asynchronous)
+output mclk; // Main system clock
+output [15:0] per_dout; // Peripheral data output
+output por; // Power-on reset
+output puc_pnd_set; // PUC pending set for the serial debug interface
+output puc_rst; // Main system reset
+output smclk; // SMCLK
+output smclk_en; // SMCLK enable
+
+// INPUTs
+//=========
+input cpu_en; // Enable CPU code execution (asynchronous)
+input cpuoff; // Turns off the CPU
+input dbg_cpu_reset;// Reset CPU from debug interface
+input dbg_en; // Debug interface enable (asynchronous)
+input dco_clk; // Fast oscillator (fast clock)
+input lfxt_clk; // Low frequency oscillator (typ 32kHz)
+input mclk_enable; // Main System Clock enable
+input mclk_wkup; // Main System Clock wake-up (asynchronous)
+input oscoff; // Turns off LFXT1 clock input
+input [13:0] per_addr; // Peripheral address
+input [15:0] per_din; // Peripheral data input
+input per_en; // Peripheral enable (high active)
+input [1:0] per_we; // Peripheral write enable (high active)
+input reset_n; // Reset Pin (low active, asynchronous)
+input scan_enable; // Scan enable (active during scan shifting)
+input scan_mode; // Scan mode
+input scg0; // System clock generator 1. Turns off the DCO
+input scg1; // System clock generator 1. Turns off the SMCLK
+input wdt_reset; // Watchdog-timer reset
+
+
+//=============================================================================
+// 1) WIRES & PARAMETER DECLARATION
+//=============================================================================
+
+// Register base address (must be aligned to decoder bit width)
+parameter [14:0] BASE_ADDR = 15'h0050;
+
+// Decoder bit width (defines how many bits are considered for address decoding)
+parameter DEC_WD = 4;
+
+// Register addresses offset
+parameter [DEC_WD-1:0] BCSCTL1 = 'h7,
+ BCSCTL2 = 'h8;
+
+// Register one-hot decoder utilities
+parameter DEC_SZ = (1 << DEC_WD);
+parameter [DEC_SZ-1:0] BASE_REG = {{DEC_SZ-1{1'b0}}, 1'b1};
+
+// Register one-hot decoder
+parameter [DEC_SZ-1:0] BCSCTL1_D = (BASE_REG << BCSCTL1),
+ BCSCTL2_D = (BASE_REG << BCSCTL2);
+
+// Local wire declarations
+wire nodiv_mclk;
+wire nodiv_mclk_n;
+wire nodiv_smclk;
+
+
+//============================================================================
+// 2) REGISTER DECODER
+//============================================================================
+
+// Local register selection
+wire reg_sel = per_en & (per_addr[13:DEC_WD-1]==BASE_ADDR[14:DEC_WD]);
+
+// Register local address
+wire [DEC_WD-1:0] reg_addr = {1'b0, per_addr[DEC_WD-2:0]};
+
+// Register address decode
+wire [DEC_SZ-1:0] reg_dec = (BCSCTL1_D & {DEC_SZ{(reg_addr==(BCSCTL1 >>1))}}) |
+ (BCSCTL2_D & {DEC_SZ{(reg_addr==(BCSCTL2 >>1))}});
+
+// Read/Write probes
+wire reg_lo_write = per_we[0] & reg_sel;
+wire reg_hi_write = per_we[1] & reg_sel;
+wire reg_read = ~|per_we & reg_sel;
+
+// Read/Write vectors
+wire [DEC_SZ-1:0] reg_hi_wr = reg_dec & {DEC_SZ{reg_hi_write}};
+wire [DEC_SZ-1:0] reg_lo_wr = reg_dec & {DEC_SZ{reg_lo_write}};
+wire [DEC_SZ-1:0] reg_rd = reg_dec & {DEC_SZ{reg_read}};
+
+
+//============================================================================
+// 3) REGISTERS
+//============================================================================
+
+// BCSCTL1 Register
+//--------------
+reg [7:0] bcsctl1;
+wire bcsctl1_wr = BCSCTL1[0] ? reg_hi_wr[BCSCTL1] : reg_lo_wr[BCSCTL1];
+wire [7:0] bcsctl1_nxt = BCSCTL1[0] ? per_din[15:8] : per_din[7:0];
+
+`ifdef ASIC
+ `ifdef ACLK_DIVIDER
+wire [7:0] divax_mask = 8'h30;
+ `else
+wire [7:0] divax_mask = 8'h00;
+ `endif
+`else
+wire [7:0] divax_mask = 8'h30;
+`endif
+
+always @ (posedge mclk or posedge puc_rst)
+ if (puc_rst) bcsctl1 <= 8'h00;
+ else if (bcsctl1_wr) bcsctl1 <= bcsctl1_nxt & divax_mask; // Mask unused bits
+
+
+// BCSCTL2 Register
+//--------------
+reg [7:0] bcsctl2;
+wire bcsctl2_wr = BCSCTL2[0] ? reg_hi_wr[BCSCTL2] : reg_lo_wr[BCSCTL2];
+wire [7:0] bcsctl2_nxt = BCSCTL2[0] ? per_din[15:8] : per_din[7:0];
+
+`ifdef MCLK_MUX
+wire [7:0] selmx_mask = 8'h80;
+`else
+wire [7:0] selmx_mask = 8'h00;
+`endif
+`ifdef MCLK_DIVIDER
+wire [7:0] divmx_mask = 8'h30;
+`else
+wire [7:0] divmx_mask = 8'h00;
+`endif
+`ifdef ASIC
+ `ifdef SMCLK_MUX
+wire [7:0] sels_mask = 8'h08;
+ `else
+wire [7:0] sels_mask = 8'h00;
+ `endif
+ `ifdef SMCLK_DIVIDER
+wire [7:0] divsx_mask = 8'h06;
+ `else
+wire [7:0] divsx_mask = 8'h00;
+ `endif
+`else
+wire [7:0] sels_mask = 8'h08;
+wire [7:0] divsx_mask = 8'h06;
+`endif
+
+always @ (posedge mclk or posedge puc_rst)
+ if (puc_rst) bcsctl2 <= 8'h00;
+ else if (bcsctl2_wr) bcsctl2 <= bcsctl2_nxt & ( sels_mask | divsx_mask |
+ selmx_mask | divmx_mask); // Mask unused bits
+
+
+//============================================================================
+// 4) DATA OUTPUT GENERATION
+//============================================================================
+
+// Data output mux
+wire [15:0] bcsctl1_rd = {8'h00, (bcsctl1 & {8{reg_rd[BCSCTL1]}})} << (8 & {4{BCSCTL1[0]}});
+wire [15:0] bcsctl2_rd = {8'h00, (bcsctl2 & {8{reg_rd[BCSCTL2]}})} << (8 & {4{BCSCTL2[0]}});
+
+wire [15:0] per_dout = bcsctl1_rd |
+ bcsctl2_rd;
+
+
+//=============================================================================
+// 5) DCO_CLK / LFXT_CLK INTERFACES (WAKEUP, ENABLE, ...)
+//=============================================================================
+
+`ifdef ASIC
+ wire cpuoff_and_mclk_enable;
+ omsp_and_gate and_cpuoff_mclk_en (.y(cpuoff_and_mclk_enable), .a(cpuoff), .b(mclk_enable));
+`endif
+
+//-----------------------------------------------------------
+// 5.1) HIGH SPEED SYSTEM CLOCK GENERATOR (DCO_CLK)
+//-----------------------------------------------------------
+// Note1: switching off the DCO osillator is only
+// supported in ASIC mode with SCG0 low power mode
+//
+// Note2: unlike the original MSP430 specification,
+// we allow to switch off the DCO even
+// if it is selected by MCLK or SMCLK.
+
+wire por_a;
+wire dco_wkup;
+wire cpu_en_wkup;
+
+`ifdef SCG0_EN
+
+ // The DCO oscillator is synchronously disabled if:
+ // - the cpu pin is disabled (in that case, wait for mclk_enable==0)
+ // - the debug interface is disabled
+ // - SCG0 is set (in that case, wait for the mclk_enable==0 if selected by SELMx)
+ //
+ // Note that we make extensive use of the AND gate module in order
+ // to prevent glitch propagation on the wakeup logic cone.
+ wire cpu_enabled_with_dco;
+ wire dco_not_enabled_by_dbg;
+ wire dco_disable_by_scg0;
+ wire dco_disable_by_cpu_en;
+ wire dco_enable_nxt;
+ omsp_and_gate and_dco_dis1 (.y(cpu_enabled_with_dco), .a(~bcsctl2[`SELMx]), .b(cpuoff_and_mclk_enable));
+ omsp_and_gate and_dco_dis2 (.y(dco_not_enabled_by_dbg), .a(~dbg_en_s), .b(~cpu_enabled_with_dco));
+ omsp_and_gate and_dco_dis3 (.y(dco_disable_by_scg0), .a(scg0), .b(dco_not_enabled_by_dbg));
+ omsp_and_gate and_dco_dis4 (.y(dco_disable_by_cpu_en), .a(~cpu_en_s), .b(~mclk_enable));
+ omsp_and_gate and_dco_dis5 (.y(dco_enable_nxt), .a(~dco_disable_by_scg0), .b(~dco_disable_by_cpu_en));
+
+ // Register to prevent glitch propagation
+ reg dco_disable;
+ always @(posedge nodiv_mclk_n or posedge por)
+ if (por) dco_disable <= 1'b1;
+ else dco_disable <= ~dco_enable_nxt;
+
+ // Note that a synchronizer is required if the MCLK mux is included
+ wire dco_clk_n = ~dco_clk;
+ `ifdef MCLK_MUX
+ omsp_sync_cell sync_cell_dco_disable (
+ .data_out (dco_enable),
+ .data_in (~dco_disable),
+ .clk (dco_clk_n),
+ .rst (por)
+ );
+ `else
+
+ assign dco_enable = ~dco_disable;
+ `endif
+
+ // The DCO oscillator will get an asynchronous wakeup if:
+ // - the MCLK generates a wakeup (only if the MCLK mux selects dco_clk)
+ // - if the DCO wants to be synchronously enabled (i.e dco_enable_nxt=1)
+ wire dco_mclk_wkup;
+ wire dco_en_wkup;
+ omsp_and_gate and_dco_mclk_wkup (.y(dco_mclk_wkup), .a(mclk_wkup), .b(~bcsctl2[`SELMx]));
+ omsp_and_gate and_dco_en_wkup (.y(dco_en_wkup), .a(~dco_enable), .b(dco_enable_nxt));
+
+ wire dco_wkup_set = dco_mclk_wkup | dco_en_wkup | cpu_en_wkup;
+
+ // Scan MUX for the asynchronous SET
+ wire dco_wkup_set_scan;
+ omsp_scan_mux scan_mux_dco_wkup (
+ .scan_mode (scan_mode),
+ .data_in_scan (por_a),
+ .data_in_func (dco_wkup_set | por),
+ .data_out (dco_wkup_set_scan)
+ );
+
+ // Scan MUX to increase coverage
+ wire dco_wkup_clear;
+ omsp_scan_mux scan_mux_dco_wkup_clear (
+ .scan_mode (scan_mode),
+ .data_in_scan (dco_wkup_set),
+ .data_in_func (1'b1),
+ .data_out (dco_wkup_clear)
+ );
+
+ // The wakeup is asynchronously set, synchronously released
+ wire dco_wkup_n;
+ omsp_sync_cell sync_cell_dco_wkup (
+ .data_out (dco_wkup_n),
+ .data_in (dco_wkup_clear),
+ .clk (dco_clk_n),
+ .rst (dco_wkup_set_scan)
+ );
+
+ omsp_and_gate and_dco_wkup (.y(dco_wkup), .a(~dco_wkup_n), .b(cpu_en));
+
+`else
+ assign dco_enable = 1'b1;
+ assign dco_wkup = 1'b1;
+`endif
+
+
+//-----------------------------------------------------------
+// 5.2) LOW FREQUENCY CRYSTAL CLOCK GENERATOR (LFXT_CLK)
+//-----------------------------------------------------------
+
+// ASIC MODE
+//------------------------------------------------
+// Note: unlike the original MSP430 specification,
+// we allow to switch off the LFXT even
+// if it is selected by MCLK or SMCLK.
+`ifdef ASIC
+
+`ifdef OSCOFF_EN
+
+ // The LFXT is synchronously disabled if:
+ // - the cpu pin is disabled (in that case, wait for mclk_enable==0)
+ // - the debug interface is disabled
+ // - OSCOFF is set (in that case, wait for the mclk_enable==0 if selected by SELMx)
+ wire cpu_enabled_with_lfxt;
+ wire lfxt_not_enabled_by_dbg;
+ wire lfxt_disable_by_oscoff;
+ wire lfxt_disable_by_cpu_en;
+ wire lfxt_enable_nxt;
+ omsp_and_gate and_lfxt_dis1 (.y(cpu_enabled_with_lfxt), .a(bcsctl2[`SELMx]), .b(cpuoff_and_mclk_enable));
+ omsp_and_gate and_lfxt_dis2 (.y(lfxt_not_enabled_by_dbg), .a(~dbg_en_s), .b(~cpu_enabled_with_lfxt));
+ omsp_and_gate and_lfxt_dis3 (.y(lfxt_disable_by_oscoff), .a(oscoff), .b(lfxt_not_enabled_by_dbg));
+ omsp_and_gate and_lfxt_dis4 (.y(lfxt_disable_by_cpu_en), .a(~cpu_en_s), .b(~mclk_enable));
+ omsp_and_gate and_lfxt_dis5 (.y(lfxt_enable_nxt), .a(~lfxt_disable_by_oscoff), .b(~lfxt_disable_by_cpu_en));
+
+ // Register to prevent glitch propagation
+ reg lfxt_disable;
+ always @(posedge nodiv_mclk_n or posedge por)
+ if (por) lfxt_disable <= 1'b1;
+ else lfxt_disable <= ~lfxt_enable_nxt;
+
+ // Synchronize the OSCOFF control signal to the LFXT clock domain
+ wire lfxt_clk_n = ~lfxt_clk;
+ omsp_sync_cell sync_cell_lfxt_disable (
+ .data_out (lfxt_enable),
+ .data_in (~lfxt_disable),
+ .clk (lfxt_clk_n),
+ .rst (por)
+ );
+
+ // The LFXT will get an asynchronous wakeup if:
+ // - the MCLK generates a wakeup (only if the MCLK mux selects lfxt_clk)
+ // - if the LFXT wants to be synchronously enabled (i.e lfxt_enable_nxt=1)
+ wire lfxt_mclk_wkup;
+ wire lfxt_en_wkup;
+ omsp_and_gate and_lfxt_mclk_wkup (.y(lfxt_mclk_wkup), .a(mclk_wkup), .b(bcsctl2[`SELMx]));
+ omsp_and_gate and_lfxt_en_wkup (.y(lfxt_en_wkup), .a(~lfxt_enable), .b(lfxt_enable_nxt));
+
+ wire lfxt_wkup_set = lfxt_mclk_wkup | lfxt_en_wkup | cpu_en_wkup;
+
+ // Scan MUX for the asynchronous SET
+ wire lfxt_wkup_set_scan;
+ omsp_scan_mux scan_mux_lfxt_wkup (
+ .scan_mode (scan_mode),
+ .data_in_scan (por_a),
+ .data_in_func (lfxt_wkup_set | por),
+ .data_out (lfxt_wkup_set_scan)
+ );
+
+ // Scan MUX to increase coverage
+ wire lfxt_wkup_clear;
+ omsp_scan_mux scan_mux_lfxt_wkup_clear (
+ .scan_mode (scan_mode),
+ .data_in_scan (lfxt_wkup_set),
+ .data_in_func (1'b1),
+ .data_out (lfxt_wkup_clear)
+ );
+
+ // The wakeup is asynchronously set, synchronously released
+ wire lfxt_wkup_n;
+ omsp_sync_cell sync_cell_lfxt_wkup (
+ .data_out (lfxt_wkup_n),
+ .data_in (lfxt_wkup_clear),
+ .clk (lfxt_clk_n),
+ .rst (lfxt_wkup_set_scan)
+ );
+
+ omsp_and_gate and_lfxt_wkup (.y(lfxt_wkup), .a(~lfxt_wkup_n), .b(cpu_en));
+
+`else
+ assign lfxt_enable = 1'b1;
+ assign lfxt_wkup = 1'b0;
+`endif
+
+
+// FPGA MODE
+//---------------------------------------
+// Synchronize LFXT_CLK & edge detection
+`else
+
+wire lfxt_clk_s;
+
+omsp_sync_cell sync_cell_lfxt_clk (
+ .data_out (lfxt_clk_s),
+ .data_in (lfxt_clk),
+ .clk (mclk),
+ .rst (por)
+);
+
+reg lfxt_clk_dly;
+
+always @ (posedge mclk or posedge por)
+ if (por) lfxt_clk_dly <= 1'b0;
+ else lfxt_clk_dly <= lfxt_clk_s;
+
+wire lfxt_clk_en = (lfxt_clk_s & ~lfxt_clk_dly) & ~(oscoff & ~bcsctl2[`SELS]);
+assign lfxt_enable = 1'b1;
+assign lfxt_wkup = 1'b0;
+`endif
+
+
+//=============================================================================
+// 6) CLOCK GENERATION
+//=============================================================================
+
+//-----------------------------------------------------------
+// 6.1) GLOBAL CPU ENABLE
+//-----------------------------------------------------------
+// ACLK and SMCLK are directly switched-off
+// with the cpu_en pin (after synchronization).
+// MCLK will be switched off once the CPU reaches
+// its IDLE state (through the mclk_enable signal)
+
+
+// Synchronize CPU_EN signal to the MCLK domain
+//----------------------------------------------
+`ifdef SYNC_CPU_EN
+ omsp_sync_cell sync_cell_cpu_en (
+ .data_out (cpu_en_s),
+ .data_in (cpu_en),
+ .clk (nodiv_mclk),
+ .rst (por)
+ );
+ omsp_and_gate and_cpu_en_wkup (.y(cpu_en_wkup), .a(cpu_en), .b(~cpu_en_s));
+`else
+ assign cpu_en_s = cpu_en;
+ assign cpu_en_wkup = 1'b0;
+`endif
+
+// Synchronize CPU_EN signal to the ACLK domain
+//----------------------------------------------
+`ifdef LFXT_DOMAIN
+ wire cpu_en_aux_s;
+ omsp_sync_cell sync_cell_cpu_aux_en (
+ .data_out (cpu_en_aux_s),
+ .data_in (cpu_en),
+ .clk (lfxt_clk),
+ .rst (por)
+ );
+`else
+ wire cpu_en_aux_s = cpu_en_s;
+`endif
+
+// Synchronize CPU_EN signal to the SMCLK domain
+//----------------------------------------------
+// Note: the synchronizer is only required if there is a SMCLK_MUX
+`ifdef ASIC
+ `ifdef SMCLK_MUX
+ wire cpu_en_sm_s;
+ omsp_sync_cell sync_cell_cpu_sm_en (
+ .data_out (cpu_en_sm_s),
+ .data_in (cpu_en),
+ .clk (nodiv_smclk),
+ .rst (por)
+ );
+ `else
+ wire cpu_en_sm_s = cpu_en_s;
+ `endif
+`endif
+
+
+//-----------------------------------------------------------
+// 6.2) MCLK GENERATION
+//-----------------------------------------------------------
+
+// Clock MUX
+//----------------------------
+`ifdef MCLK_MUX
+omsp_clock_mux clock_mux_mclk (
+ .clk_out (nodiv_mclk),
+ .clk_in0 (dco_clk),
+ .clk_in1 (lfxt_clk),
+ .reset (por),
+ .scan_mode (scan_mode),
+ .select (bcsctl2[`SELMx])
+);
+`else
+assign nodiv_mclk = dco_clk;
+`endif
+assign nodiv_mclk_n = ~nodiv_mclk;
+
+
+// Wakeup synchronizer
+//----------------------------
+wire mclk_wkup_s;
+
+`ifdef CPUOFF_EN
+omsp_sync_cell sync_cell_mclk_wkup (
+ .data_out (mclk_wkup_s),
+ .data_in (mclk_wkup),
+ .clk (nodiv_mclk),
+ .rst (puc_rst)
+);
+`else
+ assign mclk_wkup_s = 1'b0;
+`endif
+
+
+// Clock Divider
+//----------------------------
+// No need for extra synchronizer as bcsctl2
+// comes from the same clock domain.
+
+`ifdef CPUOFF_EN
+wire mclk_active = mclk_enable | mclk_wkup_s | (dbg_en_s & cpu_en_s);
+`else
+wire mclk_active = 1'b1;
+`endif
+
+`ifdef MCLK_DIVIDER
+reg [2:0] mclk_div;
+always @ (posedge nodiv_mclk or posedge puc_rst)
+ if (puc_rst) mclk_div <= 3'h0;
+ else if ((bcsctl2[`DIVMx]!=2'b00)) mclk_div <= mclk_div+3'h1;
+
+ wire mclk_div_en = mclk_active & ((bcsctl2[`DIVMx]==2'b00) ? 1'b1 :
+ (bcsctl2[`DIVMx]==2'b01) ? mclk_div[0] :
+ (bcsctl2[`DIVMx]==2'b10) ? &mclk_div[1:0] :
+ &mclk_div[2:0]);
+`else
+ wire mclk_div_en = mclk_active;
+`endif
+
+
+// Generate main system clock
+//----------------------------
+`ifdef MCLK_CGATE
+
+omsp_clock_gate clock_gate_mclk (
+ .gclk (mclk),
+ .clk (nodiv_mclk),
+ .enable (mclk_div_en),
+ .scan_enable (scan_enable)
+);
+`else
+ assign mclk = nodiv_mclk;
+`endif
+
+
+//-----------------------------------------------------------
+// 6.3) ACLK GENERATION
+//-----------------------------------------------------------
+
+// ASIC MODE
+//----------------------------
+`ifdef ASIC
+
+ `ifdef ACLK_DIVIDER
+ `ifdef LFXT_DOMAIN
+
+ wire nodiv_aclk = lfxt_clk;
+
+ // Local Reset synchronizer
+ wire puc_lfxt_rst;
+ wire puc_lfxt_noscan_n;
+ omsp_sync_cell sync_cell_puc_lfxt (
+ .data_out (puc_lfxt_noscan_n),
+ .data_in (1'b1),
+ .clk (nodiv_aclk),
+ .rst (puc_rst)
+ );
+ omsp_scan_mux scan_mux_puc_lfxt (
+ .scan_mode (scan_mode),
+ .data_in_scan (por_a),
+ .data_in_func (~puc_lfxt_noscan_n),
+ .data_out (puc_lfxt_rst)
+ );
+
+ // Local synchronizer for the bcsctl1.DIVAx configuration
+ // (note that we can live with a full bus synchronizer as
+ // it won't hurt if we get a wrong DIVAx value for a single clock cycle)
+ reg [1:0] divax_s;
+ reg [1:0] divax_ss;
+ always @ (posedge nodiv_aclk or posedge puc_lfxt_rst)
+ if (puc_lfxt_rst)
+ begin
+ divax_s <= 2'h0;
+ divax_ss <= 2'h0;
+ end
+ else
+ begin
+ divax_s <= bcsctl1[`DIVAx];
+ divax_ss <= divax_s;
+ end
+
+ // If the OSCOFF mode is enabled synchronize OSCOFF signal
+ wire oscoff_s;
+ `ifdef OSCOFF_EN
+ omsp_sync_cell sync_cell_oscoff (
+ .data_out (oscoff_s),
+ .data_in (oscoff),
+ .clk (nodiv_aclk),
+ .rst (puc_lfxt_rst)
+ );
+ `else
+ assign oscoff_s = 1'b0;
+ `endif
+ `else
+ wire puc_lfxt_rst = puc_rst;
+ wire nodiv_aclk = dco_clk;
+ wire [1:0] divax_ss = bcsctl1[`DIVAx];
+ wire oscoff_s = oscoff;
+ `endif
+
+ // Divider
+ reg [2:0] aclk_div;
+ always @ (posedge nodiv_aclk or posedge puc_lfxt_rst)
+ if (puc_lfxt_rst) aclk_div <= 3'h0;
+ else if ((divax_ss!=2'b00)) aclk_div <= aclk_div+3'h1;
+
+ wire aclk_div_en = cpu_en_aux_s & ~oscoff_s & ((divax_ss==2'b00) ? 1'b1 :
+ (divax_ss==2'b01) ? aclk_div[0] :
+ (divax_ss==2'b10) ? &aclk_div[1:0] :
+ &aclk_div[2:0]);
+
+ // Clock gate
+ omsp_clock_gate clock_gate_aclk (
+ .gclk (aclk),
+ .clk (nodiv_aclk),
+ .enable (aclk_div_en),
+ .scan_enable (scan_enable)
+ );
+
+ `else
+ `ifdef LFXT_DOMAIN
+ assign aclk = lfxt_clk;
+ `else
+ assign aclk = dco_clk;
+ `endif
+ `endif
+
+
+ assign aclk_en = 1'b1;
+
+
+// FPGA MODE
+//----------------------------
+`else
+ reg aclk_en;
+ reg [2:0] aclk_div;
+ wire aclk_en_nxt = lfxt_clk_en & ((bcsctl1[`DIVAx]==2'b00) ? 1'b1 :
+ (bcsctl1[`DIVAx]==2'b01) ? aclk_div[0] :
+ (bcsctl1[`DIVAx]==2'b10) ? &aclk_div[1:0] :
+ &aclk_div[2:0]);
+
+ always @ (posedge mclk or posedge puc_rst)
+ if (puc_rst) aclk_div <= 3'h0;
+ else if ((bcsctl1[`DIVAx]!=2'b00) & lfxt_clk_en) aclk_div <= aclk_div+3'h1;
+
+ always @ (posedge mclk or posedge puc_rst)
+ if (puc_rst) aclk_en <= 1'b0;
+ else aclk_en <= aclk_en_nxt & cpu_en_s;
+
+ assign aclk = mclk;
+`endif
+
+//-----------------------------------------------------------
+// 6.4) SMCLK GENERATION
+//-----------------------------------------------------------
+
+// Clock MUX
+//----------------------------
+`ifdef SMCLK_MUX
+omsp_clock_mux clock_mux_smclk (
+ .clk_out (nodiv_smclk),
+ .clk_in0 (dco_clk),
+ .clk_in1 (lfxt_clk),
+ .reset (por),
+ .scan_mode (scan_mode),
+ .select (bcsctl2[`SELS])
+);
+`else
+assign nodiv_smclk = dco_clk;
+`endif
+
+
+// ASIC MODE
+//----------------------------
+`ifdef ASIC
+ `ifdef SMCLK_MUX
+
+ // Synchronizers
+ //------------------------------------------------------
+ // When the SMCLK MUX is enabled, the reset and DIVSx
+ // and SCG1 signals must be synchronized, otherwise not.
+
+ // Local Reset synchronizer
+ wire puc_sm_noscan_n;
+ wire puc_sm_rst;
+ omsp_sync_cell sync_cell_puc_sm (
+ .data_out (puc_sm_noscan_n),
+ .data_in (1'b1),
+ .clk (nodiv_smclk),
+ .rst (puc_rst)
+ );
+ omsp_scan_mux scan_mux_puc_sm (
+ .scan_mode (scan_mode),
+ .data_in_scan (por_a),
+ .data_in_func (~puc_sm_noscan_n),
+ .data_out (puc_sm_rst)
+ );
+
+ // SCG1 synchronizer
+ `ifdef SCG1_EN
+ wire scg1_s;
+ omsp_sync_cell sync_cell_scg1 (
+ .data_out (scg1_s),
+ .data_in (scg1),
+ .clk (nodiv_smclk),
+ .rst (puc_sm_rst)
+ );
+ `else
+ wire scg1_s = 1'b0;
+ `endif
+
+ `ifdef SMCLK_DIVIDER
+ // Local synchronizer for the bcsctl2.DIVSx configuration
+ // (note that we can live with a full bus synchronizer as
+ // it won't hurt if we get a wrong DIVSx value for a single clock cycle)
+ reg [1:0] divsx_s;
+ reg [1:0] divsx_ss;
+ always @ (posedge nodiv_smclk or posedge puc_sm_rst)
+ if (puc_sm_rst)
+ begin
+ divsx_s <= 2'h0;
+ divsx_ss <= 2'h0;
+ end
+ else
+ begin
+ divsx_s <= bcsctl2[`DIVSx];
+ divsx_ss <= divsx_s;
+ end
+ `endif
+
+ `else
+
+ wire puc_sm_rst = puc_rst;
+ wire [1:0] divsx_ss = bcsctl2[`DIVSx];
+ wire scg1_s = scg1;
+ `endif
+
+
+
+ // Clock Divider
+ //----------------------------
+ `ifdef SMCLK_DIVIDER
+
+ reg [2:0] smclk_div;
+ always @ (posedge nodiv_smclk or posedge puc_sm_rst)
+ if (puc_sm_rst) smclk_div <= 3'h0;
+ else if ((divsx_ss!=2'b00)) smclk_div <= smclk_div+3'h1;
+
+ wire smclk_div_en = cpu_en_sm_s & ~scg1_s & ((divsx_ss==2'b00) ? 1'b1 :
+ (divsx_ss==2'b01) ? smclk_div[0] :
+ (divsx_ss==2'b10) ? &smclk_div[1:0] :
+ &smclk_div[2:0]);
+ `else
+ `ifdef SCG1_EN
+ wire smclk_div_en = cpu_en_sm_s & ~scg1_s;
+ `else
+ wire smclk_div_en = cpu_en_sm_s;
+ `endif
+ `endif
+
+
+ // Generate sub-system clock
+ //----------------------------
+ `ifdef SMCLK_CGATE
+ omsp_clock_gate clock_gate_smclk (
+ .gclk (smclk),
+ .clk (nodiv_smclk),
+ .enable (smclk_div_en),
+ .scan_enable (scan_enable)
+ );
+ `else
+ assign smclk = nodiv_smclk;
+ `endif
+
+ assign smclk_en = 1'b1;
+
+
+// FPGA MODE
+//----------------------------
+`else
+reg smclk_en;
+reg [2:0] smclk_div;
+
+wire smclk_in = ~scg1 & (bcsctl2[`SELS] ? lfxt_clk_en : 1'b1);
+
+wire smclk_en_nxt = smclk_in & ((bcsctl2[`DIVSx]==2'b00) ? 1'b1 :
+ (bcsctl2[`DIVSx]==2'b01) ? smclk_div[0] :
+ (bcsctl2[`DIVSx]==2'b10) ? &smclk_div[1:0] :
+ &smclk_div[2:0]);
+
+always @ (posedge mclk or posedge puc_rst)
+ if (puc_rst) smclk_en <= 1'b0;
+ else smclk_en <= smclk_en_nxt & cpu_en_s;
+
+always @ (posedge mclk or posedge puc_rst)
+ if (puc_rst) smclk_div <= 3'h0;
+ else if ((bcsctl2[`DIVSx]!=2'b00) & smclk_in) smclk_div <= smclk_div+3'h1;
+
+wire smclk = mclk;
+
+`endif
+
+//-----------------------------------------------------------
+// 6.5) DEBUG INTERFACE CLOCK GENERATION (DBG_CLK)
+//-----------------------------------------------------------
+
+// Synchronize DBG_EN signal to MCLK domain
+//------------------------------------------
+`ifdef DBG_EN
+`ifdef SYNC_DBG_EN
+ wire dbg_en_n_s;
+ omsp_sync_cell sync_cell_dbg_en (
+ .data_out (dbg_en_n_s),
+ .data_in (~dbg_en),
+ .clk (mclk),
+ .rst (por)
+ );
+ assign dbg_en_s = ~dbg_en_n_s;
+ wire dbg_rst_nxt = dbg_en_n_s;
+`else
+ assign dbg_en_s = dbg_en;
+ wire dbg_rst_nxt = ~dbg_en;
+`endif
+`else
+ assign dbg_en_s = 1'b0;
+ wire dbg_rst_nxt = 1'b0;
+`endif
+
+
+// Serial Debug Interface Clock gate
+//------------------------------------------------
+`ifdef DBG_EN
+ `ifdef ASIC
+ omsp_clock_gate clock_gate_dbg_clk (
+ .gclk (dbg_clk),
+ .clk (mclk),
+ .enable (dbg_en_s),
+ .scan_enable (scan_enable)
+ );
+ `else
+ assign dbg_clk = dco_clk;
+ `endif
+`else
+ assign dbg_clk = 1'b0;
+`endif
+
+
+//=============================================================================
+// 7) RESET GENERATION
+//=============================================================================
+//
+// Whenever the reset pin (reset_n) is deasserted, the internal resets of the
+// openMSP430 will be released in the following order:
+// 1- POR
+// 2- DBG_RST (if the sdi interface is enabled, i.e. dbg_en=1)
+// 3- PUC
+//
+// Note: releasing the DBG_RST before PUC is particularly important in order
+// to allow the sdi interface to halt the cpu immediately after a PUC.
+//
+
+// Generate synchronized POR to MCLK domain
+//------------------------------------------
+
+// Asynchronous reset source
+assign por_a = !reset_n;
+wire por_noscan;
+
+// Reset Synchronizer
+omsp_sync_reset sync_reset_por (
+ .rst_s (por_noscan),
+ .clk (nodiv_mclk),
+ .rst_a (por_a)
+);
+
+// Scan Reset Mux
+`ifdef ASIC
+omsp_scan_mux scan_mux_por (
+ .scan_mode (scan_mode),
+ .data_in_scan (por_a),
+ .data_in_func (por_noscan),
+ .data_out (por)
+);
+`else
+ assign por = por_noscan;
+`endif
+
+// Generate synchronized reset for the SDI
+//------------------------------------------
+`ifdef DBG_EN
+
+// Reset Generation
+reg dbg_rst_noscan;
+always @ (posedge mclk or posedge por)
+ if (por) dbg_rst_noscan <= 1'b1;
+ else dbg_rst_noscan <= dbg_rst_nxt;
+
+ // Scan Reset Mux
+ `ifdef ASIC
+ omsp_scan_mux scan_mux_dbg_rst (
+ .scan_mode (scan_mode),
+ .data_in_scan (por_a),
+ .data_in_func (dbg_rst_noscan),
+ .data_out (dbg_rst)
+ );
+ `else
+ assign dbg_rst = dbg_rst_noscan;
+ `endif
+
+`else
+ wire dbg_rst_noscan = 1'b1;
+ assign dbg_rst = 1'b1;
+`endif
+
+
+// Generate main system reset (PUC_RST)
+//--------------------------------------
+wire puc_noscan_n;
+wire puc_a_scan;
+
+// Asynchronous PUC reset
+wire puc_a = por | wdt_reset;
+
+// Synchronous PUC reset
+wire puc_s = dbg_cpu_reset | // With the debug interface command
+
+ (dbg_en_s & dbg_rst_noscan & ~puc_noscan_n); // Sequencing making sure PUC is released
+ // after DBG_RST if the debug interface is
+ // enabled at power-on-reset time
+// Scan Reset Mux
+`ifdef ASIC
+omsp_scan_mux scan_mux_puc_rst_a (
+ .scan_mode (scan_mode),
+ .data_in_scan (por_a),
+ .data_in_func (puc_a),
+ .data_out (puc_a_scan)
+);
+`else
+ assign puc_a_scan = puc_a;
+`endif
+
+// Reset Synchronizer
+// (required because of the asynchronous watchdog reset)
+omsp_sync_cell sync_cell_puc (
+ .data_out (puc_noscan_n),
+ .data_in (~puc_s),
+ .clk (mclk),
+ .rst (puc_a_scan)
+);
+
+// Scan Reset Mux
+`ifdef ASIC
+omsp_scan_mux scan_mux_puc_rst (
+ .scan_mode (scan_mode),
+ .data_in_scan (por_a),
+ .data_in_func (~puc_noscan_n),
+ .data_out (puc_rst)
+);
+`else
+ assign puc_rst = ~puc_noscan_n;
+`endif
+
+// PUC pending set the serial debug interface
+assign puc_pnd_set = ~puc_noscan_n;
+
+
+endmodule // omsp_clock_module
+
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_undefines.v"
+`endif
diff --git a/tests/openmsp430/rtl/omsp_clock_mux.v b/tests/openmsp430/rtl/omsp_clock_mux.v
new file mode 100644
index 000000000..5f8406ad0
--- /dev/null
+++ b/tests/openmsp430/rtl/omsp_clock_mux.v
@@ -0,0 +1,192 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2009 , Olivier Girard
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the authors nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE
+//
+//----------------------------------------------------------------------------
+//
+// *File Name: omsp_clock_mux.v
+//
+// *Module Description:
+// Standard clock mux for the openMSP430
+//
+// *Author(s):
+// - Olivier Girard, olgirard@gmail.com
+//
+//----------------------------------------------------------------------------
+// $Rev: 103 $
+// $LastChangedBy: olivier.girard $
+// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
+//----------------------------------------------------------------------------
+
+module omsp_clock_mux (
+
+// OUTPUTs
+ clk_out, // Clock output
+
+// INPUTs
+ clk_in0, // Clock input 0
+ clk_in1, // Clock input 1
+ reset, // Reset
+ scan_mode, // Scan mode (clk_in0 is selected in scan mode)
+ select // Clock selection
+);
+
+// OUTPUTs
+//=========
+output clk_out; // Clock output
+
+// INPUTs
+//=========
+input clk_in0; // Clock input 0
+input clk_in1; // Clock input 1
+input reset; // Reset
+input scan_mode; // Scan mode (clk_in0 is selected in scan mode)
+input select; // Clock selection
+
+
+//===========================================================================================================================//
+// 1) CLOCK MUX //
+//===========================================================================================================================//
+// //
+// The following (glitch free) clock mux is implemented as following: //
+// //
+// //
+// //
+// //
+// +-----. +--------+ +--------+ //
+// select >>----+-------------O| \ | | | | +-----. //
+// | | |---| D Q |---| D Q |--+-------| \ //
+// | +-------O| / | | | | | | |O-+ //
+// | | +-----' | | | | | +--O| / | //
+// | | | /\ | | /\ | | | +-----' | //
+// | | +--+--+--+ +--+--+--+ | | | //
+// | | O | | | | //
+// | | | | | | | +-----. //
+// clk_in0 >>----------------------------------+------------+-----------+ +--| \ //
+// | | | | |----<< clk_out //
+// | | +---------------------------------------+ +--| / //
+// | | | | +-----' //
+// | +---------------------------------------------+ | //
+// | | | | //
+// | | +-----. +--------+ +--------+ | | //
+// | +-O| \ | | | | | +-----. | //
+// | | |---| D Q |---| D Q |--+-------| \ | //
+// +--------------| / | | | | | |O-+ //
+// +-----' | | | | +--O| / //
+// | /\ | | /\ | | +-----' //
+// +--+--+--+ +--+--+--+ | //
+// O | | //
+// | | | //
+// clk_in1 >>----------------------------------+------------+-----------+ //
+// //
+// //
+//===========================================================================================================================//
+
+//-----------------------------------------------------------------------------
+// Wire declarations
+//-----------------------------------------------------------------------------
+
+wire in0_select;
+reg in0_select_s;
+reg in0_select_ss;
+wire in0_enable;
+
+wire in1_select;
+reg in1_select_s;
+reg in1_select_ss;
+wire in1_enable;
+
+wire clk_in0_inv;
+wire clk_in1_inv;
+wire gated_clk_in0;
+wire gated_clk_in1;
+
+
+//-----------------------------------------------------------------------------
+// CLK_IN0 Selection
+//-----------------------------------------------------------------------------
+
+assign in0_select = ~select & ~in1_select_ss;
+
+always @ (posedge clk_in0_inv or posedge reset)
+ if (reset) in0_select_s <= 1'b1;
+ else in0_select_s <= in0_select;
+
+always @ (posedge clk_in0 or posedge reset)
+ if (reset) in0_select_ss <= 1'b1;
+ else in0_select_ss <= in0_select_s;
+
+assign in0_enable = in0_select_ss | scan_mode;
+
+
+//-----------------------------------------------------------------------------
+// CLK_IN1 Selection
+//-----------------------------------------------------------------------------
+
+assign in1_select = select & ~in0_select_ss;
+
+always @ (posedge clk_in1_inv or posedge reset)
+ if (reset) in1_select_s <= 1'b0;
+ else in1_select_s <= in1_select;
+
+always @ (posedge clk_in1 or posedge reset)
+ if (reset) in1_select_ss <= 1'b0;
+ else in1_select_ss <= in1_select_s;
+
+assign in1_enable = in1_select_ss & ~scan_mode;
+
+
+//-----------------------------------------------------------------------------
+// Clock MUX
+//-----------------------------------------------------------------------------
+//
+// IMPORTANT NOTE:
+// Because the clock network is a critical part of the design,
+// the following combinatorial logic should be replaced with
+// direct instanciation of standard cells from target library.
+// Don't forget the "dont_touch" attribute to make sure
+// synthesis won't mess it up.
+//
+
+// Replace with standard cell INVERTER
+assign clk_in0_inv = ~clk_in0;
+assign clk_in1_inv = ~clk_in1;
+
+
+// Replace with standard cell NAND2
+assign gated_clk_in0 = ~(clk_in0_inv & in0_enable);
+assign gated_clk_in1 = ~(clk_in1_inv & in1_enable);
+
+
+// Replace with standard cell AND2
+assign clk_out = (gated_clk_in0 & gated_clk_in1);
+
+
+
+endmodule // omsp_clock_gate
+
+
+
diff --git a/tests/openmsp430/rtl/omsp_dbg.v b/tests/openmsp430/rtl/omsp_dbg.v
new file mode 100644
index 000000000..97e9ede44
--- /dev/null
+++ b/tests/openmsp430/rtl/omsp_dbg.v
@@ -0,0 +1,827 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2009 , Olivier Girard
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the authors nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE
+//
+//----------------------------------------------------------------------------
+//
+// *File Name: omsp_dbg.v
+//
+// *Module Description:
+// Debug interface
+//
+// *Author(s):
+// - Olivier Girard, olgirard@gmail.com
+//
+//----------------------------------------------------------------------------
+// $Rev: 149 $
+// $LastChangedBy: olivier.girard $
+// $LastChangedDate: 2012-07-19 22:21:12 +0200 (Thu, 19 Jul 2012) $
+//----------------------------------------------------------------------------
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_defines.v"
+`endif
+
+module omsp_dbg (
+
+// OUTPUTs
+ dbg_freeze, // Freeze peripherals
+ dbg_halt_cmd, // Halt CPU command
+ dbg_mem_addr, // Debug address for rd/wr access
+ dbg_mem_dout, // Debug unit data output
+ dbg_mem_en, // Debug unit memory enable
+ dbg_mem_wr, // Debug unit memory write
+ dbg_reg_wr, // Debug unit CPU register write
+ dbg_cpu_reset, // Reset CPU from debug interface
+ dbg_uart_txd, // Debug interface: UART TXD
+
+// INPUTs
+ cpu_en_s, // Enable CPU code execution (synchronous)
+ cpu_id, // CPU ID
+ dbg_clk, // Debug unit clock
+ dbg_en_s, // Debug interface enable (synchronous)
+ dbg_halt_st, // Halt/Run status from CPU
+ dbg_mem_din, // Debug unit Memory data input
+ dbg_reg_din, // Debug unit CPU register data input
+ dbg_rst, // Debug unit reset
+ dbg_uart_rxd, // Debug interface: UART RXD (asynchronous)
+ decode_noirq, // Frontend decode instruction
+ eu_mab, // Execution-Unit Memory address bus
+ eu_mb_en, // Execution-Unit Memory bus enable
+ eu_mb_wr, // Execution-Unit Memory bus write transfer
+ eu_mdb_in, // Memory data bus input
+ eu_mdb_out, // Memory data bus output
+ exec_done, // Execution completed
+ fe_mb_en, // Frontend Memory bus enable
+ fe_mdb_in, // Frontend Memory data bus input
+ pc, // Program counter
+ puc_pnd_set // PUC pending set for the serial debug interface
+);
+
+// OUTPUTs
+//=========
+output dbg_freeze; // Freeze peripherals
+output dbg_halt_cmd; // Halt CPU command
+output [15:0] dbg_mem_addr; // Debug address for rd/wr access
+output [15:0] dbg_mem_dout; // Debug unit data output
+output dbg_mem_en; // Debug unit memory enable
+output [1:0] dbg_mem_wr; // Debug unit memory write
+output dbg_reg_wr; // Debug unit CPU register write
+output dbg_cpu_reset; // Reset CPU from debug interface
+output dbg_uart_txd; // Debug interface: UART TXD
+
+// INPUTs
+//=========
+input cpu_en_s; // Enable CPU code execution (synchronous)
+input [31:0] cpu_id; // CPU ID
+input dbg_clk; // Debug unit clock
+input dbg_en_s; // Debug interface enable (synchronous)
+input dbg_halt_st; // Halt/Run status from CPU
+input [15:0] dbg_mem_din; // Debug unit Memory data input
+input [15:0] dbg_reg_din; // Debug unit CPU register data input
+input dbg_rst; // Debug unit reset
+input dbg_uart_rxd; // Debug interface: UART RXD (asynchronous)
+input decode_noirq; // Frontend decode instruction
+input [15:0] eu_mab; // Execution-Unit Memory address bus
+input eu_mb_en; // Execution-Unit Memory bus enable
+input [1:0] eu_mb_wr; // Execution-Unit Memory bus write transfer
+input [15:0] eu_mdb_in; // Memory data bus input
+input [15:0] eu_mdb_out; // Memory data bus output
+input exec_done; // Execution completed
+input fe_mb_en; // Frontend Memory bus enable
+input [15:0] fe_mdb_in; // Frontend Memory data bus input
+input [15:0] pc; // Program counter
+input puc_pnd_set; // PUC pending set for the serial debug interface
+
+
+//=============================================================================
+// 1) WIRE & PARAMETER DECLARATION
+//=============================================================================
+
+// Diverse wires and registers
+wire [5:0] dbg_addr;
+wire [15:0] dbg_din;
+wire dbg_wr;
+reg mem_burst;
+wire dbg_reg_rd;
+wire dbg_mem_rd;
+reg dbg_mem_rd_dly;
+wire dbg_swbrk;
+wire dbg_rd;
+reg dbg_rd_rdy;
+wire mem_burst_rd;
+wire mem_burst_wr;
+wire brk0_halt;
+wire brk0_pnd;
+wire [15:0] brk0_dout;
+wire brk1_halt;
+wire brk1_pnd;
+wire [15:0] brk1_dout;
+wire brk2_halt;
+wire brk2_pnd;
+wire [15:0] brk2_dout;
+wire brk3_halt;
+wire brk3_pnd;
+wire [15:0] brk3_dout;
+
+// Number of registers
+parameter NR_REG = 24;
+
+// Register addresses
+parameter CPU_ID_LO = 6'h00;
+parameter CPU_ID_HI = 6'h01;
+parameter CPU_CTL = 6'h02;
+parameter CPU_STAT = 6'h03;
+parameter MEM_CTL = 6'h04;
+parameter MEM_ADDR = 6'h05;
+parameter MEM_DATA = 6'h06;
+parameter MEM_CNT = 6'h07;
+`ifdef DBG_HWBRK_0
+parameter BRK0_CTL = 6'h08;
+parameter BRK0_STAT = 6'h09;
+parameter BRK0_ADDR0 = 6'h0A;
+parameter BRK0_ADDR1 = 6'h0B;
+`endif
+`ifdef DBG_HWBRK_1
+parameter BRK1_CTL = 6'h0C;
+parameter BRK1_STAT = 6'h0D;
+parameter BRK1_ADDR0 = 6'h0E;
+parameter BRK1_ADDR1 = 6'h0F;
+`endif
+`ifdef DBG_HWBRK_2
+parameter BRK2_CTL = 6'h10;
+parameter BRK2_STAT = 6'h11;
+parameter BRK2_ADDR0 = 6'h12;
+parameter BRK2_ADDR1 = 6'h13;
+`endif
+`ifdef DBG_HWBRK_3
+parameter BRK3_CTL = 6'h14;
+parameter BRK3_STAT = 6'h15;
+parameter BRK3_ADDR0 = 6'h16;
+parameter BRK3_ADDR1 = 6'h17;
+`endif
+
+// Register one-hot decoder
+parameter BASE_D = {{NR_REG-1{1'b0}}, 1'b1};
+parameter CPU_ID_LO_D = (BASE_D << CPU_ID_LO);
+parameter CPU_ID_HI_D = (BASE_D << CPU_ID_HI);
+parameter CPU_CTL_D = (BASE_D << CPU_CTL);
+parameter CPU_STAT_D = (BASE_D << CPU_STAT);
+parameter MEM_CTL_D = (BASE_D << MEM_CTL);
+parameter MEM_ADDR_D = (BASE_D << MEM_ADDR);
+parameter MEM_DATA_D = (BASE_D << MEM_DATA);
+parameter MEM_CNT_D = (BASE_D << MEM_CNT);
+`ifdef DBG_HWBRK_0
+parameter BRK0_CTL_D = (BASE_D << BRK0_CTL);
+parameter BRK0_STAT_D = (BASE_D << BRK0_STAT);
+parameter BRK0_ADDR0_D = (BASE_D << BRK0_ADDR0);
+parameter BRK0_ADDR1_D = (BASE_D << BRK0_ADDR1);
+`endif
+`ifdef DBG_HWBRK_1
+parameter BRK1_CTL_D = (BASE_D << BRK1_CTL);
+parameter BRK1_STAT_D = (BASE_D << BRK1_STAT);
+parameter BRK1_ADDR0_D = (BASE_D << BRK1_ADDR0);
+parameter BRK1_ADDR1_D = (BASE_D << BRK1_ADDR1);
+`endif
+`ifdef DBG_HWBRK_2
+parameter BRK2_CTL_D = (BASE_D << BRK2_CTL);
+parameter BRK2_STAT_D = (BASE_D << BRK2_STAT);
+parameter BRK2_ADDR0_D = (BASE_D << BRK2_ADDR0);
+parameter BRK2_ADDR1_D = (BASE_D << BRK2_ADDR1);
+`endif
+`ifdef DBG_HWBRK_3
+parameter BRK3_CTL_D = (BASE_D << BRK3_CTL);
+parameter BRK3_STAT_D = (BASE_D << BRK3_STAT);
+parameter BRK3_ADDR0_D = (BASE_D << BRK3_ADDR0);
+parameter BRK3_ADDR1_D = (BASE_D << BRK3_ADDR1);
+`endif
+
+
+//============================================================================
+// 2) REGISTER DECODER
+//============================================================================
+
+// Select Data register during a burst
+wire [5:0] dbg_addr_in = mem_burst ? MEM_DATA : dbg_addr;
+
+// Register address decode
+reg [NR_REG-1:0] reg_dec;
+always @(dbg_addr_in)
+ case (dbg_addr_in)
+ CPU_ID_LO : reg_dec = CPU_ID_LO_D;
+ CPU_ID_HI : reg_dec = CPU_ID_HI_D;
+ CPU_CTL : reg_dec = CPU_CTL_D;
+ CPU_STAT : reg_dec = CPU_STAT_D;
+ MEM_CTL : reg_dec = MEM_CTL_D;
+ MEM_ADDR : reg_dec = MEM_ADDR_D;
+ MEM_DATA : reg_dec = MEM_DATA_D;
+ MEM_CNT : reg_dec = MEM_CNT_D;
+`ifdef DBG_HWBRK_0
+ BRK0_CTL : reg_dec = BRK0_CTL_D;
+ BRK0_STAT : reg_dec = BRK0_STAT_D;
+ BRK0_ADDR0: reg_dec = BRK0_ADDR0_D;
+ BRK0_ADDR1: reg_dec = BRK0_ADDR1_D;
+`endif
+`ifdef DBG_HWBRK_1
+ BRK1_CTL : reg_dec = BRK1_CTL_D;
+ BRK1_STAT : reg_dec = BRK1_STAT_D;
+ BRK1_ADDR0: reg_dec = BRK1_ADDR0_D;
+ BRK1_ADDR1: reg_dec = BRK1_ADDR1_D;
+`endif
+`ifdef DBG_HWBRK_2
+ BRK2_CTL : reg_dec = BRK2_CTL_D;
+ BRK2_STAT : reg_dec = BRK2_STAT_D;
+ BRK2_ADDR0: reg_dec = BRK2_ADDR0_D;
+ BRK2_ADDR1: reg_dec = BRK2_ADDR1_D;
+`endif
+`ifdef DBG_HWBRK_3
+ BRK3_CTL : reg_dec = BRK3_CTL_D;
+ BRK3_STAT : reg_dec = BRK3_STAT_D;
+ BRK3_ADDR0: reg_dec = BRK3_ADDR0_D;
+ BRK3_ADDR1: reg_dec = BRK3_ADDR1_D;
+`endif
+ // pragma coverage off
+ default: reg_dec = {NR_REG{1'b0}};
+ // pragma coverage on
+ endcase
+
+// Read/Write probes
+wire reg_write = dbg_wr;
+wire reg_read = 1'b1;
+
+// Read/Write vectors
+wire [NR_REG-1:0] reg_wr = reg_dec & {NR_REG{reg_write}};
+wire [NR_REG-1:0] reg_rd = reg_dec & {NR_REG{reg_read}};
+
+
+//=============================================================================
+// 3) REGISTER: CORE INTERFACE
+//=============================================================================
+
+// CPU_ID Register
+//-----------------
+// -------------------------------------------------------------------
+// CPU_ID_LO: | 15 14 13 12 11 10 9 | 8 7 6 5 4 | 3 | 2 1 0 |
+// |----------------------------+-----------------+------+-------------|
+// | PER_SPACE | USER_VERSION | ASIC | CPU_VERSION |
+// --------------------------------------------------------------------
+// CPU_ID_HI: | 15 14 13 12 11 10 | 9 8 7 6 5 4 3 2 1 | 0 |
+// |----------------------------+-------------------------------+------|
+// | PMEM_SIZE | DMEM_SIZE | MPY |
+// -------------------------------------------------------------------
+
+// This register is assigned in the SFR module
+
+
+// CPU_CTL Register
+//-----------------------------------------------------------------------------
+// 7 6 5 4 3 2 1 0
+// Reserved CPU_RST RST_BRK_EN FRZ_BRK_EN SW_BRK_EN ISTEP RUN HALT
+//-----------------------------------------------------------------------------
+reg [6:3] cpu_ctl;
+
+wire cpu_ctl_wr = reg_wr[CPU_CTL];
+
+always @ (posedge dbg_clk or posedge dbg_rst)
+`ifdef DBG_RST_BRK_EN
+ if (dbg_rst) cpu_ctl <= 4'h6;
+`else
+ if (dbg_rst) cpu_ctl <= 4'h2;
+`endif
+ else if (cpu_ctl_wr) cpu_ctl <= dbg_din[6:3];
+
+wire [7:0] cpu_ctl_full = {1'b0, cpu_ctl, 3'b000};
+
+wire halt_cpu = cpu_ctl_wr & dbg_din[`HALT] & ~dbg_halt_st;
+wire run_cpu = cpu_ctl_wr & dbg_din[`RUN] & dbg_halt_st;
+wire istep = cpu_ctl_wr & dbg_din[`ISTEP] & dbg_halt_st;
+
+
+// CPU_STAT Register
+//------------------------------------------------------------------------------------
+// 7 6 5 4 3 2 1 0
+// HWBRK3_PND HWBRK2_PND HWBRK1_PND HWBRK0_PND SWBRK_PND PUC_PND Res. HALT_RUN
+//------------------------------------------------------------------------------------
+reg [3:2] cpu_stat;
+
+wire cpu_stat_wr = reg_wr[CPU_STAT];
+wire [3:2] cpu_stat_set = {dbg_swbrk, puc_pnd_set};
+wire [3:2] cpu_stat_clr = ~dbg_din[3:2];
+
+always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) cpu_stat <= 2'b00;
+ else if (cpu_stat_wr) cpu_stat <= ((cpu_stat & cpu_stat_clr) | cpu_stat_set);
+ else cpu_stat <= (cpu_stat | cpu_stat_set);
+
+wire [7:0] cpu_stat_full = {brk3_pnd, brk2_pnd, brk1_pnd, brk0_pnd,
+ cpu_stat, 1'b0, dbg_halt_st};
+
+
+//=============================================================================
+// 4) REGISTER: MEMORY INTERFACE
+//=============================================================================
+
+// MEM_CTL Register
+//-----------------------------------------------------------------------------
+// 7 6 5 4 3 2 1 0
+// Reserved B/W MEM/REG RD/WR START
+//
+// START : - 0 : Do nothing.
+// - 1 : Initiate memory transfer.
+//
+// RD/WR : - 0 : Read access.
+// - 1 : Write access.
+//
+// MEM/REG: - 0 : Memory access.
+// - 1 : CPU Register access.
+//
+// B/W : - 0 : 16 bit access.
+// - 1 : 8 bit access (not valid for CPU Registers).
+//
+//-----------------------------------------------------------------------------
+reg [3:1] mem_ctl;
+
+wire mem_ctl_wr = reg_wr[MEM_CTL];
+
+always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) mem_ctl <= 3'h0;
+ else if (mem_ctl_wr) mem_ctl <= dbg_din[3:1];
+
+wire [7:0] mem_ctl_full = {4'b0000, mem_ctl, 1'b0};
+
+reg mem_start;
+always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) mem_start <= 1'b0;
+ else mem_start <= mem_ctl_wr & dbg_din[0];
+
+wire mem_bw = mem_ctl[3];
+
+// MEM_DATA Register
+//------------------
+reg [15:0] mem_data;
+reg [15:0] mem_addr;
+wire mem_access;
+
+wire mem_data_wr = reg_wr[MEM_DATA];
+
+wire [15:0] dbg_mem_din_bw = ~mem_bw ? dbg_mem_din :
+ mem_addr[0] ? {8'h00, dbg_mem_din[15:8]} :
+ {8'h00, dbg_mem_din[7:0]};
+
+always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) mem_data <= 16'h0000;
+ else if (mem_data_wr) mem_data <= dbg_din;
+ else if (dbg_reg_rd) mem_data <= dbg_reg_din;
+ else if (dbg_mem_rd_dly) mem_data <= dbg_mem_din_bw;
+
+
+// MEM_ADDR Register
+//------------------
+reg [15:0] mem_cnt;
+
+wire mem_addr_wr = reg_wr[MEM_ADDR];
+wire dbg_mem_acc = (|dbg_mem_wr | (dbg_rd_rdy & ~mem_ctl[2]));
+wire dbg_reg_acc = ( dbg_reg_wr | (dbg_rd_rdy & mem_ctl[2]));
+
+wire [15:0] mem_addr_inc = (mem_cnt==16'h0000) ? 16'h0000 :
+ (dbg_mem_acc & ~mem_bw) ? 16'h0002 :
+ (dbg_mem_acc | dbg_reg_acc) ? 16'h0001 : 16'h0000;
+
+always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) mem_addr <= 16'h0000;
+ else if (mem_addr_wr) mem_addr <= dbg_din;
+ else mem_addr <= mem_addr + mem_addr_inc;
+
+// MEM_CNT Register
+//------------------
+
+wire mem_cnt_wr = reg_wr[MEM_CNT];
+
+wire [15:0] mem_cnt_dec = (mem_cnt==16'h0000) ? 16'h0000 :
+ (mem_burst & (dbg_mem_acc | dbg_reg_acc)) ? 16'hffff : 16'h0000;
+
+always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) mem_cnt <= 16'h0000;
+ else if (mem_cnt_wr) mem_cnt <= dbg_din;
+ else mem_cnt <= mem_cnt + mem_cnt_dec;
+
+
+//=============================================================================
+// 5) BREAKPOINTS / WATCHPOINTS
+//=============================================================================
+
+`ifdef DBG_HWBRK_0
+// Hardware Breakpoint/Watchpoint Register read select
+wire [3:0] brk0_reg_rd = {reg_rd[BRK0_ADDR1],
+ reg_rd[BRK0_ADDR0],
+ reg_rd[BRK0_STAT],
+ reg_rd[BRK0_CTL]};
+
+// Hardware Breakpoint/Watchpoint Register write select
+wire [3:0] brk0_reg_wr = {reg_wr[BRK0_ADDR1],
+ reg_wr[BRK0_ADDR0],
+ reg_wr[BRK0_STAT],
+ reg_wr[BRK0_CTL]};
+
+omsp_dbg_hwbrk dbg_hwbr_0 (
+
+// OUTPUTs
+ .brk_halt (brk0_halt), // Hardware breakpoint command
+ .brk_pnd (brk0_pnd), // Hardware break/watch-point pending
+ .brk_dout (brk0_dout), // Hardware break/watch-point register data input
+
+// INPUTs
+ .brk_reg_rd (brk0_reg_rd), // Hardware break/watch-point register read select
+ .brk_reg_wr (brk0_reg_wr), // Hardware break/watch-point register write select
+ .dbg_clk (dbg_clk), // Debug unit clock
+ .dbg_din (dbg_din), // Debug register data input
+ .dbg_rst (dbg_rst), // Debug unit reset
+ .eu_mab (eu_mab), // Execution-Unit Memory address bus
+ .eu_mb_en (eu_mb_en), // Execution-Unit Memory bus enable
+ .eu_mb_wr (eu_mb_wr), // Execution-Unit Memory bus write transfer
+ .eu_mdb_in (eu_mdb_in), // Memory data bus input
+ .eu_mdb_out (eu_mdb_out), // Memory data bus output
+ .exec_done (exec_done), // Execution completed
+ .fe_mb_en (fe_mb_en), // Frontend Memory bus enable
+ .pc (pc) // Program counter
+);
+
+`else
+assign brk0_halt = 1'b0;
+assign brk0_pnd = 1'b0;
+assign brk0_dout = 16'h0000;
+`endif
+
+`ifdef DBG_HWBRK_1
+// Hardware Breakpoint/Watchpoint Register read select
+wire [3:0] brk1_reg_rd = {reg_rd[BRK1_ADDR1],
+ reg_rd[BRK1_ADDR0],
+ reg_rd[BRK1_STAT],
+ reg_rd[BRK1_CTL]};
+
+// Hardware Breakpoint/Watchpoint Register write select
+wire [3:0] brk1_reg_wr = {reg_wr[BRK1_ADDR1],
+ reg_wr[BRK1_ADDR0],
+ reg_wr[BRK1_STAT],
+ reg_wr[BRK1_CTL]};
+
+omsp_dbg_hwbrk dbg_hwbr_1 (
+
+// OUTPUTs
+ .brk_halt (brk1_halt), // Hardware breakpoint command
+ .brk_pnd (brk1_pnd), // Hardware break/watch-point pending
+ .brk_dout (brk1_dout), // Hardware break/watch-point register data input
+
+// INPUTs
+ .brk_reg_rd (brk1_reg_rd), // Hardware break/watch-point register read select
+ .brk_reg_wr (brk1_reg_wr), // Hardware break/watch-point register write select
+ .dbg_clk (dbg_clk), // Debug unit clock
+ .dbg_din (dbg_din), // Debug register data input
+ .dbg_rst (dbg_rst), // Debug unit reset
+ .eu_mab (eu_mab), // Execution-Unit Memory address bus
+ .eu_mb_en (eu_mb_en), // Execution-Unit Memory bus enable
+ .eu_mb_wr (eu_mb_wr), // Execution-Unit Memory bus write transfer
+ .eu_mdb_in (eu_mdb_in), // Memory data bus input
+ .eu_mdb_out (eu_mdb_out), // Memory data bus output
+ .exec_done (exec_done), // Execution completed
+ .fe_mb_en (fe_mb_en), // Frontend Memory bus enable
+ .pc (pc) // Program counter
+);
+
+`else
+assign brk1_halt = 1'b0;
+assign brk1_pnd = 1'b0;
+assign brk1_dout = 16'h0000;
+`endif
+
+ `ifdef DBG_HWBRK_2
+// Hardware Breakpoint/Watchpoint Register read select
+wire [3:0] brk2_reg_rd = {reg_rd[BRK2_ADDR1],
+ reg_rd[BRK2_ADDR0],
+ reg_rd[BRK2_STAT],
+ reg_rd[BRK2_CTL]};
+
+// Hardware Breakpoint/Watchpoint Register write select
+wire [3:0] brk2_reg_wr = {reg_wr[BRK2_ADDR1],
+ reg_wr[BRK2_ADDR0],
+ reg_wr[BRK2_STAT],
+ reg_wr[BRK2_CTL]};
+
+omsp_dbg_hwbrk dbg_hwbr_2 (
+
+// OUTPUTs
+ .brk_halt (brk2_halt), // Hardware breakpoint command
+ .brk_pnd (brk2_pnd), // Hardware break/watch-point pending
+ .brk_dout (brk2_dout), // Hardware break/watch-point register data input
+
+// INPUTs
+ .brk_reg_rd (brk2_reg_rd), // Hardware break/watch-point register read select
+ .brk_reg_wr (brk2_reg_wr), // Hardware break/watch-point register write select
+ .dbg_clk (dbg_clk), // Debug unit clock
+ .dbg_din (dbg_din), // Debug register data input
+ .dbg_rst (dbg_rst), // Debug unit reset
+ .eu_mab (eu_mab), // Execution-Unit Memory address bus
+ .eu_mb_en (eu_mb_en), // Execution-Unit Memory bus enable
+ .eu_mb_wr (eu_mb_wr), // Execution-Unit Memory bus write transfer
+ .eu_mdb_in (eu_mdb_in), // Memory data bus input
+ .eu_mdb_out (eu_mdb_out), // Memory data bus output
+ .exec_done (exec_done), // Execution completed
+ .fe_mb_en (fe_mb_en), // Frontend Memory bus enable
+ .pc (pc) // Program counter
+);
+
+`else
+assign brk2_halt = 1'b0;
+assign brk2_pnd = 1'b0;
+assign brk2_dout = 16'h0000;
+`endif
+
+`ifdef DBG_HWBRK_3
+// Hardware Breakpoint/Watchpoint Register read select
+wire [3:0] brk3_reg_rd = {reg_rd[BRK3_ADDR1],
+ reg_rd[BRK3_ADDR0],
+ reg_rd[BRK3_STAT],
+ reg_rd[BRK3_CTL]};
+
+// Hardware Breakpoint/Watchpoint Register write select
+wire [3:0] brk3_reg_wr = {reg_wr[BRK3_ADDR1],
+ reg_wr[BRK3_ADDR0],
+ reg_wr[BRK3_STAT],
+ reg_wr[BRK3_CTL]};
+
+omsp_dbg_hwbrk dbg_hwbr_3 (
+
+// OUTPUTs
+ .brk_halt (brk3_halt), // Hardware breakpoint command
+ .brk_pnd (brk3_pnd), // Hardware break/watch-point pending
+ .brk_dout (brk3_dout), // Hardware break/watch-point register data input
+
+// INPUTs
+ .brk_reg_rd (brk3_reg_rd), // Hardware break/watch-point register read select
+ .brk_reg_wr (brk3_reg_wr), // Hardware break/watch-point register write select
+ .dbg_clk (dbg_clk), // Debug unit clock
+ .dbg_din (dbg_din), // Debug register data input
+ .dbg_rst (dbg_rst), // Debug unit reset
+ .eu_mab (eu_mab), // Execution-Unit Memory address bus
+ .eu_mb_en (eu_mb_en), // Execution-Unit Memory bus enable
+ .eu_mb_wr (eu_mb_wr), // Execution-Unit Memory bus write transfer
+ .eu_mdb_in (eu_mdb_in), // Memory data bus input
+ .eu_mdb_out (eu_mdb_out), // Memory data bus output
+ .exec_done (exec_done), // Execution completed
+ .fe_mb_en (fe_mb_en), // Frontend Memory bus enable
+ .pc (pc) // Program counter
+);
+
+`else
+assign brk3_halt = 1'b0;
+assign brk3_pnd = 1'b0;
+assign brk3_dout = 16'h0000;
+`endif
+
+
+//============================================================================
+// 6) DATA OUTPUT GENERATION
+//============================================================================
+
+wire [15:0] cpu_id_lo_rd = cpu_id[15:0] & {16{reg_rd[CPU_ID_LO]}};
+wire [15:0] cpu_id_hi_rd = cpu_id[31:16] & {16{reg_rd[CPU_ID_HI]}};
+wire [15:0] cpu_ctl_rd = {8'h00, cpu_ctl_full} & {16{reg_rd[CPU_CTL]}};
+wire [15:0] cpu_stat_rd = {8'h00, cpu_stat_full} & {16{reg_rd[CPU_STAT]}};
+wire [15:0] mem_ctl_rd = {8'h00, mem_ctl_full} & {16{reg_rd[MEM_CTL]}};
+wire [15:0] mem_data_rd = mem_data & {16{reg_rd[MEM_DATA]}};
+wire [15:0] mem_addr_rd = mem_addr & {16{reg_rd[MEM_ADDR]}};
+wire [15:0] mem_cnt_rd = mem_cnt & {16{reg_rd[MEM_CNT]}};
+
+wire [15:0] dbg_dout = cpu_id_lo_rd |
+ cpu_id_hi_rd |
+ cpu_ctl_rd |
+ cpu_stat_rd |
+ mem_ctl_rd |
+ mem_data_rd |
+ mem_addr_rd |
+ mem_cnt_rd |
+ brk0_dout |
+ brk1_dout |
+ brk2_dout |
+ brk3_dout;
+
+// Tell UART/JTAG interface that the data is ready to be read
+always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) dbg_rd_rdy <= 1'b0;
+ else if (mem_burst | mem_burst_rd) dbg_rd_rdy <= (dbg_reg_rd | dbg_mem_rd_dly);
+ else dbg_rd_rdy <= dbg_rd;
+
+
+//============================================================================
+// 7) CPU CONTROL
+//============================================================================
+
+// Reset CPU
+//--------------------------
+wire dbg_cpu_reset = cpu_ctl[`CPU_RST];
+
+
+// Break after reset
+//--------------------------
+wire halt_rst = cpu_ctl[`RST_BRK_EN] & dbg_en_s & puc_pnd_set;
+
+
+// Freeze peripherals
+//--------------------------
+wire dbg_freeze = dbg_halt_st & (cpu_ctl[`FRZ_BRK_EN] | ~cpu_en_s);
+
+
+// Software break
+//--------------------------
+assign dbg_swbrk = (fe_mdb_in==`DBG_SWBRK_OP) & decode_noirq & cpu_ctl[`SW_BRK_EN];
+
+
+// Single step
+//--------------------------
+reg [1:0] inc_step;
+always @(posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) inc_step <= 2'b00;
+ else if (istep) inc_step <= 2'b11;
+ else inc_step <= {inc_step[0], 1'b0};
+
+
+// Run / Halt
+//--------------------------
+reg halt_flag;
+
+wire mem_halt_cpu;
+wire mem_run_cpu;
+
+wire halt_flag_clr = run_cpu | mem_run_cpu;
+wire halt_flag_set = halt_cpu | halt_rst | dbg_swbrk | mem_halt_cpu |
+ brk0_halt | brk1_halt | brk2_halt | brk3_halt;
+
+always @(posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) halt_flag <= 1'b0;
+ else if (halt_flag_clr) halt_flag <= 1'b0;
+ else if (halt_flag_set) halt_flag <= 1'b1;
+
+wire dbg_halt_cmd = (halt_flag | halt_flag_set) & ~inc_step[1];
+
+
+//============================================================================
+// 8) MEMORY CONTROL
+//============================================================================
+
+// Control Memory bursts
+//------------------------------
+
+wire mem_burst_start = (mem_start & |mem_cnt);
+wire mem_burst_end = ((dbg_wr | dbg_rd_rdy) & ~|mem_cnt);
+
+// Detect when burst is on going
+always @(posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) mem_burst <= 1'b0;
+ else if (mem_burst_start) mem_burst <= 1'b1;
+ else if (mem_burst_end) mem_burst <= 1'b0;
+
+// Control signals for UART/JTAG interface
+assign mem_burst_rd = (mem_burst_start & ~mem_ctl[1]);
+assign mem_burst_wr = (mem_burst_start & mem_ctl[1]);
+
+// Trigger CPU Register or memory access during a burst
+reg mem_startb;
+always @(posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) mem_startb <= 1'b0;
+ else mem_startb <= (mem_burst & (dbg_wr | dbg_rd)) | mem_burst_rd;
+
+// Combine single and burst memory start of sequence
+wire mem_seq_start = ((mem_start & ~|mem_cnt) | mem_startb);
+
+
+// Memory access state machine
+//------------------------------
+reg [1:0] mem_state;
+reg [1:0] mem_state_nxt;
+
+// State machine definition
+parameter M_IDLE = 2'h0;
+parameter M_SET_BRK = 2'h1;
+parameter M_ACCESS_BRK = 2'h2;
+parameter M_ACCESS = 2'h3;
+
+// State transition
+always @(mem_state or mem_seq_start or dbg_halt_st)
+ case (mem_state)
+ M_IDLE : mem_state_nxt = ~mem_seq_start ? M_IDLE :
+ dbg_halt_st ? M_ACCESS : M_SET_BRK;
+ M_SET_BRK : mem_state_nxt = dbg_halt_st ? M_ACCESS_BRK : M_SET_BRK;
+ M_ACCESS_BRK : mem_state_nxt = M_IDLE;
+ M_ACCESS : mem_state_nxt = M_IDLE;
+ // pragma coverage off
+ default : mem_state_nxt = M_IDLE;
+ // pragma coverage on
+ endcase
+
+// State machine
+always @(posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) mem_state <= M_IDLE;
+ else mem_state <= mem_state_nxt;
+
+// Utility signals
+assign mem_halt_cpu = (mem_state==M_IDLE) & (mem_state_nxt==M_SET_BRK);
+assign mem_run_cpu = (mem_state==M_ACCESS_BRK) & (mem_state_nxt==M_IDLE);
+assign mem_access = (mem_state==M_ACCESS) | (mem_state==M_ACCESS_BRK);
+
+
+// Interface to CPU Registers and Memory bacbkone
+//------------------------------------------------
+assign dbg_mem_addr = mem_addr;
+assign dbg_mem_dout = ~mem_bw ? mem_data :
+ mem_addr[0] ? {mem_data[7:0], 8'h00} :
+ {8'h00, mem_data[7:0]};
+
+assign dbg_reg_wr = mem_access & mem_ctl[1] & mem_ctl[2];
+assign dbg_reg_rd = mem_access & ~mem_ctl[1] & mem_ctl[2];
+
+assign dbg_mem_en = mem_access & ~mem_ctl[2];
+assign dbg_mem_rd = dbg_mem_en & ~mem_ctl[1];
+
+wire [1:0] dbg_mem_wr_msk = ~mem_bw ? 2'b11 :
+ mem_addr[0] ? 2'b10 : 2'b01;
+assign dbg_mem_wr = {2{dbg_mem_en & mem_ctl[1]}} & dbg_mem_wr_msk;
+
+
+// It takes one additional cycle to read from Memory as from registers
+always @(posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) dbg_mem_rd_dly <= 1'b0;
+ else dbg_mem_rd_dly <= dbg_mem_rd;
+
+
+//=============================================================================
+// 9) UART COMMUNICATION
+//=============================================================================
+`ifdef DBG_UART
+omsp_dbg_uart dbg_uart_0 (
+
+// OUTPUTs
+ .dbg_addr (dbg_addr), // Debug register address
+ .dbg_din (dbg_din), // Debug register data input
+ .dbg_rd (dbg_rd), // Debug register data read
+ .dbg_uart_txd (dbg_uart_txd), // Debug interface: UART TXD
+ .dbg_wr (dbg_wr), // Debug register data write
+
+// INPUTs
+ .dbg_clk (dbg_clk), // Debug unit clock
+ .dbg_dout (dbg_dout), // Debug register data output
+ .dbg_rd_rdy (dbg_rd_rdy), // Debug register data is ready for read
+ .dbg_rst (dbg_rst), // Debug unit reset
+ .dbg_uart_rxd (dbg_uart_rxd), // Debug interface: UART RXD
+ .mem_burst (mem_burst), // Burst on going
+ .mem_burst_end(mem_burst_end), // End TX/RX burst
+ .mem_burst_rd (mem_burst_rd), // Start TX burst
+ .mem_burst_wr (mem_burst_wr), // Start RX burst
+ .mem_bw (mem_bw) // Burst byte width
+);
+
+`else
+assign dbg_addr = 6'h00;
+assign dbg_din = 16'h0000;
+assign dbg_rd = 1'b0;
+assign dbg_uart_txd = 1'b0;
+assign dbg_wr = 1'b0;
+`endif
+
+
+//=============================================================================
+// 10) JTAG COMMUNICATION
+//=============================================================================
+`ifdef DBG_JTAG
+JTAG INTERFACE IS NOT SUPPORTED YET
+`else
+`endif
+
+endmodule // dbg
+
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_undefines.v"
+`endif
diff --git a/tests/openmsp430/rtl/omsp_dbg_hwbrk.v b/tests/openmsp430/rtl/omsp_dbg_hwbrk.v
new file mode 100644
index 000000000..6f639aee9
--- /dev/null
+++ b/tests/openmsp430/rtl/omsp_dbg_hwbrk.v
@@ -0,0 +1,282 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2009 , Olivier Girard
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the authors nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE
+//
+//----------------------------------------------------------------------------
+//
+// *File Name: omsp_dbg_hwbrk.v
+//
+// *Module Description:
+// Hardware Breakpoint / Watchpoint module
+//
+// *Author(s):
+// - Olivier Girard, olgirard@gmail.com
+//
+//----------------------------------------------------------------------------
+// $Rev: 117 $
+// $LastChangedBy: olivier.girard $
+// $LastChangedDate: 2011-06-23 21:30:51 +0200 (Thu, 23 Jun 2011) $
+//----------------------------------------------------------------------------
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_defines.v"
+`endif
+
+module omsp_dbg_hwbrk (
+
+// OUTPUTs
+ brk_halt, // Hardware breakpoint command
+ brk_pnd, // Hardware break/watch-point pending
+ brk_dout, // Hardware break/watch-point register data input
+
+// INPUTs
+ brk_reg_rd, // Hardware break/watch-point register read select
+ brk_reg_wr, // Hardware break/watch-point register write select
+ dbg_clk, // Debug unit clock
+ dbg_din, // Debug register data input
+ dbg_rst, // Debug unit reset
+ eu_mab, // Execution-Unit Memory address bus
+ eu_mb_en, // Execution-Unit Memory bus enable
+ eu_mb_wr, // Execution-Unit Memory bus write transfer
+ eu_mdb_in, // Memory data bus input
+ eu_mdb_out, // Memory data bus output
+ exec_done, // Execution completed
+ fe_mb_en, // Frontend Memory bus enable
+ pc // Program counter
+);
+
+// OUTPUTs
+//=========
+output brk_halt; // Hardware breakpoint command
+output brk_pnd; // Hardware break/watch-point pending
+output [15:0] brk_dout; // Hardware break/watch-point register data input
+
+// INPUTs
+//=========
+input [3:0] brk_reg_rd; // Hardware break/watch-point register read select
+input [3:0] brk_reg_wr; // Hardware break/watch-point register write select
+input dbg_clk; // Debug unit clock
+input [15:0] dbg_din; // Debug register data input
+input dbg_rst; // Debug unit reset
+input [15:0] eu_mab; // Execution-Unit Memory address bus
+input eu_mb_en; // Execution-Unit Memory bus enable
+input [1:0] eu_mb_wr; // Execution-Unit Memory bus write transfer
+input [15:0] eu_mdb_in; // Memory data bus input
+input [15:0] eu_mdb_out; // Memory data bus output
+input exec_done; // Execution completed
+input fe_mb_en; // Frontend Memory bus enable
+input [15:0] pc; // Program counter
+
+
+//=============================================================================
+// 1) WIRE & PARAMETER DECLARATION
+//=============================================================================
+
+wire range_wr_set;
+wire range_rd_set;
+wire addr1_wr_set;
+wire addr1_rd_set;
+wire addr0_wr_set;
+wire addr0_rd_set;
+
+
+parameter BRK_CTL = 0,
+ BRK_STAT = 1,
+ BRK_ADDR0 = 2,
+ BRK_ADDR1 = 3;
+
+
+//=============================================================================
+// 2) CONFIGURATION REGISTERS
+//=============================================================================
+
+// BRK_CTL Register
+//-----------------------------------------------------------------------------
+// 7 6 5 4 3 2 1 0
+// Reserved RANGE_MODE INST_EN BREAK_EN ACCESS_MODE
+//
+// ACCESS_MODE: - 00 : Disabled
+// - 01 : Detect read access
+// - 10 : Detect write access
+// - 11 : Detect read/write access
+// NOTE: '10' & '11' modes are not supported on the instruction flow
+//
+// BREAK_EN: - 0 : Watchmode enable
+// - 1 : Break enable
+//
+// INST_EN: - 0 : Checks are done on the execution unit (data flow)
+// - 1 : Checks are done on the frontend (instruction flow)
+//
+// RANGE_MODE: - 0 : Address match on BRK_ADDR0 or BRK_ADDR1
+// - 1 : Address match on BRK_ADDR0->BRK_ADDR1 range
+//
+//-----------------------------------------------------------------------------
+reg [4:0] brk_ctl;
+
+wire brk_ctl_wr = brk_reg_wr[BRK_CTL];
+
+always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) brk_ctl <= 5'h00;
+ else if (brk_ctl_wr) brk_ctl <= {`HWBRK_RANGE & dbg_din[4], dbg_din[3:0]};
+
+wire [7:0] brk_ctl_full = {3'b000, brk_ctl};
+
+
+// BRK_STAT Register
+//-----------------------------------------------------------------------------
+// 7 6 5 4 3 2 1 0
+// Reserved RANGE_WR RANGE_RD ADDR1_WR ADDR1_RD ADDR0_WR ADDR0_RD
+//-----------------------------------------------------------------------------
+reg [5:0] brk_stat;
+
+wire brk_stat_wr = brk_reg_wr[BRK_STAT];
+wire [5:0] brk_stat_set = {range_wr_set & `HWBRK_RANGE,
+ range_rd_set & `HWBRK_RANGE,
+ addr1_wr_set, addr1_rd_set,
+ addr0_wr_set, addr0_rd_set};
+wire [5:0] brk_stat_clr = ~dbg_din[5:0];
+
+always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) brk_stat <= 6'h00;
+ else if (brk_stat_wr) brk_stat <= ((brk_stat & brk_stat_clr) | brk_stat_set);
+ else brk_stat <= (brk_stat | brk_stat_set);
+
+wire [7:0] brk_stat_full = {2'b00, brk_stat};
+wire brk_pnd = |brk_stat;
+
+
+// BRK_ADDR0 Register
+//-----------------------------------------------------------------------------
+reg [15:0] brk_addr0;
+
+wire brk_addr0_wr = brk_reg_wr[BRK_ADDR0];
+
+always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) brk_addr0 <= 16'h0000;
+ else if (brk_addr0_wr) brk_addr0 <= dbg_din;
+
+
+// BRK_ADDR1/DATA0 Register
+//-----------------------------------------------------------------------------
+reg [15:0] brk_addr1;
+
+wire brk_addr1_wr = brk_reg_wr[BRK_ADDR1];
+
+always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) brk_addr1 <= 16'h0000;
+ else if (brk_addr1_wr) brk_addr1 <= dbg_din;
+
+
+//============================================================================
+// 3) DATA OUTPUT GENERATION
+//============================================================================
+
+wire [15:0] brk_ctl_rd = {8'h00, brk_ctl_full} & {16{brk_reg_rd[BRK_CTL]}};
+wire [15:0] brk_stat_rd = {8'h00, brk_stat_full} & {16{brk_reg_rd[BRK_STAT]}};
+wire [15:0] brk_addr0_rd = brk_addr0 & {16{brk_reg_rd[BRK_ADDR0]}};
+wire [15:0] brk_addr1_rd = brk_addr1 & {16{brk_reg_rd[BRK_ADDR1]}};
+
+wire [15:0] brk_dout = brk_ctl_rd |
+ brk_stat_rd |
+ brk_addr0_rd |
+ brk_addr1_rd;
+
+
+//============================================================================
+// 4) BREAKPOINT / WATCHPOINT GENERATION
+//============================================================================
+
+// Comparators
+//---------------------------
+// Note: here the comparison logic is instanciated several times in order
+// to improve the timings, at the cost of a bit more area.
+
+wire equ_d_addr0 = eu_mb_en & (eu_mab==brk_addr0) & ~brk_ctl[`BRK_RANGE];
+wire equ_d_addr1 = eu_mb_en & (eu_mab==brk_addr1) & ~brk_ctl[`BRK_RANGE];
+wire equ_d_range = eu_mb_en & ((eu_mab>=brk_addr0) & (eu_mab<=brk_addr1)) &
+ brk_ctl[`BRK_RANGE] & `HWBRK_RANGE;
+
+reg fe_mb_en_buf;
+always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) fe_mb_en_buf <= 1'b0;
+ else fe_mb_en_buf <= fe_mb_en;
+
+wire equ_i_addr0 = fe_mb_en_buf & (pc==brk_addr0) & ~brk_ctl[`BRK_RANGE];
+wire equ_i_addr1 = fe_mb_en_buf & (pc==brk_addr1) & ~brk_ctl[`BRK_RANGE];
+wire equ_i_range = fe_mb_en_buf & ((pc>=brk_addr0) & (pc<=brk_addr1)) &
+ brk_ctl[`BRK_RANGE] & `HWBRK_RANGE;
+
+
+// Detect accesses
+//---------------------------
+
+// Detect Instruction read access
+wire i_addr0_rd = equ_i_addr0 & brk_ctl[`BRK_I_EN];
+wire i_addr1_rd = equ_i_addr1 & brk_ctl[`BRK_I_EN];
+wire i_range_rd = equ_i_range & brk_ctl[`BRK_I_EN];
+
+// Detect Execution-Unit write access
+wire d_addr0_wr = equ_d_addr0 & ~brk_ctl[`BRK_I_EN] & |eu_mb_wr;
+wire d_addr1_wr = equ_d_addr1 & ~brk_ctl[`BRK_I_EN] & |eu_mb_wr;
+wire d_range_wr = equ_d_range & ~brk_ctl[`BRK_I_EN] & |eu_mb_wr;
+
+// Detect DATA read access
+// Whenever an "ADD r9. &0x200" instruction is executed, &0x200 will be read
+// before being written back. In that case, the read flag should not be set.
+// In general, We should here make sure no write access occures during the
+// same instruction cycle before setting the read flag.
+reg [2:0] d_rd_trig;
+always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) d_rd_trig <= 3'h0;
+ else if (exec_done) d_rd_trig <= 3'h0;
+ else d_rd_trig <= {equ_d_range & ~brk_ctl[`BRK_I_EN] & ~|eu_mb_wr,
+ equ_d_addr1 & ~brk_ctl[`BRK_I_EN] & ~|eu_mb_wr,
+ equ_d_addr0 & ~brk_ctl[`BRK_I_EN] & ~|eu_mb_wr};
+
+wire d_addr0_rd = d_rd_trig[0] & exec_done & ~d_addr0_wr;
+wire d_addr1_rd = d_rd_trig[1] & exec_done & ~d_addr1_wr;
+wire d_range_rd = d_rd_trig[2] & exec_done & ~d_range_wr;
+
+
+// Set flags
+assign addr0_rd_set = brk_ctl[`BRK_MODE_RD] & (d_addr0_rd | i_addr0_rd);
+assign addr0_wr_set = brk_ctl[`BRK_MODE_WR] & d_addr0_wr;
+assign addr1_rd_set = brk_ctl[`BRK_MODE_RD] & (d_addr1_rd | i_addr1_rd);
+assign addr1_wr_set = brk_ctl[`BRK_MODE_WR] & d_addr1_wr;
+assign range_rd_set = brk_ctl[`BRK_MODE_RD] & (d_range_rd | i_range_rd);
+assign range_wr_set = brk_ctl[`BRK_MODE_WR] & d_range_wr;
+
+
+// Break CPU
+assign brk_halt = brk_ctl[`BRK_EN] & |brk_stat_set;
+
+
+endmodule // omsp_dbg_hwbrk
+
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_undefines.v"
+`endif
diff --git a/tests/openmsp430/rtl/omsp_dbg_uart.v b/tests/openmsp430/rtl/omsp_dbg_uart.v
new file mode 100644
index 000000000..319099a5f
--- /dev/null
+++ b/tests/openmsp430/rtl/omsp_dbg_uart.v
@@ -0,0 +1,298 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2009 , Olivier Girard
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the authors nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE
+//
+//----------------------------------------------------------------------------
+//
+// *File Name: omsp_dbg_uart.v
+//
+// *Module Description:
+// Debug UART communication interface (8N1, Half-duplex)
+//
+// *Author(s):
+// - Olivier Girard, olgirard@gmail.com
+//
+//----------------------------------------------------------------------------
+// $Rev: 134 $
+// $LastChangedBy: olivier.girard $
+// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $
+//----------------------------------------------------------------------------
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_defines.v"
+`endif
+
+module omsp_dbg_uart (
+
+// OUTPUTs
+ dbg_addr, // Debug register address
+ dbg_din, // Debug register data input
+ dbg_rd, // Debug register data read
+ dbg_uart_txd, // Debug interface: UART TXD
+ dbg_wr, // Debug register data write
+
+// INPUTs
+ dbg_clk, // Debug unit clock
+ dbg_dout, // Debug register data output
+ dbg_rd_rdy, // Debug register data is ready for read
+ dbg_rst, // Debug unit reset
+ dbg_uart_rxd, // Debug interface: UART RXD
+ mem_burst, // Burst on going
+ mem_burst_end, // End TX/RX burst
+ mem_burst_rd, // Start TX burst
+ mem_burst_wr, // Start RX burst
+ mem_bw // Burst byte width
+);
+
+// OUTPUTs
+//=========
+output [5:0] dbg_addr; // Debug register address
+output [15:0] dbg_din; // Debug register data input
+output dbg_rd; // Debug register data read
+output dbg_uart_txd; // Debug interface: UART TXD
+output dbg_wr; // Debug register data write
+
+// INPUTs
+//=========
+input dbg_clk; // Debug unit clock
+input [15:0] dbg_dout; // Debug register data output
+input dbg_rd_rdy; // Debug register data is ready for read
+input dbg_rst; // Debug unit reset
+input dbg_uart_rxd; // Debug interface: UART RXD
+input mem_burst; // Burst on going
+input mem_burst_end; // End TX/RX burst
+input mem_burst_rd; // Start TX burst
+input mem_burst_wr; // Start RX burst
+input mem_bw; // Burst byte width
+
+
+//=============================================================================
+// 1) UART RECEIVE LINE SYNCHRONIZTION & FILTERING
+//=============================================================================
+
+// Synchronize RXD input
+//--------------------------------
+`ifdef SYNC_DBG_UART_RXD
+
+ wire uart_rxd_n;
+
+ omsp_sync_cell sync_cell_uart_rxd (
+ .data_out (uart_rxd_n),
+ .data_in (~dbg_uart_rxd),
+ .clk (dbg_clk),
+ .rst (dbg_rst)
+ );
+ wire uart_rxd = ~uart_rxd_n;
+`else
+ wire uart_rxd = dbg_uart_rxd;
+`endif
+
+// RXD input buffer
+//--------------------------------
+reg [1:0] rxd_buf;
+always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) rxd_buf <= 2'h3;
+ else rxd_buf <= {rxd_buf[0], uart_rxd};
+
+// Majority decision
+//------------------------
+reg rxd_maj;
+
+wire rxd_maj_nxt = (uart_rxd & rxd_buf[0]) |
+ (uart_rxd & rxd_buf[1]) |
+ (rxd_buf[0] & rxd_buf[1]);
+
+always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) rxd_maj <= 1'b1;
+ else rxd_maj <= rxd_maj_nxt;
+
+wire rxd_s = rxd_maj;
+wire rxd_fe = rxd_maj & ~rxd_maj_nxt;
+wire rxd_re = ~rxd_maj & rxd_maj_nxt;
+wire rxd_edge = rxd_maj ^ rxd_maj_nxt;
+
+//=============================================================================
+// 2) UART STATE MACHINE
+//=============================================================================
+
+// Receive state
+//------------------------
+reg [2:0] uart_state;
+reg [2:0] uart_state_nxt;
+
+wire sync_done;
+wire xfer_done;
+reg [19:0] xfer_buf;
+wire [19:0] xfer_buf_nxt;
+
+// State machine definition
+parameter RX_SYNC = 3'h0;
+parameter RX_CMD = 3'h1;
+parameter RX_DATA1 = 3'h2;
+parameter RX_DATA2 = 3'h3;
+parameter TX_DATA1 = 3'h4;
+parameter TX_DATA2 = 3'h5;
+
+// State transition
+always @(uart_state or xfer_buf_nxt or mem_burst or mem_burst_wr or mem_burst_rd or mem_burst_end or mem_bw)
+ case (uart_state)
+ RX_SYNC : uart_state_nxt = RX_CMD;
+ RX_CMD : uart_state_nxt = mem_burst_wr ?
+ (mem_bw ? RX_DATA2 : RX_DATA1) :
+ mem_burst_rd ?
+ (mem_bw ? TX_DATA2 : TX_DATA1) :
+ (xfer_buf_nxt[`DBG_UART_WR] ?
+ (xfer_buf_nxt[`DBG_UART_BW] ? RX_DATA2 : RX_DATA1) :
+ (xfer_buf_nxt[`DBG_UART_BW] ? TX_DATA2 : TX_DATA1));
+ RX_DATA1 : uart_state_nxt = RX_DATA2;
+ RX_DATA2 : uart_state_nxt = (mem_burst & ~mem_burst_end) ?
+ (mem_bw ? RX_DATA2 : RX_DATA1) :
+ RX_CMD;
+ TX_DATA1 : uart_state_nxt = TX_DATA2;
+ TX_DATA2 : uart_state_nxt = (mem_burst & ~mem_burst_end) ?
+ (mem_bw ? TX_DATA2 : TX_DATA1) :
+ RX_CMD;
+ // pragma coverage off
+ default : uart_state_nxt = RX_CMD;
+ // pragma coverage on
+ endcase
+
+// State machine
+always @(posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) uart_state <= RX_SYNC;
+ else if (xfer_done | sync_done |
+ mem_burst_wr | mem_burst_rd) uart_state <= uart_state_nxt;
+
+// Utility signals
+wire cmd_valid = (uart_state==RX_CMD) & xfer_done;
+wire rx_active = (uart_state==RX_DATA1) | (uart_state==RX_DATA2) | (uart_state==RX_CMD);
+wire tx_active = (uart_state==TX_DATA1) | (uart_state==TX_DATA2);
+
+
+//=============================================================================
+// 3) UART SYNCHRONIZATION
+//=============================================================================
+// After DBG_RST, the host needs to fist send a synchronization character (0x80)
+// If this feature doesn't work properly, it is possible to disable it by
+// commenting the DBG_UART_AUTO_SYNC define in the openMSP430.inc file.
+
+reg sync_busy;
+always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) sync_busy <= 1'b0;
+ else if ((uart_state==RX_SYNC) & rxd_fe) sync_busy <= 1'b1;
+ else if ((uart_state==RX_SYNC) & rxd_re) sync_busy <= 1'b0;
+
+assign sync_done = (uart_state==RX_SYNC) & rxd_re & sync_busy;
+
+`ifdef DBG_UART_AUTO_SYNC
+
+reg [`DBG_UART_XFER_CNT_W+2:0] sync_cnt;
+always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) sync_cnt <= {{`DBG_UART_XFER_CNT_W{1'b1}}, 3'b000};
+ else if (sync_busy | (~sync_busy & sync_cnt[2])) sync_cnt <= sync_cnt+{{`DBG_UART_XFER_CNT_W+2{1'b0}}, 1'b1};
+
+wire [`DBG_UART_XFER_CNT_W-1:0] bit_cnt_max = sync_cnt[`DBG_UART_XFER_CNT_W+2:3];
+`else
+wire [`DBG_UART_XFER_CNT_W-1:0] bit_cnt_max = `DBG_UART_CNT;
+`endif
+
+
+//=============================================================================
+// 4) UART RECEIVE / TRANSMIT
+//=============================================================================
+
+// Transfer counter
+//------------------------
+reg [3:0] xfer_bit;
+reg [`DBG_UART_XFER_CNT_W-1:0] xfer_cnt;
+
+wire txd_start = dbg_rd_rdy | (xfer_done & (uart_state==TX_DATA1));
+wire rxd_start = (xfer_bit==4'h0) & rxd_fe & ((uart_state!=RX_SYNC));
+wire xfer_bit_inc = (xfer_bit!=4'h0) & (xfer_cnt=={`DBG_UART_XFER_CNT_W{1'b0}});
+assign xfer_done = rx_active ? (xfer_bit==4'ha) : (xfer_bit==4'hb);
+
+always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) xfer_bit <= 4'h0;
+ else if (txd_start | rxd_start) xfer_bit <= 4'h1;
+ else if (xfer_done) xfer_bit <= 4'h0;
+ else if (xfer_bit_inc) xfer_bit <= xfer_bit+4'h1;
+
+always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) xfer_cnt <= {`DBG_UART_XFER_CNT_W{1'b0}};
+ else if (rx_active & rxd_edge) xfer_cnt <= {1'b0, bit_cnt_max[`DBG_UART_XFER_CNT_W-1:1]};
+ else if (txd_start | xfer_bit_inc) xfer_cnt <= bit_cnt_max;
+ else if (|xfer_cnt) xfer_cnt <= xfer_cnt+{`DBG_UART_XFER_CNT_W{1'b1}};
+
+
+// Receive/Transmit buffer
+//-------------------------
+assign xfer_buf_nxt = {rxd_s, xfer_buf[19:1]};
+
+always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) xfer_buf <= 20'h00000;
+ else if (dbg_rd_rdy) xfer_buf <= {1'b1, dbg_dout[15:8], 2'b01, dbg_dout[7:0], 1'b0};
+ else if (xfer_bit_inc) xfer_buf <= xfer_buf_nxt;
+
+
+// Generate TXD output
+//------------------------
+reg dbg_uart_txd;
+
+always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) dbg_uart_txd <= 1'b1;
+ else if (xfer_bit_inc & tx_active) dbg_uart_txd <= xfer_buf[0];
+
+
+//=============================================================================
+// 5) INTERFACE TO DEBUG REGISTERS
+//=============================================================================
+
+reg [5:0] dbg_addr;
+ always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) dbg_addr <= 6'h00;
+ else if (cmd_valid) dbg_addr <= xfer_buf_nxt[`DBG_UART_ADDR];
+
+reg dbg_bw;
+always @ (posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) dbg_bw <= 1'b0;
+ else if (cmd_valid) dbg_bw <= xfer_buf_nxt[`DBG_UART_BW];
+
+wire dbg_din_bw = mem_burst ? mem_bw : dbg_bw;
+
+wire [15:0] dbg_din = dbg_din_bw ? {8'h00, xfer_buf_nxt[18:11]} :
+ {xfer_buf_nxt[18:11], xfer_buf_nxt[9:2]};
+wire dbg_wr = (xfer_done & (uart_state==RX_DATA2));
+wire dbg_rd = mem_burst ? (xfer_done & (uart_state==TX_DATA2)) :
+ (cmd_valid & ~xfer_buf_nxt[`DBG_UART_WR]) | mem_burst_rd;
+
+
+
+endmodule // omsp_dbg_uart
+
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_undefines.v"
+`endif
diff --git a/tests/openmsp430/rtl/omsp_execution_unit.v b/tests/openmsp430/rtl/omsp_execution_unit.v
new file mode 100644
index 000000000..8a2965e5c
--- /dev/null
+++ b/tests/openmsp430/rtl/omsp_execution_unit.v
@@ -0,0 +1,420 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2009 , Olivier Girard
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the authors nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE
+//
+//----------------------------------------------------------------------------
+//
+// *File Name: omsp_execution_unit.v
+//
+// *Module Description:
+// openMSP430 Execution unit
+//
+// *Author(s):
+// - Olivier Girard, olgirard@gmail.com
+//
+//----------------------------------------------------------------------------
+// $Rev: 134 $
+// $LastChangedBy: olivier.girard $
+// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $
+//----------------------------------------------------------------------------
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_defines.v"
+`endif
+
+module omsp_execution_unit (
+
+// OUTPUTs
+ cpuoff, // Turns off the CPU
+ dbg_reg_din, // Debug unit CPU register data input
+ gie, // General interrupt enable
+ mab, // Memory address bus
+ mb_en, // Memory bus enable
+ mb_wr, // Memory bus write transfer
+ mdb_out, // Memory data bus output
+ oscoff, // Turns off LFXT1 clock input
+ pc_sw, // Program counter software value
+ pc_sw_wr, // Program counter software write
+ scg0, // System clock generator 1. Turns off the DCO
+ scg1, // System clock generator 1. Turns off the SMCLK
+
+// INPUTs
+ dbg_halt_st, // Halt/Run status from CPU
+ dbg_mem_dout, // Debug unit data output
+ dbg_reg_wr, // Debug unit CPU register write
+ e_state, // Execution state
+ exec_done, // Execution completed
+ inst_ad, // Decoded Inst: destination addressing mode
+ inst_as, // Decoded Inst: source addressing mode
+ inst_alu, // ALU control signals
+ inst_bw, // Decoded Inst: byte width
+ inst_dest, // Decoded Inst: destination (one hot)
+ inst_dext, // Decoded Inst: destination extended instruction word
+ inst_irq_rst, // Decoded Inst: reset interrupt
+ inst_jmp, // Decoded Inst: Conditional jump
+ inst_mov, // Decoded Inst: mov instruction
+ inst_sext, // Decoded Inst: source extended instruction word
+ inst_so, // Decoded Inst: Single-operand arithmetic
+ inst_src, // Decoded Inst: source (one hot)
+ inst_type, // Decoded Instruction type
+ mclk, // Main system clock
+ mdb_in, // Memory data bus input
+ pc, // Program counter
+ pc_nxt, // Next PC value (for CALL & IRQ)
+ puc_rst, // Main system reset
+ scan_enable // Scan enable (active during scan shifting)
+);
+
+// OUTPUTs
+//=========
+output cpuoff; // Turns off the CPU
+output [15:0] dbg_reg_din; // Debug unit CPU register data input
+output gie; // General interrupt enable
+output [15:0] mab; // Memory address bus
+output mb_en; // Memory bus enable
+output [1:0] mb_wr; // Memory bus write transfer
+output [15:0] mdb_out; // Memory data bus output
+output oscoff; // Turns off LFXT1 clock input
+output [15:0] pc_sw; // Program counter software value
+output pc_sw_wr; // Program counter software write
+output scg0; // System clock generator 1. Turns off the DCO
+output scg1; // System clock generator 1. Turns off the SMCLK
+
+// INPUTs
+//=========
+input dbg_halt_st; // Halt/Run status from CPU
+input [15:0] dbg_mem_dout; // Debug unit data output
+input dbg_reg_wr; // Debug unit CPU register write
+input [3:0] e_state; // Execution state
+input exec_done; // Execution completed
+input [7:0] inst_ad; // Decoded Inst: destination addressing mode
+input [7:0] inst_as; // Decoded Inst: source addressing mode
+input [11:0] inst_alu; // ALU control signals
+input inst_bw; // Decoded Inst: byte width
+input [15:0] inst_dest; // Decoded Inst: destination (one hot)
+input [15:0] inst_dext; // Decoded Inst: destination extended instruction word
+input inst_irq_rst; // Decoded Inst: reset interrupt
+input [7:0] inst_jmp; // Decoded Inst: Conditional jump
+input inst_mov; // Decoded Inst: mov instruction
+input [15:0] inst_sext; // Decoded Inst: source extended instruction word
+input [7:0] inst_so; // Decoded Inst: Single-operand arithmetic
+input [15:0] inst_src; // Decoded Inst: source (one hot)
+input [2:0] inst_type; // Decoded Instruction type
+input mclk; // Main system clock
+input [15:0] mdb_in; // Memory data bus input
+input [15:0] pc; // Program counter
+input [15:0] pc_nxt; // Next PC value (for CALL & IRQ)
+input puc_rst; // Main system reset
+input scan_enable; // Scan enable (active during scan shifting)
+
+
+//=============================================================================
+// 1) INTERNAL WIRES/REGISTERS/PARAMETERS DECLARATION
+//=============================================================================
+
+wire [15:0] alu_out;
+wire [15:0] alu_out_add;
+wire [3:0] alu_stat;
+wire [3:0] alu_stat_wr;
+wire [15:0] op_dst;
+wire [15:0] op_src;
+wire [15:0] reg_dest;
+wire [15:0] reg_src;
+wire [15:0] mdb_in_bw;
+wire [15:0] mdb_in_val;
+wire [3:0] status;
+
+
+//=============================================================================
+// 2) REGISTER FILE
+//=============================================================================
+
+wire reg_dest_wr = ((e_state==`E_EXEC) & (
+ (inst_type[`INST_TO] & inst_ad[`DIR] & ~inst_alu[`EXEC_NO_WR]) |
+ (inst_type[`INST_SO] & inst_as[`DIR] & ~(inst_so[`PUSH] | inst_so[`CALL] | inst_so[`RETI])) |
+ inst_type[`INST_JMP])) | dbg_reg_wr;
+
+wire reg_sp_wr = (((e_state==`E_IRQ_1) | (e_state==`E_IRQ_3)) & ~inst_irq_rst) |
+ ((e_state==`E_DST_RD) & ((inst_so[`PUSH] | inst_so[`CALL]) & ~inst_as[`IDX] & ~((inst_as[`INDIR] | inst_as[`INDIR_I]) & inst_src[1]))) |
+ ((e_state==`E_SRC_AD) & ((inst_so[`PUSH] | inst_so[`CALL]) & inst_as[`IDX])) |
+ ((e_state==`E_SRC_RD) & ((inst_so[`PUSH] | inst_so[`CALL]) & ((inst_as[`INDIR] | inst_as[`INDIR_I]) & inst_src[1])));
+
+wire reg_sr_wr = (e_state==`E_DST_RD) & inst_so[`RETI];
+
+wire reg_sr_clr = (e_state==`E_IRQ_2);
+
+wire reg_pc_call = ((e_state==`E_EXEC) & inst_so[`CALL]) |
+ ((e_state==`E_DST_WR) & inst_so[`RETI]);
+
+wire reg_incr = (exec_done & inst_as[`INDIR_I]) |
+ ((e_state==`E_SRC_RD) & inst_so[`RETI]) |
+ ((e_state==`E_EXEC) & inst_so[`RETI]);
+
+assign dbg_reg_din = reg_dest;
+
+
+omsp_register_file register_file_0 (
+
+// OUTPUTs
+ .cpuoff (cpuoff), // Turns off the CPU
+ .gie (gie), // General interrupt enable
+ .oscoff (oscoff), // Turns off LFXT1 clock input
+ .pc_sw (pc_sw), // Program counter software value
+ .pc_sw_wr (pc_sw_wr), // Program counter software write
+ .reg_dest (reg_dest), // Selected register destination content
+ .reg_src (reg_src), // Selected register source content
+ .scg0 (scg0), // System clock generator 1. Turns off the DCO
+ .scg1 (scg1), // System clock generator 1. Turns off the SMCLK
+ .status (status), // R2 Status {V,N,Z,C}
+
+// INPUTs
+ .alu_stat (alu_stat), // ALU Status {V,N,Z,C}
+ .alu_stat_wr (alu_stat_wr), // ALU Status write {V,N,Z,C}
+ .inst_bw (inst_bw), // Decoded Inst: byte width
+ .inst_dest (inst_dest), // Register destination selection
+ .inst_src (inst_src), // Register source selection
+ .mclk (mclk), // Main system clock
+ .pc (pc), // Program counter
+ .puc_rst (puc_rst), // Main system reset
+ .reg_dest_val (alu_out), // Selected register destination value
+ .reg_dest_wr (reg_dest_wr), // Write selected register destination
+ .reg_pc_call (reg_pc_call), // Trigger PC update for a CALL instruction
+ .reg_sp_val (alu_out_add), // Stack Pointer next value
+ .reg_sp_wr (reg_sp_wr), // Stack Pointer write
+ .reg_sr_clr (reg_sr_clr), // Status register clear for interrupts
+ .reg_sr_wr (reg_sr_wr), // Status Register update for RETI instruction
+ .reg_incr (reg_incr), // Increment source register
+ .scan_enable (scan_enable) // Scan enable (active during scan shifting)
+);
+
+
+//=============================================================================
+// 3) SOURCE OPERAND MUXING
+//=============================================================================
+// inst_as[`DIR] : Register direct. -> Source is in register
+// inst_as[`IDX] : Register indexed. -> Source is in memory, address is register+offset
+// inst_as[`INDIR] : Register indirect.
+// inst_as[`INDIR_I]: Register indirect autoincrement.
+// inst_as[`SYMB] : Symbolic (operand is in memory at address PC+x).
+// inst_as[`IMM] : Immediate (operand is next word in the instruction stream).
+// inst_as[`ABS] : Absolute (operand is in memory at address x).
+// inst_as[`CONST] : Constant.
+
+wire src_reg_src_sel = (e_state==`E_IRQ_0) |
+ (e_state==`E_IRQ_2) |
+ ((e_state==`E_SRC_RD) & ~inst_as[`ABS]) |
+ ((e_state==`E_SRC_WR) & ~inst_as[`ABS]) |
+ ((e_state==`E_EXEC) & inst_as[`DIR] & ~inst_type[`INST_JMP]);
+
+wire src_reg_dest_sel = (e_state==`E_IRQ_1) |
+ (e_state==`E_IRQ_3) |
+ ((e_state==`E_DST_RD) & (inst_so[`PUSH] | inst_so[`CALL])) |
+ ((e_state==`E_SRC_AD) & (inst_so[`PUSH] | inst_so[`CALL]) & inst_as[`IDX]);
+
+wire src_mdb_in_val_sel = ((e_state==`E_DST_RD) & inst_so[`RETI]) |
+ ((e_state==`E_EXEC) & (inst_as[`INDIR] | inst_as[`INDIR_I] |
+ inst_as[`IDX] | inst_as[`SYMB] |
+ inst_as[`ABS]));
+
+wire src_inst_dext_sel = ((e_state==`E_DST_RD) & ~(inst_so[`PUSH] | inst_so[`CALL])) |
+ ((e_state==`E_DST_WR) & ~(inst_so[`PUSH] | inst_so[`CALL] |
+ inst_so[`RETI]));
+
+wire src_inst_sext_sel = ((e_state==`E_EXEC) & (inst_type[`INST_JMP] | inst_as[`IMM] |
+ inst_as[`CONST] | inst_so[`RETI]));
+
+
+assign op_src = src_reg_src_sel ? reg_src :
+ src_reg_dest_sel ? reg_dest :
+ src_mdb_in_val_sel ? mdb_in_val :
+ src_inst_dext_sel ? inst_dext :
+ src_inst_sext_sel ? inst_sext : 16'h0000;
+
+
+//=============================================================================
+// 4) DESTINATION OPERAND MUXING
+//=============================================================================
+// inst_ad[`DIR] : Register direct.
+// inst_ad[`IDX] : Register indexed.
+// inst_ad[`SYMB] : Symbolic (operand is in memory at address PC+x).
+// inst_ad[`ABS] : Absolute (operand is in memory at address x).
+
+
+wire dst_inst_sext_sel = ((e_state==`E_SRC_RD) & (inst_as[`IDX] | inst_as[`SYMB] |
+ inst_as[`ABS])) |
+ ((e_state==`E_SRC_WR) & (inst_as[`IDX] | inst_as[`SYMB] |
+ inst_as[`ABS]));
+
+wire dst_mdb_in_bw_sel = ((e_state==`E_DST_WR) & inst_so[`RETI]) |
+ ((e_state==`E_EXEC) & ~(inst_ad[`DIR] | inst_type[`INST_JMP] |
+ inst_type[`INST_SO]) & ~inst_so[`RETI]);
+
+wire dst_fffe_sel = (e_state==`E_IRQ_0) |
+ (e_state==`E_IRQ_1) |
+ (e_state==`E_IRQ_3) |
+ ((e_state==`E_DST_RD) & (inst_so[`PUSH] | inst_so[`CALL]) & ~inst_so[`RETI]) |
+ ((e_state==`E_SRC_AD) & (inst_so[`PUSH] | inst_so[`CALL]) & inst_as[`IDX]) |
+ ((e_state==`E_SRC_RD) & (inst_so[`PUSH] | inst_so[`CALL]) & (inst_as[`INDIR] | inst_as[`INDIR_I]) & inst_src[1]);
+
+wire dst_reg_dest_sel = ((e_state==`E_DST_RD) & ~(inst_so[`PUSH] | inst_so[`CALL] | inst_ad[`ABS] | inst_so[`RETI])) |
+ ((e_state==`E_DST_WR) & ~inst_ad[`ABS]) |
+ ((e_state==`E_EXEC) & (inst_ad[`DIR] | inst_type[`INST_JMP] |
+ inst_type[`INST_SO]) & ~inst_so[`RETI]);
+
+
+assign op_dst = dbg_halt_st ? dbg_mem_dout :
+ dst_inst_sext_sel ? inst_sext :
+ dst_mdb_in_bw_sel ? mdb_in_bw :
+ dst_reg_dest_sel ? reg_dest :
+ dst_fffe_sel ? 16'hfffe : 16'h0000;
+
+
+//=============================================================================
+// 5) ALU
+//=============================================================================
+
+wire exec_cycle = (e_state==`E_EXEC);
+
+omsp_alu alu_0 (
+
+// OUTPUTs
+ .alu_out (alu_out), // ALU output value
+ .alu_out_add (alu_out_add), // ALU adder output value
+ .alu_stat (alu_stat), // ALU Status {V,N,Z,C}
+ .alu_stat_wr (alu_stat_wr), // ALU Status write {V,N,Z,C}
+
+// INPUTs
+ .dbg_halt_st (dbg_halt_st), // Halt/Run status from CPU
+ .exec_cycle (exec_cycle), // Instruction execution cycle
+ .inst_alu (inst_alu), // ALU control signals
+ .inst_bw (inst_bw), // Decoded Inst: byte width
+ .inst_jmp (inst_jmp), // Decoded Inst: Conditional jump
+ .inst_so (inst_so), // Single-operand arithmetic
+ .op_dst (op_dst), // Destination operand
+ .op_src (op_src), // Source operand
+ .status (status) // R2 Status {V,N,Z,C}
+);
+
+
+//=============================================================================
+// 6) MEMORY INTERFACE
+//=============================================================================
+
+// Detect memory read/write access
+assign mb_en = ((e_state==`E_IRQ_1) & ~inst_irq_rst) |
+ ((e_state==`E_IRQ_3) & ~inst_irq_rst) |
+ ((e_state==`E_SRC_RD) & ~inst_as[`IMM]) |
+ (e_state==`E_SRC_WR) |
+ ((e_state==`E_EXEC) & inst_so[`RETI]) |
+ ((e_state==`E_DST_RD) & ~inst_type[`INST_SO]
+ & ~inst_mov) |
+ (e_state==`E_DST_WR);
+
+wire [1:0] mb_wr_msk = inst_alu[`EXEC_NO_WR] ? 2'b00 :
+ ~inst_bw ? 2'b11 :
+ alu_out_add[0] ? 2'b10 : 2'b01;
+assign mb_wr = ({2{(e_state==`E_IRQ_1)}} |
+ {2{(e_state==`E_IRQ_3)}} |
+ {2{(e_state==`E_DST_WR)}} |
+ {2{(e_state==`E_SRC_WR)}}) & mb_wr_msk;
+
+// Memory address bus
+assign mab = alu_out_add[15:0];
+
+// Memory data bus output
+reg [15:0] mdb_out_nxt;
+
+`ifdef CLOCK_GATING
+wire mdb_out_nxt_en = (e_state==`E_DST_RD) |
+ (((e_state==`E_EXEC) & ~inst_so[`CALL]) |
+ (e_state==`E_IRQ_0) | (e_state==`E_IRQ_2));
+wire mclk_mdb_out_nxt;
+omsp_clock_gate clock_gate_mdb_out_nxt (.gclk(mclk_mdb_out_nxt),
+ .clk (mclk), .enable(mdb_out_nxt_en), .scan_enable(scan_enable));
+`else
+wire mclk_mdb_out_nxt = mclk;
+`endif
+
+always @(posedge mclk_mdb_out_nxt or posedge puc_rst)
+ if (puc_rst) mdb_out_nxt <= 16'h0000;
+ else if (e_state==`E_DST_RD) mdb_out_nxt <= pc_nxt;
+`ifdef CLOCK_GATING
+ else mdb_out_nxt <= alu_out;
+`else
+ else if ((e_state==`E_EXEC & ~inst_so[`CALL]) |
+ (e_state==`E_IRQ_0) | (e_state==`E_IRQ_2)) mdb_out_nxt <= alu_out;
+`endif
+
+assign mdb_out = inst_bw ? {2{mdb_out_nxt[7:0]}} : mdb_out_nxt;
+
+// Format memory data bus input depending on BW
+reg mab_lsb;
+always @(posedge mclk or posedge puc_rst)
+ if (puc_rst) mab_lsb <= 1'b0;
+ else if (mb_en) mab_lsb <= alu_out_add[0];
+
+assign mdb_in_bw = ~inst_bw ? mdb_in :
+ mab_lsb ? {2{mdb_in[15:8]}} : mdb_in;
+
+// Memory data bus input buffer (buffer after a source read)
+reg mdb_in_buf_en;
+always @(posedge mclk or posedge puc_rst)
+ if (puc_rst) mdb_in_buf_en <= 1'b0;
+ else mdb_in_buf_en <= (e_state==`E_SRC_RD);
+
+reg mdb_in_buf_valid;
+always @(posedge mclk or posedge puc_rst)
+ if (puc_rst) mdb_in_buf_valid <= 1'b0;
+ else if (e_state==`E_EXEC) mdb_in_buf_valid <= 1'b0;
+ else if (mdb_in_buf_en) mdb_in_buf_valid <= 1'b1;
+
+reg [15:0] mdb_in_buf;
+
+`ifdef CLOCK_GATING
+wire mclk_mdb_in_buf;
+omsp_clock_gate clock_gate_mdb_in_buf (.gclk(mclk_mdb_in_buf),
+ .clk (mclk), .enable(mdb_in_buf_en), .scan_enable(scan_enable));
+`else
+wire mclk_mdb_in_buf = mclk;
+`endif
+
+always @(posedge mclk_mdb_in_buf or posedge puc_rst)
+ if (puc_rst) mdb_in_buf <= 16'h0000;
+`ifdef CLOCK_GATING
+ else mdb_in_buf <= mdb_in_bw;
+`else
+ else if (mdb_in_buf_en) mdb_in_buf <= mdb_in_bw;
+`endif
+
+assign mdb_in_val = mdb_in_buf_valid ? mdb_in_buf : mdb_in_bw;
+
+
+endmodule // omsp_execution_unit
+
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_undefines.v"
+`endif
diff --git a/tests/openmsp430/rtl/omsp_frontend.v b/tests/openmsp430/rtl/omsp_frontend.v
new file mode 100644
index 000000000..343944bd2
--- /dev/null
+++ b/tests/openmsp430/rtl/omsp_frontend.v
@@ -0,0 +1,966 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2009 , Olivier Girard
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the authors nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE
+//
+//----------------------------------------------------------------------------
+//
+// *File Name: omsp_frontend.v
+//
+// *Module Description:
+// openMSP430 Instruction fetch and decode unit
+//
+// *Author(s):
+// - Olivier Girard, olgirard@gmail.com
+//
+//----------------------------------------------------------------------------
+// $Rev: 134 $
+// $LastChangedBy: olivier.girard $
+// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $
+//----------------------------------------------------------------------------
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_defines.v"
+`endif
+
+module omsp_frontend (
+
+// OUTPUTs
+ dbg_halt_st, // Halt/Run status from CPU
+ decode_noirq, // Frontend decode instruction
+ e_state, // Execution state
+ exec_done, // Execution completed
+ inst_ad, // Decoded Inst: destination addressing mode
+ inst_as, // Decoded Inst: source addressing mode
+ inst_alu, // ALU control signals
+ inst_bw, // Decoded Inst: byte width
+ inst_dest, // Decoded Inst: destination (one hot)
+ inst_dext, // Decoded Inst: destination extended instruction word
+ inst_irq_rst, // Decoded Inst: Reset interrupt
+ inst_jmp, // Decoded Inst: Conditional jump
+ inst_mov, // Decoded Inst: mov instruction
+ inst_sext, // Decoded Inst: source extended instruction word
+ inst_so, // Decoded Inst: Single-operand arithmetic
+ inst_src, // Decoded Inst: source (one hot)
+ inst_type, // Decoded Instruction type
+ irq_acc, // Interrupt request accepted (one-hot signal)
+ mab, // Frontend Memory address bus
+ mb_en, // Frontend Memory bus enable
+ mclk_enable, // Main System Clock enable
+ mclk_wkup, // Main System Clock wake-up (asynchronous)
+ nmi_acc, // Non-Maskable interrupt request accepted
+ pc, // Program counter
+ pc_nxt, // Next PC value (for CALL & IRQ)
+
+// INPUTs
+ cpu_en_s, // Enable CPU code execution (synchronous)
+ cpuoff, // Turns off the CPU
+ dbg_halt_cmd, // Halt CPU command
+ dbg_reg_sel, // Debug selected register for rd/wr access
+ fe_pmem_wait, // Frontend wait for Instruction fetch
+ gie, // General interrupt enable
+ irq, // Maskable interrupts
+ mclk, // Main system clock
+ mdb_in, // Frontend Memory data bus input
+ nmi_pnd, // Non-maskable interrupt pending
+ nmi_wkup, // NMI Wakeup
+ pc_sw, // Program counter software value
+ pc_sw_wr, // Program counter software write
+ puc_rst, // Main system reset
+ scan_enable, // Scan enable (active during scan shifting)
+ wdt_irq, // Watchdog-timer interrupt
+ wdt_wkup, // Watchdog Wakeup
+ wkup // System Wake-up (asynchronous)
+);
+
+// OUTPUTs
+//=========
+output dbg_halt_st; // Halt/Run status from CPU
+output decode_noirq; // Frontend decode instruction
+output [3:0] e_state; // Execution state
+output exec_done; // Execution completed
+output [7:0] inst_ad; // Decoded Inst: destination addressing mode
+output [7:0] inst_as; // Decoded Inst: source addressing mode
+output [11:0] inst_alu; // ALU control signals
+output inst_bw; // Decoded Inst: byte width
+output [15:0] inst_dest; // Decoded Inst: destination (one hot)
+output [15:0] inst_dext; // Decoded Inst: destination extended instruction word
+output inst_irq_rst; // Decoded Inst: Reset interrupt
+output [7:0] inst_jmp; // Decoded Inst: Conditional jump
+output inst_mov; // Decoded Inst: mov instruction
+output [15:0] inst_sext; // Decoded Inst: source extended instruction word
+output [7:0] inst_so; // Decoded Inst: Single-operand arithmetic
+output [15:0] inst_src; // Decoded Inst: source (one hot)
+output [2:0] inst_type; // Decoded Instruction type
+output [13:0] irq_acc; // Interrupt request accepted (one-hot signal)
+output [15:0] mab; // Frontend Memory address bus
+output mb_en; // Frontend Memory bus enable
+output mclk_enable; // Main System Clock enable
+output mclk_wkup; // Main System Clock wake-up (asynchronous)
+output nmi_acc; // Non-Maskable interrupt request accepted
+output [15:0] pc; // Program counter
+output [15:0] pc_nxt; // Next PC value (for CALL & IRQ)
+
+// INPUTs
+//=========
+input cpu_en_s; // Enable CPU code execution (synchronous)
+input cpuoff; // Turns off the CPU
+input dbg_halt_cmd; // Halt CPU command
+input [3:0] dbg_reg_sel; // Debug selected register for rd/wr access
+input fe_pmem_wait; // Frontend wait for Instruction fetch
+input gie; // General interrupt enable
+input [13:0] irq; // Maskable interrupts
+input mclk; // Main system clock
+input [15:0] mdb_in; // Frontend Memory data bus input
+input nmi_pnd; // Non-maskable interrupt pending
+input nmi_wkup; // NMI Wakeup
+input [15:0] pc_sw; // Program counter software value
+input pc_sw_wr; // Program counter software write
+input puc_rst; // Main system reset
+input scan_enable; // Scan enable (active during scan shifting)
+input wdt_irq; // Watchdog-timer interrupt
+input wdt_wkup; // Watchdog Wakeup
+input wkup; // System Wake-up (asynchronous)
+
+
+//=============================================================================
+// 1) UTILITY FUNCTIONS
+//=============================================================================
+
+// 16 bits one-hot decoder
+function [15:0] one_hot16;
+ input [3:0] binary;
+ begin
+ one_hot16 = 16'h0000;
+ one_hot16[binary] = 1'b1;
+ end
+endfunction
+
+// 8 bits one-hot decoder
+function [7:0] one_hot8;
+ input [2:0] binary;
+ begin
+ one_hot8 = 8'h00;
+ one_hot8[binary] = 1'b1;
+ end
+endfunction
+
+
+//=============================================================================
+// 2) PARAMETER DEFINITIONS
+//=============================================================================
+
+//
+// 2.1) Instruction State machine definitons
+//-------------------------------------------
+
+parameter I_IRQ_FETCH = `I_IRQ_FETCH;
+parameter I_IRQ_DONE = `I_IRQ_DONE;
+parameter I_DEC = `I_DEC; // New instruction ready for decode
+parameter I_EXT1 = `I_EXT1; // 1st Extension word
+parameter I_EXT2 = `I_EXT2; // 2nd Extension word
+parameter I_IDLE = `I_IDLE; // CPU is in IDLE mode
+
+//
+// 2.2) Execution State machine definitons
+//-------------------------------------------
+
+parameter E_IRQ_0 = `E_IRQ_0;
+parameter E_IRQ_1 = `E_IRQ_1;
+parameter E_IRQ_2 = `E_IRQ_2;
+parameter E_IRQ_3 = `E_IRQ_3;
+parameter E_IRQ_4 = `E_IRQ_4;
+parameter E_SRC_AD = `E_SRC_AD;
+parameter E_SRC_RD = `E_SRC_RD;
+parameter E_SRC_WR = `E_SRC_WR;
+parameter E_DST_AD = `E_DST_AD;
+parameter E_DST_RD = `E_DST_RD;
+parameter E_DST_WR = `E_DST_WR;
+parameter E_EXEC = `E_EXEC;
+parameter E_JUMP = `E_JUMP;
+parameter E_IDLE = `E_IDLE;
+
+
+//=============================================================================
+// 3) FRONTEND STATE MACHINE
+//=============================================================================
+
+// The wire "conv" is used as state bits to calculate the next response
+reg [2:0] i_state;
+reg [2:0] i_state_nxt;
+
+reg [1:0] inst_sz;
+wire [1:0] inst_sz_nxt;
+wire irq_detect;
+wire [2:0] inst_type_nxt;
+wire is_const;
+reg [15:0] sconst_nxt;
+reg [3:0] e_state_nxt;
+
+// CPU on/off through the debug interface or cpu_en port
+wire cpu_halt_cmd = dbg_halt_cmd | ~cpu_en_s;
+
+// States Transitions
+always @(i_state or inst_sz or inst_sz_nxt or pc_sw_wr or exec_done or
+ irq_detect or cpuoff or cpu_halt_cmd or e_state)
+ case(i_state)
+ I_IDLE : i_state_nxt = (irq_detect & ~cpu_halt_cmd) ? I_IRQ_FETCH :
+ (~cpuoff & ~cpu_halt_cmd) ? I_DEC : I_IDLE;
+ I_IRQ_FETCH: i_state_nxt = I_IRQ_DONE;
+ I_IRQ_DONE : i_state_nxt = I_DEC;
+ I_DEC : i_state_nxt = irq_detect ? I_IRQ_FETCH :
+ (cpuoff | cpu_halt_cmd) & exec_done ? I_IDLE :
+ cpu_halt_cmd & (e_state==E_IDLE) ? I_IDLE :
+ pc_sw_wr ? I_DEC :
+ ~exec_done & ~(e_state==E_IDLE) ? I_DEC : // Wait in decode state
+ (inst_sz_nxt!=2'b00) ? I_EXT1 : I_DEC; // until execution is completed
+ I_EXT1 : i_state_nxt = pc_sw_wr ? I_DEC :
+ (inst_sz!=2'b01) ? I_EXT2 : I_DEC;
+ I_EXT2 : i_state_nxt = I_DEC;
+ // pragma coverage off
+ default : i_state_nxt = I_IRQ_FETCH;
+ // pragma coverage on
+ endcase
+
+// State machine
+always @(posedge mclk or posedge puc_rst)
+ if (puc_rst) i_state <= I_IRQ_FETCH;
+ else i_state <= i_state_nxt;
+
+// Utility signals
+wire decode_noirq = ((i_state==I_DEC) & (exec_done | (e_state==E_IDLE)));
+wire decode = decode_noirq | irq_detect;
+wire fetch = ~((i_state==I_DEC) & ~(exec_done | (e_state==E_IDLE))) & ~(e_state_nxt==E_IDLE);
+
+// Debug interface cpu status
+reg dbg_halt_st;
+always @(posedge mclk or posedge puc_rst)
+ if (puc_rst) dbg_halt_st <= 1'b0;
+ else dbg_halt_st <= cpu_halt_cmd & (i_state_nxt==I_IDLE);
+
+
+//=============================================================================
+// 4) INTERRUPT HANDLING & SYSTEM WAKEUP
+//=============================================================================
+
+//
+// 4.1) INTERRUPT HANDLING
+//-----------------------------------------
+
+// Detect reset interrupt
+reg inst_irq_rst;
+always @(posedge mclk or posedge puc_rst)
+ if (puc_rst) inst_irq_rst <= 1'b1;
+ else if (exec_done) inst_irq_rst <= 1'b0;
+
+// Detect other interrupts
+assign irq_detect = (nmi_pnd | ((|irq | wdt_irq) & gie)) & ~cpu_halt_cmd & ~dbg_halt_st & (exec_done | (i_state==I_IDLE));
+
+`ifdef CLOCK_GATING
+wire mclk_irq_num;
+omsp_clock_gate clock_gate_irq_num (.gclk(mclk_irq_num),
+ .clk (mclk), .enable(irq_detect), .scan_enable(scan_enable));
+`else
+wire mclk_irq_num = mclk;
+`endif
+
+// Select interrupt vector
+reg [3:0] irq_num;
+always @(posedge mclk_irq_num or posedge puc_rst)
+ if (puc_rst) irq_num <= 4'hf;
+`ifdef CLOCK_GATING
+ else irq_num <= nmi_pnd ? 4'he :
+`else
+ else if (irq_detect) irq_num <= nmi_pnd ? 4'he :
+`endif
+ irq[13] ? 4'hd :
+ irq[12] ? 4'hc :
+ irq[11] ? 4'hb :
+ (irq[10] | wdt_irq) ? 4'ha :
+ irq[9] ? 4'h9 :
+ irq[8] ? 4'h8 :
+ irq[7] ? 4'h7 :
+ irq[6] ? 4'h6 :
+ irq[5] ? 4'h5 :
+ irq[4] ? 4'h4 :
+ irq[3] ? 4'h3 :
+ irq[2] ? 4'h2 :
+ irq[1] ? 4'h1 :
+ irq[0] ? 4'h0 : 4'hf;
+
+wire [15:0] irq_addr = {11'h7ff, irq_num, 1'b0};
+
+// Interrupt request accepted
+wire [15:0] irq_acc_all = one_hot16(irq_num) & {16{(i_state==I_IRQ_FETCH)}};
+wire [13:0] irq_acc = irq_acc_all[13:0];
+wire nmi_acc = irq_acc_all[14];
+
+//
+// 4.2) SYSTEM WAKEUP
+//-----------------------------------------
+`ifdef CPUOFF_EN
+
+// Generate the main system clock enable signal
+ // Keep the clock running if:
+wire mclk_enable = inst_irq_rst ? cpu_en_s : // - the RESET interrupt is currently executing
+ // and if the CPU is enabled
+ // otherwise if:
+ ~((cpuoff | ~cpu_en_s) & // - the CPUOFF flag, cpu_en command, instruction
+ (i_state==I_IDLE) & // and execution state machines are all two
+ (e_state==E_IDLE)); // not idle.
+
+
+// Wakeup condition from maskable interrupts
+wire mirq_wkup;
+omsp_and_gate and_mirq_wkup (.y(mirq_wkup), .a(wkup | wdt_wkup), .b(gie));
+
+// Combined asynchronous wakeup detection from nmi & irq (masked if the cpu is disabled)
+omsp_and_gate and_mclk_wkup (.y(mclk_wkup), .a(nmi_wkup | mirq_wkup), .b(cpu_en_s));
+
+`else
+
+// In the CPUOFF feature is disabled, the wake-up and enable signals are always 1
+assign mclk_wkup = 1'b1;
+assign mclk_enable = 1'b1;
+`endif
+
+//=============================================================================
+// 5) FETCH INSTRUCTION
+//=============================================================================
+
+//
+// 5.1) PROGRAM COUNTER & MEMORY INTERFACE
+//-----------------------------------------
+
+// Program counter
+reg [15:0] pc;
+
+// Compute next PC value
+wire [15:0] pc_incr = pc + {14'h0000, fetch, 1'b0};
+wire [15:0] pc_nxt = pc_sw_wr ? pc_sw :
+ (i_state==I_IRQ_FETCH) ? irq_addr :
+ (i_state==I_IRQ_DONE) ? mdb_in : pc_incr;
+
+`ifdef CLOCK_GATING
+wire pc_en = fetch |
+ pc_sw_wr |
+ (i_state==I_IRQ_FETCH) |
+ (i_state==I_IRQ_DONE);
+wire mclk_pc;
+omsp_clock_gate clock_gate_pc (.gclk(mclk_pc),
+ .clk (mclk), .enable(pc_en), .scan_enable(scan_enable));
+`else
+wire mclk_pc = mclk;
+`endif
+
+always @(posedge mclk_pc or posedge puc_rst)
+ if (puc_rst) pc <= 16'h0000;
+ else pc <= pc_nxt;
+
+// Check if ROM has been busy in order to retry ROM access
+reg pmem_busy;
+always @(posedge mclk or posedge puc_rst)
+ if (puc_rst) pmem_busy <= 1'b0;
+ else pmem_busy <= fe_pmem_wait;
+
+// Memory interface
+wire [15:0] mab = pc_nxt;
+wire mb_en = fetch | pc_sw_wr | (i_state==I_IRQ_FETCH) | pmem_busy | (dbg_halt_st & ~cpu_halt_cmd);
+
+
+//
+// 5.2) INSTRUCTION REGISTER
+//--------------------------------
+
+// Instruction register
+wire [15:0] ir = mdb_in;
+
+// Detect if source extension word is required
+wire is_sext = (inst_as[`IDX] | inst_as[`SYMB] | inst_as[`ABS] | inst_as[`IMM]);
+
+// For the Symbolic addressing mode, add -2 to the extension word in order
+// to make up for the PC address
+wire [15:0] ext_incr = ((i_state==I_EXT1) & inst_as[`SYMB]) |
+ ((i_state==I_EXT2) & inst_ad[`SYMB]) |
+ ((i_state==I_EXT1) & ~inst_as[`SYMB] &
+ ~(i_state_nxt==I_EXT2) & inst_ad[`SYMB]) ? 16'hfffe : 16'h0000;
+
+wire [15:0] ext_nxt = ir + ext_incr;
+
+// Store source extension word
+reg [15:0] inst_sext;
+
+`ifdef CLOCK_GATING
+wire inst_sext_en = (decode & is_const) |
+ (decode & inst_type_nxt[`INST_JMP]) |
+ ((i_state==I_EXT1) & is_sext);
+wire mclk_inst_sext;
+omsp_clock_gate clock_gate_inst_sext (.gclk(mclk_inst_sext),
+ .clk (mclk), .enable(inst_sext_en), .scan_enable(scan_enable));
+`else
+wire mclk_inst_sext = mclk;
+`endif
+
+always @(posedge mclk_inst_sext or posedge puc_rst)
+ if (puc_rst) inst_sext <= 16'h0000;
+ else if (decode & is_const) inst_sext <= sconst_nxt;
+ else if (decode & inst_type_nxt[`INST_JMP]) inst_sext <= {{5{ir[9]}},ir[9:0],1'b0};
+`ifdef CLOCK_GATING
+ else inst_sext <= ext_nxt;
+`else
+ else if ((i_state==I_EXT1) & is_sext) inst_sext <= ext_nxt;
+`endif
+
+// Source extension word is ready
+wire inst_sext_rdy = (i_state==I_EXT1) & is_sext;
+
+
+// Store destination extension word
+reg [15:0] inst_dext;
+
+`ifdef CLOCK_GATING
+wire inst_dext_en = ((i_state==I_EXT1) & ~is_sext) |
+ (i_state==I_EXT2);
+wire mclk_inst_dext;
+omsp_clock_gate clock_gate_inst_dext (.gclk(mclk_inst_dext),
+ .clk (mclk), .enable(inst_dext_en), .scan_enable(scan_enable));
+`else
+wire mclk_inst_dext = mclk;
+`endif
+
+always @(posedge mclk_inst_dext or posedge puc_rst)
+ if (puc_rst) inst_dext <= 16'h0000;
+ else if ((i_state==I_EXT1) & ~is_sext) inst_dext <= ext_nxt;
+`ifdef CLOCK_GATING
+ else inst_dext <= ext_nxt;
+`else
+ else if (i_state==I_EXT2) inst_dext <= ext_nxt;
+`endif
+
+// Destination extension word is ready
+wire inst_dext_rdy = (((i_state==I_EXT1) & ~is_sext) | (i_state==I_EXT2));
+
+
+//=============================================================================
+// 6) DECODE INSTRUCTION
+//=============================================================================
+
+`ifdef CLOCK_GATING
+wire mclk_decode;
+omsp_clock_gate clock_gate_decode (.gclk(mclk_decode),
+ .clk (mclk), .enable(decode), .scan_enable(scan_enable));
+`else
+wire mclk_decode = mclk;
+`endif
+
+//
+// 6.1) OPCODE: INSTRUCTION TYPE
+//----------------------------------------
+// Instructions type is encoded in a one hot fashion as following:
+//
+// 3'b001: Single-operand arithmetic
+// 3'b010: Conditional jump
+// 3'b100: Two-operand arithmetic
+
+reg [2:0] inst_type;
+assign inst_type_nxt = {(ir[15:14]!=2'b00),
+ (ir[15:13]==3'b001),
+ (ir[15:13]==3'b000)} & {3{~irq_detect}};
+
+always @(posedge mclk_decode or posedge puc_rst)
+ if (puc_rst) inst_type <= 3'b000;
+`ifdef CLOCK_GATING
+ else inst_type <= inst_type_nxt;
+`else
+ else if (decode) inst_type <= inst_type_nxt;
+`endif
+
+//
+// 6.2) OPCODE: SINGLE-OPERAND ARITHMETIC
+//----------------------------------------
+// Instructions are encoded in a one hot fashion as following:
+//
+// 8'b00000001: RRC
+// 8'b00000010: SWPB
+// 8'b00000100: RRA
+// 8'b00001000: SXT
+// 8'b00010000: PUSH
+// 8'b00100000: CALL
+// 8'b01000000: RETI
+// 8'b10000000: IRQ
+
+reg [7:0] inst_so;
+wire [7:0] inst_so_nxt = irq_detect ? 8'h80 : (one_hot8(ir[9:7]) & {8{inst_type_nxt[`INST_SO]}});
+
+always @(posedge mclk_decode or posedge puc_rst)
+ if (puc_rst) inst_so <= 8'h00;
+`ifdef CLOCK_GATING
+ else inst_so <= inst_so_nxt;
+`else
+ else if (decode) inst_so <= inst_so_nxt;
+`endif
+
+//
+// 6.3) OPCODE: CONDITIONAL JUMP
+//--------------------------------
+// Instructions are encoded in a one hot fashion as following:
+//
+// 8'b00000001: JNE/JNZ
+// 8'b00000010: JEQ/JZ
+// 8'b00000100: JNC/JLO
+// 8'b00001000: JC/JHS
+// 8'b00010000: JN
+// 8'b00100000: JGE
+// 8'b01000000: JL
+// 8'b10000000: JMP
+
+reg [2:0] inst_jmp_bin;
+always @(posedge mclk_decode or posedge puc_rst)
+ if (puc_rst) inst_jmp_bin <= 3'h0;
+`ifdef CLOCK_GATING
+ else inst_jmp_bin <= ir[12:10];
+`else
+ else if (decode) inst_jmp_bin <= ir[12:10];
+`endif
+
+wire [7:0] inst_jmp = one_hot8(inst_jmp_bin) & {8{inst_type[`INST_JMP]}};
+
+
+//
+// 6.4) OPCODE: TWO-OPERAND ARITHMETIC
+//-------------------------------------
+// Instructions are encoded in a one hot fashion as following:
+//
+// 12'b000000000001: MOV
+// 12'b000000000010: ADD
+// 12'b000000000100: ADDC
+// 12'b000000001000: SUBC
+// 12'b000000010000: SUB
+// 12'b000000100000: CMP
+// 12'b000001000000: DADD
+// 12'b000010000000: BIT
+// 12'b000100000000: BIC
+// 12'b001000000000: BIS
+// 12'b010000000000: XOR
+// 12'b100000000000: AND
+
+wire [15:0] inst_to_1hot = one_hot16(ir[15:12]) & {16{inst_type_nxt[`INST_TO]}};
+wire [11:0] inst_to_nxt = inst_to_1hot[15:4];
+
+reg inst_mov;
+always @(posedge mclk_decode or posedge puc_rst)
+ if (puc_rst) inst_mov <= 1'b0;
+`ifdef CLOCK_GATING
+ else inst_mov <= inst_to_nxt[`MOV];
+`else
+ else if (decode) inst_mov <= inst_to_nxt[`MOV];
+`endif
+
+
+//
+// 6.5) SOURCE AND DESTINATION REGISTERS
+//---------------------------------------
+
+// Destination register
+reg [3:0] inst_dest_bin;
+always @(posedge mclk_decode or posedge puc_rst)
+ if (puc_rst) inst_dest_bin <= 4'h0;
+`ifdef CLOCK_GATING
+ else inst_dest_bin <= ir[3:0];
+`else
+ else if (decode) inst_dest_bin <= ir[3:0];
+`endif
+
+wire [15:0] inst_dest = dbg_halt_st ? one_hot16(dbg_reg_sel) :
+ inst_type[`INST_JMP] ? 16'h0001 :
+ inst_so[`IRQ] |
+ inst_so[`PUSH] |
+ inst_so[`CALL] ? 16'h0002 :
+ one_hot16(inst_dest_bin);
+
+
+// Source register
+reg [3:0] inst_src_bin;
+always @(posedge mclk_decode or posedge puc_rst)
+ if (puc_rst) inst_src_bin <= 4'h0;
+`ifdef CLOCK_GATING
+ else inst_src_bin <= ir[11:8];
+`else
+ else if (decode) inst_src_bin <= ir[11:8];
+`endif
+
+wire [15:0] inst_src = inst_type[`INST_TO] ? one_hot16(inst_src_bin) :
+ inst_so[`RETI] ? 16'h0002 :
+ inst_so[`IRQ] ? 16'h0001 :
+ inst_type[`INST_SO] ? one_hot16(inst_dest_bin) : 16'h0000;
+
+
+//
+// 6.6) SOURCE ADDRESSING MODES
+//--------------------------------
+// Source addressing modes are encoded in a one hot fashion as following:
+//
+// 13'b0000000000001: Register direct.
+// 13'b0000000000010: Register indexed.
+// 13'b0000000000100: Register indirect.
+// 13'b0000000001000: Register indirect autoincrement.
+// 13'b0000000010000: Symbolic (operand is in memory at address PC+x).
+// 13'b0000000100000: Immediate (operand is next word in the instruction stream).
+// 13'b0000001000000: Absolute (operand is in memory at address x).
+// 13'b0000010000000: Constant 4.
+// 13'b0000100000000: Constant 8.
+// 13'b0001000000000: Constant 0.
+// 13'b0010000000000: Constant 1.
+// 13'b0100000000000: Constant 2.
+// 13'b1000000000000: Constant -1.
+
+reg [12:0] inst_as_nxt;
+
+wire [3:0] src_reg = inst_type_nxt[`INST_SO] ? ir[3:0] : ir[11:8];
+
+always @(src_reg or ir or inst_type_nxt)
+ begin
+ if (inst_type_nxt[`INST_JMP])
+ inst_as_nxt = 13'b0000000000001;
+ else if (src_reg==4'h3) // Addressing mode using R3
+ case (ir[5:4])
+ 2'b11 : inst_as_nxt = 13'b1000000000000;
+ 2'b10 : inst_as_nxt = 13'b0100000000000;
+ 2'b01 : inst_as_nxt = 13'b0010000000000;
+ default: inst_as_nxt = 13'b0001000000000;
+ endcase
+ else if (src_reg==4'h2) // Addressing mode using R2
+ case (ir[5:4])
+ 2'b11 : inst_as_nxt = 13'b0000100000000;
+ 2'b10 : inst_as_nxt = 13'b0000010000000;
+ 2'b01 : inst_as_nxt = 13'b0000001000000;
+ default: inst_as_nxt = 13'b0000000000001;
+ endcase
+ else if (src_reg==4'h0) // Addressing mode using R0
+ case (ir[5:4])
+ 2'b11 : inst_as_nxt = 13'b0000000100000;
+ 2'b10 : inst_as_nxt = 13'b0000000000100;
+ 2'b01 : inst_as_nxt = 13'b0000000010000;
+ default: inst_as_nxt = 13'b0000000000001;
+ endcase
+ else // General Addressing mode
+ case (ir[5:4])
+ 2'b11 : inst_as_nxt = 13'b0000000001000;
+ 2'b10 : inst_as_nxt = 13'b0000000000100;
+ 2'b01 : inst_as_nxt = 13'b0000000000010;
+ default: inst_as_nxt = 13'b0000000000001;
+ endcase
+ end
+assign is_const = |inst_as_nxt[12:7];
+
+reg [7:0] inst_as;
+always @(posedge mclk_decode or posedge puc_rst)
+ if (puc_rst) inst_as <= 8'h00;
+`ifdef CLOCK_GATING
+ else inst_as <= {is_const, inst_as_nxt[6:0]};
+`else
+ else if (decode) inst_as <= {is_const, inst_as_nxt[6:0]};
+`endif
+
+
+// 13'b0000010000000: Constant 4.
+// 13'b0000100000000: Constant 8.
+// 13'b0001000000000: Constant 0.
+// 13'b0010000000000: Constant 1.
+// 13'b0100000000000: Constant 2.
+// 13'b1000000000000: Constant -1.
+always @(inst_as_nxt)
+ begin
+ if (inst_as_nxt[7]) sconst_nxt = 16'h0004;
+ else if (inst_as_nxt[8]) sconst_nxt = 16'h0008;
+ else if (inst_as_nxt[9]) sconst_nxt = 16'h0000;
+ else if (inst_as_nxt[10]) sconst_nxt = 16'h0001;
+ else if (inst_as_nxt[11]) sconst_nxt = 16'h0002;
+ else if (inst_as_nxt[12]) sconst_nxt = 16'hffff;
+ else sconst_nxt = 16'h0000;
+ end
+
+
+//
+// 6.7) DESTINATION ADDRESSING MODES
+//-----------------------------------
+// Destination addressing modes are encoded in a one hot fashion as following:
+//
+// 8'b00000001: Register direct.
+// 8'b00000010: Register indexed.
+// 8'b00010000: Symbolic (operand is in memory at address PC+x).
+// 8'b01000000: Absolute (operand is in memory at address x).
+
+reg [7:0] inst_ad_nxt;
+
+wire [3:0] dest_reg = ir[3:0];
+
+always @(dest_reg or ir or inst_type_nxt)
+ begin
+ if (~inst_type_nxt[`INST_TO])
+ inst_ad_nxt = 8'b00000000;
+ else if (dest_reg==4'h2) // Addressing mode using R2
+ case (ir[7])
+ 1'b1 : inst_ad_nxt = 8'b01000000;
+ default: inst_ad_nxt = 8'b00000001;
+ endcase
+ else if (dest_reg==4'h0) // Addressing mode using R0
+ case (ir[7])
+ 1'b1 : inst_ad_nxt = 8'b00010000;
+ default: inst_ad_nxt = 8'b00000001;
+ endcase
+ else // General Addressing mode
+ case (ir[7])
+ 1'b1 : inst_ad_nxt = 8'b00000010;
+ default: inst_ad_nxt = 8'b00000001;
+ endcase
+ end
+
+reg [7:0] inst_ad;
+always @(posedge mclk_decode or posedge puc_rst)
+ if (puc_rst) inst_ad <= 8'h00;
+`ifdef CLOCK_GATING
+ else inst_ad <= inst_ad_nxt;
+`else
+ else if (decode) inst_ad <= inst_ad_nxt;
+`endif
+
+
+//
+// 6.8) REMAINING INSTRUCTION DECODING
+//-------------------------------------
+
+// Operation size
+reg inst_bw;
+always @(posedge mclk or posedge puc_rst)
+ if (puc_rst) inst_bw <= 1'b0;
+ else if (decode) inst_bw <= ir[6] & ~inst_type_nxt[`INST_JMP] & ~irq_detect & ~cpu_halt_cmd;
+
+// Extended instruction size
+assign inst_sz_nxt = {1'b0, (inst_as_nxt[`IDX] | inst_as_nxt[`SYMB] | inst_as_nxt[`ABS] | inst_as_nxt[`IMM])} +
+ {1'b0, ((inst_ad_nxt[`IDX] | inst_ad_nxt[`SYMB] | inst_ad_nxt[`ABS]) & ~inst_type_nxt[`INST_SO])};
+always @(posedge mclk_decode or posedge puc_rst)
+ if (puc_rst) inst_sz <= 2'b00;
+`ifdef CLOCK_GATING
+ else inst_sz <= inst_sz_nxt;
+`else
+ else if (decode) inst_sz <= inst_sz_nxt;
+`endif
+
+
+//=============================================================================
+// 7) EXECUTION-UNIT STATE MACHINE
+//=============================================================================
+
+// State machine registers
+reg [3:0] e_state;
+
+
+// State machine control signals
+//--------------------------------
+
+wire src_acalc_pre = inst_as_nxt[`IDX] | inst_as_nxt[`SYMB] | inst_as_nxt[`ABS];
+wire src_rd_pre = inst_as_nxt[`INDIR] | inst_as_nxt[`INDIR_I] | inst_as_nxt[`IMM] | inst_so_nxt[`RETI];
+wire dst_acalc_pre = inst_ad_nxt[`IDX] | inst_ad_nxt[`SYMB] | inst_ad_nxt[`ABS];
+wire dst_acalc = inst_ad[`IDX] | inst_ad[`SYMB] | inst_ad[`ABS];
+wire dst_rd_pre = inst_ad_nxt[`IDX] | inst_so_nxt[`PUSH] | inst_so_nxt[`CALL] | inst_so_nxt[`RETI];
+wire dst_rd = inst_ad[`IDX] | inst_so[`PUSH] | inst_so[`CALL] | inst_so[`RETI];
+
+wire inst_branch = (inst_ad_nxt[`DIR] & (ir[3:0]==4'h0)) | inst_type_nxt[`INST_JMP] | inst_so_nxt[`RETI];
+
+reg exec_jmp;
+always @(posedge mclk or posedge puc_rst)
+ if (puc_rst) exec_jmp <= 1'b0;
+ else if (inst_branch & decode) exec_jmp <= 1'b1;
+ else if (e_state==E_JUMP) exec_jmp <= 1'b0;
+
+reg exec_dst_wr;
+always @(posedge mclk or posedge puc_rst)
+ if (puc_rst) exec_dst_wr <= 1'b0;
+ else if (e_state==E_DST_RD) exec_dst_wr <= 1'b1;
+ else if (e_state==E_DST_WR) exec_dst_wr <= 1'b0;
+
+reg exec_src_wr;
+always @(posedge mclk or posedge puc_rst)
+ if (puc_rst) exec_src_wr <= 1'b0;
+ else if (inst_type[`INST_SO] & (e_state==E_SRC_RD)) exec_src_wr <= 1'b1;
+ else if ((e_state==E_SRC_WR) || (e_state==E_DST_WR)) exec_src_wr <= 1'b0;
+
+reg exec_dext_rdy;
+always @(posedge mclk or posedge puc_rst)
+ if (puc_rst) exec_dext_rdy <= 1'b0;
+ else if (e_state==E_DST_RD) exec_dext_rdy <= 1'b0;
+ else if (inst_dext_rdy) exec_dext_rdy <= 1'b1;
+
+// Execution first state
+wire [3:0] e_first_state = ~dbg_halt_st & inst_so_nxt[`IRQ] ? E_IRQ_0 :
+ cpu_halt_cmd | (i_state==I_IDLE) ? E_IDLE :
+ cpuoff ? E_IDLE :
+ src_acalc_pre ? E_SRC_AD :
+ src_rd_pre ? E_SRC_RD :
+ dst_acalc_pre ? E_DST_AD :
+ dst_rd_pre ? E_DST_RD : E_EXEC;
+
+
+// State machine
+//--------------------------------
+
+// States Transitions
+always @(e_state or dst_acalc or dst_rd or inst_sext_rdy or
+ inst_dext_rdy or exec_dext_rdy or exec_jmp or exec_dst_wr or
+ e_first_state or exec_src_wr)
+ case(e_state)
+ E_IDLE : e_state_nxt = e_first_state;
+ E_IRQ_0 : e_state_nxt = E_IRQ_1;
+ E_IRQ_1 : e_state_nxt = E_IRQ_2;
+ E_IRQ_2 : e_state_nxt = E_IRQ_3;
+ E_IRQ_3 : e_state_nxt = E_IRQ_4;
+ E_IRQ_4 : e_state_nxt = E_EXEC;
+
+ E_SRC_AD : e_state_nxt = inst_sext_rdy ? E_SRC_RD : E_SRC_AD;
+
+ E_SRC_RD : e_state_nxt = dst_acalc ? E_DST_AD :
+ dst_rd ? E_DST_RD : E_EXEC;
+
+ E_DST_AD : e_state_nxt = (inst_dext_rdy |
+ exec_dext_rdy) ? E_DST_RD : E_DST_AD;
+
+ E_DST_RD : e_state_nxt = E_EXEC;
+
+ E_EXEC : e_state_nxt = exec_dst_wr ? E_DST_WR :
+ exec_jmp ? E_JUMP :
+ exec_src_wr ? E_SRC_WR : e_first_state;
+
+ E_JUMP : e_state_nxt = e_first_state;
+ E_DST_WR : e_state_nxt = exec_jmp ? E_JUMP : e_first_state;
+ E_SRC_WR : e_state_nxt = e_first_state;
+ // pragma coverage off
+ default : e_state_nxt = E_IRQ_0;
+ // pragma coverage on
+ endcase
+
+// State machine
+always @(posedge mclk or posedge puc_rst)
+ if (puc_rst) e_state <= E_IRQ_1;
+ else e_state <= e_state_nxt;
+
+
+// Frontend State machine control signals
+//----------------------------------------
+
+wire exec_done = exec_jmp ? (e_state==E_JUMP) :
+ exec_dst_wr ? (e_state==E_DST_WR) :
+ exec_src_wr ? (e_state==E_SRC_WR) : (e_state==E_EXEC);
+
+
+//=============================================================================
+// 8) EXECUTION-UNIT STATE CONTROL
+//=============================================================================
+
+//
+// 8.1) ALU CONTROL SIGNALS
+//-------------------------------------
+//
+// 12'b000000000001: Enable ALU source inverter
+// 12'b000000000010: Enable Incrementer
+// 12'b000000000100: Enable Incrementer on carry bit
+// 12'b000000001000: Select Adder
+// 12'b000000010000: Select AND
+// 12'b000000100000: Select OR
+// 12'b000001000000: Select XOR
+// 12'b000010000000: Select DADD
+// 12'b000100000000: Update N, Z & C (C=~Z)
+// 12'b001000000000: Update all status bits
+// 12'b010000000000: Update status bit for XOR instruction
+// 12'b100000000000: Don't write to destination
+
+reg [11:0] inst_alu;
+
+wire alu_src_inv = inst_to_nxt[`SUB] | inst_to_nxt[`SUBC] |
+ inst_to_nxt[`CMP] | inst_to_nxt[`BIC] ;
+
+wire alu_inc = inst_to_nxt[`SUB] | inst_to_nxt[`CMP];
+
+wire alu_inc_c = inst_to_nxt[`ADDC] | inst_to_nxt[`DADD] |
+ inst_to_nxt[`SUBC];
+
+wire alu_add = inst_to_nxt[`ADD] | inst_to_nxt[`ADDC] |
+ inst_to_nxt[`SUB] | inst_to_nxt[`SUBC] |
+ inst_to_nxt[`CMP] | inst_type_nxt[`INST_JMP] |
+ inst_so_nxt[`RETI];
+
+
+wire alu_and = inst_to_nxt[`AND] | inst_to_nxt[`BIC] |
+ inst_to_nxt[`BIT];
+
+wire alu_or = inst_to_nxt[`BIS];
+
+wire alu_xor = inst_to_nxt[`XOR];
+
+wire alu_dadd = inst_to_nxt[`DADD];
+
+wire alu_stat_7 = inst_to_nxt[`BIT] | inst_to_nxt[`AND] |
+ inst_so_nxt[`SXT];
+
+wire alu_stat_f = inst_to_nxt[`ADD] | inst_to_nxt[`ADDC] |
+ inst_to_nxt[`SUB] | inst_to_nxt[`SUBC] |
+ inst_to_nxt[`CMP] | inst_to_nxt[`DADD] |
+ inst_to_nxt[`BIT] | inst_to_nxt[`XOR] |
+ inst_to_nxt[`AND] |
+ inst_so_nxt[`RRC] | inst_so_nxt[`RRA] |
+ inst_so_nxt[`SXT];
+
+wire alu_shift = inst_so_nxt[`RRC] | inst_so_nxt[`RRA];
+
+wire exec_no_wr = inst_to_nxt[`CMP] | inst_to_nxt[`BIT];
+
+wire [11:0] inst_alu_nxt = {exec_no_wr,
+ alu_shift,
+ alu_stat_f,
+ alu_stat_7,
+ alu_dadd,
+ alu_xor,
+ alu_or,
+ alu_and,
+ alu_add,
+ alu_inc_c,
+ alu_inc,
+ alu_src_inv};
+
+always @(posedge mclk_decode or posedge puc_rst)
+ if (puc_rst) inst_alu <= 12'h000;
+`ifdef CLOCK_GATING
+ else inst_alu <= inst_alu_nxt;
+`else
+ else if (decode) inst_alu <= inst_alu_nxt;
+`endif
+
+
+endmodule // omsp_frontend
+
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_undefines.v"
+`endif
diff --git a/tests/openmsp430/rtl/omsp_mem_backbone.v b/tests/openmsp430/rtl/omsp_mem_backbone.v
new file mode 100644
index 000000000..299cbff88
--- /dev/null
+++ b/tests/openmsp430/rtl/omsp_mem_backbone.v
@@ -0,0 +1,275 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2009 , Olivier Girard
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the authors nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE
+//
+//----------------------------------------------------------------------------
+//
+// *File Name: omsp_mem_backbone.v
+//
+// *Module Description:
+// Memory interface backbone (decoder + arbiter)
+//
+// *Author(s):
+// - Olivier Girard, olgirard@gmail.com
+//
+//----------------------------------------------------------------------------
+// $Rev: 151 $
+// $LastChangedBy: olivier.girard $
+// $LastChangedDate: 2012-07-23 00:24:11 +0200 (Mon, 23 Jul 2012) $
+//----------------------------------------------------------------------------
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_defines.v"
+`endif
+
+module omsp_mem_backbone (
+
+// OUTPUTs
+ dbg_mem_din, // Debug unit Memory data input
+ dmem_addr, // Data Memory address
+ dmem_cen, // Data Memory chip enable (low active)
+ dmem_din, // Data Memory data input
+ dmem_wen, // Data Memory write enable (low active)
+ eu_mdb_in, // Execution Unit Memory data bus input
+ fe_mdb_in, // Frontend Memory data bus input
+ fe_pmem_wait, // Frontend wait for Instruction fetch
+ per_addr, // Peripheral address
+ per_din, // Peripheral data input
+ per_we, // Peripheral write enable (high active)
+ per_en, // Peripheral enable (high active)
+ pmem_addr, // Program Memory address
+ pmem_cen, // Program Memory chip enable (low active)
+ pmem_din, // Program Memory data input (optional)
+ pmem_wen, // Program Memory write enable (low active) (optional)
+
+// INPUTs
+ dbg_halt_st, // Halt/Run status from CPU
+ dbg_mem_addr, // Debug address for rd/wr access
+ dbg_mem_dout, // Debug unit data output
+ dbg_mem_en, // Debug unit memory enable
+ dbg_mem_wr, // Debug unit memory write
+ dmem_dout, // Data Memory data output
+ eu_mab, // Execution Unit Memory address bus
+ eu_mb_en, // Execution Unit Memory bus enable
+ eu_mb_wr, // Execution Unit Memory bus write transfer
+ eu_mdb_out, // Execution Unit Memory data bus output
+ fe_mab, // Frontend Memory address bus
+ fe_mb_en, // Frontend Memory bus enable
+ mclk, // Main system clock
+ per_dout, // Peripheral data output
+ pmem_dout, // Program Memory data output
+ puc_rst, // Main system reset
+ scan_enable // Scan enable (active during scan shifting)
+);
+
+// OUTPUTs
+//=========
+output [15:0] dbg_mem_din; // Debug unit Memory data input
+output [`DMEM_MSB:0] dmem_addr; // Data Memory address
+output dmem_cen; // Data Memory chip enable (low active)
+output [15:0] dmem_din; // Data Memory data input
+output [1:0] dmem_wen; // Data Memory write enable (low active)
+output [15:0] eu_mdb_in; // Execution Unit Memory data bus input
+output [15:0] fe_mdb_in; // Frontend Memory data bus input
+output fe_pmem_wait; // Frontend wait for Instruction fetch
+output [13:0] per_addr; // Peripheral address
+output [15:0] per_din; // Peripheral data input
+output [1:0] per_we; // Peripheral write enable (high active)
+output per_en; // Peripheral enable (high active)
+output [`PMEM_MSB:0] pmem_addr; // Program Memory address
+output pmem_cen; // Program Memory chip enable (low active)
+output [15:0] pmem_din; // Program Memory data input (optional)
+output [1:0] pmem_wen; // Program Memory write enable (low active) (optional)
+
+// INPUTs
+//=========
+input dbg_halt_st; // Halt/Run status from CPU
+input [15:0] dbg_mem_addr; // Debug address for rd/wr access
+input [15:0] dbg_mem_dout; // Debug unit data output
+input dbg_mem_en; // Debug unit memory enable
+input [1:0] dbg_mem_wr; // Debug unit memory write
+input [15:0] dmem_dout; // Data Memory data output
+input [14:0] eu_mab; // Execution Unit Memory address bus
+input eu_mb_en; // Execution Unit Memory bus enable
+input [1:0] eu_mb_wr; // Execution Unit Memory bus write transfer
+input [15:0] eu_mdb_out; // Execution Unit Memory data bus output
+input [14:0] fe_mab; // Frontend Memory address bus
+input fe_mb_en; // Frontend Memory bus enable
+input mclk; // Main system clock
+input [15:0] per_dout; // Peripheral data output
+input [15:0] pmem_dout; // Program Memory data output
+input puc_rst; // Main system reset
+input scan_enable; // Scan enable (active during scan shifting)
+
+
+//=============================================================================
+// 1) DECODER
+//=============================================================================
+
+// RAM Interface
+//------------------
+
+// Execution unit access
+wire eu_dmem_cen = ~(eu_mb_en & (eu_mab>=(`DMEM_BASE>>1)) &
+ (eu_mab<((`DMEM_BASE+`DMEM_SIZE)>>1)));
+wire [15:0] eu_dmem_addr = {1'b0, eu_mab}-(`DMEM_BASE>>1);
+
+// Debug interface access
+wire dbg_dmem_cen = ~(dbg_mem_en & (dbg_mem_addr[15:1]>=(`DMEM_BASE>>1)) &
+ (dbg_mem_addr[15:1]<((`DMEM_BASE+`DMEM_SIZE)>>1)));
+wire [15:0] dbg_dmem_addr = {1'b0, dbg_mem_addr[15:1]}-(`DMEM_BASE>>1);
+
+
+// RAM Interface
+wire [`DMEM_MSB:0] dmem_addr = ~dbg_dmem_cen ? dbg_dmem_addr[`DMEM_MSB:0] : eu_dmem_addr[`DMEM_MSB:0];
+wire dmem_cen = dbg_dmem_cen & eu_dmem_cen;
+wire [1:0] dmem_wen = ~(dbg_mem_wr | eu_mb_wr);
+wire [15:0] dmem_din = ~dbg_dmem_cen ? dbg_mem_dout : eu_mdb_out;
+
+
+// ROM Interface
+//------------------
+parameter PMEM_OFFSET = (16'hFFFF-`PMEM_SIZE+1);
+
+// Execution unit access (only read access are accepted)
+wire eu_pmem_cen = ~(eu_mb_en & ~|eu_mb_wr & (eu_mab>=(PMEM_OFFSET>>1)));
+wire [15:0] eu_pmem_addr = eu_mab-(PMEM_OFFSET>>1);
+
+// Front-end access
+wire fe_pmem_cen = ~(fe_mb_en & (fe_mab>=(PMEM_OFFSET>>1)));
+wire [15:0] fe_pmem_addr = fe_mab-(PMEM_OFFSET>>1);
+
+// Debug interface access
+wire dbg_pmem_cen = ~(dbg_mem_en & (dbg_mem_addr[15:1]>=(PMEM_OFFSET>>1)));
+wire [15:0] dbg_pmem_addr = {1'b0, dbg_mem_addr[15:1]}-(PMEM_OFFSET>>1);
+
+
+// ROM Interface (Execution unit has priority)
+wire [`PMEM_MSB:0] pmem_addr = ~dbg_pmem_cen ? dbg_pmem_addr[`PMEM_MSB:0] :
+ ~eu_pmem_cen ? eu_pmem_addr[`PMEM_MSB:0] : fe_pmem_addr[`PMEM_MSB:0];
+wire pmem_cen = fe_pmem_cen & eu_pmem_cen & dbg_pmem_cen;
+wire [1:0] pmem_wen = ~dbg_mem_wr;
+wire [15:0] pmem_din = dbg_mem_dout;
+
+wire fe_pmem_wait = (~fe_pmem_cen & ~eu_pmem_cen);
+
+
+// Peripherals
+//--------------------
+wire dbg_per_en = dbg_mem_en & (dbg_mem_addr[15:1]<(`PER_SIZE>>1));
+wire eu_per_en = eu_mb_en & (eu_mab<(`PER_SIZE>>1));
+
+wire [15:0] per_din = dbg_mem_en ? dbg_mem_dout : eu_mdb_out;
+wire [1:0] per_we = dbg_mem_en ? dbg_mem_wr : eu_mb_wr;
+wire per_en = dbg_mem_en ? dbg_per_en : eu_per_en;
+wire [`PER_MSB:0] per_addr_mux = dbg_mem_en ? dbg_mem_addr[`PER_MSB+1:1] : eu_mab[`PER_MSB:0];
+wire [14:0] per_addr_ful = {{15-`PER_AWIDTH{1'b0}}, per_addr_mux};
+wire [13:0] per_addr = per_addr_ful[13:0];
+
+reg [15:0] per_dout_val;
+always @ (posedge mclk or posedge puc_rst)
+ if (puc_rst) per_dout_val <= 16'h0000;
+ else per_dout_val <= per_dout;
+
+
+// Frontend data Mux
+//---------------------------------
+// Whenever the frontend doesn't access the ROM, backup the data
+
+// Detect whenever the data should be backuped and restored
+reg fe_pmem_cen_dly;
+always @(posedge mclk or posedge puc_rst)
+ if (puc_rst) fe_pmem_cen_dly <= 1'b0;
+ else fe_pmem_cen_dly <= fe_pmem_cen;
+
+wire fe_pmem_save = ( fe_pmem_cen & ~fe_pmem_cen_dly) & ~dbg_halt_st;
+wire fe_pmem_restore = (~fe_pmem_cen & fe_pmem_cen_dly) | dbg_halt_st;
+
+`ifdef CLOCK_GATING
+wire mclk_bckup;
+omsp_clock_gate clock_gate_bckup (.gclk(mclk_bckup),
+ .clk (mclk), .enable(fe_pmem_save), .scan_enable(scan_enable));
+`else
+wire mclk_bckup = mclk;
+`endif
+
+reg [15:0] pmem_dout_bckup;
+always @(posedge mclk_bckup or posedge puc_rst)
+ if (puc_rst) pmem_dout_bckup <= 16'h0000;
+`ifdef CLOCK_GATING
+ else pmem_dout_bckup <= pmem_dout;
+`else
+ else if (fe_pmem_save) pmem_dout_bckup <= pmem_dout;
+`endif
+
+// Mux between the ROM data and the backup
+reg pmem_dout_bckup_sel;
+always @(posedge mclk or posedge puc_rst)
+ if (puc_rst) pmem_dout_bckup_sel <= 1'b0;
+ else if (fe_pmem_save) pmem_dout_bckup_sel <= 1'b1;
+ else if (fe_pmem_restore) pmem_dout_bckup_sel <= 1'b0;
+
+assign fe_mdb_in = pmem_dout_bckup_sel ? pmem_dout_bckup : pmem_dout;
+
+
+// Execution-Unit data Mux
+//---------------------------------
+
+// Select between peripherals, RAM and ROM
+reg [1:0] eu_mdb_in_sel;
+always @(posedge mclk or posedge puc_rst)
+ if (puc_rst) eu_mdb_in_sel <= 2'b00;
+ else eu_mdb_in_sel <= {~eu_pmem_cen, per_en};
+
+// Mux
+assign eu_mdb_in = eu_mdb_in_sel[1] ? pmem_dout :
+ eu_mdb_in_sel[0] ? per_dout_val : dmem_dout;
+
+// Debug interface data Mux
+//---------------------------------
+
+// Select between peripherals, RAM and ROM
+`ifdef DBG_EN
+reg [1:0] dbg_mem_din_sel;
+always @(posedge mclk or posedge puc_rst)
+ if (puc_rst) dbg_mem_din_sel <= 2'b00;
+ else dbg_mem_din_sel <= {~dbg_pmem_cen, dbg_per_en};
+
+`else
+wire [1:0] dbg_mem_din_sel = 2'b00;
+`endif
+
+// Mux
+assign dbg_mem_din = dbg_mem_din_sel[1] ? pmem_dout :
+ dbg_mem_din_sel[0] ? per_dout_val : dmem_dout;
+
+
+endmodule // omsp_mem_backbone
+
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_undefines.v"
+`endif
diff --git a/tests/openmsp430/rtl/omsp_multiplier.v b/tests/openmsp430/rtl/omsp_multiplier.v
new file mode 100644
index 000000000..4f7b04cad
--- /dev/null
+++ b/tests/openmsp430/rtl/omsp_multiplier.v
@@ -0,0 +1,420 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2009 , Olivier Girard
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the authors nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE
+//
+//----------------------------------------------------------------------------
+//
+// *File Name: omsp_multiplier.v
+//
+// *Module Description:
+// 16x16 Hardware multiplier.
+//
+// *Author(s):
+// - Olivier Girard, olgirard@gmail.com
+//
+//----------------------------------------------------------------------------
+// $Rev: 23 $
+// $LastChangedBy: olivier.girard $
+// $LastChangedDate: 2009-08-30 18:39:26 +0200 (Sun, 30 Aug 2009) $
+//----------------------------------------------------------------------------
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_defines.v"
+`endif
+
+module omsp_multiplier (
+
+// OUTPUTs
+ per_dout, // Peripheral data output
+
+// INPUTs
+ mclk, // Main system clock
+ per_addr, // Peripheral address
+ per_din, // Peripheral data input
+ per_en, // Peripheral enable (high active)
+ per_we, // Peripheral write enable (high active)
+ puc_rst, // Main system reset
+ scan_enable // Scan enable (active during scan shifting)
+);
+
+// OUTPUTs
+//=========
+output [15:0] per_dout; // Peripheral data output
+
+// INPUTs
+//=========
+input mclk; // Main system clock
+input [13:0] per_addr; // Peripheral address
+input [15:0] per_din; // Peripheral data input
+input per_en; // Peripheral enable (high active)
+input [1:0] per_we; // Peripheral write enable (high active)
+input puc_rst; // Main system reset
+input scan_enable; // Scan enable (active during scan shifting)
+
+
+//=============================================================================
+// 1) PARAMETER/REGISTERS & WIRE DECLARATION
+//=============================================================================
+
+// Register base address (must be aligned to decoder bit width)
+parameter [14:0] BASE_ADDR = 15'h0130;
+
+// Decoder bit width (defines how many bits are considered for address decoding)
+parameter DEC_WD = 4;
+
+// Register addresses offset
+parameter [DEC_WD-1:0] OP1_MPY = 'h0,
+ OP1_MPYS = 'h2,
+ OP1_MAC = 'h4,
+ OP1_MACS = 'h6,
+ OP2 = 'h8,
+ RESLO = 'hA,
+ RESHI = 'hC,
+ SUMEXT = 'hE;
+
+// Register one-hot decoder utilities
+parameter DEC_SZ = (1 << DEC_WD);
+parameter [DEC_SZ-1:0] BASE_REG = {{DEC_SZ-1{1'b0}}, 1'b1};
+
+// Register one-hot decoder
+parameter [DEC_SZ-1:0] OP1_MPY_D = (BASE_REG << OP1_MPY),
+ OP1_MPYS_D = (BASE_REG << OP1_MPYS),
+ OP1_MAC_D = (BASE_REG << OP1_MAC),
+ OP1_MACS_D = (BASE_REG << OP1_MACS),
+ OP2_D = (BASE_REG << OP2),
+ RESLO_D = (BASE_REG << RESLO),
+ RESHI_D = (BASE_REG << RESHI),
+ SUMEXT_D = (BASE_REG << SUMEXT);
+
+
+// Wire pre-declarations
+wire result_wr;
+wire result_clr;
+wire early_read;
+
+
+//============================================================================
+// 2) REGISTER DECODER
+//============================================================================
+
+// Local register selection
+wire reg_sel = per_en & (per_addr[13:DEC_WD-1]==BASE_ADDR[14:DEC_WD]);
+
+// Register local address
+wire [DEC_WD-1:0] reg_addr = {per_addr[DEC_WD-2:0], 1'b0};
+
+// Register address decode
+wire [DEC_SZ-1:0] reg_dec = (OP1_MPY_D & {DEC_SZ{(reg_addr == OP1_MPY )}}) |
+ (OP1_MPYS_D & {DEC_SZ{(reg_addr == OP1_MPYS )}}) |
+ (OP1_MAC_D & {DEC_SZ{(reg_addr == OP1_MAC )}}) |
+ (OP1_MACS_D & {DEC_SZ{(reg_addr == OP1_MACS )}}) |
+ (OP2_D & {DEC_SZ{(reg_addr == OP2 )}}) |
+ (RESLO_D & {DEC_SZ{(reg_addr == RESLO )}}) |
+ (RESHI_D & {DEC_SZ{(reg_addr == RESHI )}}) |
+ (SUMEXT_D & {DEC_SZ{(reg_addr == SUMEXT )}});
+
+// Read/Write probes
+wire reg_write = |per_we & reg_sel;
+wire reg_read = ~|per_we & reg_sel;
+
+// Read/Write vectors
+wire [DEC_SZ-1:0] reg_wr = reg_dec & {DEC_SZ{reg_write}};
+wire [DEC_SZ-1:0] reg_rd = reg_dec & {DEC_SZ{reg_read}};
+
+
+//============================================================================
+// 3) REGISTERS
+//============================================================================
+
+// OP1 Register
+//-----------------
+reg [15:0] op1;
+
+wire op1_wr = reg_wr[OP1_MPY] |
+ reg_wr[OP1_MPYS] |
+ reg_wr[OP1_MAC] |
+ reg_wr[OP1_MACS];
+
+`ifdef CLOCK_GATING
+wire mclk_op1;
+omsp_clock_gate clock_gate_op1 (.gclk(mclk_op1),
+ .clk (mclk), .enable(op1_wr), .scan_enable(scan_enable));
+`else
+wire mclk_op1 = mclk;
+`endif
+
+always @ (posedge mclk_op1 or posedge puc_rst)
+ if (puc_rst) op1 <= 16'h0000;
+`ifdef CLOCK_GATING
+ else op1 <= per_din;
+`else
+ else if (op1_wr) op1 <= per_din;
+`endif
+
+wire [15:0] op1_rd = op1;
+
+
+// OP2 Register
+//-----------------
+reg [15:0] op2;
+
+wire op2_wr = reg_wr[OP2];
+
+`ifdef CLOCK_GATING
+wire mclk_op2;
+omsp_clock_gate clock_gate_op2 (.gclk(mclk_op2),
+ .clk (mclk), .enable(op2_wr), .scan_enable(scan_enable));
+`else
+wire mclk_op2 = mclk;
+`endif
+
+always @ (posedge mclk_op2 or posedge puc_rst)
+ if (puc_rst) op2 <= 16'h0000;
+`ifdef CLOCK_GATING
+ else op2 <= per_din;
+`else
+ else if (op2_wr) op2 <= per_din;
+`endif
+
+wire [15:0] op2_rd = op2;
+
+
+// RESLO Register
+//-----------------
+reg [15:0] reslo;
+
+wire [15:0] reslo_nxt;
+wire reslo_wr = reg_wr[RESLO];
+
+`ifdef CLOCK_GATING
+wire reslo_en = reslo_wr | result_clr | result_wr;
+wire mclk_reslo;
+omsp_clock_gate clock_gate_reslo (.gclk(mclk_reslo),
+ .clk (mclk), .enable(reslo_en), .scan_enable(scan_enable));
+`else
+wire mclk_reslo = mclk;
+`endif
+
+always @ (posedge mclk_reslo or posedge puc_rst)
+ if (puc_rst) reslo <= 16'h0000;
+ else if (reslo_wr) reslo <= per_din;
+ else if (result_clr) reslo <= 16'h0000;
+`ifdef CLOCK_GATING
+ else reslo <= reslo_nxt;
+`else
+ else if (result_wr) reslo <= reslo_nxt;
+`endif
+
+wire [15:0] reslo_rd = early_read ? reslo_nxt : reslo;
+
+
+// RESHI Register
+//-----------------
+reg [15:0] reshi;
+
+wire [15:0] reshi_nxt;
+wire reshi_wr = reg_wr[RESHI];
+
+`ifdef CLOCK_GATING
+wire reshi_en = reshi_wr | result_clr | result_wr;
+wire mclk_reshi;
+omsp_clock_gate clock_gate_reshi (.gclk(mclk_reshi),
+ .clk (mclk), .enable(reshi_en), .scan_enable(scan_enable));
+`else
+wire mclk_reshi = mclk;
+`endif
+
+always @ (posedge mclk_reshi or posedge puc_rst)
+ if (puc_rst) reshi <= 16'h0000;
+ else if (reshi_wr) reshi <= per_din;
+ else if (result_clr) reshi <= 16'h0000;
+`ifdef CLOCK_GATING
+ else reshi <= reshi_nxt;
+`else
+ else if (result_wr) reshi <= reshi_nxt;
+`endif
+
+wire [15:0] reshi_rd = early_read ? reshi_nxt : reshi;
+
+
+// SUMEXT Register
+//-----------------
+reg [1:0] sumext_s;
+
+wire [1:0] sumext_s_nxt;
+
+always @ (posedge mclk or posedge puc_rst)
+ if (puc_rst) sumext_s <= 2'b00;
+ else if (op2_wr) sumext_s <= 2'b00;
+ else if (result_wr) sumext_s <= sumext_s_nxt;
+
+wire [15:0] sumext_nxt = {{14{sumext_s_nxt[1]}}, sumext_s_nxt};
+wire [15:0] sumext = {{14{sumext_s[1]}}, sumext_s};
+wire [15:0] sumext_rd = early_read ? sumext_nxt : sumext;
+
+
+//============================================================================
+// 4) DATA OUTPUT GENERATION
+//============================================================================
+
+// Data output mux
+wire [15:0] op1_mux = op1_rd & {16{reg_rd[OP1_MPY] |
+ reg_rd[OP1_MPYS] |
+ reg_rd[OP1_MAC] |
+ reg_rd[OP1_MACS]}};
+wire [15:0] op2_mux = op2_rd & {16{reg_rd[OP2]}};
+wire [15:0] reslo_mux = reslo_rd & {16{reg_rd[RESLO]}};
+wire [15:0] reshi_mux = reshi_rd & {16{reg_rd[RESHI]}};
+wire [15:0] sumext_mux = sumext_rd & {16{reg_rd[SUMEXT]}};
+
+wire [15:0] per_dout = op1_mux |
+ op2_mux |
+ reslo_mux |
+ reshi_mux |
+ sumext_mux;
+
+
+//============================================================================
+// 5) HARDWARE MULTIPLIER FUNCTIONAL LOGIC
+//============================================================================
+
+// Multiplier configuration
+//--------------------------
+
+// Detect signed mode
+reg sign_sel;
+always @ (posedge mclk_op1 or posedge puc_rst)
+ if (puc_rst) sign_sel <= 1'b0;
+`ifdef CLOCK_GATING
+ else sign_sel <= reg_wr[OP1_MPYS] | reg_wr[OP1_MACS];
+`else
+ else if (op1_wr) sign_sel <= reg_wr[OP1_MPYS] | reg_wr[OP1_MACS];
+`endif
+
+
+// Detect accumulate mode
+reg acc_sel;
+always @ (posedge mclk_op1 or posedge puc_rst)
+ if (puc_rst) acc_sel <= 1'b0;
+`ifdef CLOCK_GATING
+ else acc_sel <= reg_wr[OP1_MAC] | reg_wr[OP1_MACS];
+`else
+ else if (op1_wr) acc_sel <= reg_wr[OP1_MAC] | reg_wr[OP1_MACS];
+`endif
+
+
+// Detect whenever the RESHI and RESLO registers should be cleared
+assign result_clr = op2_wr & ~acc_sel;
+
+// Combine RESHI & RESLO
+wire [31:0] result = {reshi, reslo};
+
+
+// 16x16 Multiplier (result computed in 1 clock cycle)
+//-----------------------------------------------------
+`ifdef MPY_16x16
+
+// Detect start of a multiplication
+reg cycle;
+always @ (posedge mclk or posedge puc_rst)
+ if (puc_rst) cycle <= 1'b0;
+ else cycle <= op2_wr;
+
+assign result_wr = cycle;
+
+// Expand the operands to support signed & unsigned operations
+wire signed [16:0] op1_xp = {sign_sel & op1[15], op1};
+wire signed [16:0] op2_xp = {sign_sel & op2[15], op2};
+
+
+// 17x17 signed multiplication
+wire signed [33:0] product = op1_xp * op2_xp;
+
+// Accumulate
+wire [32:0] result_nxt = {1'b0, result} + {1'b0, product[31:0]};
+
+
+// Next register values
+assign reslo_nxt = result_nxt[15:0];
+assign reshi_nxt = result_nxt[31:16];
+assign sumext_s_nxt = sign_sel ? {2{result_nxt[31]}} :
+ {1'b0, result_nxt[32]};
+
+
+// Since the MAC is completed within 1 clock cycle,
+// an early read can't happen.
+assign early_read = 1'b0;
+
+
+// 16x8 Multiplier (result computed in 2 clock cycles)
+//-----------------------------------------------------
+`else
+
+// Detect start of a multiplication
+reg [1:0] cycle;
+always @ (posedge mclk or posedge puc_rst)
+ if (puc_rst) cycle <= 2'b00;
+ else cycle <= {cycle[0], op2_wr};
+
+assign result_wr = |cycle;
+
+
+// Expand the operands to support signed & unsigned operations
+wire signed [16:0] op1_xp = {sign_sel & op1[15], op1};
+wire signed [8:0] op2_hi_xp = {sign_sel & op2[15], op2[15:8]};
+wire signed [8:0] op2_lo_xp = { 1'b0, op2[7:0]};
+wire signed [8:0] op2_xp = cycle[0] ? op2_hi_xp : op2_lo_xp;
+
+
+// 17x9 signed multiplication
+wire signed [25:0] product = op1_xp * op2_xp;
+
+wire [31:0] product_xp = cycle[0] ? {product[23:0], 8'h00} :
+ {{8{sign_sel & product[23]}}, product[23:0]};
+
+// Accumulate
+wire [32:0] result_nxt = {1'b0, result} + {1'b0, product_xp[31:0]};
+
+
+// Next register values
+assign reslo_nxt = result_nxt[15:0];
+assign reshi_nxt = result_nxt[31:16];
+assign sumext_s_nxt = sign_sel ? {2{result_nxt[31]}} :
+ {1'b0, result_nxt[32] | sumext_s[0]};
+
+// Since the MAC is completed within 2 clock cycle,
+// an early read can happen during the second cycle.
+assign early_read = cycle[1];
+
+`endif
+
+
+endmodule // omsp_multiplier
+
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_undefines.v"
+`endif
diff --git a/tests/openmsp430/rtl/omsp_register_file.v b/tests/openmsp430/rtl/omsp_register_file.v
new file mode 100644
index 000000000..2ccd24991
--- /dev/null
+++ b/tests/openmsp430/rtl/omsp_register_file.v
@@ -0,0 +1,618 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2009 , Olivier Girard
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the authors nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE
+//
+//----------------------------------------------------------------------------
+//
+// *File Name: omsp_register_file.v
+//
+// *Module Description:
+// openMSP430 Register files
+//
+// *Author(s):
+// - Olivier Girard, olgirard@gmail.com
+//
+//----------------------------------------------------------------------------
+// $Rev: 134 $
+// $LastChangedBy: olivier.girard $
+// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $
+//----------------------------------------------------------------------------
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_defines.v"
+`endif
+
+module omsp_register_file (
+
+// OUTPUTs
+ cpuoff, // Turns off the CPU
+ gie, // General interrupt enable
+ oscoff, // Turns off LFXT1 clock input
+ pc_sw, // Program counter software value
+ pc_sw_wr, // Program counter software write
+ reg_dest, // Selected register destination content
+ reg_src, // Selected register source content
+ scg0, // System clock generator 1. Turns off the DCO
+ scg1, // System clock generator 1. Turns off the SMCLK
+ status, // R2 Status {V,N,Z,C}
+
+// INPUTs
+ alu_stat, // ALU Status {V,N,Z,C}
+ alu_stat_wr, // ALU Status write {V,N,Z,C}
+ inst_bw, // Decoded Inst: byte width
+ inst_dest, // Register destination selection
+ inst_src, // Register source selection
+ mclk, // Main system clock
+ pc, // Program counter
+ puc_rst, // Main system reset
+ reg_dest_val, // Selected register destination value
+ reg_dest_wr, // Write selected register destination
+ reg_pc_call, // Trigger PC update for a CALL instruction
+ reg_sp_val, // Stack Pointer next value
+ reg_sp_wr, // Stack Pointer write
+ reg_sr_wr, // Status register update for RETI instruction
+ reg_sr_clr, // Status register clear for interrupts
+ reg_incr, // Increment source register
+ scan_enable // Scan enable (active during scan shifting)
+);
+
+// OUTPUTs
+//=========
+output cpuoff; // Turns off the CPU
+output gie; // General interrupt enable
+output oscoff; // Turns off LFXT1 clock input
+output [15:0] pc_sw; // Program counter software value
+output pc_sw_wr; // Program counter software write
+output [15:0] reg_dest; // Selected register destination content
+output [15:0] reg_src; // Selected register source content
+output scg0; // System clock generator 1. Turns off the DCO
+output scg1; // System clock generator 1. Turns off the SMCLK
+output [3:0] status; // R2 Status {V,N,Z,C}
+
+// INPUTs
+//=========
+input [3:0] alu_stat; // ALU Status {V,N,Z,C}
+input [3:0] alu_stat_wr; // ALU Status write {V,N,Z,C}
+input inst_bw; // Decoded Inst: byte width
+input [15:0] inst_dest; // Register destination selection
+input [15:0] inst_src; // Register source selection
+input mclk; // Main system clock
+input [15:0] pc; // Program counter
+input puc_rst; // Main system reset
+input [15:0] reg_dest_val; // Selected register destination value
+input reg_dest_wr; // Write selected register destination
+input reg_pc_call; // Trigger PC update for a CALL instruction
+input [15:0] reg_sp_val; // Stack Pointer next value
+input reg_sp_wr; // Stack Pointer write
+input reg_sr_wr; // Status register update for RETI instruction
+input reg_sr_clr; // Status register clear for interrupts
+input reg_incr; // Increment source register
+input scan_enable; // Scan enable (active during scan shifting)
+
+
+//=============================================================================
+// 1) AUTOINCREMENT UNIT
+//=============================================================================
+
+wire [15:0] inst_src_in;
+wire [15:0] incr_op = (inst_bw & ~inst_src_in[1]) ? 16'h0001 : 16'h0002;
+wire [15:0] reg_incr_val = reg_src+incr_op;
+
+wire [15:0] reg_dest_val_in = inst_bw ? {8'h00,reg_dest_val[7:0]} : reg_dest_val;
+
+
+//=============================================================================
+// 2) SPECIAL REGISTERS (R1/R2/R3)
+//=============================================================================
+
+// Source input selection mask (for interrupt support)
+//-----------------------------------------------------
+
+assign inst_src_in = reg_sr_clr ? 16'h0004 : inst_src;
+
+
+// R0: Program counter
+//---------------------
+
+wire [15:0] r0 = pc;
+
+wire [15:0] pc_sw = reg_dest_val_in;
+wire pc_sw_wr = (inst_dest[0] & reg_dest_wr) | reg_pc_call;
+
+
+// R1: Stack pointer
+//-------------------
+reg [15:0] r1;
+wire r1_wr = inst_dest[1] & reg_dest_wr;
+wire r1_inc = inst_src_in[1] & reg_incr;
+
+`ifdef CLOCK_GATING
+wire r1_en = r1_wr | reg_sp_wr | r1_inc;
+wire mclk_r1;
+omsp_clock_gate clock_gate_r1 (.gclk(mclk_r1),
+ .clk (mclk), .enable(r1_en), .scan_enable(scan_enable));
+`else
+wire mclk_r1 = mclk;
+`endif
+
+always @(posedge mclk_r1 or posedge puc_rst)
+ if (puc_rst) r1 <= 16'h0000;
+ else if (r1_wr) r1 <= reg_dest_val_in & 16'hfffe;
+ else if (reg_sp_wr) r1 <= reg_sp_val & 16'hfffe;
+`ifdef CLOCK_GATING
+ else r1 <= reg_incr_val & 16'hfffe;
+`else
+ else if (r1_inc) r1 <= reg_incr_val & 16'hfffe;
+`endif
+
+
+// R2: Status register
+//---------------------
+reg [15:0] r2;
+wire r2_wr = (inst_dest[2] & reg_dest_wr) | reg_sr_wr;
+
+`ifdef CLOCK_GATING // -- WITH CLOCK GATING --
+wire r2_c = alu_stat_wr[0] ? alu_stat[0] : reg_dest_val_in[0]; // C
+
+wire r2_z = alu_stat_wr[1] ? alu_stat[1] : reg_dest_val_in[1]; // Z
+
+wire r2_n = alu_stat_wr[2] ? alu_stat[2] : reg_dest_val_in[2]; // N
+
+wire [7:3] r2_nxt = r2_wr ? reg_dest_val_in[7:3] : r2[7:3];
+
+wire r2_v = alu_stat_wr[3] ? alu_stat[3] : reg_dest_val_in[8]; // V
+
+wire r2_en = |alu_stat_wr | r2_wr | reg_sr_clr;
+wire mclk_r2;
+omsp_clock_gate clock_gate_r2 (.gclk(mclk_r2),
+ .clk (mclk), .enable(r2_en), .scan_enable(scan_enable));
+
+`else // -- WITHOUT CLOCK GATING --
+wire r2_c = alu_stat_wr[0] ? alu_stat[0] :
+ r2_wr ? reg_dest_val_in[0] : r2[0]; // C
+
+wire r2_z = alu_stat_wr[1] ? alu_stat[1] :
+ r2_wr ? reg_dest_val_in[1] : r2[1]; // Z
+
+wire r2_n = alu_stat_wr[2] ? alu_stat[2] :
+ r2_wr ? reg_dest_val_in[2] : r2[2]; // N
+
+wire [7:3] r2_nxt = r2_wr ? reg_dest_val_in[7:3] : r2[7:3];
+
+wire r2_v = alu_stat_wr[3] ? alu_stat[3] :
+ r2_wr ? reg_dest_val_in[8] : r2[8]; // V
+
+
+wire mclk_r2 = mclk;
+`endif
+
+`ifdef ASIC
+ `ifdef CPUOFF_EN
+ wire [15:0] cpuoff_mask = 16'h0010;
+ `else
+ wire [15:0] cpuoff_mask = 16'h0000;
+ `endif
+ `ifdef OSCOFF_EN
+ wire [15:0] oscoff_mask = 16'h0020;
+ `else
+ wire [15:0] oscoff_mask = 16'h0000;
+ `endif
+ `ifdef SCG0_EN
+ wire [15:0] scg0_mask = 16'h0040;
+ `else
+ wire [15:0] scg0_mask = 16'h0000;
+ `endif
+ `ifdef SCG1_EN
+ wire [15:0] scg1_mask = 16'h0080;
+ `else
+ wire [15:0] scg1_mask = 16'h0000;
+ `endif
+`else
+ wire [15:0] cpuoff_mask = 16'h0010; // For the FPGA version: - the CPUOFF mode is emulated
+ wire [15:0] oscoff_mask = 16'h0020; // - the SCG1 mode is emulated
+ wire [15:0] scg0_mask = 16'h0000; // - the SCG0 is not supported
+ wire [15:0] scg1_mask = 16'h0080; // - the SCG1 mode is emulated
+`endif
+
+ wire [15:0] r2_mask = cpuoff_mask | oscoff_mask | scg0_mask | scg1_mask | 16'h010f;
+
+always @(posedge mclk_r2 or posedge puc_rst)
+ if (puc_rst) r2 <= 16'h0000;
+ else if (reg_sr_clr) r2 <= 16'h0000;
+ else r2 <= {7'h00, r2_v, r2_nxt, r2_n, r2_z, r2_c} & r2_mask;
+
+assign status = {r2[8], r2[2:0]};
+assign gie = r2[3];
+assign cpuoff = r2[4] | (r2_nxt[4] & r2_wr & cpuoff_mask[4]);
+assign oscoff = r2[5];
+assign scg0 = r2[6];
+assign scg1 = r2[7];
+
+
+// R3: Constant generator
+//-------------------------------------------------------------
+// Note: the auto-increment feature is not implemented for R3
+// because the @R3+ addressing mode is used for constant
+// generation (#-1).
+reg [15:0] r3;
+wire r3_wr = inst_dest[3] & reg_dest_wr;
+
+`ifdef CLOCK_GATING
+wire r3_en = r3_wr;
+wire mclk_r3;
+omsp_clock_gate clock_gate_r3 (.gclk(mclk_r3),
+ .clk (mclk), .enable(r3_en), .scan_enable(scan_enable));
+`else
+wire mclk_r3 = mclk;
+`endif
+
+always @(posedge mclk_r3 or posedge puc_rst)
+ if (puc_rst) r3 <= 16'h0000;
+`ifdef CLOCK_GATING
+ else r3 <= reg_dest_val_in;
+`else
+ else if (r3_wr) r3 <= reg_dest_val_in;
+`endif
+
+
+//=============================================================================
+// 4) GENERAL PURPOSE REGISTERS (R4...R15)
+//=============================================================================
+
+// R4
+//------------
+reg [15:0] r4;
+wire r4_wr = inst_dest[4] & reg_dest_wr;
+wire r4_inc = inst_src_in[4] & reg_incr;
+
+`ifdef CLOCK_GATING
+wire r4_en = r4_wr | r4_inc;
+wire mclk_r4;
+omsp_clock_gate clock_gate_r4 (.gclk(mclk_r4),
+ .clk (mclk), .enable(r4_en), .scan_enable(scan_enable));
+`else
+wire mclk_r4 = mclk;
+`endif
+
+always @(posedge mclk_r4 or posedge puc_rst)
+ if (puc_rst) r4 <= 16'h0000;
+ else if (r4_wr) r4 <= reg_dest_val_in;
+`ifdef CLOCK_GATING
+ else r4 <= reg_incr_val;
+`else
+ else if (r4_inc) r4 <= reg_incr_val;
+`endif
+
+// R5
+//------------
+reg [15:0] r5;
+wire r5_wr = inst_dest[5] & reg_dest_wr;
+wire r5_inc = inst_src_in[5] & reg_incr;
+
+`ifdef CLOCK_GATING
+wire r5_en = r5_wr | r5_inc;
+wire mclk_r5;
+omsp_clock_gate clock_gate_r5 (.gclk(mclk_r5),
+ .clk (mclk), .enable(r5_en), .scan_enable(scan_enable));
+`else
+wire mclk_r5 = mclk;
+`endif
+
+always @(posedge mclk_r5 or posedge puc_rst)
+ if (puc_rst) r5 <= 16'h0000;
+ else if (r5_wr) r5 <= reg_dest_val_in;
+`ifdef CLOCK_GATING
+ else r5 <= reg_incr_val;
+`else
+ else if (r5_inc) r5 <= reg_incr_val;
+`endif
+
+// R6
+//------------
+reg [15:0] r6;
+wire r6_wr = inst_dest[6] & reg_dest_wr;
+wire r6_inc = inst_src_in[6] & reg_incr;
+
+`ifdef CLOCK_GATING
+wire r6_en = r6_wr | r6_inc;
+wire mclk_r6;
+omsp_clock_gate clock_gate_r6 (.gclk(mclk_r6),
+ .clk (mclk), .enable(r6_en), .scan_enable(scan_enable));
+`else
+wire mclk_r6 = mclk;
+`endif
+
+always @(posedge mclk_r6 or posedge puc_rst)
+ if (puc_rst) r6 <= 16'h0000;
+ else if (r6_wr) r6 <= reg_dest_val_in;
+`ifdef CLOCK_GATING
+ else r6 <= reg_incr_val;
+`else
+ else if (r6_inc) r6 <= reg_incr_val;
+`endif
+
+// R7
+//------------
+reg [15:0] r7;
+wire r7_wr = inst_dest[7] & reg_dest_wr;
+wire r7_inc = inst_src_in[7] & reg_incr;
+
+`ifdef CLOCK_GATING
+wire r7_en = r7_wr | r7_inc;
+wire mclk_r7;
+omsp_clock_gate clock_gate_r7 (.gclk(mclk_r7),
+ .clk (mclk), .enable(r7_en), .scan_enable(scan_enable));
+`else
+wire mclk_r7 = mclk;
+`endif
+
+always @(posedge mclk_r7 or posedge puc_rst)
+ if (puc_rst) r7 <= 16'h0000;
+ else if (r7_wr) r7 <= reg_dest_val_in;
+`ifdef CLOCK_GATING
+ else r7 <= reg_incr_val;
+`else
+ else if (r7_inc) r7 <= reg_incr_val;
+`endif
+
+// R8
+//------------
+reg [15:0] r8;
+wire r8_wr = inst_dest[8] & reg_dest_wr;
+wire r8_inc = inst_src_in[8] & reg_incr;
+
+`ifdef CLOCK_GATING
+wire r8_en = r8_wr | r8_inc;
+wire mclk_r8;
+omsp_clock_gate clock_gate_r8 (.gclk(mclk_r8),
+ .clk (mclk), .enable(r8_en), .scan_enable(scan_enable));
+`else
+wire mclk_r8 = mclk;
+`endif
+
+always @(posedge mclk_r8 or posedge puc_rst)
+ if (puc_rst) r8 <= 16'h0000;
+ else if (r8_wr) r8 <= reg_dest_val_in;
+`ifdef CLOCK_GATING
+ else r8 <= reg_incr_val;
+`else
+ else if (r8_inc) r8 <= reg_incr_val;
+`endif
+
+// R9
+//------------
+reg [15:0] r9;
+wire r9_wr = inst_dest[9] & reg_dest_wr;
+wire r9_inc = inst_src_in[9] & reg_incr;
+
+`ifdef CLOCK_GATING
+wire r9_en = r9_wr | r9_inc;
+wire mclk_r9;
+omsp_clock_gate clock_gate_r9 (.gclk(mclk_r9),
+ .clk (mclk), .enable(r9_en), .scan_enable(scan_enable));
+`else
+wire mclk_r9 = mclk;
+`endif
+
+always @(posedge mclk_r9 or posedge puc_rst)
+ if (puc_rst) r9 <= 16'h0000;
+ else if (r9_wr) r9 <= reg_dest_val_in;
+`ifdef CLOCK_GATING
+ else r9 <= reg_incr_val;
+`else
+ else if (r9_inc) r9 <= reg_incr_val;
+`endif
+
+// R10
+//------------
+reg [15:0] r10;
+wire r10_wr = inst_dest[10] & reg_dest_wr;
+wire r10_inc = inst_src_in[10] & reg_incr;
+
+`ifdef CLOCK_GATING
+wire r10_en = r10_wr | r10_inc;
+wire mclk_r10;
+omsp_clock_gate clock_gate_r10 (.gclk(mclk_r10),
+ .clk (mclk), .enable(r10_en), .scan_enable(scan_enable));
+`else
+wire mclk_r10 = mclk;
+`endif
+
+always @(posedge mclk_r10 or posedge puc_rst)
+ if (puc_rst) r10 <= 16'h0000;
+ else if (r10_wr) r10 <= reg_dest_val_in;
+`ifdef CLOCK_GATING
+ else r10 <= reg_incr_val;
+`else
+ else if (r10_inc) r10 <= reg_incr_val;
+`endif
+
+// R11
+//------------
+reg [15:0] r11;
+wire r11_wr = inst_dest[11] & reg_dest_wr;
+wire r11_inc = inst_src_in[11] & reg_incr;
+
+`ifdef CLOCK_GATING
+wire r11_en = r11_wr | r11_inc;
+wire mclk_r11;
+omsp_clock_gate clock_gate_r11 (.gclk(mclk_r11),
+ .clk (mclk), .enable(r11_en), .scan_enable(scan_enable));
+`else
+wire mclk_r11 = mclk;
+`endif
+
+always @(posedge mclk_r11 or posedge puc_rst)
+ if (puc_rst) r11 <= 16'h0000;
+ else if (r11_wr) r11 <= reg_dest_val_in;
+`ifdef CLOCK_GATING
+ else r11 <= reg_incr_val;
+`else
+ else if (r11_inc) r11 <= reg_incr_val;
+`endif
+
+// R12
+//------------
+reg [15:0] r12;
+wire r12_wr = inst_dest[12] & reg_dest_wr;
+wire r12_inc = inst_src_in[12] & reg_incr;
+
+`ifdef CLOCK_GATING
+wire r12_en = r12_wr | r12_inc;
+wire mclk_r12;
+omsp_clock_gate clock_gate_r12 (.gclk(mclk_r12),
+ .clk (mclk), .enable(r12_en), .scan_enable(scan_enable));
+`else
+wire mclk_r12 = mclk;
+`endif
+
+always @(posedge mclk_r12 or posedge puc_rst)
+ if (puc_rst) r12 <= 16'h0000;
+ else if (r12_wr) r12 <= reg_dest_val_in;
+`ifdef CLOCK_GATING
+ else r12 <= reg_incr_val;
+`else
+ else if (r12_inc) r12 <= reg_incr_val;
+`endif
+
+// R13
+//------------
+reg [15:0] r13;
+wire r13_wr = inst_dest[13] & reg_dest_wr;
+wire r13_inc = inst_src_in[13] & reg_incr;
+
+`ifdef CLOCK_GATING
+wire r13_en = r13_wr | r13_inc;
+wire mclk_r13;
+omsp_clock_gate clock_gate_r13 (.gclk(mclk_r13),
+ .clk (mclk), .enable(r13_en), .scan_enable(scan_enable));
+`else
+wire mclk_r13 = mclk;
+`endif
+
+always @(posedge mclk_r13 or posedge puc_rst)
+ if (puc_rst) r13 <= 16'h0000;
+ else if (r13_wr) r13 <= reg_dest_val_in;
+`ifdef CLOCK_GATING
+ else r13 <= reg_incr_val;
+`else
+ else if (r13_inc) r13 <= reg_incr_val;
+`endif
+
+// R14
+//------------
+reg [15:0] r14;
+wire r14_wr = inst_dest[14] & reg_dest_wr;
+wire r14_inc = inst_src_in[14] & reg_incr;
+
+`ifdef CLOCK_GATING
+wire r14_en = r14_wr | r14_inc;
+wire mclk_r14;
+omsp_clock_gate clock_gate_r14 (.gclk(mclk_r14),
+ .clk (mclk), .enable(r14_en), .scan_enable(scan_enable));
+`else
+wire mclk_r14 = mclk;
+`endif
+
+always @(posedge mclk_r14 or posedge puc_rst)
+ if (puc_rst) r14 <= 16'h0000;
+ else if (r14_wr) r14 <= reg_dest_val_in;
+`ifdef CLOCK_GATING
+ else r14 <= reg_incr_val;
+`else
+ else if (r14_inc) r14 <= reg_incr_val;
+`endif
+
+// R15
+//------------
+reg [15:0] r15;
+wire r15_wr = inst_dest[15] & reg_dest_wr;
+wire r15_inc = inst_src_in[15] & reg_incr;
+
+`ifdef CLOCK_GATING
+wire r15_en = r15_wr | r15_inc;
+wire mclk_r15;
+omsp_clock_gate clock_gate_r15 (.gclk(mclk_r15),
+ .clk (mclk), .enable(r15_en), .scan_enable(scan_enable));
+`else
+wire mclk_r15 = mclk;
+`endif
+
+always @(posedge mclk_r15 or posedge puc_rst)
+ if (puc_rst) r15 <= 16'h0000;
+ else if (r15_wr) r15 <= reg_dest_val_in;
+ `ifdef CLOCK_GATING
+ else r15 <= reg_incr_val;
+`else
+ else if (r15_inc) r15 <= reg_incr_val;
+`endif
+
+
+//=============================================================================
+// 5) READ MUX
+//=============================================================================
+
+assign reg_src = (r0 & {16{inst_src_in[0]}}) |
+ (r1 & {16{inst_src_in[1]}}) |
+ (r2 & {16{inst_src_in[2]}}) |
+ (r3 & {16{inst_src_in[3]}}) |
+ (r4 & {16{inst_src_in[4]}}) |
+ (r5 & {16{inst_src_in[5]}}) |
+ (r6 & {16{inst_src_in[6]}}) |
+ (r7 & {16{inst_src_in[7]}}) |
+ (r8 & {16{inst_src_in[8]}}) |
+ (r9 & {16{inst_src_in[9]}}) |
+ (r10 & {16{inst_src_in[10]}}) |
+ (r11 & {16{inst_src_in[11]}}) |
+ (r12 & {16{inst_src_in[12]}}) |
+ (r13 & {16{inst_src_in[13]}}) |
+ (r14 & {16{inst_src_in[14]}}) |
+ (r15 & {16{inst_src_in[15]}});
+
+assign reg_dest = (r0 & {16{inst_dest[0]}}) |
+ (r1 & {16{inst_dest[1]}}) |
+ (r2 & {16{inst_dest[2]}}) |
+ (r3 & {16{inst_dest[3]}}) |
+ (r4 & {16{inst_dest[4]}}) |
+ (r5 & {16{inst_dest[5]}}) |
+ (r6 & {16{inst_dest[6]}}) |
+ (r7 & {16{inst_dest[7]}}) |
+ (r8 & {16{inst_dest[8]}}) |
+ (r9 & {16{inst_dest[9]}}) |
+ (r10 & {16{inst_dest[10]}}) |
+ (r11 & {16{inst_dest[11]}}) |
+ (r12 & {16{inst_dest[12]}}) |
+ (r13 & {16{inst_dest[13]}}) |
+ (r14 & {16{inst_dest[14]}}) |
+ (r15 & {16{inst_dest[15]}});
+
+
+endmodule // omsp_register_file
+
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_undefines.v"
+`endif
diff --git a/tests/openmsp430/rtl/omsp_scan_mux.v b/tests/openmsp430/rtl/omsp_scan_mux.v
new file mode 100644
index 000000000..9a906474d
--- /dev/null
+++ b/tests/openmsp430/rtl/omsp_scan_mux.v
@@ -0,0 +1,75 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2009 , Olivier Girard
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the authors nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE
+//
+//----------------------------------------------------------------------------
+//
+// *File Name: omsp_scan_mux.v
+//
+// *Module Description:
+// Generic mux for scan mode
+//
+// *Author(s):
+// - Olivier Girard, olgirard@gmail.com
+//
+//----------------------------------------------------------------------------
+// $Rev: 103 $
+// $LastChangedBy: olivier.girard $
+// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
+//----------------------------------------------------------------------------
+
+module omsp_scan_mux (
+
+// OUTPUTs
+ data_out, // Scan mux data output
+
+// INPUTs
+ data_in_scan, // Selected data input for scan mode
+ data_in_func, // Selected data input for functional mode
+ scan_mode // Scan mode
+);
+
+// OUTPUTs
+//=========
+output data_out; // Scan mux data output
+
+// INPUTs
+//=========
+input data_in_scan; // Selected data input for scan mode
+input data_in_func; // Selected data input for functional mode
+input scan_mode; // Scan mode
+
+
+//=============================================================================
+// 1) SCAN MUX
+//=============================================================================
+
+assign data_out = scan_mode ? data_in_scan : data_in_func;
+
+
+endmodule // omsp_scan_mux
+
+
diff --git a/tests/openmsp430/rtl/omsp_sfr.v b/tests/openmsp430/rtl/omsp_sfr.v
new file mode 100644
index 000000000..bc8c11a5b
--- /dev/null
+++ b/tests/openmsp430/rtl/omsp_sfr.v
@@ -0,0 +1,353 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2009 , Olivier Girard
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the authors nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE
+//
+//----------------------------------------------------------------------------
+//
+// *File Name: omsp_sfr.v
+//
+// *Module Description:
+// Processor Special function register
+// Non-Maskable Interrupt generation
+//
+// *Author(s):
+// - Olivier Girard, olgirard@gmail.com
+//
+//----------------------------------------------------------------------------
+// $Rev: 134 $
+// $LastChangedBy: olivier.girard $
+// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $
+//----------------------------------------------------------------------------
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_defines.v"
+`endif
+
+module omsp_sfr (
+
+// OUTPUTs
+ cpu_id, // CPU ID
+ nmi_pnd, // NMI Pending
+ nmi_wkup, // NMI Wakeup
+ per_dout, // Peripheral data output
+ wdtie, // Watchdog-timer interrupt enable
+ wdtifg_sw_clr, // Watchdog-timer interrupt flag software clear
+ wdtifg_sw_set, // Watchdog-timer interrupt flag software set
+
+// INPUTs
+ mclk, // Main system clock
+ nmi, // Non-maskable interrupt (asynchronous)
+ nmi_acc, // Non-Maskable interrupt request accepted
+ per_addr, // Peripheral address
+ per_din, // Peripheral data input
+ per_en, // Peripheral enable (high active)
+ per_we, // Peripheral write enable (high active)
+ puc_rst, // Main system reset
+ scan_mode, // Scan mode
+ wdtifg, // Watchdog-timer interrupt flag
+ wdtnmies // Watchdog-timer NMI edge selection
+);
+
+// OUTPUTs
+//=========
+output [31:0] cpu_id; // CPU ID
+output nmi_pnd; // NMI Pending
+output nmi_wkup; // NMI Wakeup
+output [15:0] per_dout; // Peripheral data output
+output wdtie; // Watchdog-timer interrupt enable
+output wdtifg_sw_clr;// Watchdog-timer interrupt flag software clear
+output wdtifg_sw_set;// Watchdog-timer interrupt flag software set
+
+// INPUTs
+//=========
+input mclk; // Main system clock
+input nmi; // Non-maskable interrupt (asynchronous)
+input nmi_acc; // Non-Maskable interrupt request accepted
+input [13:0] per_addr; // Peripheral address
+input [15:0] per_din; // Peripheral data input
+input per_en; // Peripheral enable (high active)
+input [1:0] per_we; // Peripheral write enable (high active)
+input puc_rst; // Main system reset
+input scan_mode; // Scan mode
+input wdtifg; // Watchdog-timer interrupt flag
+input wdtnmies; // Watchdog-timer NMI edge selection
+
+
+//=============================================================================
+// 1) PARAMETER DECLARATION
+//=============================================================================
+
+// Register base address (must be aligned to decoder bit width)
+parameter [14:0] BASE_ADDR = 15'h0000;
+
+// Decoder bit width (defines how many bits are considered for address decoding)
+parameter DEC_WD = 3;
+
+// Register addresses offset
+parameter [DEC_WD-1:0] IE1 = 'h0,
+ IFG1 = 'h2,
+ CPU_ID_LO = 'h4,
+ CPU_ID_HI = 'h6;
+
+// Register one-hot decoder utilities
+parameter DEC_SZ = (1 << DEC_WD);
+parameter [DEC_SZ-1:0] BASE_REG = {{DEC_SZ-1{1'b0}}, 1'b1};
+
+// Register one-hot decoder
+parameter [DEC_SZ-1:0] IE1_D = (BASE_REG << IE1),
+ IFG1_D = (BASE_REG << IFG1),
+ CPU_ID_LO_D = (BASE_REG << CPU_ID_LO),
+ CPU_ID_HI_D = (BASE_REG << CPU_ID_HI);
+
+
+//============================================================================
+// 2) REGISTER DECODER
+//============================================================================
+
+// Local register selection
+wire reg_sel = per_en & (per_addr[13:DEC_WD-1]==BASE_ADDR[14:DEC_WD]);
+
+// Register local address
+wire [DEC_WD-1:0] reg_addr = {1'b0, per_addr[DEC_WD-2:0]};
+
+// Register address decode
+wire [DEC_SZ-1:0] reg_dec = (IE1_D & {DEC_SZ{(reg_addr==(IE1 >>1))}}) |
+ (IFG1_D & {DEC_SZ{(reg_addr==(IFG1 >>1))}}) |
+ (CPU_ID_LO_D & {DEC_SZ{(reg_addr==(CPU_ID_LO >>1))}}) |
+ (CPU_ID_HI_D & {DEC_SZ{(reg_addr==(CPU_ID_HI >>1))}});
+
+// Read/Write probes
+wire reg_lo_write = per_we[0] & reg_sel;
+wire reg_hi_write = per_we[1] & reg_sel;
+wire reg_read = ~|per_we & reg_sel;
+
+// Read/Write vectors
+wire [DEC_SZ-1:0] reg_hi_wr = reg_dec & {DEC_SZ{reg_hi_write}};
+wire [DEC_SZ-1:0] reg_lo_wr = reg_dec & {DEC_SZ{reg_lo_write}};
+wire [DEC_SZ-1:0] reg_rd = reg_dec & {DEC_SZ{reg_read}};
+
+
+//============================================================================
+// 3) REGISTERS
+//============================================================================
+
+// IE1 Register
+//--------------
+wire [7:0] ie1;
+wire ie1_wr = IE1[0] ? reg_hi_wr[IE1] : reg_lo_wr[IE1];
+wire [7:0] ie1_nxt = IE1[0] ? per_din[15:8] : per_din[7:0];
+
+`ifdef NMI
+reg nmie;
+always @ (posedge mclk or posedge puc_rst)
+ if (puc_rst) nmie <= 1'b0;
+ else if (nmi_acc) nmie <= 1'b0;
+ else if (ie1_wr) nmie <= ie1_nxt[4];
+`else
+wire nmie = 1'b0;
+`endif
+
+`ifdef WATCHDOG
+reg wdtie;
+always @ (posedge mclk or posedge puc_rst)
+ if (puc_rst) wdtie <= 1'b0;
+ else if (ie1_wr) wdtie <= ie1_nxt[0];
+`else
+wire wdtie = 1'b0;
+`endif
+
+assign ie1 = {3'b000, nmie, 3'b000, wdtie};
+
+
+// IFG1 Register
+//---------------
+wire [7:0] ifg1;
+
+wire ifg1_wr = IFG1[0] ? reg_hi_wr[IFG1] : reg_lo_wr[IFG1];
+wire [7:0] ifg1_nxt = IFG1[0] ? per_din[15:8] : per_din[7:0];
+
+`ifdef NMI
+reg nmiifg;
+wire nmi_edge;
+always @ (posedge mclk or posedge puc_rst)
+ if (puc_rst) nmiifg <= 1'b0;
+ else if (nmi_edge) nmiifg <= 1'b1;
+ else if (ifg1_wr) nmiifg <= ifg1_nxt[4];
+`else
+wire nmiifg = 1'b0;
+`endif
+
+`ifdef WATCHDOG
+assign wdtifg_sw_clr = ifg1_wr & ~ifg1_nxt[0];
+assign wdtifg_sw_set = ifg1_wr & ifg1_nxt[0];
+`else
+assign wdtifg_sw_clr = 1'b0;
+assign wdtifg_sw_set = 1'b0;
+`endif
+
+assign ifg1 = {3'b000, nmiifg, 3'b000, wdtifg};
+
+
+// CPU_ID Register (READ ONLY)
+//-----------------------------
+// -------------------------------------------------------------------
+// CPU_ID_LO: | 15 14 13 12 11 10 9 | 8 7 6 5 4 | 3 | 2 1 0 |
+// |----------------------------+-----------------+------+-------------|
+// | PER_SPACE | USER_VERSION | ASIC | CPU_VERSION |
+// --------------------------------------------------------------------
+// CPU_ID_HI: | 15 14 13 12 11 10 | 9 8 7 6 5 4 3 2 1 | 0 |
+// |----------------------------+-------------------------------+------|
+// | PMEM_SIZE | DMEM_SIZE | MPY |
+// -------------------------------------------------------------------
+
+wire [2:0] cpu_version = `CPU_VERSION;
+`ifdef ASIC
+wire cpu_asic = 1'b1;
+`else
+wire cpu_asic = 1'b0;
+`endif
+wire [4:0] user_version = `USER_VERSION;
+wire [6:0] per_space = (`PER_SIZE >> 9); // cpu_id_per * 512 = peripheral space size
+`ifdef MULTIPLIER
+wire mpy_info = 1'b1;
+`else
+wire mpy_info = 1'b0;
+`endif
+wire [8:0] dmem_size = (`DMEM_SIZE >> 7); // cpu_id_dmem * 128 = data memory size
+wire [5:0] pmem_size = (`PMEM_SIZE >> 10); // cpu_id_pmem * 1024 = program memory size
+
+assign cpu_id = {pmem_size,
+ dmem_size,
+ mpy_info,
+ per_space,
+ user_version,
+ cpu_asic,
+ cpu_version};
+
+
+//============================================================================
+// 4) DATA OUTPUT GENERATION
+//============================================================================
+
+// Data output mux
+wire [15:0] ie1_rd = {8'h00, (ie1 & {8{reg_rd[IE1]}})} << (8 & {4{IE1[0]}});
+wire [15:0] ifg1_rd = {8'h00, (ifg1 & {8{reg_rd[IFG1]}})} << (8 & {4{IFG1[0]}});
+wire [15:0] cpu_id_lo_rd = cpu_id[15:0] & {16{reg_rd[CPU_ID_LO]}};
+wire [15:0] cpu_id_hi_rd = cpu_id[31:16] & {16{reg_rd[CPU_ID_HI]}};
+
+wire [15:0] per_dout = ie1_rd |
+ ifg1_rd |
+ cpu_id_lo_rd |
+ cpu_id_hi_rd;
+
+
+//=============================================================================
+// 5) NMI GENERATION
+//=============================================================================
+// NOTE THAT THE NMI INPUT IS ASSUMED TO BE NON-GLITCHY
+`ifdef NMI
+
+//-----------------------------------
+// Edge selection
+//-----------------------------------
+wire nmi_pol = nmi ^ wdtnmies;
+
+//-----------------------------------
+// Pulse capture and synchronization
+//-----------------------------------
+`ifdef SYNC_NMI
+ `ifdef ASIC
+ // Glitch free reset for the event capture
+ reg nmi_capture_rst;
+ always @(posedge mclk or posedge puc_rst)
+ if (puc_rst) nmi_capture_rst <= 1'b1;
+ else nmi_capture_rst <= ifg1_wr & ~ifg1_nxt[4];
+
+ // NMI event capture
+ wire nmi_capture;
+ omsp_wakeup_cell wakeup_cell_nmi (
+ .wkup_out (nmi_capture), // Wakup signal (asynchronous)
+ .scan_clk (mclk), // Scan clock
+ .scan_mode (scan_mode), // Scan mode
+ .scan_rst (puc_rst), // Scan reset
+ .wkup_clear (nmi_capture_rst), // Glitch free wakeup event clear
+ .wkup_event (nmi_pol) // Glitch free asynchronous wakeup event
+ );
+ `else
+ wire nmi_capture = nmi_pol;
+ `endif
+
+ // Synchronization
+ wire nmi_s;
+ omsp_sync_cell sync_cell_nmi (
+ .data_out (nmi_s),
+ .data_in (nmi_capture),
+ .clk (mclk),
+ .rst (puc_rst)
+ );
+
+`else
+ wire nmi_capture = nmi_pol;
+ wire nmi_s = nmi_pol;
+`endif
+
+//-----------------------------------
+// NMI Pending flag
+//-----------------------------------
+
+// Delay
+reg nmi_dly;
+always @ (posedge mclk or posedge puc_rst)
+ if (puc_rst) nmi_dly <= 1'b0;
+ else nmi_dly <= nmi_s;
+
+// Edge detection
+assign nmi_edge = ~nmi_dly & nmi_s;
+
+// NMI pending
+wire nmi_pnd = nmiifg & nmie;
+
+// NMI wakeup
+`ifdef ASIC
+wire nmi_wkup;
+omsp_and_gate and_nmi_wkup (.y(nmi_wkup), .a(nmi_capture ^ nmi_dly), .b(nmie));
+`else
+wire nmi_wkup = 1'b0;
+`endif
+
+`else
+
+wire nmi_pnd = 1'b0;
+wire nmi_wkup = 1'b0;
+
+`endif
+
+endmodule // omsp_sfr
+
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_undefines.v"
+`endif
diff --git a/tests/openmsp430/rtl/omsp_sync_cell.v b/tests/openmsp430/rtl/omsp_sync_cell.v
new file mode 100644
index 000000000..ece0682a9
--- /dev/null
+++ b/tests/openmsp430/rtl/omsp_sync_cell.v
@@ -0,0 +1,80 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2009 , Olivier Girard
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the authors nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE
+//
+//----------------------------------------------------------------------------
+//
+// *File Name: omsp_sync_cell.v
+//
+// *Module Description:
+// Generic synchronizer for the openMSP430
+//
+// *Author(s):
+// - Olivier Girard, olgirard@gmail.com
+//
+//----------------------------------------------------------------------------
+// $Rev: 103 $
+// $LastChangedBy: olivier.girard $
+// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
+//----------------------------------------------------------------------------
+
+module omsp_sync_cell (
+
+// OUTPUTs
+ data_out, // Synchronized data output
+
+// INPUTs
+ clk, // Receiving clock
+ data_in, // Asynchronous data input
+ rst // Receiving reset (active high)
+);
+
+// OUTPUTs
+//=========
+output data_out; // Synchronized data output
+
+// INPUTs
+//=========
+input clk; // Receiving clock
+input data_in; // Asynchronous data input
+input rst; // Receiving reset (active high)
+
+
+//=============================================================================
+// 1) SYNCHRONIZER
+//=============================================================================
+
+reg [1:0] data_sync;
+
+always @(posedge clk or posedge rst)
+ if (rst) data_sync <= 2'b00;
+ else data_sync <= {data_sync[0], data_in};
+
+assign data_out = data_sync[1];
+
+
+endmodule // omsp_sync_cell
+
diff --git a/tests/openmsp430/rtl/omsp_sync_reset.v b/tests/openmsp430/rtl/omsp_sync_reset.v
new file mode 100644
index 000000000..15a158b43
--- /dev/null
+++ b/tests/openmsp430/rtl/omsp_sync_reset.v
@@ -0,0 +1,78 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2009 , Olivier Girard
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the authors nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE
+//
+//----------------------------------------------------------------------------
+//
+// *File Name: omsp_sync_reset.v
+//
+// *Module Description:
+// Generic reset synchronizer for the openMSP430
+//
+// *Author(s):
+// - Olivier Girard, olgirard@gmail.com
+//
+//----------------------------------------------------------------------------
+// $Rev: 103 $
+// $LastChangedBy: olivier.girard $
+// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
+//----------------------------------------------------------------------------
+
+module omsp_sync_reset (
+
+// OUTPUTs
+ rst_s, // Synchronized reset
+
+// INPUTs
+ clk, // Receiving clock
+ rst_a // Asynchronous reset
+);
+
+// OUTPUTs
+//=========
+output rst_s; // Synchronized reset
+
+// INPUTs
+//=========
+input clk; // Receiving clock
+input rst_a; // Asynchronous reset
+
+
+//=============================================================================
+// 1) SYNCHRONIZER
+//=============================================================================
+
+reg [1:0] data_sync;
+
+always @(posedge clk or posedge rst_a)
+ if (rst_a) data_sync <= 2'b11;
+ else data_sync <= {data_sync[0], 1'b0};
+
+assign rst_s = data_sync[1];
+
+
+endmodule // omsp_sync_reset
+
diff --git a/tests/openmsp430/rtl/omsp_wakeup_cell.v b/tests/openmsp430/rtl/omsp_wakeup_cell.v
new file mode 100644
index 000000000..6e5fcd880
--- /dev/null
+++ b/tests/openmsp430/rtl/omsp_wakeup_cell.v
@@ -0,0 +1,108 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2009 , Olivier Girard
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the authors nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE
+//
+//----------------------------------------------------------------------------
+//
+// *File Name: omsp_wakeup_cell.v
+//
+// *Module Description:
+// Generic Wakeup cell
+//
+// *Author(s):
+// - Olivier Girard, olgirard@gmail.com
+//
+//----------------------------------------------------------------------------
+// $Rev: 103 $
+// $LastChangedBy: olivier.girard $
+// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
+//----------------------------------------------------------------------------
+
+module omsp_wakeup_cell (
+
+// OUTPUTs
+ wkup_out, // Wakup signal (asynchronous)
+
+// INPUTs
+ scan_clk, // Scan clock
+ scan_mode, // Scan mode
+ scan_rst, // Scan reset
+ wkup_clear, // Glitch free wakeup event clear
+ wkup_event // Glitch free asynchronous wakeup event
+);
+
+// OUTPUTs
+//=========
+output wkup_out; // Wakup signal (asynchronous)
+
+// INPUTs
+//=========
+input scan_clk; // Scan clock
+input scan_mode; // Scan mode
+input scan_rst; // Scan reset
+input wkup_clear; // Glitch free wakeup event clear
+input wkup_event; // Glitch free asynchronous wakeup event
+
+
+//=============================================================================
+// 1) AND GATE
+//=============================================================================
+
+// Scan stuff for the ASIC mode
+`ifdef ASIC
+ wire wkup_rst;
+ omsp_scan_mux scan_mux_rst (
+ .scan_mode (scan_mode),
+ .data_in_scan (scan_rst),
+ .data_in_func (wkup_clear),
+ .data_out (wkup_rst)
+ );
+
+ wire wkup_clk;
+ omsp_scan_mux scan_mux_clk (
+ .scan_mode (scan_mode),
+ .data_in_scan (scan_clk),
+ .data_in_func (wkup_event),
+ .data_out (wkup_clk)
+ );
+
+`else
+ wire wkup_rst = wkup_clear;
+ wire wkup_clk = wkup_event;
+`endif
+
+// Wakeup capture
+reg wkup_out;
+always @(posedge wkup_clk or posedge wkup_rst)
+ if (wkup_rst) wkup_out <= 1'b0;
+ else wkup_out <= 1'b1;
+
+
+endmodule // omsp_wakeup_cell
+
+
+
+
diff --git a/tests/openmsp430/rtl/omsp_watchdog.v b/tests/openmsp430/rtl/omsp_watchdog.v
new file mode 100644
index 000000000..f7cedda08
--- /dev/null
+++ b/tests/openmsp430/rtl/omsp_watchdog.v
@@ -0,0 +1,556 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2009 , Olivier Girard
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the authors nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE
+//
+//----------------------------------------------------------------------------
+//
+// *File Name: omsp_watchdog.v
+//
+// *Module Description:
+// Watchdog Timer
+//
+// *Author(s):
+// - Olivier Girard, olgirard@gmail.com
+//
+//----------------------------------------------------------------------------
+// $Rev: 134 $
+// $LastChangedBy: olivier.girard $
+// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $
+//----------------------------------------------------------------------------
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_defines.v"
+`endif
+
+module omsp_watchdog (
+
+// OUTPUTs
+ per_dout, // Peripheral data output
+ wdt_irq, // Watchdog-timer interrupt
+ wdt_reset, // Watchdog-timer reset
+ wdt_wkup, // Watchdog Wakeup
+ wdtifg, // Watchdog-timer interrupt flag
+ wdtnmies, // Watchdog-timer NMI edge selection
+
+// INPUTs
+ aclk, // ACLK
+ aclk_en, // ACLK enable
+ dbg_freeze, // Freeze Watchdog counter
+ mclk, // Main system clock
+ per_addr, // Peripheral address
+ per_din, // Peripheral data input
+ per_en, // Peripheral enable (high active)
+ per_we, // Peripheral write enable (high active)
+ por, // Power-on reset
+ puc_rst, // Main system reset
+ scan_enable, // Scan enable (active during scan shifting)
+ scan_mode, // Scan mode
+ smclk, // SMCLK
+ smclk_en, // SMCLK enable
+ wdtie, // Watchdog timer interrupt enable
+ wdtifg_irq_clr, // Watchdog-timer interrupt flag irq accepted clear
+ wdtifg_sw_clr, // Watchdog-timer interrupt flag software clear
+ wdtifg_sw_set // Watchdog-timer interrupt flag software set
+);
+
+// OUTPUTs
+//=========
+output [15:0] per_dout; // Peripheral data output
+output wdt_irq; // Watchdog-timer interrupt
+output wdt_reset; // Watchdog-timer reset
+output wdt_wkup; // Watchdog Wakeup
+output wdtifg; // Watchdog-timer interrupt flag
+output wdtnmies; // Watchdog-timer NMI edge selection
+
+// INPUTs
+//=========
+input aclk; // ACLK
+input aclk_en; // ACLK enable
+input dbg_freeze; // Freeze Watchdog counter
+input mclk; // Main system clock
+input [13:0] per_addr; // Peripheral address
+input [15:0] per_din; // Peripheral data input
+input per_en; // Peripheral enable (high active)
+input [1:0] per_we; // Peripheral write enable (high active)
+input por; // Power-on reset
+input puc_rst; // Main system reset
+input scan_enable; // Scan enable (active during scan shifting)
+input scan_mode; // Scan mode
+input smclk; // SMCLK
+input smclk_en; // SMCLK enable
+input wdtie; // Watchdog timer interrupt enable
+input wdtifg_irq_clr; // Clear Watchdog-timer interrupt flag
+input wdtifg_sw_clr; // Watchdog-timer interrupt flag software clear
+input wdtifg_sw_set; // Watchdog-timer interrupt flag software set
+
+
+//=============================================================================
+// 1) PARAMETER DECLARATION
+//=============================================================================
+
+// Register base address (must be aligned to decoder bit width)
+parameter [14:0] BASE_ADDR = 15'h0120;
+
+// Decoder bit width (defines how many bits are considered for address decoding)
+parameter DEC_WD = 2;
+
+// Register addresses offset
+parameter [DEC_WD-1:0] WDTCTL = 'h0;
+
+// Register one-hot decoder utilities
+parameter DEC_SZ = (1 << DEC_WD);
+parameter [DEC_SZ-1:0] BASE_REG = {{DEC_SZ-1{1'b0}}, 1'b1};
+
+// Register one-hot decoder
+parameter [DEC_SZ-1:0] WDTCTL_D = (BASE_REG << WDTCTL);
+
+
+//============================================================================
+// 2) REGISTER DECODER
+//============================================================================
+
+// Local register selection
+wire reg_sel = per_en & (per_addr[13:DEC_WD-1]==BASE_ADDR[14:DEC_WD]);
+
+// Register local address
+wire [DEC_WD-1:0] reg_addr = {per_addr[DEC_WD-2:0], 1'b0};
+
+// Register address decode
+wire [DEC_SZ-1:0] reg_dec = (WDTCTL_D & {DEC_SZ{(reg_addr==WDTCTL)}});
+
+// Read/Write probes
+wire reg_write = |per_we & reg_sel;
+wire reg_read = ~|per_we & reg_sel;
+
+// Read/Write vectors
+wire [DEC_SZ-1:0] reg_wr = reg_dec & {DEC_SZ{reg_write}};
+wire [DEC_SZ-1:0] reg_rd = reg_dec & {DEC_SZ{reg_read}};
+
+
+//============================================================================
+// 3) REGISTERS
+//============================================================================
+
+// WDTCTL Register
+//-----------------
+// WDTNMI is not implemented and therefore masked
+
+reg [7:0] wdtctl;
+
+wire wdtctl_wr = reg_wr[WDTCTL];
+
+`ifdef CLOCK_GATING
+wire mclk_wdtctl;
+omsp_clock_gate clock_gate_wdtctl (.gclk(mclk_wdtctl),
+ .clk (mclk), .enable(wdtctl_wr), .scan_enable(scan_enable));
+`else
+wire mclk_wdtctl = mclk;
+`endif
+
+`ifdef NMI
+parameter [7:0] WDTNMIES_MASK = 8'h40;
+`else
+parameter [7:0] WDTNMIES_MASK = 8'h00;
+`endif
+
+`ifdef ASIC
+ `ifdef WATCHDOG_MUX
+parameter [7:0] WDTSSEL_MASK = 8'h04;
+ `else
+parameter [7:0] WDTSSEL_MASK = 8'h00;
+ `endif
+`else
+parameter [7:0] WDTSSEL_MASK = 8'h04;
+`endif
+
+parameter [7:0] WDTCTL_MASK = (8'b1001_0011 | WDTSSEL_MASK | WDTNMIES_MASK);
+
+always @ (posedge mclk_wdtctl or posedge puc_rst)
+ if (puc_rst) wdtctl <= 8'h00;
+`ifdef CLOCK_GATING
+ else wdtctl <= per_din[7:0] & WDTCTL_MASK;
+`else
+ else if (wdtctl_wr) wdtctl <= per_din[7:0] & WDTCTL_MASK;
+`endif
+
+wire wdtpw_error = wdtctl_wr & (per_din[15:8]!=8'h5a);
+wire wdttmsel = wdtctl[4];
+wire wdtnmies = wdtctl[6];
+
+
+//============================================================================
+// 4) DATA OUTPUT GENERATION
+//============================================================================
+
+`ifdef NMI
+parameter [7:0] WDTNMI_RD_MASK = 8'h20;
+`else
+parameter [7:0] WDTNMI_RD_MASK = 8'h00;
+`endif
+`ifdef WATCHDOG_MUX
+parameter [7:0] WDTSSEL_RD_MASK = 8'h00;
+`else
+ `ifdef WATCHDOG_NOMUX_ACLK
+parameter [7:0] WDTSSEL_RD_MASK = 8'h04;
+ `else
+parameter [7:0] WDTSSEL_RD_MASK = 8'h00;
+ `endif
+`endif
+parameter [7:0] WDTCTL_RD_MASK = WDTNMI_RD_MASK | WDTSSEL_RD_MASK;
+
+// Data output mux
+wire [15:0] wdtctl_rd = {8'h69, wdtctl | WDTCTL_RD_MASK} & {16{reg_rd[WDTCTL]}};
+wire [15:0] per_dout = wdtctl_rd;
+
+
+//=============================================================================
+// 5) WATCHDOG TIMER (ASIC IMPLEMENTATION)
+//=============================================================================
+`ifdef ASIC
+
+// Watchdog clock source selection
+//---------------------------------
+wire wdt_clk;
+
+`ifdef WATCHDOG_MUX
+omsp_clock_mux clock_mux_watchdog (
+ .clk_out (wdt_clk),
+ .clk_in0 (smclk),
+ .clk_in1 (aclk),
+ .reset (puc_rst),
+ .scan_mode (scan_mode),
+ .select (wdtctl[2])
+);
+`else
+ `ifdef WATCHDOG_NOMUX_ACLK
+ assign wdt_clk = aclk;
+ `else
+ assign wdt_clk = smclk;
+ `endif
+`endif
+
+// Reset synchronizer for the watchdog local clock domain
+//--------------------------------------------------------
+
+wire wdt_rst_noscan;
+wire wdt_rst;
+
+// Reset Synchronizer
+omsp_sync_reset sync_reset_por (
+ .rst_s (wdt_rst_noscan),
+ .clk (wdt_clk),
+ .rst_a (puc_rst)
+);
+
+// Scan Reset Mux
+omsp_scan_mux scan_mux_wdt_rst (
+ .scan_mode (scan_mode),
+ .data_in_scan (puc_rst),
+ .data_in_func (wdt_rst_noscan),
+ .data_out (wdt_rst)
+);
+
+
+// Watchog counter clear (synchronization)
+//-----------------------------------------
+
+// Toggle bit whenever the watchog needs to be cleared
+reg wdtcnt_clr_toggle;
+wire wdtcnt_clr_detect = (wdtctl_wr & per_din[3]);
+always @ (posedge mclk or posedge puc_rst)
+ if (puc_rst) wdtcnt_clr_toggle <= 1'b0;
+ else if (wdtcnt_clr_detect) wdtcnt_clr_toggle <= ~wdtcnt_clr_toggle;
+
+// Synchronization
+wire wdtcnt_clr_sync;
+omsp_sync_cell sync_cell_wdtcnt_clr (
+ .data_out (wdtcnt_clr_sync),
+ .data_in (wdtcnt_clr_toggle),
+ .clk (wdt_clk),
+ .rst (wdt_rst)
+);
+
+// Edge detection
+reg wdtcnt_clr_sync_dly;
+always @ (posedge wdt_clk or posedge wdt_rst)
+ if (wdt_rst) wdtcnt_clr_sync_dly <= 1'b0;
+ else wdtcnt_clr_sync_dly <= wdtcnt_clr_sync;
+
+wire wdtqn_edge;
+wire wdtcnt_clr = (wdtcnt_clr_sync ^ wdtcnt_clr_sync_dly) | wdtqn_edge;
+
+
+// Watchog counter increment (synchronization)
+//----------------------------------------------
+wire wdtcnt_incr;
+
+omsp_sync_cell sync_cell_wdtcnt_incr (
+ .data_out (wdtcnt_incr),
+ .data_in (~wdtctl[7] & ~dbg_freeze),
+ .clk (wdt_clk),
+ .rst (wdt_rst)
+);
+
+
+// Watchdog 16 bit counter
+//--------------------------
+reg [15:0] wdtcnt;
+
+wire [15:0] wdtcnt_nxt = wdtcnt+16'h0001;
+
+`ifdef CLOCK_GATING
+wire wdtcnt_en = wdtcnt_clr | wdtcnt_incr;
+wire wdt_clk_cnt;
+omsp_clock_gate clock_gate_wdtcnt (.gclk(wdt_clk_cnt),
+ .clk (wdt_clk), .enable(wdtcnt_en), .scan_enable(scan_enable));
+`else
+wire wdt_clk_cnt = wdt_clk;
+`endif
+
+always @ (posedge wdt_clk_cnt or posedge wdt_rst)
+ if (wdt_rst) wdtcnt <= 16'h0000;
+ else if (wdtcnt_clr) wdtcnt <= 16'h0000;
+`ifdef CLOCK_GATING
+ else wdtcnt <= wdtcnt_nxt;
+`else
+ else if (wdtcnt_incr) wdtcnt <= wdtcnt_nxt;
+`endif
+
+
+// Local synchronizer for the wdtctl.WDTISx
+// configuration (note that we can live with
+// a full bus synchronizer as it won't hurt
+// if we get a wrong WDTISx value for a
+// single clock cycle)
+//--------------------------------------------
+reg [1:0] wdtisx_s;
+reg [1:0] wdtisx_ss;
+always @ (posedge wdt_clk_cnt or posedge wdt_rst)
+ if (wdt_rst)
+ begin
+ wdtisx_s <= 2'h0;
+ wdtisx_ss <= 2'h0;
+ end
+ else
+ begin
+ wdtisx_s <= wdtctl[1:0];
+ wdtisx_ss <= wdtisx_s;
+ end
+
+
+// Interval selection mux
+//--------------------------
+reg wdtqn;
+
+always @(wdtisx_ss or wdtcnt_nxt)
+ case(wdtisx_ss)
+ 2'b00 : wdtqn = wdtcnt_nxt[15];
+ 2'b01 : wdtqn = wdtcnt_nxt[13];
+ 2'b10 : wdtqn = wdtcnt_nxt[9];
+ default: wdtqn = wdtcnt_nxt[6];
+ endcase
+
+
+// Watchdog event detection
+//-----------------------------
+
+// Interval end detection
+assign wdtqn_edge = (wdtqn & wdtcnt_incr);
+
+// Toggle bit for the transmition to the MCLK domain
+reg wdt_evt_toggle;
+always @ (posedge wdt_clk_cnt or posedge wdt_rst)
+ if (wdt_rst) wdt_evt_toggle <= 1'b0;
+ else if (wdtqn_edge) wdt_evt_toggle <= ~wdt_evt_toggle;
+
+// Synchronize in the MCLK domain
+wire wdt_evt_toggle_sync;
+omsp_sync_cell sync_cell_wdt_evt (
+ .data_out (wdt_evt_toggle_sync),
+ .data_in (wdt_evt_toggle),
+ .clk (mclk),
+ .rst (puc_rst)
+);
+
+// Delay for edge detection of the toggle bit
+reg wdt_evt_toggle_sync_dly;
+always @ (posedge mclk or posedge puc_rst)
+ if (puc_rst) wdt_evt_toggle_sync_dly <= 1'b0;
+ else wdt_evt_toggle_sync_dly <= wdt_evt_toggle_sync;
+
+wire wdtifg_evt = (wdt_evt_toggle_sync_dly ^ wdt_evt_toggle_sync) | wdtpw_error;
+
+
+// Watchdog wakeup generation
+//-------------------------------------------------------------
+
+// Clear wakeup when the watchdog flag is cleared (glitch free)
+reg wdtifg_clr_reg;
+wire wdtifg_clr;
+always @ (posedge mclk or posedge puc_rst)
+ if (puc_rst) wdtifg_clr_reg <= 1'b1;
+ else wdtifg_clr_reg <= wdtifg_clr;
+
+// Set wakeup when the watchdog event is detected (glitch free)
+reg wdtqn_edge_reg;
+always @ (posedge wdt_clk_cnt or posedge wdt_rst)
+ if (wdt_rst) wdtqn_edge_reg <= 1'b0;
+ else wdtqn_edge_reg <= wdtqn_edge;
+
+// Watchdog wakeup cell
+wire wdt_wkup_pre;
+omsp_wakeup_cell wakeup_cell_wdog (
+ .wkup_out (wdt_wkup_pre), // Wakup signal (asynchronous)
+ .scan_clk (mclk), // Scan clock
+ .scan_mode (scan_mode), // Scan mode
+ .scan_rst (puc_rst), // Scan reset
+ .wkup_clear (wdtifg_clr_reg), // Glitch free wakeup event clear
+ .wkup_event (wdtqn_edge_reg) // Glitch free asynchronous wakeup event
+);
+
+// When not in HOLD, the watchdog can generate a wakeup when:
+// - in interval mode (if interrupts are enabled)
+// - in reset mode (always)
+reg wdt_wkup_en;
+always @ (posedge mclk or posedge puc_rst)
+ if (puc_rst) wdt_wkup_en <= 1'b0;
+ else wdt_wkup_en <= ~wdtctl[7] & (~wdttmsel | (wdttmsel & wdtie));
+
+// Make wakeup when not enabled
+wire wdt_wkup;
+omsp_and_gate and_wdt_wkup (.y(wdt_wkup), .a(wdt_wkup_pre), .b(wdt_wkup_en));
+
+
+// Watchdog interrupt flag
+//------------------------------
+reg wdtifg;
+
+wire wdtifg_set = wdtifg_evt | wdtifg_sw_set;
+assign wdtifg_clr = (wdtifg_irq_clr & wdttmsel) | wdtifg_sw_clr;
+
+always @ (posedge mclk or posedge por)
+ if (por) wdtifg <= 1'b0;
+ else if (wdtifg_set) wdtifg <= 1'b1;
+ else if (wdtifg_clr) wdtifg <= 1'b0;
+
+
+// Watchdog interrupt generation
+//---------------------------------
+wire wdt_irq = wdttmsel & wdtifg & wdtie;
+
+
+// Watchdog reset generation
+//-----------------------------
+reg wdt_reset;
+
+always @ (posedge mclk or posedge por)
+ if (por) wdt_reset <= 1'b0;
+ else wdt_reset <= wdtpw_error | (wdtifg_set & ~wdttmsel);
+
+
+
+//=============================================================================
+// 6) WATCHDOG TIMER (FPGA IMPLEMENTATION)
+//=============================================================================
+`else
+
+// Watchdog clock source selection
+//---------------------------------
+wire clk_src_en = wdtctl[2] ? aclk_en : smclk_en;
+
+
+// Watchdog 16 bit counter
+//--------------------------
+reg [15:0] wdtcnt;
+
+wire wdtifg_evt;
+wire wdtcnt_clr = (wdtctl_wr & per_din[3]) | wdtifg_evt;
+wire wdtcnt_incr = ~wdtctl[7] & clk_src_en & ~dbg_freeze;
+
+wire [15:0] wdtcnt_nxt = wdtcnt+16'h0001;
+
+always @ (posedge mclk or posedge puc_rst)
+ if (puc_rst) wdtcnt <= 16'h0000;
+ else if (wdtcnt_clr) wdtcnt <= 16'h0000;
+ else if (wdtcnt_incr) wdtcnt <= wdtcnt_nxt;
+
+
+// Interval selection mux
+//--------------------------
+reg wdtqn;
+
+always @(wdtctl or wdtcnt_nxt)
+ case(wdtctl[1:0])
+ 2'b00 : wdtqn = wdtcnt_nxt[15];
+ 2'b01 : wdtqn = wdtcnt_nxt[13];
+ 2'b10 : wdtqn = wdtcnt_nxt[9];
+ default: wdtqn = wdtcnt_nxt[6];
+ endcase
+
+
+// Watchdog event detection
+//-----------------------------
+
+assign wdtifg_evt = (wdtqn & wdtcnt_incr) | wdtpw_error;
+
+
+// Watchdog interrupt flag
+//------------------------------
+reg wdtifg;
+
+wire wdtifg_set = wdtifg_evt | wdtifg_sw_set;
+wire wdtifg_clr = (wdtifg_irq_clr & wdttmsel) | wdtifg_sw_clr;
+
+always @ (posedge mclk or posedge por)
+ if (por) wdtifg <= 1'b0;
+ else if (wdtifg_set) wdtifg <= 1'b1;
+ else if (wdtifg_clr) wdtifg <= 1'b0;
+
+
+// Watchdog interrupt generation
+//---------------------------------
+wire wdt_irq = wdttmsel & wdtifg & wdtie;
+wire wdt_wkup = 1'b0;
+
+
+// Watchdog reset generation
+//-----------------------------
+reg wdt_reset;
+
+always @ (posedge mclk or posedge por)
+ if (por) wdt_reset <= 1'b0;
+ else wdt_reset <= wdtpw_error | (wdtifg_set & ~wdttmsel);
+
+
+`endif
+
+
+endmodule // omsp_watchdog
+
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_undefines.v"
+`endif
diff --git a/tests/openmsp430/rtl/openMSP430.v b/tests/openmsp430/rtl/openMSP430.v
new file mode 100644
index 000000000..938548aaf
--- /dev/null
+++ b/tests/openmsp430/rtl/openMSP430.v
@@ -0,0 +1,584 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2009 , Olivier Girard
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the authors nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE
+//
+//----------------------------------------------------------------------------
+//
+// *File Name: openMSP430.v
+//
+// *Module Description:
+// openMSP430 Top level file
+//
+// *Author(s):
+// - Olivier Girard, olgirard@gmail.com
+//
+//----------------------------------------------------------------------------
+// $Rev: 134 $
+// $LastChangedBy: olivier.girard $
+// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $
+//----------------------------------------------------------------------------
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_defines.v"
+`endif
+
+module openMSP430 (
+
+// OUTPUTs
+ aclk, // ASIC ONLY: ACLK
+ aclk_en, // FPGA ONLY: ACLK enable
+ dbg_freeze, // Freeze peripherals
+ dbg_uart_txd, // Debug interface: UART TXD
+ dco_enable, // ASIC ONLY: Fast oscillator enable
+ dco_wkup, // ASIC ONLY: Fast oscillator wake-up (asynchronous)
+ dmem_addr, // Data Memory address
+ dmem_cen, // Data Memory chip enable (low active)
+ dmem_din, // Data Memory data input
+ dmem_wen, // Data Memory write enable (low active)
+ irq_acc, // Interrupt request accepted (one-hot signal)
+ lfxt_enable, // ASIC ONLY: Low frequency oscillator enable
+ lfxt_wkup, // ASIC ONLY: Low frequency oscillator wake-up (asynchronous)
+ mclk, // Main system clock
+ per_addr, // Peripheral address
+ per_din, // Peripheral data input
+ per_we, // Peripheral write enable (high active)
+ per_en, // Peripheral enable (high active)
+ pmem_addr, // Program Memory address
+ pmem_cen, // Program Memory chip enable (low active)
+ pmem_din, // Program Memory data input (optional)
+ pmem_wen, // Program Memory write enable (low active) (optional)
+ puc_rst, // Main system reset
+ smclk, // ASIC ONLY: SMCLK
+ smclk_en, // FPGA ONLY: SMCLK enable
+
+// INPUTs
+ cpu_en, // Enable CPU code execution (asynchronous and non-glitchy)
+ dbg_en, // Debug interface enable (asynchronous and non-glitchy)
+ dbg_uart_rxd, // Debug interface: UART RXD (asynchronous)
+ dco_clk, // Fast oscillator (fast clock)
+ dmem_dout, // Data Memory data output
+ irq, // Maskable interrupts
+ lfxt_clk, // Low frequency oscillator (typ 32kHz)
+ nmi, // Non-maskable interrupt (asynchronous)
+ per_dout, // Peripheral data output
+ pmem_dout, // Program Memory data output
+ reset_n, // Reset Pin (low active, asynchronous and non-glitchy)
+ scan_enable, // ASIC ONLY: Scan enable (active during scan shifting)
+ scan_mode, // ASIC ONLY: Scan mode
+ wkup // ASIC ONLY: System Wake-up (asynchronous and non-glitchy)
+);
+
+// OUTPUTs
+//=========
+output aclk; // ASIC ONLY: ACLK
+output aclk_en; // FPGA ONLY: ACLK enable
+output dbg_freeze; // Freeze peripherals
+output dbg_uart_txd; // Debug interface: UART TXD
+output dco_enable; // ASIC ONLY: Fast oscillator enable
+output dco_wkup; // ASIC ONLY: Fast oscillator wake-up (asynchronous)
+output [`DMEM_MSB:0] dmem_addr; // Data Memory address
+output dmem_cen; // Data Memory chip enable (low active)
+output [15:0] dmem_din; // Data Memory data input
+output [1:0] dmem_wen; // Data Memory write enable (low active)
+output [13:0] irq_acc; // Interrupt request accepted (one-hot signal)
+output lfxt_enable; // ASIC ONLY: Low frequency oscillator enable
+output lfxt_wkup; // ASIC ONLY: Low frequency oscillator wake-up (asynchronous)
+output mclk; // Main system clock
+output [13:0] per_addr; // Peripheral address
+output [15:0] per_din; // Peripheral data input
+output [1:0] per_we; // Peripheral write enable (high active)
+output per_en; // Peripheral enable (high active)
+output [`PMEM_MSB:0] pmem_addr; // Program Memory address
+output pmem_cen; // Program Memory chip enable (low active)
+output [15:0] pmem_din; // Program Memory data input (optional)
+output [1:0] pmem_wen; // Program Memory write enable (low active) (optional)
+output puc_rst; // Main system reset
+output smclk; // ASIC ONLY: SMCLK
+output smclk_en; // FPGA ONLY: SMCLK enable
+
+
+// INPUTs
+//=========
+input cpu_en; // Enable CPU code execution (asynchronous and non-glitchy)
+input dbg_en; // Debug interface enable (asynchronous and non-glitchy)
+input dbg_uart_rxd; // Debug interface: UART RXD (asynchronous)
+input dco_clk; // Fast oscillator (fast clock)
+input [15:0] dmem_dout; // Data Memory data output
+input [13:0] irq; // Maskable interrupts
+input lfxt_clk; // Low frequency oscillator (typ 32kHz)
+input nmi; // Non-maskable interrupt (asynchronous and non-glitchy)
+input [15:0] per_dout; // Peripheral data output
+input [15:0] pmem_dout; // Program Memory data output
+input reset_n; // Reset Pin (active low, asynchronous and non-glitchy)
+input scan_enable; // ASIC ONLY: Scan enable (active during scan shifting)
+input scan_mode; // ASIC ONLY: Scan mode
+input wkup; // ASIC ONLY: System Wake-up (asynchronous and non-glitchy)
+
+
+
+//=============================================================================
+// 1) INTERNAL WIRES/REGISTERS/PARAMETERS DECLARATION
+//=============================================================================
+
+wire [7:0] inst_ad;
+wire [7:0] inst_as;
+wire [11:0] inst_alu;
+wire inst_bw;
+wire inst_irq_rst;
+wire inst_mov;
+wire [15:0] inst_dest;
+wire [15:0] inst_dext;
+wire [15:0] inst_sext;
+wire [7:0] inst_so;
+wire [15:0] inst_src;
+wire [2:0] inst_type;
+wire [7:0] inst_jmp;
+wire [3:0] e_state;
+wire exec_done;
+wire decode_noirq;
+wire cpu_en_s;
+wire cpuoff;
+wire oscoff;
+wire scg0;
+wire scg1;
+wire por;
+wire gie;
+wire mclk_enable;
+wire mclk_wkup;
+wire [31:0] cpu_id;
+
+wire [15:0] eu_mab;
+wire [15:0] eu_mdb_in;
+wire [15:0] eu_mdb_out;
+wire [1:0] eu_mb_wr;
+wire eu_mb_en;
+wire [15:0] fe_mab;
+wire [15:0] fe_mdb_in;
+wire fe_mb_en;
+wire fe_pmem_wait;
+
+wire pc_sw_wr;
+wire [15:0] pc_sw;
+wire [15:0] pc;
+wire [15:0] pc_nxt;
+
+wire nmi_acc;
+wire nmi_pnd;
+wire nmi_wkup;
+
+wire wdtie;
+wire wdtnmies;
+wire wdtifg;
+wire wdt_irq;
+wire wdt_wkup;
+wire wdt_reset;
+wire wdtifg_sw_clr;
+wire wdtifg_sw_set;
+
+wire dbg_clk;
+wire dbg_rst;
+wire dbg_en_s;
+wire dbg_halt_st;
+wire dbg_halt_cmd;
+wire dbg_mem_en;
+wire dbg_reg_wr;
+wire dbg_cpu_reset;
+wire [15:0] dbg_mem_addr;
+wire [15:0] dbg_mem_dout;
+wire [15:0] dbg_mem_din;
+wire [15:0] dbg_reg_din;
+wire [1:0] dbg_mem_wr;
+wire puc_pnd_set;
+
+wire [15:0] per_dout_or;
+wire [15:0] per_dout_sfr;
+wire [15:0] per_dout_wdog;
+wire [15:0] per_dout_mpy;
+wire [15:0] per_dout_clk;
+
+
+//=============================================================================
+// 2) GLOBAL CLOCK & RESET MANAGEMENT
+//=============================================================================
+
+omsp_clock_module clock_module_0 (
+
+// OUTPUTs
+ .aclk (aclk), // ACLK
+ .aclk_en (aclk_en), // ACLK enablex
+ .cpu_en_s (cpu_en_s), // Enable CPU code execution (synchronous)
+ .dbg_clk (dbg_clk), // Debug unit clock
+ .dbg_en_s (dbg_en_s), // Debug interface enable (synchronous)
+ .dbg_rst (dbg_rst), // Debug unit reset
+ .dco_enable (dco_enable), // Fast oscillator enable
+ .dco_wkup (dco_wkup), // Fast oscillator wake-up (asynchronous)
+ .lfxt_enable (lfxt_enable), // Low frequency oscillator enable
+ .lfxt_wkup (lfxt_wkup), // Low frequency oscillator wake-up (asynchronous)
+ .mclk (mclk), // Main system clock
+ .per_dout (per_dout_clk), // Peripheral data output
+ .por (por), // Power-on reset
+ .puc_pnd_set (puc_pnd_set), // PUC pending set for the serial debug interface
+ .puc_rst (puc_rst), // Main system reset
+ .smclk (smclk), // SMCLK
+ .smclk_en (smclk_en), // SMCLK enable
+
+// INPUTs
+ .cpu_en (cpu_en), // Enable CPU code execution (asynchronous)
+ .cpuoff (cpuoff), // Turns off the CPU
+ .dbg_cpu_reset(dbg_cpu_reset), // Reset CPU from debug interface
+ .dbg_en (dbg_en), // Debug interface enable (asynchronous)
+ .dco_clk (dco_clk), // Fast oscillator (fast clock)
+ .lfxt_clk (lfxt_clk), // Low frequency oscillator (typ 32kHz)
+ .mclk_enable (mclk_enable), // Main System Clock enable
+ .mclk_wkup (mclk_wkup), // Main System Clock wake-up (asynchronous)
+ .oscoff (oscoff), // Turns off LFXT1 clock input
+ .per_addr (per_addr), // Peripheral address
+ .per_din (per_din), // Peripheral data input
+ .per_en (per_en), // Peripheral enable (high active)
+ .per_we (per_we), // Peripheral write enable (high active)
+ .reset_n (reset_n), // Reset Pin (low active, asynchronous)
+ .scan_enable (scan_enable), // Scan enable (active during scan shifting)
+ .scan_mode (scan_mode), // Scan mode
+ .scg0 (scg0), // System clock generator 1. Turns off the DCO
+ .scg1 (scg1), // System clock generator 1. Turns off the SMCLK
+ .wdt_reset (wdt_reset) // Watchdog-timer reset
+);
+
+
+//=============================================================================
+// 3) FRONTEND (<=> FETCH & DECODE)
+//=============================================================================
+
+omsp_frontend frontend_0 (
+
+// OUTPUTs
+ .dbg_halt_st (dbg_halt_st), // Halt/Run status from CPU
+ .decode_noirq (decode_noirq), // Frontend decode instruction
+ .e_state (e_state), // Execution state
+ .exec_done (exec_done), // Execution completed
+ .inst_ad (inst_ad), // Decoded Inst: destination addressing mode
+ .inst_as (inst_as), // Decoded Inst: source addressing mode
+ .inst_alu (inst_alu), // ALU control signals
+ .inst_bw (inst_bw), // Decoded Inst: byte width
+ .inst_dest (inst_dest), // Decoded Inst: destination (one hot)
+ .inst_dext (inst_dext), // Decoded Inst: destination extended instruction word
+ .inst_irq_rst (inst_irq_rst), // Decoded Inst: Reset interrupt
+ .inst_jmp (inst_jmp), // Decoded Inst: Conditional jump
+ .inst_mov (inst_mov), // Decoded Inst: mov instruction
+ .inst_sext (inst_sext), // Decoded Inst: source extended instruction word
+ .inst_so (inst_so), // Decoded Inst: Single-operand arithmetic
+ .inst_src (inst_src), // Decoded Inst: source (one hot)
+ .inst_type (inst_type), // Decoded Instruction type
+ .irq_acc (irq_acc), // Interrupt request accepted
+ .mab (fe_mab), // Frontend Memory address bus
+ .mb_en (fe_mb_en), // Frontend Memory bus enable
+ .mclk_enable (mclk_enable), // Main System Clock enable
+ .mclk_wkup (mclk_wkup), // Main System Clock wake-up (asynchronous)
+ .nmi_acc (nmi_acc), // Non-Maskable interrupt request accepted
+ .pc (pc), // Program counter
+ .pc_nxt (pc_nxt), // Next PC value (for CALL & IRQ)
+
+// INPUTs
+ .cpu_en_s (cpu_en_s), // Enable CPU code execution (synchronous)
+ .cpuoff (cpuoff), // Turns off the CPU
+ .dbg_halt_cmd (dbg_halt_cmd), // Halt CPU command
+ .dbg_reg_sel (dbg_mem_addr[3:0]), // Debug selected register for rd/wr access
+ .fe_pmem_wait (fe_pmem_wait), // Frontend wait for Instruction fetch
+ .gie (gie), // General interrupt enable
+ .irq (irq), // Maskable interrupts
+ .mclk (mclk), // Main system clock
+ .mdb_in (fe_mdb_in), // Frontend Memory data bus input
+ .nmi_pnd (nmi_pnd), // Non-maskable interrupt pending
+ .nmi_wkup (nmi_wkup), // NMI Wakeup
+ .pc_sw (pc_sw), // Program counter software value
+ .pc_sw_wr (pc_sw_wr), // Program counter software write
+ .puc_rst (puc_rst), // Main system reset
+ .scan_enable (scan_enable), // Scan enable (active during scan shifting)
+ .wdt_irq (wdt_irq), // Watchdog-timer interrupt
+ .wdt_wkup (wdt_wkup), // Watchdog Wakeup
+ .wkup (wkup) // System Wake-up (asynchronous)
+);
+
+
+//=============================================================================
+// 4) EXECUTION UNIT
+//=============================================================================
+
+omsp_execution_unit execution_unit_0 (
+
+// OUTPUTs
+ .cpuoff (cpuoff), // Turns off the CPU
+ .dbg_reg_din (dbg_reg_din), // Debug unit CPU register data input
+ .mab (eu_mab), // Memory address bus
+ .mb_en (eu_mb_en), // Memory bus enable
+ .mb_wr (eu_mb_wr), // Memory bus write transfer
+ .mdb_out (eu_mdb_out), // Memory data bus output
+ .oscoff (oscoff), // Turns off LFXT1 clock input
+ .pc_sw (pc_sw), // Program counter software value
+ .pc_sw_wr (pc_sw_wr), // Program counter software write
+ .scg0 (scg0), // System clock generator 1. Turns off the DCO
+ .scg1 (scg1), // System clock generator 1. Turns off the SMCLK
+
+// INPUTs
+ .dbg_halt_st (dbg_halt_st), // Halt/Run status from CPU
+ .dbg_mem_dout (dbg_mem_dout), // Debug unit data output
+ .dbg_reg_wr (dbg_reg_wr), // Debug unit CPU register write
+ .e_state (e_state), // Execution state
+ .exec_done (exec_done), // Execution completed
+ .gie (gie), // General interrupt enable
+ .inst_ad (inst_ad), // Decoded Inst: destination addressing mode
+ .inst_as (inst_as), // Decoded Inst: source addressing mode
+ .inst_alu (inst_alu), // ALU control signals
+ .inst_bw (inst_bw), // Decoded Inst: byte width
+ .inst_dest (inst_dest), // Decoded Inst: destination (one hot)
+ .inst_dext (inst_dext), // Decoded Inst: destination extended instruction word
+ .inst_irq_rst (inst_irq_rst), // Decoded Inst: reset interrupt
+ .inst_jmp (inst_jmp), // Decoded Inst: Conditional jump
+ .inst_mov (inst_mov), // Decoded Inst: mov instruction
+ .inst_sext (inst_sext), // Decoded Inst: source extended instruction word
+ .inst_so (inst_so), // Decoded Inst: Single-operand arithmetic
+ .inst_src (inst_src), // Decoded Inst: source (one hot)
+ .inst_type (inst_type), // Decoded Instruction type
+ .mclk (mclk), // Main system clock
+ .mdb_in (eu_mdb_in), // Memory data bus input
+ .pc (pc), // Program counter
+ .pc_nxt (pc_nxt), // Next PC value (for CALL & IRQ)
+ .puc_rst (puc_rst), // Main system reset
+ .scan_enable (scan_enable) // Scan enable (active during scan shifting)
+);
+
+
+//=============================================================================
+// 5) MEMORY BACKBONE
+//=============================================================================
+
+omsp_mem_backbone mem_backbone_0 (
+
+// OUTPUTs
+ .dbg_mem_din (dbg_mem_din), // Debug unit Memory data input
+ .dmem_addr (dmem_addr), // Data Memory address
+ .dmem_cen (dmem_cen), // Data Memory chip enable (low active)
+ .dmem_din (dmem_din), // Data Memory data input
+ .dmem_wen (dmem_wen), // Data Memory write enable (low active)
+ .eu_mdb_in (eu_mdb_in), // Execution Unit Memory data bus input
+ .fe_mdb_in (fe_mdb_in), // Frontend Memory data bus input
+ .fe_pmem_wait (fe_pmem_wait), // Frontend wait for Instruction fetch
+ .per_addr (per_addr), // Peripheral address
+ .per_din (per_din), // Peripheral data input
+ .per_we (per_we), // Peripheral write enable (high active)
+ .per_en (per_en), // Peripheral enable (high active)
+ .pmem_addr (pmem_addr), // Program Memory address
+ .pmem_cen (pmem_cen), // Program Memory chip enable (low active)
+ .pmem_din (pmem_din), // Program Memory data input (optional)
+ .pmem_wen (pmem_wen), // Program Memory write enable (low active) (optional)
+
+// INPUTs
+ .dbg_halt_st (dbg_halt_st), // Halt/Run status from CPU
+ .dbg_mem_addr (dbg_mem_addr), // Debug address for rd/wr access
+ .dbg_mem_dout (dbg_mem_dout), // Debug unit data output
+ .dbg_mem_en (dbg_mem_en), // Debug unit memory enable
+ .dbg_mem_wr (dbg_mem_wr), // Debug unit memory write
+ .dmem_dout (dmem_dout), // Data Memory data output
+ .eu_mab (eu_mab[15:1]), // Execution Unit Memory address bus
+ .eu_mb_en (eu_mb_en), // Execution Unit Memory bus enable
+ .eu_mb_wr (eu_mb_wr), // Execution Unit Memory bus write transfer
+ .eu_mdb_out (eu_mdb_out), // Execution Unit Memory data bus output
+ .fe_mab (fe_mab[15:1]), // Frontend Memory address bus
+ .fe_mb_en (fe_mb_en), // Frontend Memory bus enable
+ .mclk (mclk), // Main system clock
+ .per_dout (per_dout_or), // Peripheral data output
+ .pmem_dout (pmem_dout), // Program Memory data output
+ .puc_rst (puc_rst), // Main system reset
+ .scan_enable (scan_enable) // Scan enable (active during scan shifting)
+);
+
+
+//=============================================================================
+// 6) SPECIAL FUNCTION REGISTERS
+//=============================================================================
+omsp_sfr sfr_0 (
+
+// OUTPUTs
+ .cpu_id (cpu_id), // CPU ID
+ .nmi_pnd (nmi_pnd), // NMI Pending
+ .nmi_wkup (nmi_wkup), // NMI Wakeup
+ .per_dout (per_dout_sfr), // Peripheral data output
+ .wdtie (wdtie), // Watchdog-timer interrupt enable
+ .wdtifg_sw_clr(wdtifg_sw_clr), // Watchdog-timer interrupt flag software clear
+ .wdtifg_sw_set(wdtifg_sw_set), // Watchdog-timer interrupt flag software set
+
+// INPUTs
+ .mclk (mclk), // Main system clock
+ .nmi (nmi), // Non-maskable interrupt (asynchronous)
+ .nmi_acc (nmi_acc), // Non-Maskable interrupt request accepted
+ .per_addr (per_addr), // Peripheral address
+ .per_din (per_din), // Peripheral data input
+ .per_en (per_en), // Peripheral enable (high active)
+ .per_we (per_we), // Peripheral write enable (high active)
+ .puc_rst (puc_rst), // Main system reset
+ .scan_mode (scan_mode), // Scan mode
+ .wdtifg (wdtifg), // Watchdog-timer interrupt flag
+ .wdtnmies (wdtnmies) // Watchdog-timer NMI edge selection
+);
+
+
+//=============================================================================
+// 7) WATCHDOG TIMER
+//=============================================================================
+`ifdef WATCHDOG
+omsp_watchdog watchdog_0 (
+
+// OUTPUTs
+ .per_dout (per_dout_wdog), // Peripheral data output
+ .wdt_irq (wdt_irq), // Watchdog-timer interrupt
+ .wdt_reset (wdt_reset), // Watchdog-timer reset
+ .wdt_wkup (wdt_wkup), // Watchdog Wakeup
+ .wdtifg (wdtifg), // Watchdog-timer interrupt flag
+ .wdtnmies (wdtnmies), // Watchdog-timer NMI edge selection
+
+// INPUTs
+ .aclk (aclk), // ACLK
+ .aclk_en (aclk_en), // ACLK enable
+ .dbg_freeze (dbg_freeze), // Freeze Watchdog counter
+ .mclk (mclk), // Main system clock
+ .per_addr (per_addr), // Peripheral address
+ .per_din (per_din), // Peripheral data input
+ .per_en (per_en), // Peripheral enable (high active)
+ .per_we (per_we), // Peripheral write enable (high active)
+ .por (por), // Power-on reset
+ .puc_rst (puc_rst), // Main system reset
+ .scan_enable (scan_enable), // Scan enable (active during scan shifting)
+ .scan_mode (scan_mode), // Scan mode
+ .smclk (smclk), // SMCLK
+ .smclk_en (smclk_en), // SMCLK enable
+ .wdtie (wdtie), // Watchdog-timer interrupt enable
+ .wdtifg_irq_clr (irq_acc[10]), // Clear Watchdog-timer interrupt flag
+ .wdtifg_sw_clr (wdtifg_sw_clr), // Watchdog-timer interrupt flag software clear
+ .wdtifg_sw_set (wdtifg_sw_set) // Watchdog-timer interrupt flag software set
+);
+`else
+assign per_dout_wdog = 16'h0000;
+assign wdt_irq = 1'b0;
+assign wdt_reset = 1'b0;
+assign wdt_wkup = 1'b0;
+assign wdtifg = 1'b0;
+assign wdtnmies = 1'b0;
+`endif
+
+
+//=============================================================================
+// 8) HARDWARE MULTIPLIER
+//=============================================================================
+`ifdef MULTIPLIER
+omsp_multiplier multiplier_0 (
+
+// OUTPUTs
+ .per_dout (per_dout_mpy), // Peripheral data output
+
+// INPUTs
+ .mclk (mclk), // Main system clock
+ .per_addr (per_addr), // Peripheral address
+ .per_din (per_din), // Peripheral data input
+ .per_en (per_en), // Peripheral enable (high active)
+ .per_we (per_we), // Peripheral write enable (high active)
+ .puc_rst (puc_rst), // Main system reset
+ .scan_enable (scan_enable) // Scan enable (active during scan shifting)
+);
+`else
+assign per_dout_mpy = 16'h0000;
+`endif
+
+//=============================================================================
+// 9) PERIPHERALS' OUTPUT BUS
+//=============================================================================
+
+assign per_dout_or = per_dout |
+ per_dout_clk |
+ per_dout_sfr |
+ per_dout_wdog |
+ per_dout_mpy;
+
+
+//=============================================================================
+// 10) DEBUG INTERFACE
+//=============================================================================
+
+`ifdef DBG_EN
+omsp_dbg dbg_0 (
+
+// OUTPUTs
+ .dbg_freeze (dbg_freeze), // Freeze peripherals
+ .dbg_halt_cmd (dbg_halt_cmd), // Halt CPU command
+ .dbg_mem_addr (dbg_mem_addr), // Debug address for rd/wr access
+ .dbg_mem_dout (dbg_mem_dout), // Debug unit data output
+ .dbg_mem_en (dbg_mem_en), // Debug unit memory enable
+ .dbg_mem_wr (dbg_mem_wr), // Debug unit memory write
+ .dbg_reg_wr (dbg_reg_wr), // Debug unit CPU register write
+ .dbg_cpu_reset(dbg_cpu_reset), // Reset CPU from debug interface
+ .dbg_uart_txd (dbg_uart_txd), // Debug interface: UART TXD
+
+// INPUTs
+ .cpu_en_s (cpu_en_s), // Enable CPU code execution (synchronous)
+ .cpu_id (cpu_id), // CPU ID
+ .dbg_clk (dbg_clk), // Debug unit clock
+ .dbg_en_s (dbg_en_s), // Debug interface enable (synchronous)
+ .dbg_halt_st (dbg_halt_st), // Halt/Run status from CPU
+ .dbg_mem_din (dbg_mem_din), // Debug unit Memory data input
+ .dbg_reg_din (dbg_reg_din), // Debug unit CPU register data input
+ .dbg_rst (dbg_rst), // Debug unit reset
+ .dbg_uart_rxd (dbg_uart_rxd), // Debug interface: UART RXD (asynchronous)
+ .decode_noirq (decode_noirq), // Frontend decode instruction
+ .eu_mab (eu_mab), // Execution-Unit Memory address bus
+ .eu_mb_en (eu_mb_en), // Execution-Unit Memory bus enable
+ .eu_mb_wr (eu_mb_wr), // Execution-Unit Memory bus write transfer
+ .eu_mdb_in (eu_mdb_in), // Memory data bus input
+ .eu_mdb_out (eu_mdb_out), // Memory data bus output
+ .exec_done (exec_done), // Execution completed
+ .fe_mb_en (fe_mb_en), // Frontend Memory bus enable
+ .fe_mdb_in (fe_mdb_in), // Frontend Memory data bus input
+ .pc (pc), // Program counter
+ .puc_pnd_set (puc_pnd_set) // PUC pending set for the serial debug interface
+);
+
+`else
+assign dbg_freeze = ~cpu_en_s;
+assign dbg_halt_cmd = 1'b0;
+assign dbg_mem_addr = 16'h0000;
+assign dbg_mem_dout = 16'h0000;
+assign dbg_mem_en = 1'b0;
+assign dbg_mem_wr = 2'b00;
+assign dbg_reg_wr = 1'b0;
+assign dbg_cpu_reset = 1'b0;
+assign dbg_uart_txd = 1'b0;
+`endif
+
+
+endmodule // openMSP430
+
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_undefines.v"
+`endif
diff --git a/tests/openmsp430/rtl/openMSP430_defines.v b/tests/openmsp430/rtl/openMSP430_defines.v
new file mode 100644
index 000000000..368f7a5b1
--- /dev/null
+++ b/tests/openmsp430/rtl/openMSP430_defines.v
@@ -0,0 +1,843 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2009 , Olivier Girard
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the authors nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE
+//
+//----------------------------------------------------------------------------
+//
+// *File Name: openMSP430_defines.v
+//
+// *Module Description:
+// openMSP430 Configuration file
+//
+// *Author(s):
+// - Olivier Girard, olgirard@gmail.com
+//
+//----------------------------------------------------------------------------
+// $Rev: 151 $
+// $LastChangedBy: olivier.girard $
+// $LastChangedDate: 2012-07-23 00:24:11 +0200 (Mon, 23 Jul 2012) $
+//----------------------------------------------------------------------------
+//`define OMSP_NO_INCLUDE
+`ifdef OMSP_NO_INCLUDE
+`else
+`include "openMSP430_undefines.v"
+`endif
+
+//============================================================================
+//============================================================================
+// BASIC SYSTEM CONFIGURATION
+//============================================================================
+//============================================================================
+//
+// Note: the sum of program, data and peripheral memory spaces must not
+// exceed 64 kB
+//
+
+// Program Memory Size:
+// Uncomment the required memory size
+//-------------------------------------------------------
+//`define PMEM_SIZE_CUSTOM
+//`define PMEM_SIZE_59_KB
+//`define PMEM_SIZE_55_KB
+//`define PMEM_SIZE_54_KB
+//`define PMEM_SIZE_51_KB
+//`define PMEM_SIZE_48_KB
+//`define PMEM_SIZE_41_KB
+//`define PMEM_SIZE_32_KB
+//`define PMEM_SIZE_24_KB
+//`define PMEM_SIZE_16_KB
+//`define PMEM_SIZE_12_KB
+//`define PMEM_SIZE_8_KB
+//`define PMEM_SIZE_4_KB
+`define PMEM_SIZE_2_KB
+//`define PMEM_SIZE_1_KB
+
+
+// Data Memory Size:
+// Uncomment the required memory size
+//-------------------------------------------------------
+//`define DMEM_SIZE_CUSTOM
+//`define DMEM_SIZE_32_KB
+//`define DMEM_SIZE_24_KB
+//`define DMEM_SIZE_16_KB
+//`define DMEM_SIZE_10_KB
+//`define DMEM_SIZE_8_KB
+//`define DMEM_SIZE_5_KB
+//`define DMEM_SIZE_4_KB
+//`define DMEM_SIZE_2p5_KB
+//`define DMEM_SIZE_2_KB
+//`define DMEM_SIZE_1_KB
+//`define DMEM_SIZE_512_B
+//`define DMEM_SIZE_256_B
+`define DMEM_SIZE_128_B
+
+
+// Include/Exclude Hardware Multiplier
+`define MULTIPLIER
+
+
+// Include/Exclude Serial Debug interface
+`define DBG_EN
+
+
+//============================================================================
+//============================================================================
+// ADVANCED SYSTEM CONFIGURATION (FOR EXPERIENCED USERS)
+//============================================================================
+//============================================================================
+
+//-------------------------------------------------------
+// Custom user version number
+//-------------------------------------------------------
+// This 5 bit field can be freely used in order to allow
+// custom identification of the system through the debug
+// interface.
+// (see CPU_ID.USER_VERSION field in the documentation)
+//-------------------------------------------------------
+`define USER_VERSION 5'b00000
+
+
+//-------------------------------------------------------
+// Include/Exclude Watchdog timer
+//-------------------------------------------------------
+// When excluded, the following functionality will be
+// lost:
+// - Watchog (both interval and watchdog modes)
+// - NMI interrupt edge selection
+// - Possibility to generate a software PUC reset
+//-------------------------------------------------------
+`define WATCHDOG
+
+
+///-------------------------------------------------------
+// Include/Exclude Non-Maskable-Interrupt support
+//-------------------------------------------------------
+`define NMI
+
+
+//-------------------------------------------------------
+// Input synchronizers
+//-------------------------------------------------------
+// In some cases, the asynchronous input ports might
+// already be synchronized externally.
+// If an extensive CDC design review showed that this
+// is really the case, the individual synchronizers
+// can be disabled with the following defines.
+//
+// Notes:
+// - all three signals are all sampled in the MCLK domain
+//
+// - the dbg_en signal reset the debug interface
+// when 0. Therefore make sure it is glitch free.
+//
+//-------------------------------------------------------
+`define SYNC_NMI
+//`define SYNC_CPU_EN
+//`define SYNC_DBG_EN
+
+
+//-------------------------------------------------------
+// Peripheral Memory Space:
+//-------------------------------------------------------
+// The original MSP430 architecture map the peripherals
+// from 0x0000 to 0x01FF (i.e. 512B of the memory space).
+// The following defines allow you to expand this space
+// up to 32 kB (i.e. from 0x0000 to 0x7fff).
+// As a consequence, the data memory mapping will be
+// shifted up and a custom linker script will therefore
+// be required by the GCC compiler.
+//-------------------------------------------------------
+//`define PER_SIZE_CUSTOM
+//`define PER_SIZE_32_KB
+//`define PER_SIZE_16_KB
+//`define PER_SIZE_8_KB
+//`define PER_SIZE_4_KB
+//`define PER_SIZE_2_KB
+//`define PER_SIZE_1_KB
+`define PER_SIZE_512_B
+
+
+//-------------------------------------------------------
+// Defines the debugger CPU_CTL.RST_BRK_EN reset value
+// (CPU break on PUC reset)
+//-------------------------------------------------------
+// When defined, the CPU will automatically break after
+// a PUC occurrence by default. This is typically useful
+// when the program memory can only be initialized through
+// the serial debug interface.
+//-------------------------------------------------------
+`define DBG_RST_BRK_EN
+
+
+//============================================================================
+//============================================================================
+// EXPERT SYSTEM CONFIGURATION ( !!!! EXPERTS ONLY !!!! )
+//============================================================================
+//============================================================================
+//
+// IMPORTANT NOTE: Please update following configuration options ONLY if
+// you have a good reason to do so... and if you know what
+// you are doing :-P
+//
+//============================================================================
+
+//-------------------------------------------------------
+// Number of hardware breakpoint/watchpoint units
+// (each unit contains two hardware addresses available
+// for breakpoints or watchpoints):
+// - DBG_HWBRK_0 -> Include hardware breakpoints unit 0
+// - DBG_HWBRK_1 -> Include hardware breakpoints unit 1
+// - DBG_HWBRK_2 -> Include hardware breakpoints unit 2
+// - DBG_HWBRK_3 -> Include hardware breakpoints unit 3
+//-------------------------------------------------------
+// Please keep in mind that hardware breakpoints only
+// make sense whenever the program memory is not an SRAM
+// (i.e. Flash/OTP/ROM/...) or when you are interested
+// in data breakpoints.
+//-------------------------------------------------------
+//`define DBG_HWBRK_0
+//`define DBG_HWBRK_1
+//`define DBG_HWBRK_2
+//`define DBG_HWBRK_3
+
+
+//-------------------------------------------------------
+// Enable/Disable the hardware breakpoint RANGE mode
+//-------------------------------------------------------
+// When enabled this feature allows the hardware breakpoint
+// units to stop the cpu whenever an instruction or data
+// access lays within an address range.
+// Note that this feature is not supported by GDB.
+//-------------------------------------------------------
+//`define DBG_HWBRK_RANGE
+
+
+//-------------------------------------------------------
+// Custom Program/Data and Peripheral Memory Spaces
+//-------------------------------------------------------
+// The following values are valid only if the
+// corresponding *_SIZE_CUSTOM defines are uncommented:
+//
+// - *_SIZE : size of the section in bytes.
+// - *_AWIDTH : address port width, this value must allow
+// to address all WORDS of the section
+// (i.e. the *_SIZE divided by 2)
+//-------------------------------------------------------
+
+// Custom Program memory (enabled with PMEM_SIZE_CUSTOM)
+`define PMEM_CUSTOM_AWIDTH 10
+`define PMEM_CUSTOM_SIZE 2028
+
+// Custom Data memory (enabled with DMEM_SIZE_CUSTOM)
+`define DMEM_CUSTOM_AWIDTH 6
+`define DMEM_CUSTOM_SIZE 128
+
+// Custom Peripheral memory (enabled with PER_SIZE_CUSTOM)
+`define PER_CUSTOM_AWIDTH 8
+`define PER_CUSTOM_SIZE 512
+
+
+//-------------------------------------------------------
+// ASIC version
+//-------------------------------------------------------
+// When uncommented, this define will enable the
+// ASIC system configuration section (see below) and
+// will activate scan support for production test.
+//
+// WARNING: if you target an FPGA, leave this define
+// commented.
+//-------------------------------------------------------
+//`define ASIC
+
+
+//============================================================================
+//============================================================================
+// ASIC SYSTEM CONFIGURATION ( !!!! EXPERTS/PROFESSIONALS ONLY !!!! )
+//============================================================================
+//============================================================================
+`ifdef ASIC
+
+//===============================================================
+// FINE GRAINED CLOCK GATING
+//===============================================================
+
+//-------------------------------------------------------
+// When uncommented, this define will enable the fine
+// grained clock gating of all registers in the core.
+//-------------------------------------------------------
+`define CLOCK_GATING
+
+
+//===============================================================
+// LFXT CLOCK DOMAIN
+//===============================================================
+
+//-------------------------------------------------------
+// When uncommented, this define will enable the lfxt_clk
+// clock domain.
+// When commented out, the whole chip is clocked with dco_clk.
+//-------------------------------------------------------
+`define LFXT_DOMAIN
+
+
+//===============================================================
+// CLOCK MUXES
+//===============================================================
+
+//-------------------------------------------------------
+// MCLK: Clock Mux
+//-------------------------------------------------------
+// When uncommented, this define will enable the
+// MCLK clock MUX allowing the selection between
+// DCO_CLK and LFXT_CLK with the BCSCTL2.SELMx register.
+// When commented, DCO_CLK is selected.
+//-------------------------------------------------------
+`define MCLK_MUX
+
+//-------------------------------------------------------
+// SMCLK: Clock Mux
+//-------------------------------------------------------
+// When uncommented, this define will enable the
+// SMCLK clock MUX allowing the selection between
+// DCO_CLK and LFXT_CLK with the BCSCTL2.SELS register.
+// When commented, DCO_CLK is selected.
+//-------------------------------------------------------
+`define SMCLK_MUX
+
+//-------------------------------------------------------
+// WATCHDOG: Clock Mux
+//-------------------------------------------------------
+// When uncommented, this define will enable the
+// Watchdog clock MUX allowing the selection between
+// ACLK and SMCLK with the WDTCTL.WDTSSEL register.
+// When commented out, ACLK is selected if the
+// WATCHDOG_NOMUX_ACLK define is uncommented, SMCLK is
+// selected otherwise.
+//-------------------------------------------------------
+`define WATCHDOG_MUX
+//`define WATCHDOG_NOMUX_ACLK
+
+
+//===============================================================
+// CLOCK DIVIDERS
+//===============================================================
+
+//-------------------------------------------------------
+// MCLK: Clock divider
+//-------------------------------------------------------
+// When uncommented, this define will enable the
+// MCLK clock divider (/1/2/4/8)
+//-------------------------------------------------------
+`define MCLK_DIVIDER
+
+//-------------------------------------------------------
+// SMCLK: Clock divider (/1/2/4/8)
+//-------------------------------------------------------
+// When uncommented, this define will enable the
+// SMCLK clock divider
+//-------------------------------------------------------
+`define SMCLK_DIVIDER
+
+//-------------------------------------------------------
+// ACLK: Clock divider (/1/2/4/8)
+//-------------------------------------------------------
+// When uncommented, this define will enable the
+// ACLK clock divider
+//-------------------------------------------------------
+`define ACLK_DIVIDER
+
+
+//===============================================================
+// LOW POWER MODES
+//===============================================================
+
+//-------------------------------------------------------
+// LOW POWER MODE: CPUOFF
+//-------------------------------------------------------
+// When uncommented, this define will include the
+// clock gate allowing to switch off MCLK in
+// all low power modes: LPM0, LPM1, LPM2, LPM3, LPM4
+//-------------------------------------------------------
+`define CPUOFF_EN
+
+//-------------------------------------------------------
+// LOW POWER MODE: SCG0
+//-------------------------------------------------------
+// When uncommented, this define will enable the
+// DCO_ENABLE/WKUP port control (always 1 when commented).
+// This allows to switch off the DCO oscillator in the
+// following low power modes: LPM1, LPM3, LPM4
+//-------------------------------------------------------
+`define SCG0_EN
+
+//-------------------------------------------------------
+// LOW POWER MODE: SCG1
+//-------------------------------------------------------
+// When uncommented, this define will include the
+// clock gate allowing to switch off SMCLK in
+// the following low power modes: LPM2, LPM3, LPM4
+//-------------------------------------------------------
+`define SCG1_EN
+
+//-------------------------------------------------------
+// LOW POWER MODE: OSCOFF
+//-------------------------------------------------------
+// When uncommented, this define will include the
+// LFXT_CLK clock gate and enable the LFXT_ENABLE/WKUP
+// port control (always 1 when commented).
+// This allows to switch off the low frequency oscillator
+// in the following low power modes: LPM4
+//-------------------------------------------------------
+`define OSCOFF_EN
+
+
+
+`endif
+
+//==========================================================================//
+//==========================================================================//
+//==========================================================================//
+//==========================================================================//
+//===== SYSTEM CONSTANTS --- !!!!!!!! DO NOT EDIT !!!!!!!! =====//
+//==========================================================================//
+//==========================================================================//
+//==========================================================================//
+//==========================================================================//
+
+//
+// PROGRAM, DATA & PERIPHERAL MEMORY CONFIGURATION
+//==================================================
+
+// Program Memory Size
+`ifdef PMEM_SIZE_59_KB
+ `define PMEM_AWIDTH 15
+ `define PMEM_SIZE 60416
+`endif
+`ifdef PMEM_SIZE_55_KB
+ `define PMEM_AWIDTH 15
+ `define PMEM_SIZE 56320
+`endif
+`ifdef PMEM_SIZE_54_KB
+ `define PMEM_AWIDTH 15
+ `define PMEM_SIZE 55296
+`endif
+`ifdef PMEM_SIZE_51_KB
+ `define PMEM_AWIDTH 15
+ `define PMEM_SIZE 52224
+`endif
+`ifdef PMEM_SIZE_48_KB
+ `define PMEM_AWIDTH 15
+ `define PMEM_SIZE 49152
+`endif
+`ifdef PMEM_SIZE_41_KB
+ `define PMEM_AWIDTH 15
+ `define PMEM_SIZE 41984
+`endif
+`ifdef PMEM_SIZE_32_KB
+ `define PMEM_AWIDTH 14
+ `define PMEM_SIZE 32768
+`endif
+`ifdef PMEM_SIZE_24_KB
+ `define PMEM_AWIDTH 14
+ `define PMEM_SIZE 24576
+`endif
+`ifdef PMEM_SIZE_16_KB
+ `define PMEM_AWIDTH 13
+ `define PMEM_SIZE 16384
+`endif
+`ifdef PMEM_SIZE_12_KB
+ `define PMEM_AWIDTH 13
+ `define PMEM_SIZE 12288
+`endif
+`ifdef PMEM_SIZE_8_KB
+ `define PMEM_AWIDTH 12
+ `define PMEM_SIZE 8192
+`endif
+`ifdef PMEM_SIZE_4_KB
+ `define PMEM_AWIDTH 11
+ `define PMEM_SIZE 4096
+`endif
+`ifdef PMEM_SIZE_2_KB
+ `define PMEM_AWIDTH 10
+ `define PMEM_SIZE 2048
+`endif
+`ifdef PMEM_SIZE_1_KB
+ `define PMEM_AWIDTH 9
+ `define PMEM_SIZE 1024
+`endif
+`ifdef PMEM_SIZE_CUSTOM
+ `define PMEM_AWIDTH `PMEM_CUSTOM_AWIDTH
+ `define PMEM_SIZE `PMEM_CUSTOM_SIZE
+`endif
+
+// Data Memory Size
+`ifdef DMEM_SIZE_32_KB
+ `define DMEM_AWIDTH 14
+ `define DMEM_SIZE 32768
+`endif
+`ifdef DMEM_SIZE_24_KB
+ `define DMEM_AWIDTH 14
+ `define DMEM_SIZE 24576
+`endif
+`ifdef DMEM_SIZE_16_KB
+ `define DMEM_AWIDTH 13
+ `define DMEM_SIZE 16384
+`endif
+`ifdef DMEM_SIZE_10_KB
+ `define DMEM_AWIDTH 13
+ `define DMEM_SIZE 10240
+`endif
+`ifdef DMEM_SIZE_8_KB
+ `define DMEM_AWIDTH 12
+ `define DMEM_SIZE 8192
+`endif
+`ifdef DMEM_SIZE_5_KB
+ `define DMEM_AWIDTH 12
+ `define DMEM_SIZE 5120
+`endif
+`ifdef DMEM_SIZE_4_KB
+ `define DMEM_AWIDTH 11
+ `define DMEM_SIZE 4096
+`endif
+`ifdef DMEM_SIZE_2p5_KB
+ `define DMEM_AWIDTH 11
+ `define DMEM_SIZE 2560
+`endif
+`ifdef DMEM_SIZE_2_KB
+ `define DMEM_AWIDTH 10
+ `define DMEM_SIZE 2048
+`endif
+`ifdef DMEM_SIZE_1_KB
+ `define DMEM_AWIDTH 9
+ `define DMEM_SIZE 1024
+`endif
+`ifdef DMEM_SIZE_512_B
+ `define DMEM_AWIDTH 8
+ `define DMEM_SIZE 512
+`endif
+`ifdef DMEM_SIZE_256_B
+ `define DMEM_AWIDTH 7
+ `define DMEM_SIZE 256
+`endif
+`ifdef DMEM_SIZE_128_B
+ `define DMEM_AWIDTH 6
+ `define DMEM_SIZE 128
+`endif
+`ifdef DMEM_SIZE_CUSTOM
+ `define DMEM_AWIDTH `DMEM_CUSTOM_AWIDTH
+ `define DMEM_SIZE `DMEM_CUSTOM_SIZE
+`endif
+
+// Peripheral Memory Size
+`ifdef PER_SIZE_32_KB
+ `define PER_AWIDTH 14
+ `define PER_SIZE 32768
+`endif
+`ifdef PER_SIZE_16_KB
+ `define PER_AWIDTH 13
+ `define PER_SIZE 16384
+`endif
+`ifdef PER_SIZE_8_KB
+ `define PER_AWIDTH 12
+ `define PER_SIZE 8192
+`endif
+`ifdef PER_SIZE_4_KB
+ `define PER_AWIDTH 11
+ `define PER_SIZE 4096
+`endif
+`ifdef PER_SIZE_2_KB
+ `define PER_AWIDTH 10
+ `define PER_SIZE 2048
+`endif
+`ifdef PER_SIZE_1_KB
+ `define PER_AWIDTH 9
+ `define PER_SIZE 1024
+`endif
+`ifdef PER_SIZE_512_B
+ `define PER_AWIDTH 8
+ `define PER_SIZE 512
+`endif
+`ifdef PER_SIZE_CUSTOM
+ `define PER_AWIDTH `PER_CUSTOM_AWIDTH
+ `define PER_SIZE `PER_CUSTOM_SIZE
+`endif
+
+// Data Memory Base Adresses
+`define DMEM_BASE `PER_SIZE
+
+// Program & Data Memory most significant address bit (for 16 bit words)
+`define PMEM_MSB `PMEM_AWIDTH-1
+`define DMEM_MSB `DMEM_AWIDTH-1
+`define PER_MSB `PER_AWIDTH-1
+
+//
+// STATES, REGISTER FIELDS, ...
+//======================================
+
+// Instructions type
+`define INST_SO 0
+`define INST_JMP 1
+`define INST_TO 2
+
+// Single-operand arithmetic
+`define RRC 0
+`define SWPB 1
+`define RRA 2
+`define SXT 3
+`define PUSH 4
+`define CALL 5
+`define RETI 6
+`define IRQ 7
+
+// Conditional jump
+`define JNE 0
+`define JEQ 1
+`define JNC 2
+`define JC 3
+`define JN 4
+`define JGE 5
+`define JL 6
+`define JMP 7
+
+// Two-operand arithmetic
+`define MOV 0
+`define ADD 1
+`define ADDC 2
+`define SUBC 3
+`define SUB 4
+`define CMP 5
+`define DADD 6
+`define BIT 7
+`define BIC 8
+`define BIS 9
+`define XOR 10
+`define AND 11
+
+// Addressing modes
+`define DIR 0
+`define IDX 1
+`define INDIR 2
+`define INDIR_I 3
+`define SYMB 4
+`define IMM 5
+`define ABS 6
+`define CONST 7
+
+// Instruction state machine
+`define I_IRQ_FETCH 3'h0
+`define I_IRQ_DONE 3'h1
+`define I_DEC 3'h2
+`define I_EXT1 3'h3
+`define I_EXT2 3'h4
+`define I_IDLE 3'h5
+
+// Execution state machine
+// (swapped E_IRQ_0 and E_IRQ_2 values to suppress glitch generation warning from lint tool)
+`define E_IRQ_0 4'h2
+`define E_IRQ_1 4'h1
+`define E_IRQ_2 4'h0
+`define E_IRQ_3 4'h3
+`define E_IRQ_4 4'h4
+`define E_SRC_AD 4'h5
+`define E_SRC_RD 4'h6
+`define E_SRC_WR 4'h7
+`define E_DST_AD 4'h8
+`define E_DST_RD 4'h9
+`define E_DST_WR 4'hA
+`define E_EXEC 4'hB
+`define E_JUMP 4'hC
+`define E_IDLE 4'hD
+
+// ALU control signals
+`define ALU_SRC_INV 0
+`define ALU_INC 1
+`define ALU_INC_C 2
+`define ALU_ADD 3
+`define ALU_AND 4
+`define ALU_OR 5
+`define ALU_XOR 6
+`define ALU_DADD 7
+`define ALU_STAT_7 8
+`define ALU_STAT_F 9
+`define ALU_SHIFT 10
+`define EXEC_NO_WR 11
+
+// Debug interface
+`define DBG_UART_WR 18
+`define DBG_UART_BW 17
+`define DBG_UART_ADDR 16:11
+
+// Debug interface CPU_CTL register
+`define HALT 0
+`define RUN 1
+`define ISTEP 2
+`define SW_BRK_EN 3
+`define FRZ_BRK_EN 4
+`define RST_BRK_EN 5
+`define CPU_RST 6
+
+// Debug interface CPU_STAT register
+`define HALT_RUN 0
+`define PUC_PND 1
+`define SWBRK_PND 3
+`define HWBRK0_PND 4
+`define HWBRK1_PND 5
+
+// Debug interface BRKx_CTL register
+`define BRK_MODE_RD 0
+`define BRK_MODE_WR 1
+`define BRK_MODE 1:0
+`define BRK_EN 2
+`define BRK_I_EN 3
+`define BRK_RANGE 4
+
+// Basic clock module: BCSCTL1 Control Register
+`define DIVAx 5:4
+
+// Basic clock module: BCSCTL2 Control Register
+`define SELMx 7
+`define DIVMx 5:4
+`define SELS 3
+`define DIVSx 2:1
+
+// MCLK Clock gate
+`ifdef CPUOFF_EN
+ `define MCLK_CGATE
+`else
+`ifdef MCLK_DIVIDER
+ `define MCLK_CGATE
+`endif
+`endif
+
+// SMCLK Clock gate
+`ifdef SCG1_EN
+ `define SMCLK_CGATE
+`else
+`ifdef SMCLK_DIVIDER
+ `define SMCLK_CGATE
+`endif
+`endif
+
+//
+// DEBUG INTERFACE EXTRA CONFIGURATION
+//======================================
+
+// Debug interface: CPU version
+`define CPU_VERSION 3'h2
+
+// Debug interface: Software breakpoint opcode
+`define DBG_SWBRK_OP 16'h4343
+
+// Debug UART interface auto data synchronization
+// If the following define is commented out, then
+// the DBG_UART_BAUD and DBG_DCO_FREQ need to be properly
+// defined.
+`define DBG_UART_AUTO_SYNC
+
+// Debug UART interface data rate
+// In order to properly setup the UART debug interface, you
+// need to specify the DCO_CLK frequency (DBG_DCO_FREQ) and
+// the chosen BAUD rate from the UART interface.
+//
+//`define DBG_UART_BAUD 9600
+//`define DBG_UART_BAUD 19200
+//`define DBG_UART_BAUD 38400
+//`define DBG_UART_BAUD 57600
+//`define DBG_UART_BAUD 115200
+//`define DBG_UART_BAUD 230400
+//`define DBG_UART_BAUD 460800
+//`define DBG_UART_BAUD 576000
+//`define DBG_UART_BAUD 921600
+`define DBG_UART_BAUD 2000000
+`define DBG_DCO_FREQ 20000000
+`define DBG_UART_CNT ((`DBG_DCO_FREQ/`DBG_UART_BAUD)-1)
+
+// Debug interface selection
+// `define DBG_UART -> Enable UART (8N1) debug interface
+// `define DBG_JTAG -> DON'T UNCOMMENT, NOT SUPPORTED
+//
+`define DBG_UART
+//`define DBG_JTAG
+
+// Debug interface input synchronizer
+`define SYNC_DBG_UART_RXD
+
+// Enable/Disable the hardware breakpoint RANGE mode
+`ifdef DBG_HWBRK_RANGE
+ `define HWBRK_RANGE 1'b1
+`else
+ `define HWBRK_RANGE 1'b0
+`endif
+
+// Counter width for the debug interface UART
+`define DBG_UART_XFER_CNT_W 16
+
+// Check configuration
+`ifdef DBG_EN
+ `ifdef DBG_UART
+ `ifdef DBG_JTAG
+CONFIGURATION ERROR: JTAG AND UART DEBUG INTERFACE ARE BOTH ENABLED
+ `endif
+ `else
+ `ifdef DBG_JTAG
+CONFIGURATION ERROR: JTAG INTERFACE NOT SUPPORTED
+ `else
+CONFIGURATION ERROR: JTAG OR UART DEBUG INTERFACE SHOULD BE ENABLED
+ `endif
+ `endif
+`endif
+
+//
+// MULTIPLIER CONFIGURATION
+//======================================
+
+// If uncommented, the following define selects
+// the 16x16 multiplier (1 cycle) instead of the
+// default 16x8 multplier (2 cycles)
+//`define MPY_16x16
+
+//======================================
+// CONFIGURATION CHECKS
+//======================================
+`ifdef LFXT_DOMAIN
+`else
+ `ifdef MCLK_MUX
+CONFIGURATION ERROR: THE MCLK_MUX CAN ONLY BE ENABLED IF THE LFXT_DOMAIN IS ENABLED AS WELL
+ `endif
+ `ifdef SMCLK_MUX
+CONFIGURATION ERROR: THE SMCLK_MUX CAN ONLY BE ENABLED IF THE LFXT_DOMAIN IS ENABLED AS WELL
+ `endif
+ `ifdef WATCHDOG_MUX
+CONFIGURATION ERROR: THE WATCHDOG_MUX CAN ONLY BE ENABLED IF THE LFXT_DOMAIN IS ENABLED AS WELL
+ `else
+ `ifdef WATCHDOG_NOMUX_ACLK
+CONFIGURATION ERROR: THE WATCHDOG_NOMUX_ACLK CAN ONLY BE ENABLED IF THE LFXT_DOMAIN IS ENABLED AS WELL
+ `endif
+ `endif
+ `ifdef OSCOFF_EN
+CONFIGURATION ERROR: THE OSCOFF LOW POWER MODE CAN ONLY BE ENABLED IF THE LFXT_DOMAIN IS ENABLED AS WELL
+ `endif
+`endif
diff --git a/tests/openmsp430/rtl/openMSP430_undefines.v b/tests/openmsp430/rtl/openMSP430_undefines.v
new file mode 100644
index 000000000..a399ae779
--- /dev/null
+++ b/tests/openmsp430/rtl/openMSP430_undefines.v
@@ -0,0 +1,732 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2009 , Olivier Girard
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the authors nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE
+//
+//----------------------------------------------------------------------------
+//
+// *File Name: openMSP430_undefines.v
+//
+// *Module Description:
+// openMSP430 Verilog `undef file
+//
+// *Author(s):
+// - Olivier Girard, olgirard@gmail.com
+//
+//----------------------------------------------------------------------------
+// $Rev: 23 $
+// $LastChangedBy: olivier.girard $
+// $LastChangedDate: 2009-08-30 18:39:26 +0200 (Sun, 30 Aug 2009) $
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+// BASIC SYSTEM CONFIGURATION
+//----------------------------------------------------------------------------
+
+// Program Memory sizes
+`ifdef PMEM_SIZE_59_KB
+`undef PMEM_SIZE_59_KB
+`endif
+`ifdef PMEM_SIZE_55_KB
+`undef PMEM_SIZE_55_KB
+`endif
+`ifdef PMEM_SIZE_54_KB
+`undef PMEM_SIZE_54_KB
+`endif
+`ifdef PMEM_SIZE_51_KB
+`undef PMEM_SIZE_51_KB
+`endif
+`ifdef PMEM_SIZE_48_KB
+`undef PMEM_SIZE_48_KB
+`endif
+`ifdef PMEM_SIZE_41_KB
+`undef PMEM_SIZE_41_KB
+`endif
+`ifdef PMEM_SIZE_32_KB
+`undef PMEM_SIZE_32_KB
+`endif
+`ifdef PMEM_SIZE_24_KB
+`undef PMEM_SIZE_24_KB
+`endif
+`ifdef PMEM_SIZE_16_KB
+`undef PMEM_SIZE_16_KB
+`endif
+`ifdef PMEM_SIZE_12_KB
+`undef PMEM_SIZE_12_KB
+`endif
+`ifdef PMEM_SIZE_8_KB
+`undef PMEM_SIZE_8_KB
+`endif
+`ifdef PMEM_SIZE_4_KB
+`undef PMEM_SIZE_4_KB
+`endif
+`ifdef PMEM_SIZE_2_KB
+`undef PMEM_SIZE_2_KB
+`endif
+`ifdef PMEM_SIZE_1_KB
+`undef PMEM_SIZE_1_KB
+`endif
+
+// Data Memory sizes
+`ifdef DMEM_SIZE_32_KB
+`undef DMEM_SIZE_32_KB
+`endif
+`ifdef DMEM_SIZE_24_KB
+`undef DMEM_SIZE_24_KB
+`endif
+`ifdef DMEM_SIZE_16_KB
+`undef DMEM_SIZE_16_KB
+`endif
+`ifdef DMEM_SIZE_10_KB
+`undef DMEM_SIZE_10_KB
+`endif
+`ifdef DMEM_SIZE_8_KB
+`undef DMEM_SIZE_8_KB
+`endif
+`ifdef DMEM_SIZE_5_KB
+`undef DMEM_SIZE_5_KB
+`endif
+`ifdef DMEM_SIZE_4_KB
+`undef DMEM_SIZE_4_KB
+`endif
+`ifdef DMEM_SIZE_2p5_KB
+`undef DMEM_SIZE_2p5_KB
+`endif
+`ifdef DMEM_SIZE_2_KB
+`undef DMEM_SIZE_2_KB
+`endif
+`ifdef DMEM_SIZE_1_KB
+`undef DMEM_SIZE_1_KB
+`endif
+`ifdef DMEM_SIZE_512_B
+`undef DMEM_SIZE_512_B
+`endif
+`ifdef DMEM_SIZE_256_B
+`undef DMEM_SIZE_256_B
+`endif
+`ifdef DMEM_SIZE_128_B
+`undef DMEM_SIZE_128_B
+`endif
+
+// Include/Exclude Hardware Multiplier
+`ifdef MULTIPLIER
+`undef MULTIPLIER
+`endif
+
+// Include Debug interface
+`ifdef DBG_EN
+`undef DBG_EN
+`endif
+
+
+//----------------------------------------------------------------------------
+// ADVANCED SYSTEM CONFIGURATION (FOR EXPERIENCED USERS)
+//----------------------------------------------------------------------------
+
+// Peripheral Memory Space:
+`ifdef PER_SIZE_32_KB
+`undef PER_SIZE_32_KB
+`endif
+`ifdef PER_SIZE_16_KB
+`undef PER_SIZE_16_KB
+`endif
+`ifdef PER_SIZE_8_KB
+`undef PER_SIZE_8_KB
+`endif
+`ifdef PER_SIZE_4_KB
+`undef PER_SIZE_4_KB
+`endif
+`ifdef PER_SIZE_2_KB
+`undef PER_SIZE_2_KB
+`endif
+`ifdef PER_SIZE_1_KB
+`undef PER_SIZE_1_KB
+`endif
+`ifdef PER_SIZE_512_B
+`undef PER_SIZE_512_B
+`endif
+
+// Let the CPU break after a PUC occurrence by default
+`ifdef DBG_RST_BRK_EN
+`undef DBG_RST_BRK_EN
+`endif
+
+// Custom user version number
+`ifdef USER_VERSION
+`undef USER_VERSION
+`endif
+
+// Include/Exclude Watchdog timer
+`ifdef WATCHDOG
+`undef WATCHDOG
+`endif
+
+// Include/Exclude Non-Maskable-Interrupt support
+`ifdef NMI
+`undef NMI
+`endif
+
+//----------------------------------------------------------------------------
+// EXPERT SYSTEM CONFIGURATION ( !!!! EXPERTS ONLY !!!! )
+//----------------------------------------------------------------------------
+
+// Number of hardware breakpoint units
+`ifdef DBG_HWBRK_0
+`undef DBG_HWBRK_0
+`endif
+`ifdef DBG_HWBRK_1
+`undef DBG_HWBRK_1
+`endif
+`ifdef DBG_HWBRK_2
+`undef DBG_HWBRK_2
+`endif
+`ifdef DBG_HWBRK_3
+`undef DBG_HWBRK_3
+`endif
+
+// Enable/Disable the hardware breakpoint RANGE mode
+`ifdef DBG_HWBRK_RANGE
+`undef DBG_HWBRK_RANGE
+`endif
+
+// Input synchronizers
+`ifdef SYNC_CPU_EN
+`undef SYNC_CPU_EN
+`endif
+`ifdef SYNC_DBG_EN
+`undef SYNC_DBG_EN
+`endif
+`ifdef SYNC_DBG_UART_RXD
+`undef SYNC_DBG_UART_RXD
+`endif
+`ifdef SYNC_NMI
+`undef SYNC_NMI
+`endif
+
+// ASIC version
+`ifdef ASIC
+`undef ASIC
+`endif
+
+
+//----------------------------------------------------------------------------
+// ASIC SYSTEM CONFIGURATION ( !!!! EXPERTS ONLY !!!! )
+//----------------------------------------------------------------------------
+
+// Fine grained clock gating
+`ifdef CLOCK_GATING
+`undef CLOCK_GATING
+`endif
+
+// LFXT clock domain
+`ifdef LFXT_DOMAIN
+`undef LFXT_DOMAIN
+`endif
+
+// MCLK: Clock Mux
+`ifdef MCLK_MUX
+`undef MCLK_MUX
+`endif
+
+// SMCLK: Clock Mux
+`ifdef SMCLK_MUX
+`undef SMCLK_MUX
+`endif
+
+// WATCHDOG: Clock Mux
+`ifdef WATCHDOG_MUX
+`undef WATCHDOG_MUX
+`endif
+
+// MCLK: Clock divider
+`ifdef MCLK_DIVIDER
+`undef MCLK_DIVIDER
+`endif
+
+// SMCLK: Clock divider (/1/2/4/8)
+`ifdef SMCLK_DIVIDER
+`undef SMCLK_DIVIDER
+`endif
+
+// ACLK: Clock divider (/1/2/4/8)
+`ifdef ACLK_DIVIDER
+`undef ACLK_DIVIDER
+`endif
+
+// LOW POWER MODE: CPUOFF
+`ifdef CPUOFF_EN
+`undef CPUOFF_EN
+`endif
+
+// LOW POWER MODE: OSCOFF
+`ifdef OSCOFF_EN
+`undef OSCOFF_EN
+`endif
+
+// LOW POWER MODE: SCG0
+`ifdef SCG0_EN
+`undef SCG0_EN
+`endif
+
+// LOW POWER MODE: SCG1
+`ifdef SCG1_EN
+`undef SCG1_EN
+`endif
+
+
+//==========================================================================//
+//==========================================================================//
+//==========================================================================//
+//==========================================================================//
+//===== SYSTEM CONSTANTS --- !!!!!!!! DO NOT EDIT !!!!!!!! =====//
+//==========================================================================//
+//==========================================================================//
+//==========================================================================//
+//==========================================================================//
+
+// Program Memory Size
+`ifdef PMEM_AWIDTH
+`undef PMEM_AWIDTH
+`endif
+`ifdef PMEM_SIZE
+`undef PMEM_SIZE
+`endif
+
+// Data Memory Size
+`ifdef DMEM_AWIDTH
+`undef DMEM_AWIDTH
+`endif
+`ifdef DMEM_SIZE
+`undef DMEM_SIZE
+`endif
+
+// Peripheral Memory Size
+`ifdef PER_AWIDTH
+`undef PER_AWIDTH
+`endif
+`ifdef PER_SIZE
+`undef PER_SIZE
+`endif
+
+// Data Memory Base Adresses
+`ifdef DMEM_BASE
+`undef DMEM_BASE
+`endif
+
+// Program & Data Memory most significant address bit (for 16 bit words)
+`ifdef PMEM_MSB
+`undef PMEM_MSB
+`endif
+`ifdef DMEM_MSB
+`undef DMEM_MSB
+`endif
+`ifdef PER_MSB
+`undef PER_MSB
+`endif
+
+// Instructions type
+`ifdef INST_SO
+`undef INST_SO
+`endif
+`ifdef INST_JMP
+`undef INST_JMP
+`endif
+`ifdef INST_TO
+`undef INST_TO
+`endif
+
+// Single-operand arithmetic
+`ifdef RRC
+`undef RRC
+`endif
+`ifdef SWPB
+`undef SWPB
+`endif
+`ifdef RRA
+`undef RRA
+`endif
+`ifdef SXT
+`undef SXT
+`endif
+`ifdef PUSH
+`undef PUSH
+`endif
+`ifdef CALL
+`undef CALL
+`endif
+`ifdef RETI
+`undef RETI
+`endif
+`ifdef IRQ
+`undef IRQ
+`endif
+
+// Conditional jump
+`ifdef JNE
+`undef JNE
+`endif
+`ifdef JEQ
+`undef JEQ
+`endif
+`ifdef JNC
+`undef JNC
+`endif
+`ifdef JC
+`undef JC
+`endif
+`ifdef JN
+`undef JN
+`endif
+`ifdef JGE
+`undef JGE
+`endif
+`ifdef JL
+`undef JL
+`endif
+`ifdef JMP
+`undef JMP
+`endif
+
+// Two-operand arithmetic
+`ifdef MOV
+`undef MOV
+`endif
+`ifdef ADD
+`undef ADD
+`endif
+`ifdef ADDC
+`undef ADDC
+`endif
+`ifdef SUBC
+`undef SUBC
+`endif
+`ifdef SUB
+`undef SUB
+`endif
+`ifdef CMP
+`undef CMP
+`endif
+`ifdef DADD
+`undef DADD
+`endif
+`ifdef BIT
+`undef BIT
+`endif
+`ifdef BIC
+`undef BIC
+`endif
+`ifdef BIS
+`undef BIS
+`endif
+`ifdef XOR
+`undef XOR
+`endif
+`ifdef AND
+`undef AND
+`endif
+
+// Addressing modes
+`ifdef DIR
+`undef DIR
+`endif
+`ifdef IDX
+`undef IDX
+`endif
+`ifdef INDIR
+`undef INDIR
+`endif
+`ifdef INDIR_I
+`undef INDIR_I
+`endif
+`ifdef SYMB
+`undef SYMB
+`endif
+`ifdef IMM
+`undef IMM
+`endif
+`ifdef ABS
+`undef ABS
+`endif
+`ifdef CONST
+`undef CONST
+`endif
+
+// Instruction state machine
+`ifdef I_IRQ_FETCH
+`undef I_IRQ_FETCH
+`endif
+`ifdef I_IRQ_DONE
+`undef I_IRQ_DONE
+`endif
+`ifdef I_DEC
+`undef I_DEC
+`endif
+`ifdef I_EXT1
+`undef I_EXT1
+`endif
+`ifdef I_EXT2
+`undef I_EXT2
+`endif
+`ifdef I_IDLE
+`undef I_IDLE
+`endif
+
+// Execution state machine
+`ifdef E_IRQ_0
+`undef E_IRQ_0
+`endif
+`ifdef E_IRQ_1
+`undef E_IRQ_1
+`endif
+`ifdef E_IRQ_2
+`undef E_IRQ_2
+`endif
+`ifdef E_IRQ_3
+`undef E_IRQ_3
+`endif
+`ifdef E_IRQ_4
+`undef E_IRQ_4
+`endif
+`ifdef E_SRC_AD
+`undef E_SRC_AD
+`endif
+`ifdef E_SRC_RD
+`undef E_SRC_RD
+`endif
+`ifdef E_SRC_WR
+`undef E_SRC_WR
+`endif
+`ifdef E_DST_AD
+`undef E_DST_AD
+`endif
+`ifdef E_DST_RD
+`undef E_DST_RD
+`endif
+`ifdef E_DST_WR
+`undef E_DST_WR
+`endif
+`ifdef E_EXEC
+`undef E_EXEC
+`endif
+`ifdef E_JUMP
+`undef E_JUMP
+`endif
+`ifdef E_IDLE
+`undef E_IDLE
+`endif
+
+// ALU control signals
+`ifdef ALU_SRC_INV
+`undef ALU_SRC_INV
+`endif
+`ifdef ALU_INC
+`undef ALU_INC
+`endif
+`ifdef ALU_INC_C
+`undef ALU_INC_C
+`endif
+`ifdef ALU_ADD
+`undef ALU_ADD
+`endif
+`ifdef ALU_AND
+`undef ALU_AND
+`endif
+`ifdef ALU_OR
+`undef ALU_OR
+`endif
+`ifdef ALU_XOR
+`undef ALU_XOR
+`endif
+`ifdef ALU_DADD
+`undef ALU_DADD
+`endif
+`ifdef ALU_STAT_7
+`undef ALU_STAT_7
+`endif
+`ifdef ALU_STAT_F
+`undef ALU_STAT_F
+`endif
+`ifdef ALU_SHIFT
+`undef ALU_SHIFT
+`endif
+`ifdef EXEC_NO_WR
+`undef EXEC_NO_WR
+`endif
+
+// Debug interface
+`ifdef DBG_UART_WR
+`undef DBG_UART_WR
+`endif
+`ifdef DBG_UART_BW
+`undef DBG_UART_BW
+`endif
+`ifdef DBG_UART_ADDR
+`undef DBG_UART_ADDR
+`endif
+
+// Debug interface CPU_CTL register
+`ifdef HALT
+`undef HALT
+`endif
+`ifdef RUN
+`undef RUN
+`endif
+`ifdef ISTEP
+`undef ISTEP
+`endif
+`ifdef SW_BRK_EN
+`undef SW_BRK_EN
+`endif
+`ifdef FRZ_BRK_EN
+`undef FRZ_BRK_EN
+`endif
+`ifdef RST_BRK_EN
+`undef RST_BRK_EN
+`endif
+`ifdef CPU_RST
+`undef CPU_RST
+`endif
+
+// Debug interface CPU_STAT register
+`ifdef HALT_RUN
+`undef HALT_RUN
+`endif
+`ifdef PUC_PND
+`undef PUC_PND
+`endif
+`ifdef SWBRK_PND
+`undef SWBRK_PND
+`endif
+`ifdef HWBRK0_PND
+`undef HWBRK0_PND
+`endif
+`ifdef HWBRK1_PND
+`undef HWBRK1_PND
+`endif
+
+// Debug interface BRKx_CTL register
+`ifdef BRK_MODE_RD
+`undef BRK_MODE_RD
+`endif
+`ifdef BRK_MODE_WR
+`undef BRK_MODE_WR
+`endif
+`ifdef BRK_MODE
+`undef BRK_MODE
+`endif
+`ifdef BRK_EN
+`undef BRK_EN
+`endif
+`ifdef BRK_I_EN
+`undef BRK_I_EN
+`endif
+`ifdef BRK_RANGE
+`undef BRK_RANGE
+`endif
+
+// Basic clock module: BCSCTL1 Control Register
+`ifdef DIVAx
+`undef DIVAx
+`endif
+
+// Basic clock module: BCSCTL2 Control Register
+`ifdef SELMx
+`undef SELMx
+`endif
+`ifdef DIVMx
+`undef DIVMx
+`endif
+`ifdef SELS
+`undef SELS
+`endif
+`ifdef DIVSx
+`undef DIVSx
+`endif
+
+// MCLK Clock gate
+`ifdef MCLK_CGATE
+`undef MCLK_CGATE
+`endif
+
+// SMCLK Clock gate
+`ifdef SMCLK_CGATE
+`undef SMCLK_CGATE
+`endif
+
+//
+// DEBUG INTERFACE EXTRA CONFIGURATION
+//======================================
+
+// Debug interface: CPU version
+`ifdef CPU_VERSION
+`undef CPU_VERSION
+`endif
+
+// Debug interface: Software breakpoint opcode
+`ifdef DBG_SWBRK_OP
+`undef DBG_SWBRK_OP
+`endif
+
+// Debug UART interface auto data synchronization
+`ifdef DBG_UART_AUTO_SYNC
+`undef DBG_UART_AUTO_SYNC
+`endif
+
+// Debug UART interface data rate
+`ifdef DBG_UART_BAUD
+`undef DBG_UART_BAUD
+`endif
+`ifdef DBG_DCO_FREQ
+`undef DBG_DCO_FREQ
+`endif
+`ifdef DBG_UART_CNT
+`undef DBG_UART_CNT
+`endif
+
+// Debug interface selection
+`ifdef DBG_UART
+`undef DBG_UART
+`endif
+`ifdef DBG_JTAG
+`undef DBG_JTAG
+`endif
+
+// Enable/Disable the hardware breakpoint RANGE mode
+`ifdef HWBRK_RANGE
+`undef HWBRK_RANGE
+`endif
+
+// Counter width for the debug interface UART
+`ifdef DBG_UART_XFER_CNT_W
+`undef DBG_UART_XFER_CNT_W
+`endif
+
+//
+// MULTIPLIER CONFIGURATION
+//======================================
+
+`ifdef MPY_16x16
+`undef MPY_16x16
+`endif
diff --git a/tests/openmsp430/run-fm.do b/tests/openmsp430/run-fm.do
new file mode 100644
index 000000000..766d974c3
--- /dev/null
+++ b/tests/openmsp430/run-fm.do
@@ -0,0 +1,37 @@
+
+set hdlin_ignore_full_case false
+set hdlin_ignore_parallel_case false
+set svf_ignore_unqualified_fsm_information true
+set hdlin_warn_on_mismatch_message "FMR_ELAB-115 FMR_VLOG-079 FMR_VLOG-091"
+
+read_verilog -container r -libname WORK -01 rtl/omsp_alu.v
+read_verilog -container r -libname WORK -01 rtl/omsp_and_gate.v
+read_verilog -container r -libname WORK -01 rtl/omsp_clock_gate.v
+read_verilog -container r -libname WORK -01 rtl/omsp_clock_module.v
+read_verilog -container r -libname WORK -01 rtl/omsp_clock_mux.v
+read_verilog -container r -libname WORK -01 rtl/omsp_dbg_hwbrk.v
+read_verilog -container r -libname WORK -01 rtl/omsp_dbg_uart.v
+read_verilog -container r -libname WORK -01 rtl/omsp_dbg.v
+read_verilog -container r -libname WORK -01 rtl/omsp_execution_unit.v
+read_verilog -container r -libname WORK -01 rtl/omsp_frontend.v
+read_verilog -container r -libname WORK -01 rtl/omsp_mem_backbone.v
+read_verilog -container r -libname WORK -01 rtl/omsp_multiplier.v
+read_verilog -container r -libname WORK -01 rtl/omsp_register_file.v
+read_verilog -container r -libname WORK -01 rtl/omsp_scan_mux.v
+read_verilog -container r -libname WORK -01 rtl/omsp_sfr.v
+read_verilog -container r -libname WORK -01 rtl/omsp_sync_cell.v
+read_verilog -container r -libname WORK -01 rtl/omsp_sync_reset.v
+read_verilog -container r -libname WORK -01 rtl/omsp_wakeup_cell.v
+read_verilog -container r -libname WORK -01 rtl/omsp_watchdog.v
+read_verilog -container r -libname WORK -01 rtl/openMSP430.v
+set_top r:/WORK/openMSP430
+
+read_verilog -container i -libname WORK -01 synth.v
+read_verilog -container i -technology_library -libname TECH_WORK -01 ../../techlibs/stdcells_sim.v
+read_verilog -container i -technology_library -libname TECH_WORK -01 sim_mul.v
+set_top i:/WORK/openMSP430
+
+source fsm_info.txt
+
+if ![verify] start_gui exit
+
diff --git a/tests/openmsp430/run-fm.sh b/tests/openmsp430/run-fm.sh
new file mode 100644
index 000000000..5fd1c6cf8
--- /dev/null
+++ b/tests/openmsp430/run-fm.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+if [ -n "$REMOTE_YOSYS_ROOT" ]; then
+ rsync --exclude=".svn" --exclude="*.log" -rv -e "${REMOTE_YOSYS_SSH:-ssh} -C" "$REMOTE_YOSYS_ROOT"/tests/openmsp430/. .
+fi
+fm_shell -64 -file run-fm.do 2>&1 | tee run-fm.log
diff --git a/tests/openmsp430/run-synth.sh b/tests/openmsp430/run-synth.sh
new file mode 100644
index 000000000..e4d6bc720
--- /dev/null
+++ b/tests/openmsp430/run-synth.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+time ../../yosys -b "verilog -noexpr" -o synth.v -tl synth.log -s run-synth.ys \
+ rtl/omsp_*.v rtl/openMSP430.v 2>&1 | egrep '^\[[0-9.]+\] (ERROR|-- |[0-9]+\.)'
diff --git a/tests/openmsp430/run-synth.ys b/tests/openmsp430/run-synth.ys
new file mode 100644
index 000000000..af39147fb
--- /dev/null
+++ b/tests/openmsp430/run-synth.ys
@@ -0,0 +1,11 @@
+hierarchy -check -top openMSP430
+proc
+opt
+memory
+opt
+fsm -fm_set_fsm_file fsm_info.txt
+opt
+techmap
+opt
+abc
+opt
diff --git a/tests/openmsp430/sim_mul.v b/tests/openmsp430/sim_mul.v
new file mode 100644
index 000000000..8762bb25f
--- /dev/null
+++ b/tests/openmsp430/sim_mul.v
@@ -0,0 +1,29 @@
+
+module \$mul (A, B, Y);
+
+parameter A_SIGNED = 0;
+parameter B_SIGNED = 0;
+parameter A_WIDTH = 0;
+parameter B_WIDTH = 0;
+parameter Y_WIDTH = 0;
+
+input [A_WIDTH-1:0] A;
+generate if (A_SIGNED) begin:A_BUF
+ wire signed [A_WIDTH-1:0] val = A;
+end else begin:A_BUF
+ wire [A_WIDTH-1:0] val = A;
+end endgenerate
+
+input [B_WIDTH-1:0] B;
+generate if (B_SIGNED) begin:B_BUF
+ wire signed [B_WIDTH-1:0] val = B;
+end else begin:B_BUF
+ wire [B_WIDTH-1:0] val = B;
+end endgenerate
+
+output [Y_WIDTH-1:0] Y;
+
+assign Y = A_BUF.val * B_BUF.val;
+
+endmodule
+
diff --git a/tests/or1200/config.patch b/tests/or1200/config.patch
new file mode 100644
index 000000000..7826edeb6
--- /dev/null
+++ b/tests/or1200/config.patch
@@ -0,0 +1,46 @@
+Index: or1200_defines.v
+===================================================================
+--- or1200_defines.v (revision 812)
++++ or1200_defines.v (working copy)
+@@ -56,7 +56,7 @@
+ //
+ //`define OR1200_VERBOSE
+
+-// `define OR1200_ASIC
++`define OR1200_ASIC
+ ////////////////////////////////////////////////////////
+ //
+ // Typical configuration for an ASIC
+@@ -69,7 +69,7 @@
+ //`define OR1200_ARTISAN_SSP
+ //`define OR1200_ARTISAN_SDP
+ //`define OR1200_ARTISAN_STP
+-`define OR1200_VIRTUALSILICON_SSP
++//`define OR1200_VIRTUALSILICON_SSP
+ //`define OR1200_VIRTUALSILICON_STP_T1
+ //`define OR1200_VIRTUALSILICON_STP_T2
+
+@@ -96,17 +96,17 @@
+ //
+ // Select between ASIC optimized and generic multiplier
+ //
+-//`define OR1200_ASIC_MULTP2_32X32
+-`define OR1200_GENERIC_MULTP2_32X32
++`define OR1200_ASIC_MULTP2_32X32
++//`define OR1200_GENERIC_MULTP2_32X32
+
+ //
+ // Size/type of insn/data cache if implemented
+ //
+-// `define OR1200_IC_1W_512B
++`define OR1200_IC_1W_512B
+ // `define OR1200_IC_1W_4KB
+-`define OR1200_IC_1W_8KB
+-// `define OR1200_DC_1W_4KB
+-`define OR1200_DC_1W_8KB
++// `define OR1200_IC_1W_8KB
++`define OR1200_DC_1W_4KB
++// `define OR1200_DC_1W_8KB
+
+ `else
+
diff --git a/tests/or1200/run-checkout.sh b/tests/or1200/run-checkout.sh
new file mode 100644
index 000000000..c9d4a1024
--- /dev/null
+++ b/tests/or1200/run-checkout.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+rm -rf rtl
+svn co http://opencores.org/ocsvn/openrisc/openrisc/trunk/or1200/rtl/verilog rtl
+( cd rtl; patch -p0 < ../config.patch; )
diff --git a/tests/or1200/run-fm-mods.sh b/tests/or1200/run-fm-mods.sh
new file mode 100644
index 000000000..6b8487730
--- /dev/null
+++ b/tests/or1200/run-fm-mods.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+if [ -n "$REMOTE_YOSYS_ROOT" ]; then
+ rsync --exclude=".svn" --exclude="*.log" -rv -e "${REMOTE_YOSYS_SSH:-ssh} -C" "$REMOTE_YOSYS_ROOT"/tests/or1200/. .
+fi
+for mod in $( grep '^module or1200_' synth.v | awk -F '[ (]' '{ print $2; }'; )
+do
+ {
+ grep '^set ' run-fm.do
+ grep '^read_verilog -container r ' run-fm.do
+ echo "set_top r:/WORK/$mod"
+ grep '^read_verilog -container i ' run-fm.do
+ echo "set_top i:/WORK/$mod"
+ echo "verify"
+ echo "exit"
+ } > run-fm-${mod}.do
+ fm_shell -64 -file run-fm-${mod}.do 2>&1 | tee run-fm-${mod}.log
+ rsync -v -e "${REMOTE_YOSYS_SSH:-ssh}" run-fm-${mod}.log "$REMOTE_YOSYS_ROOT"/tests/or1200/
+done
+
+echo; echo
+for x in run-fm-*.log; do
+ echo -e "${x%/*}\\t$( egrep '^Verification (SUCCEEDED|FAILED)' $x; )"
+done | expand -t20
+echo; echo
diff --git a/tests/or1200/run-fm.do b/tests/or1200/run-fm.do
new file mode 100644
index 000000000..ed5c72282
--- /dev/null
+++ b/tests/or1200/run-fm.do
@@ -0,0 +1,53 @@
+
+set hdlin_ignore_full_case false
+set hdlin_warn_on_mismatch_message "FMR_ELAB-115 FMR_VLOG-079 FMR_VLOG-091"
+
+read_verilog -container r -libname WORK -01 rtl/or1200_alu.v
+read_verilog -container r -libname WORK -01 rtl/or1200_amultp2_32x32.v
+read_verilog -container r -libname WORK -01 rtl/or1200_cfgr.v
+read_verilog -container r -libname WORK -01 rtl/or1200_cpu.v
+read_verilog -container r -libname WORK -01 rtl/or1200_ctrl.v
+read_verilog -container r -libname WORK -01 rtl/or1200_dc_fsm.v
+read_verilog -container r -libname WORK -01 rtl/or1200_dc_ram.v
+read_verilog -container r -libname WORK -01 rtl/or1200_dc_tag.v
+read_verilog -container r -libname WORK -01 rtl/or1200_dc_top.v
+read_verilog -container r -libname WORK -01 rtl/or1200_dmmu_tlb.v
+read_verilog -container r -libname WORK -01 rtl/or1200_dmmu_top.v
+read_verilog -container r -libname WORK -01 rtl/or1200_dpram.v
+read_verilog -container r -libname WORK -01 rtl/or1200_du.v
+read_verilog -container r -libname WORK -01 rtl/or1200_except.v
+read_verilog -container r -libname WORK -01 rtl/or1200_fpu.v
+read_verilog -container r -libname WORK -01 rtl/or1200_freeze.v
+read_verilog -container r -libname WORK -01 rtl/or1200_genpc.v
+read_verilog -container r -libname WORK -01 rtl/or1200_ic_fsm.v
+read_verilog -container r -libname WORK -01 rtl/or1200_ic_ram.v
+read_verilog -container r -libname WORK -01 rtl/or1200_ic_tag.v
+read_verilog -container r -libname WORK -01 rtl/or1200_ic_top.v
+read_verilog -container r -libname WORK -01 rtl/or1200_if.v
+read_verilog -container r -libname WORK -01 rtl/or1200_immu_tlb.v
+read_verilog -container r -libname WORK -01 rtl/or1200_immu_top.v
+read_verilog -container r -libname WORK -01 rtl/or1200_lsu.v
+read_verilog -container r -libname WORK -01 rtl/or1200_mem2reg.v
+read_verilog -container r -libname WORK -01 rtl/or1200_mult_mac.v
+read_verilog -container r -libname WORK -01 rtl/or1200_operandmuxes.v
+read_verilog -container r -libname WORK -01 rtl/or1200_pic.v
+read_verilog -container r -libname WORK -01 rtl/or1200_pm.v
+read_verilog -container r -libname WORK -01 rtl/or1200_qmem_top.v
+read_verilog -container r -libname WORK -01 rtl/or1200_reg2mem.v
+read_verilog -container r -libname WORK -01 rtl/or1200_rf.v
+read_verilog -container r -libname WORK -01 rtl/or1200_sb.v
+read_verilog -container r -libname WORK -01 rtl/or1200_spram_32_bw.v
+read_verilog -container r -libname WORK -01 rtl/or1200_spram.v
+read_verilog -container r -libname WORK -01 rtl/or1200_sprs.v
+read_verilog -container r -libname WORK -01 rtl/or1200_top.v
+read_verilog -container r -libname WORK -01 rtl/or1200_tt.v
+read_verilog -container r -libname WORK -01 rtl/or1200_wb_biu.v
+read_verilog -container r -libname WORK -01 rtl/or1200_wbmux.v
+set_top r:/WORK/or1200_top
+
+read_verilog -container i -libname WORK -01 synth.v
+read_verilog -container i -technology_library -libname TECH_WORK -01 ../../techlibs/stdcells_sim.v
+set_top i:/WORK/or1200_top
+
+if ![verify] start_gui exit
+
diff --git a/tests/or1200/run-fm.sh b/tests/or1200/run-fm.sh
new file mode 100644
index 000000000..3023809c9
--- /dev/null
+++ b/tests/or1200/run-fm.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+if [ -n "$REMOTE_YOSYS_ROOT" ]; then
+ rsync --exclude=".svn" --exclude="*.log" -rv -e "${REMOTE_YOSYS_SSH:-ssh} -C" "$REMOTE_YOSYS_ROOT"/tests/or1200/. .
+fi
+fm_shell -64 -file run-fm.do 2>&1 | tee run-fm.log
diff --git a/tests/or1200/run-synth.sh b/tests/or1200/run-synth.sh
new file mode 100644
index 000000000..9f7e43fd6
--- /dev/null
+++ b/tests/or1200/run-synth.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+time ../../yosys -b "verilog -noexpr" -o synth.v -tl synth.log -s run-synth.ys rtl/or1200_*.v 2>&1 | egrep '^\[[0-9.]+\] (ERROR|--|[0-9]+\.)'
diff --git a/tests/or1200/run-synth.ys b/tests/or1200/run-synth.ys
new file mode 100644
index 000000000..1f0d8a82b
--- /dev/null
+++ b/tests/or1200/run-synth.ys
@@ -0,0 +1,11 @@
+hierarchy -check -top or1200_top
+proc
+opt
+memory
+opt
+# fsm -norecode
+# opt
+techmap
+opt
+abc
+opt
diff --git a/tests/or1200/run-vg.sh b/tests/or1200/run-vg.sh
new file mode 100644
index 000000000..54147cf5f
--- /dev/null
+++ b/tests/or1200/run-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+time valgrind --leak-check=full --show-reachable=yes --log-file=valgrind.log \
+ ../../yosys -o synth.v -tl synth.log -p "hierarchy -check -top or1200_top" \
+ -p opt_const -p proc -p memory -p opt -p techmap -p opt -p abc -p opt rtl/or1200_*.v
diff --git a/tests/simple/aes_kexp128.v b/tests/simple/aes_kexp128.v
new file mode 100644
index 000000000..3ee034789
--- /dev/null
+++ b/tests/simple/aes_kexp128.v
@@ -0,0 +1,24 @@
+
+// test taken from aes_core from iwls2005
+
+module aes_key_expand_128(clk, kld, key, wo_0, wo_1, wo_2, wo_3);
+
+input clk, kld;
+input [15:0] key;
+output [3:0] wo_0, wo_1, wo_2, wo_3;
+reg [3:0] w[3:0];
+
+assign wo_0 = w[0];
+assign wo_1 = w[1];
+assign wo_2 = w[2];
+assign wo_3 = w[3];
+
+always @(posedge clk) begin
+ w[0] <= kld ? key[15:12] : w[0];
+ w[1] <= kld ? key[11: 8] : w[0]^w[1];
+ w[2] <= kld ? key[ 7: 4] : w[0]^w[1]^w[2];
+ w[3] <= kld ? key[ 3: 0] : w[0]^w[1]^w[2]^w[3];
+end
+
+endmodule
+
diff --git a/tests/simple/dff_different_styles.v b/tests/simple/dff_different_styles.v
new file mode 100644
index 000000000..23d89b5dc
--- /dev/null
+++ b/tests/simple/dff_different_styles.v
@@ -0,0 +1,52 @@
+
+module dff(clk, d, q);
+input clk, d;
+output reg q;
+always @(posedge clk)
+ q <= d;
+endmodule
+
+module dffa(clk, arst, d, q);
+input clk, arst, d;
+output reg q;
+always @(posedge clk or posedge arst) begin
+ if (arst)
+ q <= 1;
+ else
+ q <= d;
+end
+endmodule
+
+module dffa1(clk, arst, d, q);
+input clk, arst, d;
+output reg q;
+always @(posedge clk or negedge arst) begin
+ if (~arst)
+ q <= 0;
+ else
+ q <= d;
+end
+endmodule
+
+module dffa2(clk, arst, d, q);
+input clk, arst, d;
+output reg q;
+always @(posedge clk or negedge arst) begin
+ if (!arst)
+ q <= 0;
+ else
+ q <= d;
+end
+endmodule
+
+module dffa3(clk, arst, d, q);
+input clk, arst, d;
+output reg q;
+always @(posedge clk or negedge arst) begin
+ if (~(!arst))
+ q <= d;
+ else
+ q <= 1;
+end
+endmodule
+
diff --git a/tests/simple/fiedler-cooley.v b/tests/simple/fiedler-cooley.v
new file mode 100644
index 000000000..96861973a
--- /dev/null
+++ b/tests/simple/fiedler-cooley.v
@@ -0,0 +1,33 @@
+// borrowed with some modifications from
+// http://www.ee.ed.ac.uk/~gerard/Teach/Verilog/manual/Example/lrgeEx2/cooley.html
+module up3down5(clock, data_in, up, down, carry_out, borrow_out, count_out, parity_out);
+
+input [8:0] data_in;
+input clock, up, down;
+
+output reg [8:0] count_out;
+output reg carry_out, borrow_out, parity_out;
+
+reg [9:0] cnt_up, cnt_dn;
+reg [8:0] count_nxt;
+
+always @(posedge clock)
+begin
+ cnt_dn = count_out - 3'b 101;
+ cnt_up = count_out + 2'b 11;
+
+ case ({up,down})
+ 2'b 00 : count_nxt = data_in;
+ 2'b 01 : count_nxt = cnt_dn;
+ 2'b 10 : count_nxt = cnt_up;
+ 2'b 11 : count_nxt = count_out;
+ default : count_nxt = 9'bX;
+ endcase
+
+ parity_out <= ^count_nxt;
+ carry_out <= up & cnt_up[9];
+ borrow_out <= down & cnt_dn[9];
+ count_out <= count_nxt;
+end
+
+endmodule
diff --git a/tests/simple/fsm.v b/tests/simple/fsm.v
new file mode 100644
index 000000000..79ca041dd
--- /dev/null
+++ b/tests/simple/fsm.v
@@ -0,0 +1,69 @@
+
+// `define ASYNC_RESET
+
+module test(clk, reset, button_a, button_b, red_a, green_a, red_b, green_b);
+
+input clk, reset, button_a, button_b;
+output reg red_a, green_a, red_b, green_b;
+
+(* gentb_constant = 0 *)
+wire reset;
+
+integer state;
+reg [3:0] cnt;
+
+`ifdef ASYNC_RESET
+always @(posedge clk, posedge reset)
+`else
+always @(posedge clk)
+`endif
+begin
+ cnt <= 0;
+ red_a <= 1;
+ red_b <= 1;
+ green_a <= 0;
+ green_b <= 0;
+
+ if (reset)
+ state <= 100;
+ else
+ case (state)
+ 100: begin
+ if (button_a && !button_b)
+ state <= 200;
+ if (!button_a && button_b)
+ state <= 300;
+ end
+ 200: begin
+ red_a <= 0;
+ green_a <= 1;
+ cnt <= cnt + 1;
+ if (cnt == 5)
+ state <= 210;
+ end
+ 210: begin
+ red_a <= 0;
+ green_a <= cnt[0];
+ cnt <= cnt + 1;
+ if (cnt == 10)
+ state <= 100;
+ end
+ 300: begin
+ red_b <= 0;
+ green_b <= 1;
+ cnt <= cnt + 1;
+ if (cnt == 5)
+ state <= 310;
+ end
+ 310: begin
+ red_b <= 0;
+ green_b <= cnt[0];
+ cnt <= cnt + 1;
+ if (cnt == 10)
+ state <= 100;
+ end
+ endcase
+end
+
+endmodule
+
diff --git a/tests/simple/generate.v b/tests/simple/generate.v
new file mode 100644
index 000000000..d458c076d
--- /dev/null
+++ b/tests/simple/generate.v
@@ -0,0 +1,67 @@
+
+module test1(clk, a, b, y);
+
+input clk;
+input [7:0] a, b;
+output reg [7:0] y;
+
+genvar i, j;
+wire [15:0] tmp1;
+
+generate
+
+ for (i = 0; i < 8; i = i + 1) begin:gen1
+ wire and_wire, or_wire;
+ assign and_wire = a[i] & b[i];
+ assign or_wire = a[i] | b[i];
+ if (i % 2 == 0) begin:gen2true
+ assign tmp1[i] = and_wire;
+ assign tmp1[i+8] = or_wire;
+ end else begin:gen2false
+ assign tmp1[i] = or_wire;
+ assign tmp1[i+8] = and_wire;
+ end
+ end
+
+ for (i = 0; i < 8; i = i + 1) begin:gen3
+ wire [4:0] tmp2;
+ for (j = 0; j <= 4; j = j + 1) begin:gen4
+ wire tmpbuf;
+ assign tmpbuf = tmp1[i+2*j];
+ assign tmp2[j] = tmpbuf;
+ end
+ always @(posedge clk)
+ y[i] <= ^tmp2;
+ end
+
+endgenerate
+
+endmodule
+
+// ------------------------------------------
+
+module test2(clk, a, b, y);
+
+input clk;
+input [7:0] a, b;
+output reg [8:0] y;
+
+integer i;
+reg [8:0] carry;
+
+always @(posedge clk) begin
+ carry[0] = 0;
+ for (i = 0; i < 8; i = i + 1) begin
+ casez ({a[i], b[i], carry[i]})
+ 3'b?11, 3'b1?1, 3'b11?:
+ carry[i+1] = 1;
+ default:
+ carry[i+1] = 0;
+ endcase
+ y[i] = a[i] ^ b[i] ^ carry[i];
+ end
+ y[8] = carry[8];
+end
+
+endmodule
+
diff --git a/tests/simple/i2c_master_tests.v b/tests/simple/i2c_master_tests.v
new file mode 100644
index 000000000..f8f564085
--- /dev/null
+++ b/tests/simple/i2c_master_tests.v
@@ -0,0 +1,62 @@
+// one of my early test cases was the OpenCores I2C master
+// This is a collection of stripped down code snippets from
+// this core that triggered bugs in early versions of yosys.
+
+// from i2c_master_bit_ctrl
+module test01(clk, rst, nReset, al);
+
+ input clk, rst, nReset;
+ output reg al;
+
+ reg cmd_stop;
+ always @(posedge clk or negedge nReset)
+ if (~nReset)
+ cmd_stop <= #1 1'b0;
+ else if (rst)
+ cmd_stop <= #1 1'b0;
+
+ always @(posedge clk or negedge nReset)
+ if (~nReset)
+ al <= #1 1'b0;
+ else if (rst)
+ al <= #1 1'b0;
+ else
+ al <= #1 ~cmd_stop;
+
+endmodule
+
+// from i2c_master_bit_ctrl
+module test02(clk, slave_wait, clk_cnt, cmd, cmd_stop, cnt);
+
+ input clk, slave_wait, clk_cnt;
+ input cmd;
+
+ output reg cmd_stop;
+
+ reg clk_en;
+ output reg [15:0] cnt;
+
+ always @(posedge clk)
+ if (~|cnt)
+ if (~slave_wait)
+ begin
+ cnt <= #1 clk_cnt;
+ clk_en <= #1 1'b1;
+ end
+ else
+ begin
+ cnt <= #1 cnt;
+ clk_en <= #1 1'b0;
+ end
+ else
+ begin
+ cnt <= #1 cnt - 16'h1;
+ clk_en <= #1 1'b0;
+ end
+
+ always @(posedge clk)
+ if (clk_en)
+ cmd_stop <= #1 cmd;
+
+endmodule
+
diff --git a/tests/simple/loops.v b/tests/simple/loops.v
new file mode 100644
index 000000000..77cdcd8e2
--- /dev/null
+++ b/tests/simple/loops.v
@@ -0,0 +1,79 @@
+
+// a simple test case extracted from systemcaes (as included in iwls2005)
+// this design has latches (or logic loops) for the two temp variables.
+// this latches (or logic loops) must be removed in the final synthesis results
+
+module aes(
+ // inputs
+ input [3:0] addroundkey_data_i,
+ input [3:0] addroundkey_data_reg,
+ input [3:0] addroundkey_round,
+ input [3:0] key_i,
+ input [3:0] keysched_new_key_o,
+ input [3:0] round,
+ input addroundkey_start_i,
+ input keysched_ready_o,
+
+ // outputs
+ output reg [3:0] keysched_last_key_i,
+ output reg [3:0] keysched_round_i,
+ output reg [3:0] next_addroundkey_data_reg,
+ output reg [3:0] next_addroundkey_round,
+ output reg [3:0] round_data_var,
+ output reg keysched_start_i,
+ output reg next_addroundkey_ready_o
+);
+
+// temp variables
+reg [3:0] data_var;
+reg [3:0] round_key_var;
+
+always @*
+begin
+ keysched_start_i = 0;
+ keysched_round_i = addroundkey_round;
+ round_data_var = addroundkey_data_reg;
+ next_addroundkey_data_reg = addroundkey_data_reg;
+ next_addroundkey_ready_o = 0;
+ next_addroundkey_round = addroundkey_round;
+
+ if (addroundkey_round == 1 || addroundkey_round == 0)
+ keysched_last_key_i = key_i;
+ else
+ keysched_last_key_i = keysched_new_key_o;
+
+ if (round == 0 && addroundkey_start_i)
+ begin
+ data_var = addroundkey_data_i;
+ round_key_var = key_i;
+ round_data_var = round_key_var ^ data_var;
+ next_addroundkey_data_reg = round_data_var;
+ next_addroundkey_ready_o = 1;
+ end
+ else if (addroundkey_start_i && round != 0)
+ begin
+ keysched_last_key_i = key_i;
+ keysched_start_i = 1;
+ keysched_round_i = 1;
+ next_addroundkey_round = 1;
+ end
+ else if (addroundkey_round != round && keysched_ready_o)
+ begin
+ next_addroundkey_round = addroundkey_round + 1;
+ keysched_last_key_i = keysched_new_key_o;
+ keysched_start_i = 1;
+ keysched_round_i = addroundkey_round + 1;
+ end
+ else if (addroundkey_round == round && keysched_ready_o)
+ begin
+ data_var = addroundkey_data_i;
+ round_key_var = keysched_new_key_o;
+ round_data_var = round_key_var ^ data_var;
+ next_addroundkey_data_reg = round_data_var;
+ next_addroundkey_ready_o = 1;
+ next_addroundkey_round = 0;
+ end
+end
+
+endmodule
+
diff --git a/tests/simple/mem2reg.v b/tests/simple/mem2reg.v
new file mode 100644
index 000000000..7be32b0b3
--- /dev/null
+++ b/tests/simple/mem2reg.v
@@ -0,0 +1,17 @@
+module test1(in_addr, in_data, out_addr, out_data);
+
+input [1:0] in_addr, out_addr;
+input [3:0] in_data;
+output reg [3:0] out_data;
+
+reg [3:0] array [2:0];
+
+always @* begin
+ array[0] = 0;
+ array[1] = 23;
+ array[2] = 42;
+ array[in_addr] = in_data;
+ out_data = array[out_addr];
+end
+
+endmodule
diff --git a/tests/simple/memory.v b/tests/simple/memory.v
new file mode 100644
index 000000000..c25bcd928
--- /dev/null
+++ b/tests/simple/memory.v
@@ -0,0 +1,19 @@
+
+module test01(clk, wr_en, wr_addr, wr_value, rd_addr, rd_value);
+
+input clk, wr_en;
+input [3:0] wr_addr, rd_addr;
+input [7:0] wr_value;
+output reg [7:0] rd_value;
+
+reg [7:0] data [15:0];
+
+always @(posedge clk)
+ if (wr_en)
+ data[wr_addr] <= wr_value;
+
+always @(posedge clk)
+ rd_value <= data[rd_addr];
+
+endmodule
+
diff --git a/tests/simple/muxtree.v b/tests/simple/muxtree.v
new file mode 100644
index 000000000..6996206c0
--- /dev/null
+++ b/tests/simple/muxtree.v
@@ -0,0 +1,50 @@
+
+// test case generated from IWLS 2005 usb_phy core
+// (triggered a bug in opt_muxtree pass)
+
+module usb_tx_phy(clk, rst, DataOut_i, TxValid_i, hold_reg);
+
+input clk;
+input rst;
+input DataOut_i;
+input TxValid_i;
+output reg hold_reg;
+
+reg state, next_state;
+reg ld_sop_d;
+reg ld_data_d;
+
+always @(posedge clk)
+ if(ld_sop_d)
+ hold_reg <= 0;
+ else
+ hold_reg <= DataOut_i;
+
+always @(posedge clk)
+ if(!rst) state <= 0;
+ else state <= next_state;
+
+always @(state or TxValid_i)
+ begin
+ next_state = state;
+
+ ld_sop_d = 1'b0;
+ ld_data_d = 1'b0;
+
+ case(state) // synopsys full_case parallel_case
+ 0:
+ if(TxValid_i)
+ begin
+ ld_sop_d = 1'b1;
+ next_state = 1;
+ end
+ 1:
+ if(TxValid_i)
+ begin
+ ld_data_d = 1'b1;
+ next_state = 0;
+ end
+ endcase
+ end
+
+endmodule
diff --git a/tests/simple/omsp_dbg_uart.v b/tests/simple/omsp_dbg_uart.v
new file mode 100644
index 000000000..dc8860dee
--- /dev/null
+++ b/tests/simple/omsp_dbg_uart.v
@@ -0,0 +1,34 @@
+
+module omsp_dbg_uart (dbg_clk, dbg_rst, mem_burst, cmd_valid);
+
+input dbg_clk;
+input dbg_rst;
+input mem_burst;
+output cmd_valid;
+
+reg [2:0] uart_state;
+reg [2:0] uart_state_nxt;
+
+wire xfer_done;
+
+parameter RX_SYNC = 3'h0;
+parameter RX_CMD = 3'h1;
+parameter RX_DATA = 3'h2;
+
+always @(uart_state or mem_burst)
+ case (uart_state)
+ RX_SYNC : uart_state_nxt = RX_CMD;
+ RX_CMD : uart_state_nxt = mem_burst ? RX_DATA : RX_SYNC;
+ RX_DATA : uart_state_nxt = RX_SYNC;
+ default : uart_state_nxt = RX_CMD;
+ endcase
+
+always @(posedge dbg_clk or posedge dbg_rst)
+ if (dbg_rst) uart_state <= RX_SYNC;
+ else if (xfer_done | mem_burst) uart_state <= uart_state_nxt;
+
+assign cmd_valid = (uart_state==RX_CMD) & xfer_done;
+assign xfer_done = uart_state!=RX_SYNC;
+
+endmodule
+
diff --git a/tests/simple/operators.v b/tests/simple/operators.v
new file mode 100644
index 000000000..b9bbc13c8
--- /dev/null
+++ b/tests/simple/operators.v
@@ -0,0 +1,97 @@
+
+module test(clk, mode, u1, s1, u2, s2, y);
+
+input clk;
+input [5:0] mode;
+
+input [3:0] u1, u2;
+input signed [3:0] s1, s2;
+
+output reg [7:0] y;
+
+always @(posedge clk) begin
+ y <= 8'h42;
+ case (mode)
+ 0: y <= u1 << u2;
+ 1: y <= u1 << s2;
+ 2: y <= s1 << u2;
+ 3: y <= s1 << s2;
+
+ 4: y <= u1 >> u2;
+ 5: y <= u1 >> s2;
+ 6: y <= s1 >> u2;
+ 7: y <= s1 >> s2;
+
+ 8: y <= u1 <<< u2;
+ 9: y <= u1 <<< s2;
+ 10: y <= s1 <<< u2;
+ 11: y <= s1 <<< s2;
+
+ 12: y <= u1 >>> u2;
+ 13: y <= u1 >>> s2;
+ 14: y <= s1 >>> u2;
+ 15: y <= s1 >>> s2;
+
+ 16: y <= u1 < u2;
+ 17: y <= u1 < s2;
+ 18: y <= s1 < u2;
+ 19: y <= s1 < s2;
+
+ 20: y <= u1 <= u2;
+ 21: y <= u1 <= s2;
+ 22: y <= s1 <= u2;
+ 23: y <= s1 <= s2;
+
+ 24: y <= u1 == u2;
+ 25: y <= u1 == s2;
+ 26: y <= s1 == u2;
+ 27: y <= s1 == s2;
+
+ 28: y <= u1 != u2;
+ 29: y <= u1 != s2;
+ 30: y <= s1 != u2;
+ 31: y <= s1 != s2;
+
+ 32: y <= u1 >= u2;
+ 33: y <= u1 >= s2;
+ 34: y <= s1 >= u2;
+ 35: y <= s1 >= s2;
+
+ 36: y <= u1 > u2;
+ 37: y <= u1 > s2;
+ 38: y <= s1 > u2;
+ 39: y <= s1 > s2;
+
+ 40: y <= u1 + u2;
+ 41: y <= u1 + s2;
+ 42: y <= s1 + u2;
+ 43: y <= s1 + s2;
+
+ 44: y <= u1 - u2;
+ 45: y <= u1 - s2;
+ 46: y <= s1 - u2;
+ 47: y <= s1 - s2;
+
+ 48: y <= +u1;
+ 49: y <= -u1;
+ 50: y <= +s1;
+ 51: y <= -s1;
+
+ 52: y <= { &u1, ~&u1, |u1, ~|u1, ^u1, ~^u1, ^~u1 };
+ 53: y <= { &s1, ~&s1, |s1, ~|s1, ^s1, ~^s1, ^~s1 };
+ 54: y <= { &u1[1:0], ~&u1[1:0], |u1[1:0], ~|u1[1:0], ^u1[1:0], ~^u1[1:0], ^~u1[1:0] };
+ 55: y <= { &s1[1:0], ~&s1[1:0], |s1[1:0], ~|s1[1:0], ^s1[1:0], ~^s1[1:0], ^~s1[1:0] };
+
+ 56: y <= { u1[1:0] && u2[1:0], u1[1:0] && u2[1:0], !u1[1:0] };
+ 57: y <= {4{u1[1:0]}};
+ 58: y <= {u1, u2} ^ {s1, s2};
+ 59: y <= {u1, u2} & {s1, s2};
+
+ 60: y <= u1[0] ? u1 : u2;
+ 61: y <= u1[0] ? u1 : s2;
+ 62: y <= u1[0] ? s1 : u2;
+ 63: y <= u1[0] ? s1 : s2;
+ endcase
+end
+
+endmodule
diff --git a/tests/simple/paramods.v b/tests/simple/paramods.v
new file mode 100644
index 000000000..94fd2dfc2
--- /dev/null
+++ b/tests/simple/paramods.v
@@ -0,0 +1,37 @@
+
+module test1(a, b, x, y);
+
+input [7:0] a, b;
+output [7:0] x, y;
+
+inc #(.step(3)) inc_a (.in(a), .out(x));
+inc #(.width(4), .step(7)) inc_b (b, y);
+
+endmodule
+
+// -----------------------------------
+
+module test2(a, b, x, y);
+
+input [7:0] a, b;
+output [7:0] x, y;
+
+inc #(5) inc_a (.in(a), .out(x));
+inc #(4, 7) inc_b (b, y);
+
+endmodule
+
+// -----------------------------------
+
+module inc(in, out);
+
+parameter width = 8;
+parameter step = 1;
+
+input [width-1:0] in;
+output [width-1:0] out;
+
+assign out = in + step;
+
+endmodule
+
diff --git a/tests/simple/process.v b/tests/simple/process.v
new file mode 100644
index 000000000..532586649
--- /dev/null
+++ b/tests/simple/process.v
@@ -0,0 +1,65 @@
+
+module uut(clk, arst, a, b, c, d, e, f, out1);
+
+input clk, arst, a, b, c, d, e, f;
+output reg [3:0] out1;
+
+always @(posedge clk, posedge arst) begin
+ if (arst)
+ out1 = 0;
+ else begin
+ if (a) begin
+ case ({b, c})
+ 2'b00:
+ out1 = out1 + 9;
+ 2'b01, 2'b10:
+ out1 = out1 + 13;
+ endcase
+ if (d) begin
+ out1 = out1 + 2;
+ out1 = out1 + 1;
+ end
+ case ({e, f})
+ 2'b11:
+ out1 = out1 + 8;
+ 2'b00:
+ ;
+ default:
+ out1 = out1 + 10;
+ endcase
+ out1 = out1 ^ 7;
+ end
+ out1 = out1 + 14;
+ end
+end
+
+endmodule
+
+// -------------------------------------------------------------
+
+// extracted from ../asicworld/code_hdl_models_uart.v
+// (triggered a bug in the proc_mux pass)
+module uart (reset, txclk, ld_tx_data, tx_empty, tx_cnt);
+
+input reset;
+input txclk;
+input ld_tx_data;
+
+output reg tx_empty;
+output reg [3:0] tx_cnt;
+
+always @ (posedge txclk)
+if (reset) begin
+ tx_empty <= 1;
+ tx_cnt <= 0;
+end else begin
+ if (ld_tx_data) begin
+ tx_empty <= 0;
+ end
+ if (!tx_empty) begin
+ tx_cnt <= tx_cnt + 1;
+ end
+end
+
+endmodule
+
diff --git a/tests/simple/run-test.sh b/tests/simple/run-test.sh
new file mode 100755
index 000000000..bf27d15f8
--- /dev/null
+++ b/tests/simple/run-test.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+make -C ../.. || exit 1
+exec bash ../tools/autotest.sh *.v
diff --git a/tests/simple/subbytes.v b/tests/simple/subbytes.v
new file mode 100644
index 000000000..04269a99f
--- /dev/null
+++ b/tests/simple/subbytes.v
@@ -0,0 +1,82 @@
+
+// test taken from systemcaes from iwls2005
+
+module subbytes_00(clk, reset, start_i, decrypt_i, data_i, ready_o, data_o, sbox_data_o, sbox_data_i, sbox_decrypt_o);
+
+input clk;
+input reset;
+input start_i;
+input decrypt_i;
+input [31:0] data_i;
+output ready_o;
+output [31:0] data_o;
+output [7:0] sbox_data_o;
+input [7:0] sbox_data_i;
+output sbox_decrypt_o;
+
+reg ready_o;
+reg [31:0] data_o;
+reg [7:0] sbox_data_o;
+reg sbox_decrypt_o;
+
+reg [1:0] state;
+reg [1:0] next_state;
+reg [31:0] data_reg;
+reg [31:0] next_data_reg;
+reg next_ready_o;
+
+always @(posedge clk or negedge reset)
+begin
+ if (!reset) begin
+ data_reg = 0;
+ state = 0;
+ ready_o = 0;
+ end else begin
+ data_reg = next_data_reg;
+ state = next_state;
+ ready_o = next_ready_o;
+ end
+end
+
+reg [31:0] data_i_var, data_reg_128;
+reg [7:0] data_array [3:0];
+reg [7:0] data_reg_var [3:0];
+
+always @(decrypt_i or start_i or state or data_i or sbox_data_i or data_reg)
+begin
+ data_i_var = data_i;
+
+ data_array[0] = data_i_var[ 31: 24];
+ data_array[1] = data_i_var[ 23: 16];
+ data_array[2] = data_i_var[ 15: 8];
+ data_array[3] = data_i_var[ 7: 0];
+
+ data_reg_var[0] = data_reg[ 31: 24];
+ data_reg_var[1] = data_reg[ 23: 16];
+ data_reg_var[2] = data_reg[ 15: 8];
+ data_reg_var[3] = data_reg[ 7: 0];
+
+ sbox_decrypt_o = decrypt_i;
+ sbox_data_o = data_array[state];
+ next_state = state;
+ next_data_reg = data_reg;
+
+ next_ready_o = 0;
+ data_o = data_reg;
+
+ if (state) begin
+ if (start_i) begin
+ next_state = 1;
+ end
+ end else begin
+ data_reg_var[state] = sbox_data_i;
+ data_reg_128[ 31: 24] = data_reg_var[0];
+ data_reg_128[ 23: 16] = data_reg_var[1];
+ data_reg_128[ 15: 8] = data_reg_var[2];
+ data_reg_128[ 7: 0] = data_reg_var[3];
+ next_data_reg = data_reg_128;
+ next_state = state + 1;
+ end
+end
+
+endmodule
diff --git a/tests/simple/task_func.v b/tests/simple/task_func.v
new file mode 100644
index 000000000..3a09cbc35
--- /dev/null
+++ b/tests/simple/task_func.v
@@ -0,0 +1,35 @@
+
+module test01(clk, a, b, c, x, y, z, w);
+
+input clk;
+input [7:0] a, b, c;
+output reg [7:0] x, y, z, w;
+
+function [7:0] sum_shift;
+input [3:0] s1, s2, s3;
+sum_shift = s1 + (s2 << 2) + (s3 << 4);
+endfunction
+
+task reset_w;
+w = 0;
+endtask
+
+task add_to;
+output [7:0] out;
+input [7:0] in;
+out = out + in;
+endtask
+
+always @(posedge clk) begin
+ x = sum_shift(a, b, c);
+ y = sum_shift(a[7:4], b[5:2], c[3:0]);
+ z = sum_shift(a[0], b[5:4], c >> 5) ^ sum_shift(1, 2, 3);
+
+ reset_w;
+ add_to(w, x);
+ add_to(w, y);
+ add_to(w, z);
+end
+
+endmodule
+
diff --git a/tests/simple/usb_phy_tetsts.v b/tests/simple/usb_phy_tetsts.v
new file mode 100644
index 000000000..2375183d8
--- /dev/null
+++ b/tests/simple/usb_phy_tetsts.v
@@ -0,0 +1,36 @@
+
+// from usb_rx_phy
+module test01(clk, rst, rx_en, fs_ce);
+
+input clk, rst;
+input rx_en;
+output reg fs_ce;
+reg [1:0] dpll_next_state;
+reg [1:0] dpll_state;
+
+always @(posedge clk)
+ dpll_state <= rst ? 0 : dpll_next_state;
+
+always @*
+ begin
+ fs_ce = 1'b0;
+ case(dpll_state)
+ 2'h0:
+ if(rx_en) dpll_next_state = 2'h0;
+ else dpll_next_state = 2'h1;
+ 2'h1:begin
+ fs_ce = 1'b1;
+ if(rx_en) dpll_next_state = 2'h3;
+ else dpll_next_state = 2'h2;
+ end
+ 2'h2:
+ if(rx_en) dpll_next_state = 2'h0;
+ else dpll_next_state = 2'h3;
+ 2'h3:
+ if(rx_en) dpll_next_state = 2'h0;
+ else dpll_next_state = 2'h0;
+ endcase
+ end
+
+endmodule
+
diff --git a/tests/simple/values.v b/tests/simple/values.v
new file mode 100644
index 000000000..9fae4da9d
--- /dev/null
+++ b/tests/simple/values.v
@@ -0,0 +1,44 @@
+
+module test_signed(a, b, c, d, y);
+
+input [3:0] a, b, c;
+input signed [3:0] d;
+output reg [7:0] y;
+
+always @* begin
+ if (a && b)
+ y = c;
+ else
+ y = d;
+end
+
+endmodule
+
+module test_const(a, y);
+
+input [3:0] a;
+output reg [28:0] y;
+
+always @*
+ case (a)
+ 4'b0000: y = 0;
+ 4'b0001: y = 11;
+ 4'b0010: y = 222;
+ 4'b0011: y = 3456;
+ 4'b0100: y = 'b10010010;
+ 4'b0101: y = 'h123abc;
+ 4'b0110: y = 'o1234567;
+ 4'b0111: y = 'd3456789;
+ 4'b1000: y = 16'b10010010;
+ 4'b1001: y = 16'h123abc;
+ 4'b1010: y = 16'o1234567;
+ 4'b1011: y = 16'd3456789;
+ 4'b1100: y = "foobar";
+ 4'b1101: y = "foobarfoobarfoobar";
+ 4'b1110: y = 16'h1;
+ 4'b1111: y = a;
+ default: y = 'bx;
+ endcase
+
+endmodule
+
diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh
new file mode 100755
index 000000000..6b22f9023
--- /dev/null
+++ b/tests/tools/autotest.sh
@@ -0,0 +1,164 @@
+#!/bin/bash
+
+libs=""
+genvcd=false
+use_isim=false
+verbose=false
+keeprunning=false
+backend_opts="-noattr -noexpr"
+kompare_xst=false
+scriptfiles=""
+toolsdir="$(cd $(dirname $0); pwd)"
+
+if [ ! -f $toolsdir/cmp_tbdata -o $toolsdir/cmp_tbdata.c -nt $toolsdir/cmp_tbdata ]; then
+ ( set -ex; gcc -Wall -o $toolsdir/cmp_tbdata $toolsdir/cmp_tbdata.c; ) || exit 1
+fi
+
+while getopts il:wkvrxs: opt; do
+ case "$opt" in
+ i)
+ use_isim=true ;;
+ l)
+ libs="$libs $(cd $(dirname $OPTARG); pwd)/$(basename $OPTARG)";;
+ w)
+ genvcd=true ;;
+ k)
+ keeprunning=true ;;
+ v)
+ verbose=true ;;
+ r)
+ backend_opts="$backend_opts norename" ;;
+ x)
+ kompare_xst=true ;;
+ s)
+ [[ "$OPTARG" == /* ]] || OPTARG="$PWD/$OPTARG"
+ scriptfiles="$scriptfiles $OPTARG" ;;
+ *)
+ echo "Usage: $0 [-i] [-w] [-k] [-v] [-r] [-x] [-l libs] [-s script] verilog-files\n" >&2
+ exit 1
+ esac
+done
+
+create_ref() {
+ if $kompare_xst; then
+ echo "verilog work $1" > $2.prj
+ cat <<- EOT > $2.xst
+ run
+ -ifn $2.prj -ifmt mixed -ofn $2 -ofmt NGC -p xc6slx4-3-tqg144
+ -top $( grep ^module $1 | sed -r 's,[^0-9A-Za-z_]+, ,g' | awk '{ print $2; exit; }'; )
+ -opt_mode Speed -opt_level 1 -iobuf NO
+ EOT
+ (
+ set +x
+ prefix="$2"
+ xilver=$( ls -v /opt/Xilinx/ | tail -n1; )
+ case "$( uname -m )" in
+ x86_64)
+ set --; . /opt/Xilinx/$xilver/ISE_DS/settings64.sh ;;
+ *)
+ set --; . /opt/Xilinx/$xilver/ISE_DS/settings32.sh ;;
+ esac
+ set -x
+ xst -ifn $prefix.xst
+ netgen -w -ofmt verilog $prefix.ngc $prefix
+ )
+ else
+ cp "$1" "$2.v"
+ fi
+}
+
+compile_and_run() {
+ exe="$1"; output="$2"; shift 2
+ if $use_isim; then
+ (
+ set +x
+ files=( "$@" )
+ xilver=$( ls -v /opt/Xilinx/ | tail -n1; )
+ case "$( uname -m )" in
+ x86_64)
+ set --; . /opt/Xilinx/$xilver/ISE_DS/settings64.sh ;;
+ *)
+ set --; . /opt/Xilinx/$xilver/ISE_DS/settings32.sh ;;
+ esac
+ set -x
+ vlogcomp "${files[@]}"
+ if $kompare_xst; then
+ fuse -o "$exe" -lib unisims_ver -top testbench -top glbl
+ else
+ fuse -o "$exe" -top testbench
+ fi
+ { echo "run all"; echo "exit"; } > run-all.tcl
+ PATH="$PATH:" "$exe" -tclbatch run-all.tcl > "$output"
+ )
+ else
+ iverilog -s testbench -o "$exe" "$@"
+ vvp -n "$exe" > "$output"
+ fi
+}
+
+shift $((OPTIND - 1))
+
+for fn
+do
+ bn=${fn%.v}
+ if [ "$bn" == "$fn" ]; then
+ echo "Invalid argument: $fn" >&2
+ exit 1
+ fi
+ [[ "$bn" == *_tb ]] && continue
+ echo -n "Test: $bn "
+
+ rm -f ${bn}.{err,log}
+ mkdir -p ${bn}.out
+ rm -rf ${bn}.out/*
+
+ body() {
+ cd ${bn}.out
+ cp ../$fn $fn
+ if [ ! -f ../${bn}_tb.v ]; then
+ "$toolsdir"/../../yosys -b autotest -o ${bn}_tb.v $fn
+ else
+ cp ../${bn}_tb.v ${bn}_tb.v
+ fi
+ if $genvcd; then sed -i 's,// \$dump,$dump,g' ${bn}_tb.v; fi
+ create_ref $fn ${bn}_ref
+ compile_and_run ${bn}_tb_ref ${bn}_out_ref ${bn}_tb.v ${bn}_ref.v $libs
+ if $genvcd; then mv testbench.vcd ${bn}_ref.vcd; fi
+
+ test_count=0
+ test_passes() {
+ "$toolsdir"/../../yosys -b "verilog $backend_opts" "$@" -o ${bn}_syn${test_count}.v $fn $scriptfiles
+ compile_and_run ${bn}_tb_syn${test_count} ${bn}_out_syn${test_count} \
+ ${bn}_tb.v ${bn}_syn${test_count}.v $libs \
+ "$toolsdir"/../../techlibs/simlib.v \
+ "$toolsdir"/../../techlibs/stdcells_sim.v
+ if $genvcd; then mv testbench.vcd ${bn}_syn${test_count}.vcd; fi
+ $toolsdir/cmp_tbdata ${bn}_out_ref ${bn}_out_syn${test_count}
+ test_count=$(( test_count + 1 ))
+ }
+
+ if [ -n "$scriptfiles" ]; then
+ test_passes
+ else
+ test_passes -p hierarchy -p proc -p memory -p opt -p fsm -p opt
+ test_passes -p hierarchy -p proc -p memory -p opt -p fsm -p opt -p techmap -p opt
+ # test_passes -p hierarchy -p proc -p memory -p opt -p techmap -p opt -p abc -p opt
+ fi
+ touch ../${bn}.log
+ }
+
+ if $verbose; then
+ echo ".."
+ echo "Output written to console." > ${bn}.err
+ ( set -ex; body; )
+ else
+ ( set -ex; body; ) > ${bn}.err 2>&1
+ fi
+
+ if [ -f ${bn}.log ]; then
+ mv ${bn}.err ${bn}.log
+ echo "-> ok"
+ else echo "-> ERROR!"; $keeprunning || exit 1; fi
+done
+
+exit 0
diff --git a/tests/tools/cmp_tbdata.c b/tests/tools/cmp_tbdata.c
new file mode 100644
index 000000000..86485efd0
--- /dev/null
+++ b/tests/tools/cmp_tbdata.c
@@ -0,0 +1,67 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+
+int line = 0;
+char buffer1[1024];
+char buffer2[1024];
+
+void check(bool ok)
+{
+ if (ok)
+ return;
+ fprintf(stderr, "Error in testbench output compare (line=%d):\n-%s\n+%s\n", line, buffer1, buffer2);
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ FILE *f1, *f2;
+ bool eof1, eof2;
+ int i;
+
+ check(argc == 3);
+
+ f1 = fopen(argv[1], "r");
+ f2 = fopen(argv[2], "r");
+
+ check(f1 && f2);
+
+ while (!feof(f1) && !feof(f2))
+ {
+ line++;
+ buffer1[0] = 0;
+ buffer2[0] = 0;
+
+ eof1 = fgets(buffer1, 1024, f1) == NULL;
+ eof2 = fgets(buffer2, 1024, f2) == NULL;
+
+ if (*buffer1 && buffer1[strlen(buffer1)-1] == '\n')
+ buffer1[strlen(buffer1)-1] = 0;
+
+ if (*buffer2 && buffer2[strlen(buffer2)-1] == '\n')
+ buffer2[strlen(buffer2)-1] = 0;
+
+ check(eof1 == eof2);
+
+ for (i = 0; buffer1[i] || buffer2[i]; i++)
+ {
+ check(buffer1[i] != 0 && buffer2[i] != 0);
+
+ // first argument is the reference. An 'z' or 'x'
+ // here means we don't care about the result.
+ if (buffer1[i] == 'z' || buffer1[i] == 'x')
+ continue;
+
+ check(buffer1[i] == buffer2[i]);
+ }
+ }
+
+ check(feof(f1) && feof(f2));
+
+ fclose(f1);
+ fclose(f2);
+ return 0;
+}
+
diff --git a/tests/tools/profiler.pl b/tests/tools/profiler.pl
new file mode 100755
index 000000000..456f634bc
--- /dev/null
+++ b/tests/tools/profiler.pl
@@ -0,0 +1,55 @@
+#!/usr/bin/perl
+# parse 'yosys -t' logfile and find slow passes
+
+my $max_depth = 0;
+my %last_line_by_depth;
+my %last_time_by_depth;
+
+my @lines_text;
+my @lines_depth;
+my @lines_time;
+
+while (<>)
+{
+ chomp;
+ next unless /^\[([0-9.]+)\] (([0-9]+\.)+)/;
+ my ($this_time, $this_id, $this_header) = ($1, $2, $4);
+
+ push @lines_text, $_;
+ push @lines_depth, 0;
+ push @lines_time, 0;
+
+ my $depth = $this_id;
+ $depth =~ s/[^.]//g;
+ $depth = length $depth;
+ $max_depth = $depth if $depth > $max_depth;
+
+ for (my $i = $depth; $i <= $max_depth; $i++) {
+ next unless exists $last_time_by_depth{$i};
+ $lines_time[$last_line_by_depth{$i}] = $this_time-$last_time_by_depth{$i};
+ delete $last_time_by_depth{$i};
+ delete $last_header_by_depth{$i};
+ }
+
+ $last_time_by_depth{$depth} = $this_time;
+ $last_line_by_depth{$depth} = $#lines_text;
+ $lines_depth[$#lines_text] = $depth;
+}
+
+for (my $depth = 1; $depth <= $max_depth; $depth++) {
+ printf "\nSlow passes on recursion depth %d:\n", $depth;
+ my @lines;
+ for (my $i = 0; $i <= $#lines_text; $i++) {
+ next if $lines_depth[$i] != $depth or $lines_time[$i] < 1.0;
+ push @lines, sprintf("%3d %08.2f %s\n", $lines_depth[$i], $lines_time[$i], $lines_text[$i]);
+ }
+ for my $line (sort {$b cmp $a} @lines) {
+ print $line;
+ }
+}
+
+printf "\nFull journal of headers:\n";
+for (my $i = 0; $i <= $#lines_text; $i++) {
+ printf "%3d %08.2f %s\n", $lines_depth[$i], $lines_time[$i], $lines_text[$i];
+}
+
diff --git a/tests/tools/rtlview.sh b/tests/tools/rtlview.sh
new file mode 100755
index 000000000..6a4adcae1
--- /dev/null
+++ b/tests/tools/rtlview.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+
+# using Xilinx ISE to display RTL schematics
+
+if [ ! -f "$1" ]; then
+ echo "Usage: $0 <verilog-file>" >&2
+ exit 1
+fi
+
+prjdir="$(dirname $0)/rtlview.tmp"
+mkdir -p "$prjdir"
+
+cp "$1" "$prjdir"/schematic.v
+cp "$(dirname $0)"/../../techlibs/blackbox.v "$prjdir"/blackbox.v
+cd "$prjdir"
+
+if fuser -s ise.out; then
+ echo "ISE already running. Re-create RTL schematic from GUI."
+ exit 1
+fi
+
+xilver=$( ls -v /opt/Xilinx/ | grep '^[0-9]' | tail -n1; )
+
+cat > rtlview.xise << EOT
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema">
+ <header/>
+ <version xil_pn:ise_version="$xilver" xil_pn:schema_version="2"/>
+
+ <files>
+ <file xil_pn:name="schematic.v" xil_pn:type="FILE_VERILOG">
+ <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="1"/>
+ <association xil_pn:name="Implementation" xil_pn:seqID="2"/>
+ </file>
+ <file xil_pn:name="blackbox.v" xil_pn:type="FILE_VERILOG">
+ <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="1"/>
+ <association xil_pn:name="Implementation" xil_pn:seqID="2"/>
+ </file>
+ </files>
+
+ <properties>
+ <property xil_pn:name="Device" xil_pn:value="xc6slx4" xil_pn:valueState="default"/>
+ <property xil_pn:name="Device Family" xil_pn:value="Spartan6" xil_pn:valueState="non-default"/>
+ <property xil_pn:name="Device Speed Grade/Select ABS Minimum" xil_pn:value="-3" xil_pn:valueState="default"/>
+ </properties>
+
+ <bindings/>
+ <libraries/>
+ <autoManagedFiles/>
+</project>
+EOT
+
+set --
+case "$( uname -m )" in
+x86_64)
+ . /opt/Xilinx/$xilver/ISE_DS/settings64.sh ;;
+*)
+ . /opt/Xilinx/$xilver/ISE_DS/settings32.sh ;;
+esac
+
+ise rtlview.xise > ise.out 2>&1 &
+echo "ISE is now starting up. Create RTL schematic from GUI."
+
diff --git a/tests/tools/vcdcd.pl b/tests/tools/vcdcd.pl
new file mode 100755
index 000000000..4875eeeb0
--- /dev/null
+++ b/tests/tools/vcdcd.pl
@@ -0,0 +1,201 @@
+#!/usr/bin/perl -w
+#
+# Note: You might need to install the Verilog::VCD package using CPAN..
+
+use strict;
+use Data::Dumper;
+use Verilog::VCD qw(parse_vcd list_sigs);
+
+$| = 1;
+
+if ($#ARGV != 1) {
+ print STDERR "\n";
+ print STDERR "VCDCD - Value Change Dump Change Dumper\n";
+ print STDERR "\n";
+ print STDERR "Usage: $0 gold.vcd gate.vcd\n";
+ print STDERR "\n";
+ print STDERR "Compare a known-good (gold) vcd file with a second (gate) vcd file.\n";
+ print STDERR "This is not very efficient -- so use with care with large vcd files.\n";
+ print STDERR "\n";
+ exit 1;
+}
+
+my $fn_gold = $ARGV[0];
+my $fn_gate = $ARGV[1];
+
+print "Finding common signals..\n";
+my @gold_signals = list_sigs($fn_gold);
+my @gate_signals = list_sigs($fn_gate);
+
+my %gold_signals_hash;
+my %gate_signals_hash;
+
+for (@gold_signals) {
+ my $fullname = $_;
+ s/(\[([0-9]+|[0-9]+:[0-9]+)\])$//;
+ $gold_signals_hash{$_}->{$fullname} = 1 unless /(^|\.)_[0-9]+_/;
+}
+
+for (@gate_signals) {
+ my $fullname = $_;
+ s/(\[([0-9]+|[0-9]+:[0-9]+)\])$//;
+ $gate_signals_hash{$_}->{$fullname} = 1 unless /(^|\.)_[0-9]+_/;
+}
+
+my @signals;
+for my $net (sort keys %gold_signals_hash) {
+ next unless exists $gate_signals_hash{$net};
+ # next unless $net eq "tst_bench_top.i2c_top.byte_controller.bit_controller.cnt";
+ my %orig_net_names;
+ print "common signal: $net";
+ for my $fullname (keys $gold_signals_hash{$net}) {
+ $orig_net_names{$fullname} = 1;
+ }
+ for my $fullname (keys $gate_signals_hash{$net}) {
+ $orig_net_names{$fullname} = 1;
+ }
+ for my $_ (sort keys %orig_net_names) {
+ push @signals, $_;
+ print " $1" if /(\[([0-9]+|[0-9]+:[0-9]+)\])$/;
+ }
+ print "\n";
+}
+
+print "Loading gold vcd data..\n";
+my $vcd_gold = parse_vcd($fn_gold, {siglist => \@signals});
+
+print "Loading gate vcd data..\n";
+my $vcd_gate = parse_vcd($fn_gate, {siglist => \@signals});
+
+# print Dumper($vcd_gold);
+# print Dumper($vcd_gate);
+
+my %times;
+my $signal_maxlen = 8;
+my $data_gold = { };
+my $data_gate = { };
+
+sub checklen($$)
+{
+ my ($net, $val) = @_;
+ my $thislen = length $val;
+ $thislen += $1 if $net =~ /\[([0-9]+)\]$/;
+ $thislen += $1 if $net =~ /\[([0-9]+):[0-9]+\]$/;
+ $signal_maxlen = $thislen if $signal_maxlen < $thislen;
+}
+
+print "Processing gold vcd data..\n";
+for my $key (keys %$vcd_gold) {
+ for my $net (@{$vcd_gold->{$key}->{'nets'}}) {
+ my $netname = $net->{'hier'} . "." . $net->{'name'};
+ for my $tv (@{$vcd_gold->{$key}->{'tv'}}) {
+ my $time = int($tv->[0]);
+ my $value = $tv->[1];
+ checklen($netname, $value);
+ $data_gold->{$time}->{$netname} = $value;
+ $times{$time} = 1;
+ }
+ }
+}
+
+print "Processing gate vcd data..\n";
+for my $key (keys %$vcd_gate) {
+ for my $net (@{$vcd_gate->{$key}->{'nets'}}) {
+ my $netname = $net->{'hier'} . "." . $net->{'name'};
+ for my $tv (@{$vcd_gate->{$key}->{'tv'}}) {
+ my $time = int($tv->[0]);
+ my $value = $tv->[1];
+ checklen($netname, $value);
+ $data_gate->{$time}->{$netname} = $value;
+ $times{$time} = 1;
+ }
+ }
+}
+
+my $diffcount = 0;
+my %state_gold;
+my %state_gate;
+my %signal_sync;
+my %touched_nets;
+
+sub set_state_bit($$$$)
+{
+ my ($state, $net, $bit, $value) = @_;
+ my @data;
+ @data = split //, $state->{$net} if exists $state->{$net};
+ unshift @data, "-" while $#data < $bit;
+ $data[$#data - $bit] = $value;
+ $state->{$net} = join "", @data;
+ $signal_sync{$net} = 1 unless exists $signal_sync{$net};
+ $touched_nets{$net} = 1;
+}
+
+sub set_state($$$)
+{
+ my ($state, $net, $value) = @_;
+
+ if ($net =~ /(.*)\[([0-9]+)\]$/) {
+ set_state_bit($state, $1, $2, $value);
+ return;
+ }
+
+ if ($net =~ /(.*)\[([0-9]+):([0-9]+)\]$/) {
+ my ($n, $u, $d) = ($1, $2, $3);
+ my @bits = split //, $value;
+ my $extbit = $bits[0] eq "1" ? "0" : $bits[0];
+ unshift @bits, $extbit while $#bits < $u - $d;
+ set_state_bit($state, $n, $u--, shift @bits) while $u >= $d;
+ return;
+ }
+
+ $state->{$net} = $value;
+ $signal_sync{$net} = 1 unless exists $signal_sync{$net};
+ $touched_nets{$net} = 1;
+}
+
+sub cmp_signal($$)
+{
+ my ($a, $b) = @_;
+ return 1 if $a eq $b;
+
+ my @a = split //, $a;
+ my @b = split //, $b;
+
+ unshift @a, "-" while $#a < $#b;
+ unshift @b, "-" while $#b < $#a;
+
+ for (my $i = 0; $i <= $#a; $i++) {
+ return 0 if $a[$i] ne "x" && $a[$i] ne $b[$i];
+ }
+
+ return 1;
+}
+
+print "Comparing vcd data..\n";
+for my $time (sort { $a <=> $b } keys %times)
+{
+ %touched_nets = ();
+ for my $net (keys %{$data_gold->{$time}}) {
+ set_state(\%state_gold, $net, $data_gold->{$time}->{$net});
+ }
+ for my $net (keys %{$data_gate->{$time}}) {
+ set_state(\%state_gate, $net, $data_gate->{$time}->{$net});
+ }
+ for my $net (sort keys %touched_nets) {
+ my ($stgo, $stga) = ('-', '-');
+ $stgo = $state_gold{$net} if exists $state_gold{$net};
+ $stga = $state_gate{$net} if exists $state_gate{$net};
+ if (cmp_signal($stgo, $stga)) {
+ next if $signal_sync{$net};
+ printf "%-10s %-20d %-*s %-*s %s\n", "<sync>", $time, $signal_maxlen, $stgo, $signal_maxlen, $stga, $net;
+ $signal_sync{$net} = 1;
+ } else {
+ printf "\n%-10s %-20s %-*s %-*s %s\n", "count", "time", $signal_maxlen, "gold", $signal_maxlen, "gate", "net" if $diffcount++ == 0;
+ printf "%-10d %-20d %-*s %-*s %s\n", $diffcount, $time, $signal_maxlen, $stgo, $signal_maxlen, $stga, $net;
+ $signal_sync{$net} = 0;
+ }
+ }
+}
+
+print "Found $diffcount differences.\n";
+exit ($diffcount > 0 ? 1 : 0);