├── .gitignore ├── .lint_rules.vlt ├── 01_combinational_logic ├── 01_01_mux_question │ ├── 01_01_mux_question.sv │ └── testbench.sv ├── 01_02_mux_if │ ├── 01_02_mux_if.sv │ └── testbench.sv ├── 01_03_mux_case │ ├── 01_03_mux_case.sv │ └── testbench.sv ├── 01_04_mux_index │ ├── 01_04_mux_index.sv │ └── testbench.sv ├── 01_05_mux_gates │ ├── 01_05_mux_gates.sv │ └── testbench.sv ├── 01_06_mux_2n_using_muxes_n │ ├── 01_06_mux_2n_using_muxes_n.sv │ └── testbench.sv ├── 01_07_mux_using_narrow_data_muxes │ ├── 01_07_mux_using_narrow_data_muxes.sv │ └── testbench.sv ├── 01_08_not_gate_using_mux │ ├── 01_08_not_gate_using_mux.sv │ └── testbench.sv ├── 01_09_and_gate_using_mux │ ├── 01_09_and_gate_using_mux.sv │ └── testbench.sv ├── 01_10_or_gate_using_mux │ ├── 01_10_or_gate_using_mux.sv │ └── testbench.sv ├── 01_11_xor_gate_using_mux │ ├── 01_11_xor_gate_using_mux.sv │ └── testbench.sv ├── README.md ├── expected_log.txt ├── lint_linux_mac.sh ├── run_linux_mac.sh └── run_windows.bat ├── 02_sequential_basics ├── 02_01_edge_and_pulse_detection │ ├── 02_01_edge_and_pulse_detection.sv │ └── testbench.sv ├── 02_02_single_and_double_rate_fibonacci │ ├── 02_02_single_and_double_rate_fibonacci.sv │ └── testbench.sv ├── 02_03_serial_adder_using_logic_operations_only │ ├── 02_03_serial_adder_using_logic_operations_only.sv │ └── testbench.sv ├── 02_04_serial_adder_with_vld │ ├── 02_04_serial_adder_with_vld.sv │ └── testbench.sv ├── 02_05_serial_comparator_most_significant_first │ ├── 02_05_serial_comparator_most_significant_first.sv │ └── testbench.sv ├── 02_06_serial_comparator_most_significant_first_using_fsm │ ├── 02_06_serial_comparator_most_significant_first_using_fsm.sv │ └── testbench.sv ├── 02_07_halve_tokens │ ├── 02_07_halve_tokens.sv │ └── testbench.sv ├── 02_08_double_tokens │ ├── 02_08_double_tokens.sv │ └── testbench.sv ├── 02_09_round_robin_arbiter_with_2_requests │ ├── 02_09_round_robin_arbiter_with_2_requests.sv │ └── testbench.sv ├── 02_10_serial_to_parallel │ ├── 02_10_serial_to_parallel.sv │ └── testbench.sv ├── README_ru.md ├── README_ru.pdf ├── expected_log.txt ├── lint_linux_mac.sh ├── run_linux_mac.sh └── run_windows.bat ├── 03_finite_state_machines ├── 03_01_detect_sequence_using_fsm │ ├── 03_01_detect_sequence_using_fsm.sv │ └── testbench.sv ├── 03_02_detect_sequence_using_shift_reg │ ├── 03_02_detect_sequence_using_shift_reg.sv │ └── testbench.sv ├── 03_03_serial_divisibility_using_fsm │ ├── 03_03_serial_divisibility_using_fsm.sv │ └── testbench.sv ├── 03_04_05_sqrt_formula_fsms │ ├── 03_04_formula_1_impl_2_fsm.sv │ ├── 03_05_formula_2_fsm.sv │ ├── formula_1_fn.svh │ ├── formula_1_impl_1_fsm.sv │ ├── formula_1_impl_1_fsm_style_2.sv │ ├── formula_1_impl_1_top.sv │ ├── formula_1_impl_2_top.sv │ ├── formula_2_fn.svh │ ├── formula_2_top.sv │ ├── gtkwave.tcl │ ├── lint_linux_mac.sh │ ├── run_linux_mac.sh │ ├── run_windows.bat │ ├── testbenches │ │ ├── formula_tb.sv │ │ ├── isqrt_fn.svh │ │ └── tb.sv │ ├── wave_linux_mac.sh │ └── wave_windows.bat ├── 03_06_sort_floats │ ├── 03_06_sort_floats.sv │ └── testbench.sv ├── 03_07_sort_floats_using_fsm │ ├── 03_07_sort_floats_using_fsm.sv │ └── testbench.sv ├── 03_08_float_discriminant │ ├── 03_08_float_discriminant.sv │ └── testbench.sv ├── README_ru.md ├── README_ru.pdf ├── lint_linux_mac.sh ├── run_linux_mac.sh ├── run_windows.bat ├── wave_linux_mac.sh └── wave_windows.bat ├── 04_arithmetics_and_pipelining ├── 04_01_signed_add_with_overflow │ ├── 04_01_signed_add_with_overflow.sv │ └── testbench.sv ├── 04_02_signed_add_with_saturation │ ├── 04_02_signed_add_with_saturation.sv │ └── testbench.sv ├── 04_03_signed_or_unsigned_mul │ ├── 04_03_signed_or_unsigned_mul.sv │ └── testbench.sv ├── 04_04_four_ways_of_doing_shift │ ├── 04_04_four_ways_of_doing_shift.sv │ └── testbench.sv ├── 04_05_circular_shifts │ ├── 04_05_circular_shifts.sv │ └── testbench.sv ├── 04_06_arithmetic_shift_or_signed_divide_by_power_of_2 │ ├── 04_06_arithmetic_shift_or_signed_divide_by_power_of_2.sv │ └── testbench.sv ├── 04_07_10_sqrt_formula_pipe │ ├── 04_07_formula_1_pipe.sv │ ├── 04_08_formula_1_pipe_aware_fsm.sv │ ├── 04_09_shift_register_with_valid.sv │ ├── 04_10_formula_2_pipe.sv │ ├── black_boxes │ │ ├── isqrt.sv │ │ ├── isqrt_slice_comb.sv │ │ └── isqrt_slice_reg.sv │ ├── formula_1_fn.svh │ ├── formula_1_pipe_aware_fsm_top.sv │ ├── formula_2_fn.svh │ ├── gtkwave.tcl │ ├── lint_linux_mac.sh │ ├── run_linux_mac.sh │ ├── run_windows.bat │ ├── testbenches │ │ ├── formula_tb.sv │ │ ├── isqrt_fn.svh │ │ ├── shift_register_with_valid_tb.sv │ │ └── tb.sv │ ├── wave_linux_mac.sh │ └── wave_windows.bat ├── 04_11_sqrt_formula_distributor │ ├── 03_04_formula_1_impl_2_fsm.sv │ ├── 03_05_formula_2_fsm.sv │ ├── 04_11_sqrt_formula_distributor.sv │ ├── diagram.pdf │ ├── formula_1_fn.svh │ ├── formula_1_impl_1_fsm.sv │ ├── formula_1_impl_1_fsm_style_2.sv │ ├── formula_1_impl_1_top.sv │ ├── formula_1_impl_2_top.sv │ ├── formula_2_fn.svh │ ├── formula_2_top.sv │ ├── gtkwave.tcl │ ├── lint_linux_mac.sh │ ├── run_linux_mac.sh │ ├── run_windows.bat │ ├── testbenches │ │ ├── formula_tb.sv │ │ ├── isqrt_fn.svh │ │ └── tb.sv │ ├── wave_linux_mac.sh │ └── wave_windows.bat ├── 04_12_float_discriminant_distributor │ ├── 03_08_float_discriminant.sv │ ├── 04_12_float_discriminant_distributor.sv │ ├── diagram.pdf │ └── testbench.sv ├── 04_13_put_in_order │ ├── 04_13_put_in_order.sv │ ├── delay_data_model.sv │ ├── diagram.pdf │ ├── testbench.sv │ ├── testbench_1.sv │ └── testbench_2.sv ├── README_ru.md ├── README_ru.pdf ├── expected_log.txt ├── lint_linux_mac.sh ├── run_linux_mac.sh └── run_windows.bat ├── 05_fifo_and_single_cycle_cpu ├── 05_01_fifo_with_counter_baseline │ ├── fifo_monitor.sv │ ├── flip_flop_fifo_with_counter.sv │ ├── gtkwave.tcl │ ├── lint_linux_mac.sh │ ├── run_linux_mac.sh │ ├── run_windows.bat │ ├── tb.sv │ ├── wave_linux_mac.sh │ └── wave_windows.bat ├── 05_02_fifo_pow2_depth │ ├── ff_fifo_pow2_depth.sv │ ├── fifo_monitor.sv │ ├── gtkwave.tcl │ ├── lint_linux_mac.sh │ ├── run_linux_mac.sh │ ├── run_windows.bat │ ├── tb.sv │ ├── wave_linux_mac.sh │ └── wave_windows.bat ├── 05_03_fifo_empty_full_optimized │ ├── fifo_monitor.sv │ ├── flip_flop_fifo_empty_full_optimized.sv │ ├── gtkwave.tcl │ ├── lint_linux_mac.sh │ ├── run_linux_mac.sh │ ├── run_windows.bat │ ├── tb.sv │ ├── wave_linux_mac.sh │ └── wave_windows.bat ├── 05_04_fifo_with_reg_empty_full │ ├── ff_fifo_with_reg_empty_full.sv │ ├── fifo_monitor.sv │ ├── gtkwave.tcl │ ├── lint_linux_mac.sh │ ├── run_linux_mac.sh │ ├── run_windows.bat │ ├── tb.sv │ ├── wave_linux_mac.sh │ └── wave_windows.bat ├── 05_05_1_a_plus_b_using_double_buffers │ ├── a_plus_b_using_double_buffers.sv │ ├── double_buffer_from_dally_harting.sv │ ├── run_linux_mac.sh │ ├── run_windows.bat │ ├── tb.sv │ └── wave_windows.bat ├── 05_05_2_a_plus_b_using_fifos │ ├── a_plus_b_using_fifos.sv │ ├── ff_fifo_wrapped_in_valid_ready.sv │ ├── flip_flop_fifo.sv │ ├── run_linux_mac.sh │ ├── run_windows.bat │ ├── tb.sv │ └── wave_windows.bat ├── 05_05_a_plus_b_using_fifos_and_double_buffer │ ├── a_plus_b_using_fifos_and_double_buffer.sv │ ├── double_buffer_from_dally_harting.sv │ ├── flip_flop_fifo_with_counter.sv │ ├── lint_linux_mac.sh │ ├── run_linux_mac.sh │ ├── run_windows.bat │ ├── tb.sv │ ├── wave_linux_mac.sh │ └── wave_windows.bat ├── 05_06_sqrt_formula_pipe │ ├── 04_07_formula_1_pipe.sv │ ├── 04_08_formula_1_pipe_aware_fsm.sv │ ├── 04_09_shift_register_with_valid.sv │ ├── 04_10_formula_2_pipe.sv │ ├── 05_06_formula_2_pipe_using_fifos.sv │ ├── black_boxes │ │ ├── isqrt.sv │ │ ├── isqrt_slice_comb.sv │ │ └── isqrt_slice_reg.sv │ ├── flip_flop_fifo_with_counter.sv │ ├── formula_1_fn.svh │ ├── formula_1_pipe_aware_fsm_top.sv │ ├── formula_2_fn.svh │ ├── gtkwave.tcl │ ├── lint_linux_mac.sh │ ├── run_linux_mac.sh │ ├── run_windows.bat │ ├── testbenches │ │ ├── formula_tb.sv │ │ ├── isqrt_fn.svh │ │ ├── shift_register_with_valid_tb.sv │ │ └── tb.sv │ ├── wave_linux_mac.sh │ └── wave_windows.bat ├── 05_07_cpu_baseline │ ├── gtkwave.tcl │ ├── instruction_rom.sv │ ├── lint_linux_mac.sh │ ├── program.s │ ├── register_with_rst.sv │ ├── run_linux_mac.sh │ ├── run_rars_linux_mac.sh │ ├── run_rars_windows.bat │ ├── run_windows.bat │ ├── sr_alu.sv │ ├── sr_control.sv │ ├── sr_cpu.sv │ ├── sr_cpu.svh │ ├── sr_decode.sv │ ├── sr_register_file.sv │ ├── tb.sv │ ├── wave_linux_mac.sh │ └── wave_windows.bat ├── 05_08_cpu_with_comb_mul_instr │ ├── gtkwave.tcl │ ├── instruction_rom.sv │ ├── lint_linux_mac.sh │ ├── program.s │ ├── register_with_rst.sv │ ├── run_linux_mac.sh │ ├── run_rars_linux_mac.sh │ ├── run_rars_windows.bat │ ├── run_windows.bat │ ├── sr_alu.sv │ ├── sr_control.sv │ ├── sr_cpu.sv │ ├── sr_cpu.svh │ ├── sr_decode.sv │ ├── sr_register_file.sv │ ├── tb.sv │ ├── wave_linux_mac.sh │ └── wave_windows.bat ├── 05_09_cpu_mul_with_latency │ ├── gtkwave.tcl │ ├── instruction_rom.sv │ ├── lint_linux_mac.sh │ ├── program.s │ ├── register_with_rst_and_en.sv │ ├── run_linux_mac.sh │ ├── run_rars_linux_mac.sh │ ├── run_rars_windows.bat │ ├── run_windows.bat │ ├── sr_alu.sv │ ├── sr_control.sv │ ├── sr_cpu.sv │ ├── sr_cpu.svh │ ├── sr_decode.sv │ ├── sr_mdu.sv │ ├── sr_register_file.sv │ ├── tb.sv │ ├── wave_linux_mac.sh │ └── wave_windows.bat ├── 05_10_cpu_with_b_instr │ ├── gtkwave.tcl │ ├── instruction_rom.sv │ ├── lint_linux_mac.sh │ ├── program.s │ ├── register_with_rst.sv │ ├── run_linux_mac.sh │ ├── run_rars_linux_mac.sh │ ├── run_rars_windows.bat │ ├── run_windows.bat │ ├── sr_alu.sv │ ├── sr_control.sv │ ├── sr_cpu.sv │ ├── sr_cpu.svh │ ├── sr_decode.sv │ ├── sr_register_file.sv │ ├── tb.sv │ ├── wave_linux_mac.sh │ └── wave_windows.bat ├── 05_11_cpu_fetch_with_latency │ ├── gtkwave.tcl │ ├── instruction_rom.sv │ ├── lint_linux_mac.sh │ ├── program.s │ ├── register_with_rst_and_en.sv │ ├── run_linux_mac.sh │ ├── run_rars_linux_mac.sh │ ├── run_rars_windows.bat │ ├── run_windows.bat │ ├── sr_alu.sv │ ├── sr_control.sv │ ├── sr_cpu.sv │ ├── sr_cpu.svh │ ├── sr_decode.sv │ ├── sr_register_file.sv │ ├── tb.sv │ ├── wave_linux_mac.sh │ └── wave_windows.bat ├── 05_12_three_cpus_sharing_instr_memory │ ├── cpu_cluster.sv │ ├── gtkwave.tcl │ ├── instruction_rom.sv │ ├── lint_linux_mac.sh │ ├── program.s │ ├── register_with_rst_value_and_enable.sv │ ├── round_robin_arbiter_8.sv │ ├── run_linux_mac.sh │ ├── run_rars_linux_mac.sh │ ├── run_rars_windows.bat │ ├── run_windows.bat │ ├── sr_alu.sv │ ├── sr_control.sv │ ├── sr_cpu.sv │ ├── sr_cpu.svh │ ├── sr_decode.sv │ ├── sr_register_file.sv │ ├── tb.sv │ ├── wave_linux_mac.sh │ └── wave_windows.bat ├── README.md ├── README.pdf ├── README_ru.md ├── README_ru.pdf ├── run_linux_mac.sh └── run_windows.bat ├── 06_cache ├── 06_1_testing_cache_patterson_hennessy │ ├── cache_def_pkg.sv │ ├── dm_cache_data.sv │ ├── dm_cache_fsm.sv │ ├── dm_cache_tag.sv │ ├── main_memory_model.sv │ ├── runme.sh │ └── testbench.sv ├── lint_linux_mac.sh ├── run_linux_mac.sh └── run_windows.bat ├── 10_exam └── 1_sharada_yeluri_challenge │ └── sharada_yeluri_challenge.sv ├── LICENSE ├── README.md ├── README.pdf ├── README_ru.md ├── bin └── rars1_6.jar ├── common ├── isqrt │ ├── isqrt.sv │ ├── isqrt_slice_comb.sv │ └── isqrt_slice_reg.sv ├── util.svh └── wally_fpu │ ├── f_add.sv │ ├── f_div.sv │ ├── f_fpu_tb.sv │ ├── f_less_or_equal.sv │ ├── f_less_or_equal_tb.sv │ ├── f_mult.sv │ ├── f_sqrt.sv │ ├── f_sub.sv │ ├── test_fpu.sh │ └── wally_fpu.sv ├── doc ├── discriminant │ ├── discriminant_fsm.jpg │ ├── discriminant_fsm.wave │ ├── discriminant_fsm.wave.png │ ├── discriminant_pipeline.wave │ ├── discriminant_pipeline.wave.png │ ├── discriminant_pipeline_fifo.jpg │ └── discriminant_pipeline_shift_register.jpg ├── homework2 │ ├── 02_07_01_halve_tokens.png │ ├── 02_07_01_halve_tokens.wave │ ├── 02_08_01_double_tokens.png │ ├── 02_08_01_double_tokens.wave │ ├── 02_09_01_rr_arbiter_2_req.png │ ├── 02_09_01_rr_arbiter_2_req.wave │ ├── 02_10_01_serial_to_parallel.png │ ├── 02_10_01_serial_to_parallel.wave │ ├── 02_10_01_serial_to_parallel_with_combinational_output.png │ └── 02_10_01_serial_to_parallel_with_registered_output.png ├── homework4 │ ├── 04_11_fix_latency.json │ ├── 04_11_fix_latency.png │ ├── 04_11_fix_latency_wave.png │ ├── 4_13_home_work_diagram.png │ └── 4_13_wave.png ├── isqrt │ ├── 01_isqrt.png │ ├── 01_isqrt.wave │ ├── 01_isqrt.wave.png │ ├── 01_isqrt_alt.png │ ├── 02_fa_fb_fc_3.png │ ├── 02_fa_fb_fc_3.wave │ ├── 02_fa_fb_fc_3.wave.png │ ├── 03_fsm_1.png │ ├── 03_fsm_1.vcd.png │ ├── 04_fsm_2.png │ ├── 05_f_a_f_b_fc_incorrect.png │ ├── 06_shift_reg.png │ ├── 06_shift_reg_alt.png │ ├── 07_f_a_f_b_fc_pipe.png │ ├── 08_f_a_f_b_fc_pipe_with_fifo.png │ └── 09_valid_ready_wide.wave └── quadratic │ ├── 01_parts.png │ ├── 02_quadratic_equation.png │ ├── 03_quadratic_equation_valid_ready.png │ └── 04_quadratic_equation_individual_valid_ready.png └── scripts ├── run_linux_mac.sh ├── run_rars_linux_mac.sh ├── run_rars_windows.bat └── run_windows.bat /.gitignore: -------------------------------------------------------------------------------- 1 | import/ 2 | *.hex 3 | sim.out 4 | dump*.vcd 5 | log.txt 6 | lint.txt 7 | -------------------------------------------------------------------------------- /.lint_rules.vlt: -------------------------------------------------------------------------------- 1 | `verilator_config 2 | 3 | lint_off -rule DECLFILENAME 4 | lint_off -rule INITIALDLY 5 | lint_off -file "*/common/wally_fpu/*" 6 | lint_off -file "*/import/preprocessed/cvw/*" 7 | -------------------------------------------------------------------------------- /01_combinational_logic/01_01_mux_question/01_01_mux_question.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Example 3 | //---------------------------------------------------------------------------- 4 | 5 | module mux_2_1 6 | ( 7 | input [3:0] d0, d1, 8 | input sel, 9 | output [3:0] y 10 | ); 11 | 12 | assign y = sel ? d1 : d0; 13 | 14 | endmodule 15 | 16 | //---------------------------------------------------------------------------- 17 | // Task 18 | //---------------------------------------------------------------------------- 19 | 20 | module mux_4_1 21 | ( 22 | input [3:0] d0, d1, d2, d3, 23 | input [1:0] sel, 24 | output [3:0] y 25 | ); 26 | 27 | // Task: 28 | // Using code for mux_2_1 as an example, 29 | // write code for 4:1 mux using "?:" operator 30 | 31 | 32 | endmodule 33 | -------------------------------------------------------------------------------- /01_combinational_logic/01_01_mux_question/testbench.sv: -------------------------------------------------------------------------------- 1 | `include "util.svh" 2 | 3 | module testbench; 4 | 5 | logic [3:0] d0, d1, d2, d3; 6 | logic [1:0] sel; 7 | logic [3:0] y; 8 | 9 | mux_4_1 inst 10 | ( 11 | .d0 (d0), .d1 (d1), .d2 (d2), .d3 (d3), 12 | .sel (sel), 13 | .y (y) 14 | ); 15 | 16 | task test 17 | ( 18 | input [3:0] td0, td1, td2, td3, 19 | input [1:0] tsel, 20 | input [3:0] ty 21 | ); 22 | 23 | { d0, d1, d2, d3, sel } = { td0, td1, td2, td3, tsel }; 24 | 25 | # 1; 26 | 27 | if (y !== ty) 28 | begin 29 | $display("FAIL %s", `__FILE__); 30 | $display("++ INPUT => {%s, %s, %s, %s, %s}", `PH(d0), `PH(d1), `PH(d2), `PH(d3), `PH(sel)); 31 | $display("++ EXPECTED => {%s}", `PH(ty)); 32 | $display("++ ACTUAL => {%s}", `PH(y)); 33 | $finish(1); 34 | end 35 | 36 | endtask 37 | 38 | initial 39 | begin 40 | test ('ha, 'hb, 'hc, 'hd, 0, 'ha); 41 | test ('ha, 'hb, 'hc, 'hd, 1, 'hb); 42 | test ('ha, 'hb, 'hc, 'hd, 2, 'hc); 43 | test ('ha, 'hb, 'hc, 'hd, 3, 'hd); 44 | 45 | test (7, 10, 3, 'x, 0, 7); 46 | test (7, 10, 3, 'x, 1, 10); 47 | test (7, 10, 3, 'x, 2, 3); 48 | test (7, 10, 3, 'x, 3, 'x); 49 | 50 | $display ("PASS %s", `__FILE__); 51 | $finish; 52 | end 53 | 54 | endmodule 55 | -------------------------------------------------------------------------------- /01_combinational_logic/01_02_mux_if/01_02_mux_if.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Example 3 | //---------------------------------------------------------------------------- 4 | 5 | module mux_2_1 6 | ( 7 | input [3:0] d0, d1, 8 | input sel, 9 | output logic [3:0] y 10 | ); 11 | 12 | always_comb 13 | if (sel) 14 | y = d1; 15 | else 16 | y = d0; 17 | 18 | endmodule 19 | 20 | //---------------------------------------------------------------------------- 21 | // Task 22 | //---------------------------------------------------------------------------- 23 | 24 | module mux_4_1 25 | ( 26 | input [3:0] d0, d1, d2, d3, 27 | input [1:0] sel, 28 | output logic [3:0] y 29 | ); 30 | 31 | // Task: 32 | // Using code for mux_2_1 as an example, 33 | // write code for 4:1 mux using the "if" statement 34 | 35 | 36 | endmodule 37 | -------------------------------------------------------------------------------- /01_combinational_logic/01_02_mux_if/testbench.sv: -------------------------------------------------------------------------------- 1 | `include "util.svh" 2 | 3 | module testbench; 4 | 5 | logic [3:0] d0, d1, d2, d3; 6 | logic [1:0] sel; 7 | logic [3:0] y; 8 | 9 | mux_4_1 inst 10 | ( 11 | .d0 (d0), .d1 (d1), .d2 (d2), .d3 (d3), 12 | .sel (sel), 13 | .y (y) 14 | ); 15 | 16 | task test 17 | ( 18 | input [3:0] td0, td1, td2, td3, 19 | input [1:0] tsel, 20 | input [3:0] ty 21 | ); 22 | 23 | { d0, d1, d2, d3, sel } = { td0, td1, td2, td3, tsel }; 24 | 25 | # 1; 26 | 27 | if (y !== ty) 28 | begin 29 | $display("FAIL %s", `__FILE__); 30 | $display("++ INPUT => {%s, %s, %s, %s, %s}", `PH(d0), `PH(d1), `PH(d2), `PH(d3), `PH(sel)); 31 | $display("++ EXPECTED => {%s}", `PH(ty)); 32 | $display("++ ACTUAL => {%s}", `PH(y)); 33 | $finish(1); 34 | end 35 | 36 | endtask 37 | 38 | initial 39 | begin 40 | test ('ha, 'hb, 'hc, 'hd, 0, 'ha); 41 | test ('ha, 'hb, 'hc, 'hd, 1, 'hb); 42 | test ('ha, 'hb, 'hc, 'hd, 2, 'hc); 43 | test ('ha, 'hb, 'hc, 'hd, 3, 'hd); 44 | 45 | test (7, 10, 3, 'x, 0, 7); 46 | test (7, 10, 3, 'x, 1, 10); 47 | test (7, 10, 3, 'x, 2, 3); 48 | test (7, 10, 3, 'x, 3, 'x); 49 | 50 | $display ("PASS %s", `__FILE__); 51 | $finish; 52 | end 53 | 54 | endmodule 55 | -------------------------------------------------------------------------------- /01_combinational_logic/01_03_mux_case/01_03_mux_case.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Example 3 | //---------------------------------------------------------------------------- 4 | 5 | module mux_2_1 6 | ( 7 | input [3:0] d0, d1, 8 | input sel, 9 | output logic [3:0] y 10 | ); 11 | 12 | always_comb 13 | case (sel) 14 | 1'd0: y = d0; 15 | 1'd1: y = d1; 16 | endcase 17 | 18 | endmodule 19 | 20 | //---------------------------------------------------------------------------- 21 | // Task 22 | //---------------------------------------------------------------------------- 23 | 24 | module mux_4_1 25 | ( 26 | input [3:0] d0, d1, d2, d3, 27 | input [1:0] sel, 28 | output logic [3:0] y 29 | ); 30 | 31 | // Task: 32 | // Using code for mux_2_1 as an example, 33 | // write code for 4:1 mux using the "case" statement 34 | 35 | 36 | endmodule 37 | -------------------------------------------------------------------------------- /01_combinational_logic/01_03_mux_case/testbench.sv: -------------------------------------------------------------------------------- 1 | `include "util.svh" 2 | 3 | module testbench; 4 | 5 | logic [3:0] d0, d1, d2, d3; 6 | logic [1:0] sel; 7 | logic [3:0] y; 8 | 9 | mux_4_1 inst 10 | ( 11 | .d0 (d0), .d1 (d1), .d2 (d2), .d3 (d3), 12 | .sel (sel), 13 | .y (y) 14 | ); 15 | 16 | task test 17 | ( 18 | input [3:0] td0, td1, td2, td3, 19 | input [1:0] tsel, 20 | input [3:0] ty 21 | ); 22 | 23 | { d0, d1, d2, d3, sel } = { td0, td1, td2, td3, tsel }; 24 | 25 | # 1; 26 | 27 | if (y !== ty) 28 | begin 29 | $display("FAIL %s", `__FILE__); 30 | $display("++ INPUT => {%s, %s, %s, %s, %s}", `PH(d0), `PH(d1), `PH(d2), `PH(d3), `PH(sel)); 31 | $display("++ EXPECTED => {%s}", `PH(ty)); 32 | $display("++ ACTUAL => {%s}", `PH(y)); 33 | $finish(1); 34 | end 35 | 36 | endtask 37 | 38 | initial 39 | begin 40 | test ('ha, 'hb, 'hc, 'hd, 0, 'ha); 41 | test ('ha, 'hb, 'hc, 'hd, 1, 'hb); 42 | test ('ha, 'hb, 'hc, 'hd, 2, 'hc); 43 | test ('ha, 'hb, 'hc, 'hd, 3, 'hd); 44 | 45 | test (7, 10, 3, 'x, 0, 7); 46 | test (7, 10, 3, 'x, 1, 10); 47 | test (7, 10, 3, 'x, 2, 3); 48 | test (7, 10, 3, 'x, 3, 'x); 49 | 50 | $display ("PASS %s", `__FILE__); 51 | $finish; 52 | end 53 | 54 | endmodule 55 | -------------------------------------------------------------------------------- /01_combinational_logic/01_04_mux_index/01_04_mux_index.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Example 3 | //---------------------------------------------------------------------------- 4 | 5 | module mux_2_1 6 | ( 7 | input [3:0] d0, d1, 8 | input sel, 9 | output [3:0] y 10 | ); 11 | 12 | logic [3:0] d [0:1]; 13 | 14 | assign d [0] = d0; 15 | assign d [1] = d1; 16 | 17 | assign y = d [sel]; 18 | 19 | endmodule 20 | 21 | //---------------------------------------------------------------------------- 22 | // Task 23 | //---------------------------------------------------------------------------- 24 | 25 | module mux_4_1 26 | ( 27 | input [3:0] d0, d1, d2, d3, 28 | input [1:0] sel, 29 | output [3:0] y 30 | ); 31 | 32 | // Task: 33 | // Using code for mux_2_1 as an example, 34 | // write code for 4:1 mux using array index 35 | 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /01_combinational_logic/01_04_mux_index/testbench.sv: -------------------------------------------------------------------------------- 1 | `include "util.svh" 2 | 3 | module testbench; 4 | 5 | logic [3:0] d0, d1, d2, d3; 6 | logic [1:0] sel; 7 | logic [3:0] y; 8 | 9 | mux_4_1 inst 10 | ( 11 | .d0 (d0), .d1 (d1), .d2 (d2), .d3 (d3), 12 | .sel (sel), 13 | .y (y) 14 | ); 15 | 16 | task test 17 | ( 18 | input [3:0] td0, td1, td2, td3, 19 | input [1:0] tsel, 20 | input [3:0] ty 21 | ); 22 | 23 | { d0, d1, d2, d3, sel } = { td0, td1, td2, td3, tsel }; 24 | 25 | # 1; 26 | 27 | if (y !== ty) 28 | begin 29 | $display("FAIL %s", `__FILE__); 30 | $display("++ INPUT => {%s, %s, %s, %s, %s}", `PH(d0), `PH(d1), `PH(d2), `PH(d3), `PH(sel)); 31 | $display("++ EXPECTED => {%s}", `PH(ty)); 32 | $display("++ ACTUAL => {%s}", `PH(y)); 33 | $finish(1); 34 | end 35 | 36 | endtask 37 | 38 | initial 39 | begin 40 | test ('ha, 'hb, 'hc, 'hd, 0, 'ha); 41 | test ('ha, 'hb, 'hc, 'hd, 1, 'hb); 42 | test ('ha, 'hb, 'hc, 'hd, 2, 'hc); 43 | test ('ha, 'hb, 'hc, 'hd, 3, 'hd); 44 | 45 | test (7, 10, 3, 'x, 0, 7); 46 | test (7, 10, 3, 'x, 1, 10); 47 | test (7, 10, 3, 'x, 2, 3); 48 | test (7, 10, 3, 'x, 3, 'x); 49 | 50 | $display ("PASS %s", `__FILE__); 51 | $finish; 52 | end 53 | 54 | endmodule 55 | -------------------------------------------------------------------------------- /01_combinational_logic/01_05_mux_gates/testbench.sv: -------------------------------------------------------------------------------- 1 | `include "util.svh" 2 | 3 | module testbench; 4 | 5 | logic [3:0] d0, d1, d2, d3; 6 | logic [1:0] sel; 7 | logic [3:0] y; 8 | 9 | mux_4_1 inst 10 | ( 11 | .d0 (d0), .d1 (d1), .d2 (d2), .d3 (d3), 12 | .sel (sel), 13 | .y (y) 14 | ); 15 | 16 | task test 17 | ( 18 | input [3:0] td0, td1, td2, td3, 19 | input [1:0] tsel, 20 | input [3:0] ty 21 | ); 22 | 23 | { d0, d1, d2, d3, sel } = { td0, td1, td2, td3, tsel }; 24 | 25 | # 1; 26 | 27 | if (y !== ty) 28 | begin 29 | $display("FAIL %s", `__FILE__); 30 | $display("++ INPUT => {%s, %s, %s, %s, %s}", `PH(d0), `PH(d1), `PH(d2), `PH(d3), `PH(sel)); 31 | $display("++ EXPECTED => {%s}", `PH(ty)); 32 | $display("++ ACTUAL => {%s}", `PH(y)); 33 | $finish(1); 34 | end 35 | 36 | endtask 37 | 38 | initial 39 | begin 40 | test ('ha, 'hb, 'hc, 'hd, 0, 'ha); 41 | test ('ha, 'hb, 'hc, 'hd, 1, 'hb); 42 | test ('ha, 'hb, 'hc, 'hd, 2, 'hc); 43 | test ('ha, 'hb, 'hc, 'hd, 3, 'hd); 44 | 45 | test (7, 10, 3, 'x, 0, 7); 46 | test (7, 10, 3, 'x, 1, 10); 47 | test (7, 10, 3, 'x, 2, 3); 48 | test (7, 10, 3, 'x, 3, 'x); 49 | 50 | $display ("PASS %s", `__FILE__); 51 | $finish; 52 | end 53 | 54 | endmodule 55 | -------------------------------------------------------------------------------- /01_combinational_logic/01_06_mux_2n_using_muxes_n/01_06_mux_2n_using_muxes_n.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Example 3 | //---------------------------------------------------------------------------- 4 | 5 | module mux_2_1 6 | ( 7 | input [3:0] d0, d1, 8 | input sel, 9 | output [3:0] y 10 | ); 11 | 12 | assign y = sel ? d1 : d0; 13 | 14 | endmodule 15 | 16 | //---------------------------------------------------------------------------- 17 | // Task 18 | //---------------------------------------------------------------------------- 19 | 20 | module mux_4_1 21 | ( 22 | input [3:0] d0, d1, d2, d3, 23 | input [1:0] sel, 24 | output [3:0] y 25 | ); 26 | 27 | // Task: 28 | // Implement mux_4_1 using three instances of mux_2_1 29 | 30 | 31 | endmodule 32 | -------------------------------------------------------------------------------- /01_combinational_logic/01_06_mux_2n_using_muxes_n/testbench.sv: -------------------------------------------------------------------------------- 1 | `include "util.svh" 2 | 3 | module testbench; 4 | 5 | logic [3:0] d0, d1, d2, d3; 6 | logic [1:0] sel; 7 | logic [3:0] y; 8 | 9 | mux_4_1 inst 10 | ( 11 | .d0 (d0), .d1 (d1), .d2 (d2), .d3 (d3), 12 | .sel (sel), 13 | .y (y) 14 | ); 15 | 16 | task test 17 | ( 18 | input [3:0] td0, td1, td2, td3, 19 | input [1:0] tsel, 20 | input [3:0] ty 21 | ); 22 | 23 | { d0, d1, d2, d3, sel } = { td0, td1, td2, td3, tsel }; 24 | 25 | # 1; 26 | 27 | if (y !== ty) 28 | begin 29 | $display("FAIL %s", `__FILE__); 30 | $display("++ INPUT => {%s, %s, %s, %s, %s}", `PH(d0), `PH(d1), `PH(d2), `PH(d3), `PH(sel)); 31 | $display("++ EXPECTED => {%s}", `PH(ty)); 32 | $display("++ ACTUAL => {%s}", `PH(y)); 33 | $finish(1); 34 | end 35 | 36 | endtask 37 | 38 | initial 39 | begin 40 | test ('ha, 'hb, 'hc, 'hd, 0, 'ha); 41 | test ('ha, 'hb, 'hc, 'hd, 1, 'hb); 42 | test ('ha, 'hb, 'hc, 'hd, 2, 'hc); 43 | test ('ha, 'hb, 'hc, 'hd, 3, 'hd); 44 | 45 | test (7, 10, 3, 'x, 0, 7); 46 | test (7, 10, 3, 'x, 1, 10); 47 | test (7, 10, 3, 'x, 2, 3); 48 | test (7, 10, 3, 'x, 3, 'x); 49 | 50 | $display ("PASS %s", `__FILE__); 51 | $finish; 52 | end 53 | 54 | endmodule 55 | -------------------------------------------------------------------------------- /01_combinational_logic/01_07_mux_using_narrow_data_muxes/01_07_mux_using_narrow_data_muxes.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Example 3 | //---------------------------------------------------------------------------- 4 | 5 | module mux_4_1_width_2 6 | ( 7 | input [1:0] d0, d1, d2, d3, 8 | input [1:0] sel, 9 | output [1:0] y 10 | ); 11 | 12 | assign y = sel [1] ? (sel [0] ? d3 : d2) 13 | : (sel [0] ? d1 : d0); 14 | 15 | endmodule 16 | 17 | //---------------------------------------------------------------------------- 18 | // Task 19 | //---------------------------------------------------------------------------- 20 | 21 | module mux_4_1 22 | ( 23 | input [3:0] d0, d1, d2, d3, 24 | input [1:0] sel, 25 | output [3:0] y 26 | ); 27 | 28 | // Task: 29 | // Implement mux_4_1 with 4-bit data 30 | // using two instances of mux_4_1_width_2 with 2-bit data 31 | 32 | 33 | endmodule 34 | -------------------------------------------------------------------------------- /01_combinational_logic/01_07_mux_using_narrow_data_muxes/testbench.sv: -------------------------------------------------------------------------------- 1 | `include "util.svh" 2 | 3 | module testbench; 4 | 5 | logic [3:0] d0, d1, d2, d3; 6 | logic [1:0] sel; 7 | logic [3:0] y; 8 | 9 | mux_4_1 inst 10 | ( 11 | .d0 (d0), .d1 (d1), .d2 (d2), .d3 (d3), 12 | .sel (sel), 13 | .y (y) 14 | ); 15 | 16 | task test 17 | ( 18 | input [3:0] td0, td1, td2, td3, 19 | input [1:0] tsel, 20 | input [3:0] ty 21 | ); 22 | 23 | { d0, d1, d2, d3, sel } = { td0, td1, td2, td3, tsel }; 24 | 25 | # 1; 26 | 27 | if (y !== ty) 28 | begin 29 | $display("FAIL %s", `__FILE__); 30 | $display("++ INPUT => {%s, %s, %s, %s, %s}", `PH(d0), `PH(d1), `PH(d2), `PH(d3), `PH(sel)); 31 | $display("++ EXPECTED => {%s}", `PH(ty)); 32 | $display("++ ACTUAL => {%s}", `PH(y)); 33 | $finish(1); 34 | end 35 | 36 | endtask 37 | 38 | initial 39 | begin 40 | test ('ha, 'hb, 'hc, 'hd, 0, 'ha); 41 | test ('ha, 'hb, 'hc, 'hd, 1, 'hb); 42 | test ('ha, 'hb, 'hc, 'hd, 2, 'hc); 43 | test ('ha, 'hb, 'hc, 'hd, 3, 'hd); 44 | 45 | test (7, 10, 3, 'x, 0, 7); 46 | test (7, 10, 3, 'x, 1, 10); 47 | test (7, 10, 3, 'x, 2, 3); 48 | test (7, 10, 3, 'x, 3, 'x); 49 | 50 | $display ("PASS %s", `__FILE__); 51 | $finish; 52 | end 53 | 54 | endmodule 55 | -------------------------------------------------------------------------------- /01_combinational_logic/01_08_not_gate_using_mux/01_08_not_gate_using_mux.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Example 3 | //---------------------------------------------------------------------------- 4 | 5 | module mux 6 | ( 7 | input d0, d1, 8 | input sel, 9 | output y 10 | ); 11 | 12 | assign y = sel ? d1 : d0; 13 | 14 | endmodule 15 | 16 | //---------------------------------------------------------------------------- 17 | // Task 18 | //---------------------------------------------------------------------------- 19 | 20 | module not_gate_using_mux 21 | ( 22 | input i, 23 | output o 24 | ); 25 | 26 | // Task: 27 | // Implement not gate using instance(s) of mux, 28 | // constants 0 and 1, and wire connections 29 | 30 | 31 | endmodule 32 | -------------------------------------------------------------------------------- /01_combinational_logic/01_08_not_gate_using_mux/testbench.sv: -------------------------------------------------------------------------------- 1 | `include "util.svh" 2 | 3 | module testbench; 4 | 5 | logic a, o; 6 | int i; 7 | 8 | not_gate_using_mux inst (a, o); 9 | 10 | initial 11 | begin 12 | for (i = 0; i <= 1; i++) 13 | begin 14 | a = 1' (i); 15 | 16 | # 1; 17 | 18 | if (o !== ~ a) 19 | begin 20 | $display("FAIL %s", `__FILE__); 21 | $display("++ INPUT => {%s, %s}", `PH(a), `PH(i)); 22 | $display("++ EXPECTED => {%s}", `PH(~a)); 23 | $display("++ ACTUAL => {%s}", `PH(o)); 24 | $finish(1); 25 | end 26 | end 27 | 28 | $display ("PASS %s", `__FILE__); 29 | $finish; 30 | end 31 | 32 | endmodule 33 | -------------------------------------------------------------------------------- /01_combinational_logic/01_09_and_gate_using_mux/01_09_and_gate_using_mux.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Example 3 | //---------------------------------------------------------------------------- 4 | 5 | module mux 6 | ( 7 | input d0, d1, 8 | input sel, 9 | output y 10 | ); 11 | 12 | assign y = sel ? d1 : d0; 13 | 14 | endmodule 15 | 16 | //---------------------------------------------------------------------------- 17 | // Task 18 | //---------------------------------------------------------------------------- 19 | 20 | module and_gate_using_mux 21 | ( 22 | input a, 23 | input b, 24 | output o 25 | ); 26 | 27 | // Task: 28 | // Implement and gate using instance(s) of mux, 29 | // constants 0 and 1, and wire connections 30 | 31 | 32 | endmodule 33 | -------------------------------------------------------------------------------- /01_combinational_logic/01_09_and_gate_using_mux/testbench.sv: -------------------------------------------------------------------------------- 1 | `include "util.svh" 2 | 3 | module testbench; 4 | 5 | logic a, b, o; 6 | int i, j; 7 | 8 | and_gate_using_mux inst (a, b, o); 9 | 10 | initial 11 | begin 12 | for (i = 0; i <= 1; i++) 13 | for (j = 0; j <= 1; j++) 14 | begin 15 | a = 1' (i); 16 | b = 1' (j); 17 | 18 | # 1; 19 | 20 | if (o !== (a & b)) 21 | begin 22 | $display("FAIL %s", `__FILE__); 23 | $display("++ INPUT => {%s, %s, %s, %s}", `PH(a), `PH(b), `PH(i), `PH(j)); 24 | $display("++ EXPECTED => {%s}", `PH(a&b)); 25 | $display("++ ACTUAL => {%s}", `PH(o)); 26 | $finish(1); 27 | end 28 | end 29 | 30 | $display ("PASS %s", `__FILE__); 31 | $finish; 32 | end 33 | 34 | endmodule 35 | -------------------------------------------------------------------------------- /01_combinational_logic/01_10_or_gate_using_mux/01_10_or_gate_using_mux.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Example 3 | //---------------------------------------------------------------------------- 4 | 5 | module mux 6 | ( 7 | input d0, d1, 8 | input sel, 9 | output y 10 | ); 11 | 12 | assign y = sel ? d1 : d0; 13 | 14 | endmodule 15 | 16 | //---------------------------------------------------------------------------- 17 | // Task 18 | //---------------------------------------------------------------------------- 19 | 20 | module or_gate_using_mux 21 | ( 22 | input a, 23 | input b, 24 | output o 25 | ); 26 | 27 | // Task: 28 | 29 | // Implement or gate using instance(s) of mux, 30 | // constants 0 and 1, and wire connections 31 | 32 | 33 | endmodule 34 | -------------------------------------------------------------------------------- /01_combinational_logic/01_10_or_gate_using_mux/testbench.sv: -------------------------------------------------------------------------------- 1 | `include "util.svh" 2 | 3 | module testbench; 4 | 5 | logic a, b, o; 6 | int i, j; 7 | 8 | or_gate_using_mux inst (a, b, o); 9 | 10 | initial 11 | begin 12 | for (i = 0; i <= 1; i++) 13 | for (j = 0; j <= 1; j++) 14 | begin 15 | a = 1' (i); 16 | b = 1' (j); 17 | 18 | # 1; 19 | 20 | if (o !== (a | b)) 21 | begin 22 | $display("FAIL %s", `__FILE__); 23 | $display("++ INPUT => {%s, %s, %s, %s}", `PH(a), `PH(b), `PH(i), `PH(j)); 24 | $display("++ EXPECTED => {%s}", `PH(a|b)); 25 | $display("++ ACTUAL => {%s}", `PH(o)); 26 | $finish(1); 27 | end 28 | end 29 | 30 | $display ("PASS %s", `__FILE__); 31 | $finish; 32 | end 33 | 34 | endmodule 35 | -------------------------------------------------------------------------------- /01_combinational_logic/01_11_xor_gate_using_mux/01_11_xor_gate_using_mux.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Example 3 | //---------------------------------------------------------------------------- 4 | 5 | module mux 6 | ( 7 | input d0, d1, 8 | input sel, 9 | output y 10 | ); 11 | 12 | assign y = sel ? d1 : d0; 13 | 14 | endmodule 15 | 16 | //---------------------------------------------------------------------------- 17 | // Task 18 | //---------------------------------------------------------------------------- 19 | 20 | module xor_gate_using_mux 21 | ( 22 | input a, 23 | input b, 24 | output o 25 | ); 26 | 27 | // Task: 28 | // Implement xor gate using instance(s) of mux, 29 | // constants 0 and 1, and wire connections 30 | 31 | 32 | endmodule 33 | -------------------------------------------------------------------------------- /01_combinational_logic/01_11_xor_gate_using_mux/testbench.sv: -------------------------------------------------------------------------------- 1 | `include "util.svh" 2 | 3 | module testbench; 4 | 5 | logic a, b, o; 6 | int i, j; 7 | 8 | xor_gate_using_mux inst (a, b, o); 9 | 10 | initial 11 | begin 12 | for (i = 0; i <= 1; i++) 13 | for (j = 0; j <= 1; j++) 14 | begin 15 | a = 1' (i); 16 | b = 1' (j); 17 | 18 | # 1; 19 | 20 | if (o !== (a ^ b)) 21 | begin 22 | $display("FAIL %s", `__FILE__); 23 | $display("++ INPUT => {%s, %s, %s, %s}", `PH(a), `PH(b), `PH(i), `PH(j)); 24 | $display("++ EXPECTED => {%s}", `PH(a^b)); 25 | $display("++ ACTUAL => {%s}", `PH(o)); 26 | $finish(1); 27 | end 28 | end 29 | 30 | $display ("PASS %s", `__FILE__); 31 | $finish; 32 | end 33 | 34 | endmodule 35 | -------------------------------------------------------------------------------- /01_combinational_logic/lint_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --lint 4 | -------------------------------------------------------------------------------- /01_combinational_logic/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /01_combinational_logic/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "%1" 23 | -------------------------------------------------------------------------------- /02_sequential_basics/02_01_edge_and_pulse_detection/02_01_edge_and_pulse_detection.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Example 3 | //---------------------------------------------------------------------------- 4 | 5 | module posedge_detector (input clk, rst, a, output detected); 6 | 7 | logic a_r; 8 | 9 | // Note: 10 | // The a_r flip-flop input value d propogates to the output q 11 | // only on the next clock cycle. 12 | 13 | always_ff @ (posedge clk) 14 | if (rst) 15 | a_r <= '0; 16 | else 17 | a_r <= a; 18 | 19 | assign detected = ~ a_r & a; 20 | 21 | endmodule 22 | 23 | //---------------------------------------------------------------------------- 24 | // Task 25 | //---------------------------------------------------------------------------- 26 | 27 | module one_cycle_pulse_detector (input clk, rst, a, output detected); 28 | 29 | // Task: 30 | // Create an one cycle pulse (010) detector. 31 | // 32 | // Note: 33 | // See the testbench for the output format ($display task). 34 | 35 | 36 | endmodule 37 | -------------------------------------------------------------------------------- /02_sequential_basics/02_02_single_and_double_rate_fibonacci/02_02_single_and_double_rate_fibonacci.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Example 3 | //---------------------------------------------------------------------------- 4 | 5 | module fibonacci 6 | ( 7 | input clk, 8 | input rst, 9 | output logic [15:0] num 10 | ); 11 | 12 | logic [15:0] num2; 13 | 14 | always_ff @ (posedge clk) 15 | if (rst) 16 | { num, num2 } <= { 16'd1, 16'd1 }; 17 | else 18 | { num, num2 } <= { num2, num + num2 }; 19 | 20 | endmodule 21 | 22 | //---------------------------------------------------------------------------- 23 | // Task 24 | //---------------------------------------------------------------------------- 25 | 26 | module fibonacci_2 27 | ( 28 | input clk, 29 | input rst, 30 | output logic [15:0] num, 31 | output logic [15:0] num2 32 | ); 33 | 34 | // Task: 35 | // Implement a module that generates two fibonacci numbers per cycle 36 | 37 | 38 | endmodule 39 | -------------------------------------------------------------------------------- /02_sequential_basics/02_03_serial_adder_using_logic_operations_only/02_03_serial_adder_using_logic_operations_only.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Example 3 | //---------------------------------------------------------------------------- 4 | 5 | module serial_adder 6 | ( 7 | input clk, 8 | input rst, 9 | input a, 10 | input b, 11 | output sum 12 | ); 13 | 14 | // Note: 15 | // carry_d represents the combinational data input to the carry register. 16 | 17 | logic carry; 18 | wire carry_d; 19 | 20 | assign { carry_d, sum } = a + b + carry; 21 | 22 | always_ff @ (posedge clk) 23 | if (rst) 24 | carry <= '0; 25 | else 26 | carry <= carry_d; 27 | 28 | endmodule 29 | 30 | //---------------------------------------------------------------------------- 31 | // Task 32 | //---------------------------------------------------------------------------- 33 | 34 | module serial_adder_using_logic_operations_only 35 | ( 36 | input clk, 37 | input rst, 38 | input a, 39 | input b, 40 | output sum 41 | ); 42 | 43 | // Task: 44 | // Implement a serial adder using only ^ (XOR), | (OR), & (AND), ~ (NOT) bitwise operations. 45 | // 46 | // Notes: 47 | // See Harris & Harris book 48 | // or https://en.wikipedia.org/wiki/Adder_(electronics)#Full_adder webpage 49 | // for information about the 1-bit full adder implementation. 50 | // 51 | // See the testbench for the output format ($display task). 52 | 53 | 54 | endmodule 55 | -------------------------------------------------------------------------------- /02_sequential_basics/02_04_serial_adder_with_vld/02_04_serial_adder_with_vld.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Task 3 | //---------------------------------------------------------------------------- 4 | 5 | module serial_adder_with_vld 6 | ( 7 | input clk, 8 | input rst, 9 | input vld, 10 | input a, 11 | input b, 12 | input last, 13 | output sum 14 | ); 15 | 16 | // Task: 17 | // Implement a module that performs serial addition of two numbers 18 | // (one pair of bits is summed per clock cycle). 19 | // 20 | // It should have input signals a and b, and output signal sum. 21 | // Additionally, the module have two control signals, vld and last. 22 | // 23 | // The vld signal indicates when the input values are valid. 24 | // The last signal indicates when the last digits of the input numbers has been received. 25 | // 26 | // When vld is high, the module should add the values of a and b and produce the sum. 27 | // When last is high, the module should output the sum and reset its internal state, but 28 | // only if vld is also high, otherwise last should be ignored. 29 | // 30 | // When rst is high, the module should reset its internal state. 31 | 32 | 33 | endmodule 34 | -------------------------------------------------------------------------------- /02_sequential_basics/02_07_halve_tokens/02_07_halve_tokens.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Task 3 | //---------------------------------------------------------------------------- 4 | 5 | module halve_tokens 6 | ( 7 | input clk, 8 | input rst, 9 | input a, 10 | output b 11 | ); 12 | // Task: 13 | // Implement a serial module that reduces amount of incoming '1' tokens by half. 14 | // 15 | // Note: 16 | // Check the waveform diagram in the README for better understanding. 17 | // 18 | // Example: 19 | // a -> 110_011_101_000_1111 20 | // b -> 010_001_001_000_0101 21 | 22 | 23 | endmodule 24 | -------------------------------------------------------------------------------- /02_sequential_basics/02_08_double_tokens/02_08_double_tokens.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Task 3 | //---------------------------------------------------------------------------- 4 | 5 | module double_tokens 6 | ( 7 | input clk, 8 | input rst, 9 | input a, 10 | output b, 11 | output logic overflow 12 | ); 13 | // Task: 14 | // Implement a serial module that doubles each incoming token '1' two times. 15 | // The module should handle doubling for at least 200 tokens '1' arriving in a row. 16 | // 17 | // In case module detects more than 200 sequential tokens '1', it should assert 18 | // an overflow error. The overflow error should be sticky. Once the error is on, 19 | // the only way to clear it is by using the "rst" reset signal. 20 | // 21 | // Note: 22 | // Check the waveform diagram in the README for better understanding. 23 | // 24 | // Example: 25 | // a -> 10010011000110100001100100 26 | // b -> 11011011110111111001111110 27 | 28 | 29 | endmodule 30 | -------------------------------------------------------------------------------- /02_sequential_basics/02_09_round_robin_arbiter_with_2_requests/02_09_round_robin_arbiter_with_2_requests.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Task 3 | //---------------------------------------------------------------------------- 4 | 5 | module round_robin_arbiter_with_2_requests 6 | ( 7 | input clk, 8 | input rst, 9 | input [1:0] requests, 10 | output [1:0] grants 11 | ); 12 | // Task: 13 | // Implement a "arbiter" module that accepts up to two requests 14 | // and grants one of them to operate in a round-robin manner. 15 | // 16 | // The module should maintain an internal register 17 | // to keep track of which requester is next in line for a grant. 18 | // 19 | // Note: 20 | // Check the waveform diagram in the README for better understanding. 21 | // 22 | // Example: 23 | // requests -> 01 00 10 11 11 00 11 00 11 11 24 | // grants -> 01 00 10 01 10 00 01 00 10 01 25 | 26 | 27 | endmodule 28 | -------------------------------------------------------------------------------- /02_sequential_basics/02_10_serial_to_parallel/02_10_serial_to_parallel.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Task 3 | //---------------------------------------------------------------------------- 4 | 5 | module serial_to_parallel 6 | # ( 7 | parameter width = 8 8 | ) 9 | ( 10 | input clk, 11 | input rst, 12 | 13 | input serial_valid, 14 | input serial_data, 15 | 16 | output logic parallel_valid, 17 | output logic [width - 1:0] parallel_data 18 | ); 19 | // Task: 20 | // Implement a module that converts serial data to the parallel multibit value. 21 | // 22 | // The module should accept one-bit values with valid interface in a serial manner. 23 | // After accumulating 'width' bits, the module should assert the parallel_valid 24 | // output and set the data. 25 | // 26 | // Note: 27 | // Check the waveform diagram in the README for better understanding. 28 | 29 | 30 | endmodule 31 | -------------------------------------------------------------------------------- /02_sequential_basics/README_ru.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/02_sequential_basics/README_ru.pdf -------------------------------------------------------------------------------- /02_sequential_basics/lint_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --lint 4 | -------------------------------------------------------------------------------- /02_sequential_basics/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /02_sequential_basics/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "%1" 23 | -------------------------------------------------------------------------------- /03_finite_state_machines/03_02_detect_sequence_using_shift_reg/03_02_detect_sequence_using_shift_reg.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Example 3 | //---------------------------------------------------------------------------- 4 | 5 | module detect_4_bit_sequence_using_shift_reg 6 | ( 7 | input clk, 8 | input rst, 9 | input new_bit, 10 | output detected 11 | ); 12 | 13 | // Detection of the "1010" sequence using shift register 14 | 15 | logic [3:0] shift_reg; 16 | 17 | assign detected = shift_reg[3] & 18 | ~ shift_reg[2] & 19 | shift_reg[1] & 20 | ~ shift_reg[0]; 21 | 22 | always_ff @ (posedge clk) 23 | if (rst) 24 | shift_reg <= '0; 25 | else 26 | shift_reg <= {shift_reg[2:0], new_bit }; 27 | 28 | endmodule 29 | 30 | //---------------------------------------------------------------------------- 31 | // Task 32 | //---------------------------------------------------------------------------- 33 | 34 | module detect_6_bit_sequence_using_shift_reg 35 | ( 36 | input clk, 37 | input rst, 38 | input new_bit, 39 | output detected 40 | ); 41 | 42 | // Task: 43 | // Implement a module that detects the "110011" sequence 44 | 45 | 46 | endmodule 47 | -------------------------------------------------------------------------------- /03_finite_state_machines/03_04_05_sqrt_formula_fsms/03_04_formula_1_impl_2_fsm.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Task 3 | //---------------------------------------------------------------------------- 4 | 5 | module formula_1_impl_2_fsm 6 | ( 7 | input clk, 8 | input rst, 9 | 10 | input arg_vld, 11 | input [31:0] a, 12 | input [31:0] b, 13 | input [31:0] c, 14 | 15 | output logic res_vld, 16 | output logic [31:0] res, 17 | 18 | // isqrt interface 19 | 20 | output logic isqrt_1_x_vld, 21 | output logic [31:0] isqrt_1_x, 22 | 23 | input isqrt_1_y_vld, 24 | input [15:0] isqrt_1_y, 25 | 26 | output logic isqrt_2_x_vld, 27 | output logic [31:0] isqrt_2_x, 28 | 29 | input isqrt_2_y_vld, 30 | input [15:0] isqrt_2_y 31 | ); 32 | 33 | // Task: 34 | // Implement a module that calculates the formula from the `formula_1_fn.svh` file 35 | // using two instances of the isqrt module in parallel. 36 | // 37 | // Design the FSM to calculate an answer and provide the correct `res` value 38 | // 39 | // You can read the discussion of this problem 40 | // in the article by Yuri Panchul published in 41 | // FPGA-Systems Magazine :: FSM :: Issue ALFA (state_0) 42 | // You can download this issue from https://fpga-systems.ru/fsm 43 | 44 | 45 | endmodule 46 | -------------------------------------------------------------------------------- /03_finite_state_machines/03_04_05_sqrt_formula_fsms/03_05_formula_2_fsm.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Task 3 | //---------------------------------------------------------------------------- 4 | 5 | module formula_2_fsm 6 | ( 7 | input clk, 8 | input rst, 9 | 10 | input arg_vld, 11 | input [31:0] a, 12 | input [31:0] b, 13 | input [31:0] c, 14 | 15 | output logic res_vld, 16 | output logic [31:0] res, 17 | 18 | // isqrt interface 19 | 20 | output logic isqrt_x_vld, 21 | output logic [31:0] isqrt_x, 22 | 23 | input isqrt_y_vld, 24 | input [15:0] isqrt_y 25 | ); 26 | // Task: 27 | // Implement a module that calculates the formula from the `formula_2_fn.svh` file 28 | // using only one instance of the isqrt module. 29 | // 30 | // Design the FSM to calculate answer step-by-step and provide the correct `res` value 31 | // 32 | // You can read the discussion of this problem 33 | // in the article by Yuri Panchul published in 34 | // FPGA-Systems Magazine :: FSM :: Issue ALFA (state_0) 35 | // You can download this issue from https://fpga-systems.ru/fsm 36 | 37 | 38 | endmodule 39 | -------------------------------------------------------------------------------- /03_finite_state_machines/03_04_05_sqrt_formula_fsms/formula_1_fn.svh: -------------------------------------------------------------------------------- 1 | `ifndef FORMULA_1_FN_SVH 2 | `define FORMULA_1_FN_SVH 3 | 4 | //---------------------------------------------------------------------------- 5 | // Header file defining the formula. DO NOT MODIFY 6 | //---------------------------------------------------------------------------- 7 | 8 | `include "isqrt_fn.svh" 9 | 10 | function [31:0] formula_1_fn 11 | ( 12 | input [31:0] a, 13 | input [31:0] b, 14 | input [31:0] c 15 | ); 16 | return 32' (isqrt_fn (a)) + 32' (isqrt_fn (b)) + 32' (isqrt_fn (c)); 17 | 18 | endfunction 19 | 20 | `endif 21 | -------------------------------------------------------------------------------- /03_finite_state_machines/03_04_05_sqrt_formula_fsms/formula_1_impl_1_top.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Top file wiring everything together. DO NOT MODIFY 3 | //---------------------------------------------------------------------------- 4 | 5 | module formula_1_impl_1_top 6 | ( 7 | input clk, 8 | input rst, 9 | 10 | input arg_vld, 11 | input [31:0] a, 12 | input [31:0] b, 13 | input [31:0] c, 14 | 15 | output res_vld, 16 | output [31:0] res 17 | ); 18 | 19 | wire isqrt_x_vld; 20 | wire [31:0] isqrt_x; 21 | 22 | wire isqrt_y_vld; 23 | wire [15:0] isqrt_y; 24 | 25 | formula_1_impl_1_fsm i_formula_1_impl_1_fsm (.*); 26 | 27 | isqrt # (.n_pipe_stages (4)) i_isqrt 28 | ( 29 | .clk ( clk ), 30 | .rst ( rst ), 31 | .x_vld ( isqrt_x_vld ), 32 | .x ( isqrt_x ), 33 | .y_vld ( isqrt_y_vld ), 34 | .y ( isqrt_y ) 35 | ); 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /03_finite_state_machines/03_04_05_sqrt_formula_fsms/formula_1_impl_2_top.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Top file wiring everything together. DO NOT MODIFY 3 | //---------------------------------------------------------------------------- 4 | 5 | module formula_1_impl_2_top 6 | ( 7 | input clk, 8 | input rst, 9 | 10 | input arg_vld, 11 | input [31:0] a, 12 | input [31:0] b, 13 | input [31:0] c, 14 | 15 | output res_vld, 16 | output [31:0] res 17 | ); 18 | 19 | wire isqrt_1_x_vld; 20 | wire [31:0] isqrt_1_x; 21 | 22 | wire isqrt_1_y_vld; 23 | wire [15:0] isqrt_1_y; 24 | 25 | wire isqrt_2_x_vld; 26 | wire [31:0] isqrt_2_x; 27 | 28 | wire isqrt_2_y_vld; 29 | wire [15:0] isqrt_2_y; 30 | 31 | formula_1_impl_2_fsm i_formula_1_impl_2_fsm (.*); 32 | 33 | isqrt i_isqrt_1 34 | ( 35 | .clk ( clk ), 36 | .rst ( rst ), 37 | .x_vld ( isqrt_1_x_vld ), 38 | .x ( isqrt_1_x ), 39 | .y_vld ( isqrt_1_y_vld ), 40 | .y ( isqrt_1_y ) 41 | ); 42 | 43 | isqrt i_isqrt_2 44 | ( 45 | .clk ( clk ), 46 | .rst ( rst ), 47 | .x_vld ( isqrt_2_x_vld ), 48 | .x ( isqrt_2_x ), 49 | .y_vld ( isqrt_2_y_vld ), 50 | .y ( isqrt_2_y ) 51 | ); 52 | 53 | endmodule 54 | -------------------------------------------------------------------------------- /03_finite_state_machines/03_04_05_sqrt_formula_fsms/formula_2_fn.svh: -------------------------------------------------------------------------------- 1 | `ifndef FORMULA_2_FN_SVH 2 | `define FORMULA_2_FN_SVH 3 | 4 | //---------------------------------------------------------------------------- 5 | // Header file defining the formula. DO NOT MODIFY 6 | //---------------------------------------------------------------------------- 7 | 8 | `include "isqrt_fn.svh" 9 | 10 | function [31:0] formula_2_fn 11 | ( 12 | input [31:0] a, 13 | input [31:0] b, 14 | input [31:0] c 15 | ); 16 | return 32' (isqrt_fn (a + 32' (isqrt_fn (b + 32' (isqrt_fn (c) ) ) ) ) ); 17 | 18 | endfunction 19 | 20 | `endif 21 | -------------------------------------------------------------------------------- /03_finite_state_machines/03_04_05_sqrt_formula_fsms/formula_2_top.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Top file wiring everything together. DO NOT MODIFY 3 | //---------------------------------------------------------------------------- 4 | 5 | module formula_2_top 6 | ( 7 | input clk, 8 | input rst, 9 | 10 | input arg_vld, 11 | input [31:0] a, 12 | input [31:0] b, 13 | input [31:0] c, 14 | 15 | output res_vld, 16 | output [31:0] res 17 | ); 18 | 19 | wire isqrt_x_vld; 20 | wire [31:0] isqrt_x; 21 | 22 | wire isqrt_y_vld; 23 | wire [15:0] isqrt_y; 24 | 25 | formula_2_fsm i_formula_2_fsm (.*); 26 | 27 | isqrt i_isqrt 28 | ( 29 | .clk ( clk ), 30 | .rst ( rst ), 31 | .x_vld ( isqrt_x_vld ), 32 | .x ( isqrt_x ), 33 | .y_vld ( isqrt_y_vld ), 34 | .y ( isqrt_y ) 35 | ); 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /03_finite_state_machines/03_04_05_sqrt_formula_fsms/lint_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --lint 4 | -------------------------------------------------------------------------------- /03_finite_state_machines/03_04_05_sqrt_formula_fsms/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /03_finite_state_machines/03_04_05_sqrt_formula_fsms/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | if not exist "C:\Program Files\Git\bin\bash.exe" ( 4 | echo "Starting from Homework 3, this Windows batch script invokes" 5 | echo "a Bash shell interpreter from the Git for Windows package." 6 | echo "This is necessary for more flexible checking of the results." 7 | echo "Please install Git for Windows from https://gitforwindows.org/ and re-run this batch again." 8 | 9 | exit /b 10 | ) 11 | 12 | "C:\Program Files\Git\bin\bash.exe" run_linux_mac.sh 13 | -------------------------------------------------------------------------------- /03_finite_state_machines/03_04_05_sqrt_formula_fsms/testbenches/isqrt_fn.svh: -------------------------------------------------------------------------------- 1 | // This example is written by Yuri Panchul 2 | // The algorithm is from Hacker's Delight by Henry Warren 3 | 4 | `ifndef ISQRT_FN_SVH 5 | `define ISQRT_FN_SVH 6 | 7 | function [15:0] isqrt_fn (input [31:0] x); 8 | 9 | logic [31:0] m, tx, ty, b; 10 | 11 | m = 32'h4000_0000; 12 | tx = x; 13 | ty = 0; 14 | 15 | repeat (16) 16 | begin 17 | b = ty | m; 18 | ty = ty >> 1; 19 | 20 | if (tx >= b) 21 | begin 22 | tx = tx - b; 23 | ty = ty | m; 24 | end 25 | 26 | m = m >> 2; 27 | end 28 | 29 | return ty [15:0]; 30 | 31 | endfunction 32 | 33 | `endif 34 | -------------------------------------------------------------------------------- /03_finite_state_machines/03_04_05_sqrt_formula_fsms/testbenches/tb.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Top testbench file. 3 | // Runs all testbenches 4 | //---------------------------------------------------------------------------- 5 | 6 | module tb; 7 | 8 | formula_tb # ( .homework (3), .formula (1), .impl (1) ) formula_1_impl_1_tb (); 9 | formula_tb # ( .homework (3), .formula (1), .impl (2) ) formula_1_impl_2_tb (); 10 | formula_tb # ( .homework (3), .formula (2) ) formula_2_tb (); 11 | 12 | initial 13 | begin 14 | `ifdef __ICARUS__ 15 | // Uncomment the following line 16 | // to generate a VCD file and analyze it using GTKwave 17 | 18 | // $dumpvars; 19 | `endif 20 | 21 | formula_1_impl_1_tb .run (); 22 | formula_1_impl_2_tb .run (); 23 | formula_2_tb .run (); 24 | 25 | $finish; 26 | end 27 | 28 | endmodule 29 | -------------------------------------------------------------------------------- /03_finite_state_machines/03_04_05_sqrt_formula_fsms/wave_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --wave 4 | -------------------------------------------------------------------------------- /03_finite_state_machines/03_04_05_sqrt_formula_fsms/wave_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | if not exist "C:\Program Files\Git\bin\bash.exe" ( 4 | echo "Starting from Homework 3, this Windows batch script invokes" 5 | echo "a Bash shell interpreter from the Git for Windows package." 6 | echo "This is necessary for more flexible checking of the results." 7 | echo "Please install Git for Windows from https://gitforwindows.org/ and re-run this batch again." 8 | 9 | exit /b 10 | ) 11 | 12 | "C:\Program Files\Git\bin\bash.exe" run_linux_mac.sh --wave 13 | -------------------------------------------------------------------------------- /03_finite_state_machines/03_08_float_discriminant/03_08_float_discriminant.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Task 3 | //---------------------------------------------------------------------------- 4 | 5 | module float_discriminant ( 6 | input clk, 7 | input rst, 8 | 9 | input arg_vld, 10 | input [FLEN - 1:0] a, 11 | input [FLEN - 1:0] b, 12 | input [FLEN - 1:0] c, 13 | 14 | output logic res_vld, 15 | output logic [FLEN - 1:0] res, 16 | output logic res_negative, 17 | output logic err, 18 | 19 | output logic busy 20 | ); 21 | 22 | // Task: 23 | // Implement a module that accepts three Floating-Point numbers and outputs their discriminant. 24 | // The resulting value res should be calculated as a discriminant of the quadratic polynomial. 25 | // That is, res = b^2 - 4ac == b*b - 4*a*c 26 | // 27 | // Note: 28 | // If any argument is not a valid number, that is NaN or Inf, the "err" flag should be set. 29 | // 30 | // The FLEN parameter is defined in the "import/preprocessed/cvw/config-shared.vh" file 31 | // and usually equal to the bit width of the double-precision floating-point number, FP64, 64 bits. 32 | 33 | 34 | endmodule 35 | -------------------------------------------------------------------------------- /03_finite_state_machines/README_ru.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/03_finite_state_machines/README_ru.pdf -------------------------------------------------------------------------------- /03_finite_state_machines/lint_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --lint 4 | -------------------------------------------------------------------------------- /03_finite_state_machines/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /03_finite_state_machines/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | if not exist "C:\Program Files\Git\bin\bash.exe" ( 4 | echo "Starting from Homework 3, this Windows batch script invokes" 5 | echo "a Bash shell interpreter from the Git for Windows package." 6 | echo "This is necessary for more flexible checking of the results." 7 | echo "Please install Git for Windows from https://gitforwindows.org/ and re-run this batch again." 8 | 9 | exit /b 10 | ) 11 | 12 | "C:\Program Files\Git\bin\bash.exe" run_linux_mac.sh 13 | -------------------------------------------------------------------------------- /03_finite_state_machines/wave_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --wave 4 | -------------------------------------------------------------------------------- /03_finite_state_machines/wave_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | if not exist "C:\Program Files\Git\bin\bash.exe" ( 4 | echo "Starting from Homework 3, this Windows batch script invokes" 5 | echo "a Bash shell interpreter from the Git for Windows package." 6 | echo "This is necessary for more flexible checking of the results." 7 | echo "Please install Git for Windows from https://gitforwindows.org/ and re-run this batch again." 8 | 9 | exit /b 10 | ) 11 | 12 | "C:\Program Files\Git\bin\bash.exe" run_linux_mac.sh --wave 13 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_01_signed_add_with_overflow/04_01_signed_add_with_overflow.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Example 3 | //---------------------------------------------------------------------------- 4 | 5 | module add 6 | ( 7 | input [3:0] a, b, 8 | output [3:0] sum 9 | ); 10 | 11 | assign sum = a + b; 12 | 13 | endmodule 14 | 15 | //---------------------------------------------------------------------------- 16 | // Task 17 | //---------------------------------------------------------------------------- 18 | 19 | module signed_add_with_overflow 20 | ( 21 | input [3:0] a, b, 22 | output [3:0] sum, 23 | output overflow 24 | ); 25 | 26 | // Task: 27 | // 28 | // Implement a module that adds two signed numbers 29 | // and detects an overflow. 30 | // 31 | // By "signed" we mean "two's complement numbers". 32 | // See https://en.wikipedia.org/wiki/Two%27s_complement for details. 33 | // 34 | // The 'overflow' output bit should be set to 1 35 | // when the sum (either positive or negative) 36 | // of two input arguments does not fit into 4 bits. 37 | // Otherwise the 'overflow' should be set to 0. 38 | 39 | 40 | endmodule 41 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_02_signed_add_with_saturation/04_02_signed_add_with_saturation.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Example 3 | //---------------------------------------------------------------------------- 4 | 5 | module add 6 | ( 7 | input [3:0] a, b, 8 | output [3:0] sum 9 | ); 10 | 11 | assign sum = a + b; 12 | 13 | endmodule 14 | 15 | //---------------------------------------------------------------------------- 16 | // Task 17 | //---------------------------------------------------------------------------- 18 | 19 | module signed_add_with_saturation 20 | ( 21 | input [3:0] a, b, 22 | output [3:0] sum 23 | ); 24 | 25 | // Task: 26 | // 27 | // Implement a module that adds two signed numbers with saturation. 28 | // 29 | // "Adding with saturation" means: 30 | // 31 | // When the result does not fit into 4 bits, 32 | // and the arguments are positive, 33 | // the sum should be set to the maximum positive number. 34 | // 35 | // When the result does not fit into 4 bits, 36 | // and the arguments are negative, 37 | // the sum should be set to the minimum negative number. 38 | 39 | 40 | endmodule 41 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_03_signed_or_unsigned_mul/04_03_signed_or_unsigned_mul.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Example 3 | //---------------------------------------------------------------------------- 4 | 5 | // A non-parameterized module 6 | // that implements the signed multiplication of 4-bit numbers 7 | // which produces 8-bit result 8 | 9 | module signed_mul_4 10 | ( 11 | input signed [3:0] a, b, 12 | output signed [7:0] res 13 | ); 14 | 15 | assign res = a * b; 16 | 17 | endmodule 18 | 19 | // A parameterized module 20 | // that implements the unsigned multiplication of N-bit numbers 21 | // which produces 2N-bit result 22 | 23 | module unsigned_mul 24 | # ( 25 | parameter n = 8 26 | ) 27 | ( 28 | input [ n - 1:0] a, b, 29 | output [2 * n - 1:0] res 30 | ); 31 | 32 | assign res = a * b; 33 | 34 | endmodule 35 | 36 | //---------------------------------------------------------------------------- 37 | // Task 38 | //---------------------------------------------------------------------------- 39 | 40 | // Task: 41 | // 42 | // Implement a parameterized module 43 | // that produces either signed or unsigned result 44 | // of the multiplication depending on the 'signed_mul' input bit. 45 | 46 | module signed_or_unsigned_mul 47 | # ( 48 | parameter n = 8 49 | ) 50 | ( 51 | input [ n - 1:0] a, b, 52 | input signed_mul, 53 | output [2 * n - 1:0] res 54 | ); 55 | 56 | endmodule 57 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_04_four_ways_of_doing_shift/testbench.sv: -------------------------------------------------------------------------------- 1 | module testbench; 2 | 3 | localparam N = 8, S = 3; 4 | 5 | logic [N - 1:0] a, res [0:7]; 6 | 7 | left_shift_of_8_by_3_using_left_shift_operation i0 (a, res [0]); 8 | left_shift_of_8_by_3_using_concatenation i1 (a, res [1]); 9 | left_shift_of_8_by_3_using_for_inside_always i2 (a, res [2]); 10 | left_shift_of_8_by_3_using_for_inside_generate i3 (a, res [3]); 11 | 12 | right_shift_of_N_by_S_using_right_shift_operation 13 | # (.N (N), .S (S)) i4 (a, res [4]); 14 | 15 | right_shift_of_N_by_S_using_concatenation 16 | # (.N (N), .S (S)) i5 (a, res [5]); 17 | 18 | right_shift_of_N_by_S_using_for_inside_always 19 | # (.N (N), .S (S)) i6 (a, res [6]); 20 | 21 | right_shift_of_N_by_S_using_for_inside_generate 22 | # (.N (N), .S (S)) i7 (a, res [7]); 23 | 24 | initial 25 | begin 26 | repeat (20) 27 | begin 28 | a = N' ($urandom()); 29 | # 1 30 | 31 | $write ("TEST %b", a); 32 | 33 | for (int i = 0; i < 8; i ++) 34 | $write (" %b", res [i]); 35 | 36 | $display; 37 | 38 | for (int i = 0; i < 8; i ++) 39 | if (res [i] !== res [i / 4 * 4]) 40 | begin 41 | $display ("FAIL %s - see above", `__FILE__); 42 | $finish; 43 | end 44 | end 45 | 46 | $display ("PASS %s", `__FILE__); 47 | $finish; 48 | end 49 | 50 | endmodule 51 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_06_arithmetic_shift_or_signed_divide_by_power_of_2/testbench.sv: -------------------------------------------------------------------------------- 1 | module testbench; 2 | 3 | localparam N = 8, S = 3; 4 | 5 | logic signed [N - 1:0] a, res [0:3]; 6 | 7 | arithmetic_right_shift_of_N_by_S_using_arithmetic_right_shift_operation 8 | # (.N (N), .S (S)) i4 (a, res [0]); 9 | 10 | arithmetic_right_shift_of_N_by_S_using_concatenation 11 | # (.N (N), .S (S)) i5 (a, res [1]); 12 | 13 | arithmetic_right_shift_of_N_by_S_using_for_inside_always 14 | # (.N (N), .S (S)) i6 (a, res [2]); 15 | 16 | arithmetic_right_shift_of_N_by_S_using_for_inside_generate 17 | # (.N (N), .S (S)) i7 (a, res [3]); 18 | 19 | initial 20 | begin 21 | repeat (20) 22 | begin 23 | a = N' ($urandom()); 24 | # 1 25 | 26 | $write ("TEST %d %b", a, a); 27 | 28 | for (int i = 0; i < 4; i ++) 29 | $write (" %d %b", res [i], res [i]); 30 | 31 | $display; 32 | 33 | for (int i = 1; i < 4; i ++) 34 | if (res [i] !== res [0]) 35 | begin 36 | $display ("FAIL %s. EXPECTED %d %b", 37 | `__FILE__, res [0], res [0]); 38 | 39 | $finish; 40 | end 41 | 42 | /* 43 | if (res [i] !== a / 2 ** S) 44 | begin 45 | $display ("%s FAIL. EXPECTED %d %b", 46 | `__FILE__, a / (8'sd2 ** S), a / (8'sd2 ** S)); 47 | 48 | $finish; 49 | end 50 | */ 51 | end 52 | 53 | $display ("PASS %s", `__FILE__); 54 | $finish; 55 | end 56 | 57 | endmodule 58 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_07_10_sqrt_formula_pipe/black_boxes/isqrt_slice_comb.sv: -------------------------------------------------------------------------------- 1 | module isqrt_slice_comb 2 | # ( 3 | parameter [31:0] m = 32'h4000_0000 4 | ) 5 | ( 6 | input [31:0] ix, 7 | input [31:0] iy, 8 | output [31:0] ox, 9 | output [31:0] oy 10 | ); 11 | 12 | wire [31:0] b = iy | m; 13 | wire x_ge_b = ix >= b; 14 | 15 | assign ox = x_ge_b ? ix - b : ix; 16 | assign oy = (iy >> 1) | (x_ge_b ? m : 0); 17 | 18 | endmodule 19 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_07_10_sqrt_formula_pipe/black_boxes/isqrt_slice_reg.sv: -------------------------------------------------------------------------------- 1 | module isqrt_slice_reg 2 | # ( 3 | parameter [31:0] m = 32'h4000_0000 4 | ) 5 | ( 6 | input clk, 7 | input rst, 8 | 9 | input ivld, 10 | input [31:0] ix, 11 | input [31:0] iy, 12 | 13 | output logic ovld, 14 | output logic [31:0] ox, 15 | output logic [31:0] oy 16 | ); 17 | 18 | wire [31:0] cox, coy; 19 | 20 | isqrt_slice_comb # (.m (m)) inst 21 | ( 22 | .ix ( ix ), 23 | .iy ( iy ), 24 | .ox ( cox ), 25 | .oy ( coy ) 26 | ); 27 | 28 | always_ff @ (posedge clk) 29 | if (rst) 30 | ovld <= 1'b0; 31 | else 32 | ovld <= ivld; 33 | 34 | always_ff @ (posedge clk) 35 | if (ivld) 36 | begin 37 | ox <= cox; 38 | oy <= coy; 39 | end 40 | 41 | endmodule 42 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_07_10_sqrt_formula_pipe/formula_1_fn.svh: -------------------------------------------------------------------------------- 1 | `ifndef FORMULA_1_FN_SVH 2 | `define FORMULA_1_FN_SVH 3 | 4 | //---------------------------------------------------------------------------- 5 | // Header file defining the formula. DO NOT MODIFY 6 | //---------------------------------------------------------------------------- 7 | 8 | `include "isqrt_fn.svh" 9 | 10 | function [31:0] formula_1_fn 11 | ( 12 | input [31:0] a, 13 | input [31:0] b, 14 | input [31:0] c 15 | ); 16 | return 32' (isqrt_fn (a)) + 32' (isqrt_fn (b)) + 32' (isqrt_fn (c)); 17 | 18 | endfunction 19 | 20 | `endif 21 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_07_10_sqrt_formula_pipe/formula_1_pipe_aware_fsm_top.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Top file wiring everything together. DO NOT MODIFY 3 | //---------------------------------------------------------------------------- 4 | 5 | module formula_1_pipe_aware_fsm_top 6 | ( 7 | input clk, 8 | input rst, 9 | 10 | input arg_vld, 11 | input [31:0] a, 12 | input [31:0] b, 13 | input [31:0] c, 14 | 15 | output res_vld, 16 | output [31:0] res 17 | ); 18 | 19 | wire isqrt_x_vld; 20 | wire [31:0] isqrt_x; 21 | 22 | wire isqrt_y_vld; 23 | wire [15:0] isqrt_y; 24 | 25 | formula_1_pipe_aware_fsm i_formula_1_pipe_aware_fsm (.*); 26 | 27 | isqrt # (.n_pipe_stages (4)) i_isqrt 28 | ( 29 | .clk ( clk ), 30 | .rst ( rst ), 31 | .x_vld ( isqrt_x_vld ), 32 | .x ( isqrt_x ), 33 | .y_vld ( isqrt_y_vld ), 34 | .y ( isqrt_y ) 35 | ); 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_07_10_sqrt_formula_pipe/formula_2_fn.svh: -------------------------------------------------------------------------------- 1 | `ifndef FORMULA_2_FN_SVH 2 | `define FORMULA_2_FN_SVH 3 | 4 | //---------------------------------------------------------------------------- 5 | // Header file defining the formula. DO NOT MODIFY 6 | //---------------------------------------------------------------------------- 7 | 8 | `include "isqrt_fn.svh" 9 | 10 | function [31:0] formula_2_fn 11 | ( 12 | input [31:0] a, 13 | input [31:0] b, 14 | input [31:0] c 15 | ); 16 | return 32' (isqrt_fn (a + 32' (isqrt_fn (b + 32' (isqrt_fn (c) ) ) ) ) ); 17 | 18 | endfunction 19 | 20 | `endif 21 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_07_10_sqrt_formula_pipe/lint_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --lint 4 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_07_10_sqrt_formula_pipe/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_07_10_sqrt_formula_pipe/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | if not exist "C:\Program Files\Git\bin\bash.exe" ( 4 | echo "Starting from Homework 3, this Windows batch script invokes" 5 | echo "a Bash shell interpreter from the Git for Windows package." 6 | echo "This is necessary for more flexible checking of the results." 7 | echo "Please install Git for Windows from https://gitforwindows.org/ and re-run this batch again." 8 | 9 | exit /b 10 | ) 11 | 12 | "C:\Program Files\Git\bin\bash.exe" run_linux_mac.sh 13 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_07_10_sqrt_formula_pipe/testbenches/isqrt_fn.svh: -------------------------------------------------------------------------------- 1 | // This example is written by Yuri Panchul 2 | // The algorithm is from Hacker's Delight by Henry Warren 3 | 4 | `ifndef ISQRT_FN_SVH 5 | `define ISQRT_FN_SVH 6 | 7 | function [15:0] isqrt_fn (input [31:0] x); 8 | 9 | logic [31:0] m, tx, ty, b; 10 | 11 | m = 32'h4000_0000; 12 | tx = x; 13 | ty = 0; 14 | 15 | repeat (16) 16 | begin 17 | b = ty | m; 18 | ty = ty >> 1; 19 | 20 | if (tx >= b) 21 | begin 22 | tx = tx - b; 23 | ty = ty | m; 24 | end 25 | 26 | m = m >> 2; 27 | end 28 | 29 | return ty [15:0]; 30 | 31 | endfunction 32 | 33 | `endif 34 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_07_10_sqrt_formula_pipe/testbenches/tb.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Top testbench file. 3 | // Runs all testbenches 4 | //---------------------------------------------------------------------------- 5 | 6 | module tb; 7 | 8 | formula_tb # ( .homework (4), .formula (1), .pipe (1) ) i_formula_1_pipe_tb (); 9 | formula_tb # ( .homework (4), .formula (1), .pipe (0) ) i_formula_1_pipe_aware_fsm_tb (); 10 | 11 | shift_register_with_valid_tb # ( .width (8), .depth (8) ) 12 | i_shift_register_with_valid_tb1 (); 13 | 14 | shift_register_with_valid_tb # ( .width (17), .depth (13) ) 15 | i_shift_register_with_valid_tb2 (); 16 | 17 | formula_tb # ( .homework (4), .formula (2), .pipe (1) ) i_formula_2_pipe_tb (); 18 | 19 | initial 20 | begin 21 | `ifdef __ICARUS__ 22 | // Uncomment the following line 23 | // to generate a VCD file and analyze it using GTKwave 24 | 25 | // $dumpvars; 26 | `endif 27 | 28 | i_formula_1_pipe_tb .run (); 29 | i_formula_1_pipe_aware_fsm_tb .run (); 30 | i_shift_register_with_valid_tb1 .run (); 31 | i_shift_register_with_valid_tb2 .run (); 32 | i_formula_2_pipe_tb .run (); 33 | 34 | $finish; 35 | end 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_07_10_sqrt_formula_pipe/wave_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --wave 4 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_07_10_sqrt_formula_pipe/wave_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | if not exist "C:\Program Files\Git\bin\bash.exe" ( 4 | echo "Starting from Homework 3, this Windows batch script invokes" 5 | echo "a Bash shell interpreter from the Git for Windows package." 6 | echo "This is necessary for more flexible checking of the results." 7 | echo "Please install Git for Windows from https://gitforwindows.org/ and re-run this batch again." 8 | 9 | exit /b 10 | ) 11 | 12 | "C:\Program Files\Git\bin\bash.exe" run_linux_mac.sh --wave 13 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_11_sqrt_formula_distributor/03_04_formula_1_impl_2_fsm.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Task 3 | //---------------------------------------------------------------------------- 4 | 5 | module formula_1_impl_2_fsm 6 | ( 7 | input clk, 8 | input rst, 9 | 10 | input arg_vld, 11 | input [31:0] a, 12 | input [31:0] b, 13 | input [31:0] c, 14 | 15 | output logic res_vld, 16 | output logic [31:0] res, 17 | 18 | // isqrt interface 19 | 20 | output logic isqrt_1_x_vld, 21 | output logic [31:0] isqrt_1_x, 22 | 23 | input isqrt_1_y_vld, 24 | input [15:0] isqrt_1_y, 25 | 26 | output logic isqrt_2_x_vld, 27 | output logic [31:0] isqrt_2_x, 28 | 29 | input isqrt_2_y_vld, 30 | input [15:0] isqrt_2_y 31 | ); 32 | 33 | // Task: 34 | // Implement a module that calculates the formula from the `formula_1_fn.svh` file 35 | // using two instances of the isqrt module in parallel. 36 | // 37 | // Design the FSM to calculate an answer and provide the correct `res` value 38 | // 39 | // You can read the discussion of this problem 40 | // in the article by Yuri Panchul published in 41 | // FPGA-Systems Magazine :: FSM :: Issue ALFA (state_0) 42 | // You can download this issue from https://fpga-systems.ru/fsm 43 | 44 | 45 | endmodule 46 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_11_sqrt_formula_distributor/03_05_formula_2_fsm.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Task 3 | //---------------------------------------------------------------------------- 4 | 5 | module formula_2_fsm 6 | ( 7 | input clk, 8 | input rst, 9 | 10 | input arg_vld, 11 | input [31:0] a, 12 | input [31:0] b, 13 | input [31:0] c, 14 | 15 | output logic res_vld, 16 | output logic [31:0] res, 17 | 18 | // isqrt interface 19 | 20 | output logic isqrt_x_vld, 21 | output logic [31:0] isqrt_x, 22 | 23 | input isqrt_y_vld, 24 | input [15:0] isqrt_y 25 | ); 26 | 27 | // Task: 28 | // 29 | // Implement a module that calculates the formula from the `formula_2_fn.svh` file 30 | // using only one instance of the isqrt module. 31 | // 32 | // Design the FSM to calculate answer step-by-step and provide the correct `res` value 33 | // 34 | // You can read the discussion of this problem 35 | // in the article by Yuri Panchul published in 36 | // FPGA-Systems Magazine :: FSM :: Issue ALFA (state_0) 37 | // You can download this issue from https://fpga-systems.ru/fsm 38 | 39 | 40 | endmodule 41 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_11_sqrt_formula_distributor/diagram.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/04_arithmetics_and_pipelining/04_11_sqrt_formula_distributor/diagram.pdf -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_11_sqrt_formula_distributor/formula_1_fn.svh: -------------------------------------------------------------------------------- 1 | `ifndef FORMULA_1_FN_SVH 2 | `define FORMULA_1_FN_SVH 3 | 4 | //---------------------------------------------------------------------------- 5 | // Header file defining the formula. DO NOT MODIFY 6 | //---------------------------------------------------------------------------- 7 | 8 | `include "isqrt_fn.svh" 9 | 10 | function [31:0] formula_1_fn 11 | ( 12 | input [31:0] a, 13 | input [31:0] b, 14 | input [31:0] c 15 | ); 16 | return 32' (isqrt_fn (a)) + 32' (isqrt_fn (b)) + 32' (isqrt_fn (c)); 17 | 18 | endfunction 19 | 20 | `endif 21 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_11_sqrt_formula_distributor/formula_1_impl_1_top.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Top file wiring everything together. DO NOT MODIFY 3 | //---------------------------------------------------------------------------- 4 | 5 | module formula_1_impl_1_top 6 | ( 7 | input clk, 8 | input rst, 9 | 10 | input arg_vld, 11 | input [31:0] a, 12 | input [31:0] b, 13 | input [31:0] c, 14 | 15 | output res_vld, 16 | output [31:0] res 17 | ); 18 | 19 | wire isqrt_x_vld; 20 | wire [31:0] isqrt_x; 21 | 22 | wire isqrt_y_vld; 23 | wire [15:0] isqrt_y; 24 | 25 | formula_1_impl_1_fsm i_formula_1_impl_1_fsm (.*); 26 | 27 | isqrt # (.n_pipe_stages (4)) i_isqrt 28 | ( 29 | .clk ( clk ), 30 | .rst ( rst ), 31 | .x_vld ( isqrt_x_vld ), 32 | .x ( isqrt_x ), 33 | .y_vld ( isqrt_y_vld ), 34 | .y ( isqrt_y ) 35 | ); 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_11_sqrt_formula_distributor/formula_1_impl_2_top.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Top file wiring everything together. DO NOT MODIFY 3 | //---------------------------------------------------------------------------- 4 | 5 | module formula_1_impl_2_top 6 | ( 7 | input clk, 8 | input rst, 9 | 10 | input arg_vld, 11 | input [31:0] a, 12 | input [31:0] b, 13 | input [31:0] c, 14 | 15 | output res_vld, 16 | output [31:0] res 17 | ); 18 | 19 | wire isqrt_1_x_vld; 20 | wire [31:0] isqrt_1_x; 21 | 22 | wire isqrt_1_y_vld; 23 | wire [15:0] isqrt_1_y; 24 | 25 | wire isqrt_2_x_vld; 26 | wire [31:0] isqrt_2_x; 27 | 28 | wire isqrt_2_y_vld; 29 | wire [15:0] isqrt_2_y; 30 | 31 | formula_1_impl_2_fsm i_formula_1_impl_2_fsm (.*); 32 | 33 | isqrt i_isqrt_1 34 | ( 35 | .clk ( clk ), 36 | .rst ( rst ), 37 | .x_vld ( isqrt_1_x_vld ), 38 | .x ( isqrt_1_x ), 39 | .y_vld ( isqrt_1_y_vld ), 40 | .y ( isqrt_1_y ) 41 | ); 42 | 43 | isqrt i_isqrt_2 44 | ( 45 | .clk ( clk ), 46 | .rst ( rst ), 47 | .x_vld ( isqrt_2_x_vld ), 48 | .x ( isqrt_2_x ), 49 | .y_vld ( isqrt_2_y_vld ), 50 | .y ( isqrt_2_y ) 51 | ); 52 | 53 | endmodule 54 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_11_sqrt_formula_distributor/formula_2_fn.svh: -------------------------------------------------------------------------------- 1 | `ifndef FORMULA_2_FN_SVH 2 | `define FORMULA_2_FN_SVH 3 | 4 | //---------------------------------------------------------------------------- 5 | // Header file defining the formula. DO NOT MODIFY 6 | //---------------------------------------------------------------------------- 7 | 8 | `include "isqrt_fn.svh" 9 | 10 | function [31:0] formula_2_fn 11 | ( 12 | input [31:0] a, 13 | input [31:0] b, 14 | input [31:0] c 15 | ); 16 | return 32' (isqrt_fn (a + 32' (isqrt_fn (b + 32' (isqrt_fn (c) ) ) ) ) ); 17 | 18 | endfunction 19 | 20 | `endif 21 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_11_sqrt_formula_distributor/formula_2_top.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Top file wiring everything together. DO NOT MODIFY 3 | //---------------------------------------------------------------------------- 4 | 5 | module formula_2_top 6 | ( 7 | input clk, 8 | input rst, 9 | 10 | input arg_vld, 11 | input [31:0] a, 12 | input [31:0] b, 13 | input [31:0] c, 14 | 15 | output res_vld, 16 | output [31:0] res 17 | ); 18 | 19 | wire isqrt_x_vld; 20 | wire [31:0] isqrt_x; 21 | 22 | wire isqrt_y_vld; 23 | wire [15:0] isqrt_y; 24 | 25 | formula_2_fsm i_formula_2_fsm (.*); 26 | 27 | isqrt i_isqrt 28 | ( 29 | .clk ( clk ), 30 | .rst ( rst ), 31 | .x_vld ( isqrt_x_vld ), 32 | .x ( isqrt_x ), 33 | .y_vld ( isqrt_y_vld ), 34 | .y ( isqrt_y ) 35 | ); 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_11_sqrt_formula_distributor/lint_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --lint 4 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_11_sqrt_formula_distributor/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_11_sqrt_formula_distributor/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | if not exist "C:\Program Files\Git\bin\bash.exe" ( 4 | echo "Starting from Homework 3, this Windows batch script invokes" 5 | echo "a Bash shell interpreter from the Git for Windows package." 6 | echo "This is necessary for more flexible checking of the results." 7 | echo "Please install Git for Windows from https://gitforwindows.org/ and re-run this batch again." 8 | 9 | exit /b 10 | ) 11 | 12 | "C:\Program Files\Git\bin\bash.exe" run_linux_mac.sh 13 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_11_sqrt_formula_distributor/testbenches/isqrt_fn.svh: -------------------------------------------------------------------------------- 1 | // This example is written by Yuri Panchul 2 | // The algorithm is from Hacker's Delight by Henry Warren 3 | 4 | `ifndef ISQRT_FN_SVH 5 | `define ISQRT_FN_SVH 6 | 7 | function [15:0] isqrt_fn (input [31:0] x); 8 | 9 | logic [31:0] m, tx, ty, b; 10 | 11 | m = 32'h4000_0000; 12 | tx = x; 13 | ty = 0; 14 | 15 | repeat (16) 16 | begin 17 | b = ty | m; 18 | ty = ty >> 1; 19 | 20 | if (tx >= b) 21 | begin 22 | tx = tx - b; 23 | ty = ty | m; 24 | end 25 | 26 | m = m >> 2; 27 | end 28 | 29 | return ty [15:0]; 30 | 31 | endfunction 32 | 33 | `endif 34 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_11_sqrt_formula_distributor/testbenches/tb.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Top testbench file. 3 | // Runs all testbenches 4 | //---------------------------------------------------------------------------- 5 | 6 | module tb; 7 | 8 | formula_tb # ( .homework (4), .distributor (1), .formula (1), .impl (1) ) formula_1_impl_1_tb (); 9 | formula_tb # ( .homework (4), .distributor (1), .formula (1), .impl (2) ) formula_1_impl_2_tb (); 10 | formula_tb # ( .homework (4), .distributor (1), .formula (2) ) formula_2_tb (); 11 | 12 | initial 13 | begin 14 | `ifdef __ICARUS__ 15 | // Uncomment the following line 16 | // to generate a VCD file and analyze it using GTKwave 17 | 18 | // $dumpvars; 19 | `endif 20 | 21 | formula_1_impl_1_tb .run (); 22 | formula_1_impl_2_tb .run (); 23 | formula_2_tb .run (); 24 | 25 | $finish; 26 | end 27 | 28 | endmodule 29 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_11_sqrt_formula_distributor/wave_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --wave 4 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_11_sqrt_formula_distributor/wave_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | if not exist "C:\Program Files\Git\bin\bash.exe" ( 4 | echo "Starting from Homework 3, this Windows batch script invokes" 5 | echo "a Bash shell interpreter from the Git for Windows package." 6 | echo "This is necessary for more flexible checking of the results." 7 | echo "Please install Git for Windows from https://gitforwindows.org/ and re-run this batch again." 8 | 9 | exit /b 10 | ) 11 | 12 | "C:\Program Files\Git\bin\bash.exe" run_linux_mac.sh --wave 13 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_12_float_discriminant_distributor/03_08_float_discriminant.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Task 3 | //---------------------------------------------------------------------------- 4 | 5 | module float_discriminant ( 6 | input clk, 7 | input rst, 8 | 9 | input arg_vld, 10 | input [FLEN - 1:0] a, 11 | input [FLEN - 1:0] b, 12 | input [FLEN - 1:0] c, 13 | 14 | output logic res_vld, 15 | output logic [FLEN - 1:0] res, 16 | output logic res_negative, 17 | output logic err, 18 | 19 | output logic busy 20 | ); 21 | 22 | // Task: 23 | // Implement a module that accepts three Floating-Point numbers and outputs their discriminant. 24 | // The resulting value res should be calculated as a discriminant of the quadratic polynomial. 25 | // That is, res = b^2 - 4ac == b*b - 4*a*c 26 | // 27 | // Note: 28 | // If any argument is not a valid number, that is NaN or Inf, the "err" flag should be set. 29 | // 30 | // The FLEN parameter is defined in the "import/preprocessed/cvw/config-shared.vh" file 31 | // and usually equal to the bit width of the double-precision floating-point number, FP64, 64 bits. 32 | 33 | 34 | endmodule 35 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_12_float_discriminant_distributor/04_12_float_discriminant_distributor.sv: -------------------------------------------------------------------------------- 1 | module float_discriminant_distributor ( 2 | input clk, 3 | input rst, 4 | 5 | input arg_vld, 6 | input [FLEN - 1:0] a, 7 | input [FLEN - 1:0] b, 8 | input [FLEN - 1:0] c, 9 | 10 | output logic res_vld, 11 | output logic [FLEN - 1:0] res, 12 | output logic res_negative, 13 | output logic err, 14 | 15 | output logic busy 16 | ); 17 | 18 | // Task: 19 | // 20 | // Implement a module that will calculate the discriminant based 21 | // on the triplet of input number a, b, c. The module must be pipelined. 22 | // It should be able to accept a new triple of arguments on each clock cycle 23 | // and also, after some time, provide the result on each clock cycle. 24 | // The idea of the task is similar to the task 04_11. The main difference is 25 | // in the underlying module 03_08 instead of formula modules. 26 | // 27 | // Note 1: 28 | // Reuse your file "03_08_float_discriminant.sv" from the Homework 03. 29 | // 30 | // Note 2: 31 | // Latency of the module "float_discriminant" should be clarified from the waveform. 32 | 33 | 34 | endmodule 35 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_12_float_discriminant_distributor/diagram.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/04_arithmetics_and_pipelining/04_12_float_discriminant_distributor/diagram.pdf -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_13_put_in_order/04_13_put_in_order.sv: -------------------------------------------------------------------------------- 1 | module put_in_order 2 | # ( 3 | parameter width = 16, 4 | n_inputs = 4 5 | ) 6 | ( 7 | input clk, 8 | input rst, 9 | 10 | input [ n_inputs - 1 : 0 ] up_vlds, 11 | input [ n_inputs - 1 : 0 ] 12 | [ width - 1 : 0 ] up_data, 13 | 14 | output down_vld, 15 | output [ width - 1 : 0 ] down_data 16 | ); 17 | 18 | // Task: 19 | // 20 | // Implement a module that accepts many outputs of the computational blocks 21 | // and outputs them one by one in order. Input signals "up_vlds" and "up_data" 22 | // are coming from an array of non-pipelined computational blocks. 23 | // These external computational blocks have a variable latency. 24 | // 25 | // The order of incoming "up_vlds" is not determent, and the task is to 26 | // output "down_vld" and corresponding data in a round-robin manner, 27 | // one after another, in order. 28 | // 29 | // Comment: 30 | // The idea of the block is kinda similar to the "parallel_to_serial" block 31 | // from Homework 2, but here block should also preserve the output order. 32 | 33 | 34 | endmodule 35 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_13_put_in_order/diagram.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/04_arithmetics_and_pipelining/04_13_put_in_order/diagram.pdf -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/04_13_put_in_order/testbench.sv: -------------------------------------------------------------------------------- 1 | module testbench; 2 | 3 | testbench_1 tb_1 (); 4 | testbench_2 tb_2 (); 5 | 6 | initial 7 | begin 8 | // First, prevent tb_1 from running by stalling its clock 9 | 10 | force tb_1.clk = '0; 11 | 12 | // Now run tb_2 13 | 14 | tb_2.run (); 15 | 16 | // Finally, let tb_1 to run 17 | 18 | release tb_1.clk; 19 | end 20 | 21 | endmodule 22 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/README_ru.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/04_arithmetics_and_pipelining/README_ru.pdf -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/lint_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --lint 4 | -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" -------------------------------------------------------------------------------- /04_arithmetics_and_pipelining/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | if not exist "C:\Program Files\Git\bin\bash.exe" ( 4 | echo "Starting from Homework 3, this Windows batch script invokes" 5 | echo "a Bash shell interpreter from the Git for Windows package." 6 | echo "This is necessary for more flexible checking of the results." 7 | echo "Please install Git for Windows from https://gitforwindows.org/ and re-run this batch again." 8 | 9 | exit /b 10 | ) 11 | 12 | "C:\Program Files\Git\bin\bash.exe" run_linux_mac.sh 13 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_01_fifo_with_counter_baseline/gtkwave.tcl: -------------------------------------------------------------------------------- 1 | # gtkwave::loadFile "dump.vcd" 2 | 3 | set all_signals [list] 4 | 5 | lappend all_signals tb.clk 6 | lappend all_signals tb.rst 7 | lappend all_signals tb.push 8 | lappend all_signals tb.pop 9 | lappend all_signals tb.write_data 10 | lappend all_signals tb.read_data 11 | lappend all_signals tb.empty 12 | lappend all_signals tb.full 13 | 14 | set num_added [ gtkwave::addSignalsFromList $all_signals ] 15 | 16 | gtkwave::/Time/Zoom/Zoom_Full 17 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_01_fifo_with_counter_baseline/lint_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --lint 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_01_fifo_with_counter_baseline/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_01_fifo_with_counter_baseline/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "%1" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_01_fifo_with_counter_baseline/wave_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --wave 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_01_fifo_with_counter_baseline/wave_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "-wave" 23 | 24 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_02_fifo_pow2_depth/gtkwave.tcl: -------------------------------------------------------------------------------- 1 | # gtkwave::loadFile "dump.vcd" 2 | 3 | set all_signals [list] 4 | 5 | lappend all_signals tb.clk 6 | lappend all_signals tb.rst 7 | lappend all_signals tb.push 8 | lappend all_signals tb.pop 9 | lappend all_signals tb.write_data 10 | lappend all_signals tb.read_data 11 | lappend all_signals tb.empty 12 | lappend all_signals tb.full 13 | 14 | set num_added [ gtkwave::addSignalsFromList $all_signals ] 15 | 16 | gtkwave::/Time/Zoom/Zoom_Full 17 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_02_fifo_pow2_depth/lint_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --lint 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_02_fifo_pow2_depth/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_02_fifo_pow2_depth/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "%1" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_02_fifo_pow2_depth/wave_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --wave 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_02_fifo_pow2_depth/wave_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "-wave" 23 | 24 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_03_fifo_empty_full_optimized/gtkwave.tcl: -------------------------------------------------------------------------------- 1 | # gtkwave::loadFile "dump.vcd" 2 | 3 | set all_signals [list] 4 | 5 | lappend all_signals tb.clk 6 | lappend all_signals tb.rst 7 | lappend all_signals tb.push 8 | lappend all_signals tb.pop 9 | lappend all_signals tb.write_data 10 | lappend all_signals tb.read_data 11 | lappend all_signals tb.empty 12 | lappend all_signals tb.full 13 | 14 | set num_added [ gtkwave::addSignalsFromList $all_signals ] 15 | 16 | gtkwave::/Time/Zoom/Zoom_Full 17 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_03_fifo_empty_full_optimized/lint_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --lint 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_03_fifo_empty_full_optimized/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_03_fifo_empty_full_optimized/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "%1" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_03_fifo_empty_full_optimized/wave_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --wave 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_03_fifo_empty_full_optimized/wave_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "-wave" 23 | 24 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_04_fifo_with_reg_empty_full/gtkwave.tcl: -------------------------------------------------------------------------------- 1 | # gtkwave::loadFile "dump.vcd" 2 | 3 | set all_signals [list] 4 | 5 | lappend all_signals tb.clk 6 | lappend all_signals tb.rst 7 | lappend all_signals tb.push 8 | lappend all_signals tb.pop 9 | lappend all_signals tb.write_data 10 | lappend all_signals tb.read_data 11 | lappend all_signals tb.empty 12 | lappend all_signals tb.full 13 | 14 | set num_added [ gtkwave::addSignalsFromList $all_signals ] 15 | 16 | gtkwave::/Time/Zoom/Zoom_Full 17 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_04_fifo_with_reg_empty_full/lint_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --lint 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_04_fifo_with_reg_empty_full/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_04_fifo_with_reg_empty_full/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "%1" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_04_fifo_with_reg_empty_full/wave_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --wave 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_04_fifo_with_reg_empty_full/wave_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "-wave" 23 | 24 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_05_1_a_plus_b_using_double_buffers/double_buffer_from_dally_harting.sv: -------------------------------------------------------------------------------- 1 | // This design is a Yuri Panchul's edition 2 | // of the code derived from: 3 | // 4 | // Digital Design: A Systems Approach 5 | // by William James Dally and R. Curtis Harting 6 | // 2012 7 | 8 | module double_buffer_from_dally_harting 9 | # ( 10 | parameter width = 0 11 | ) 12 | ( 13 | input clk, 14 | input rst, 15 | 16 | input up_valid, 17 | output logic up_ready, 18 | input [width - 1:0] up_data, 19 | 20 | output logic down_valid, 21 | input down_ready, 22 | output logic [width - 1:0] down_data 23 | ); 24 | 25 | logic buf_valid; 26 | logic [width - 1:0] buf_data; 27 | 28 | always_ff @ (posedge clk) 29 | begin 30 | if (up_ready & ~ down_ready) 31 | buf_data <= up_data; 32 | 33 | if (down_ready) 34 | down_data <= up_ready ? up_data : buf_data; 35 | end 36 | 37 | always_ff @ (posedge clk or posedge rst) 38 | if (rst) 39 | begin 40 | buf_valid <= 1'b0; 41 | down_valid <= 1'b0; 42 | up_ready <= 1'b1; 43 | end 44 | else 45 | begin 46 | if (up_ready & ~ down_ready) 47 | buf_valid <= up_valid; 48 | 49 | if (down_ready) 50 | down_valid <= up_ready ? up_valid : buf_valid; 51 | 52 | up_ready <= down_ready; 53 | end 54 | 55 | endmodule 56 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_05_1_a_plus_b_using_double_buffers/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_05_1_a_plus_b_using_double_buffers/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "%1" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_05_1_a_plus_b_using_double_buffers/wave_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "-wave" 23 | 24 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_05_2_a_plus_b_using_fifos/ff_fifo_wrapped_in_valid_ready.sv: -------------------------------------------------------------------------------- 1 | module ff_fifo_wrapped_in_valid_ready 2 | # ( 3 | parameter width = 8, depth = 10 4 | ) 5 | ( 6 | input clk, 7 | input rst, 8 | 9 | input up_valid, // upstream 10 | output up_ready, 11 | input [width - 1:0] up_data, 12 | 13 | output down_valid, // downstream 14 | input down_ready, 15 | output [width - 1:0] down_data 16 | ); 17 | 18 | wire fifo_push; 19 | wire fifo_pop; 20 | wire fifo_empty; 21 | wire fifo_full; 22 | 23 | assign up_ready = ~ fifo_full; 24 | assign fifo_push = up_valid & up_ready; 25 | 26 | assign down_valid = ~ fifo_empty; 27 | assign fifo_pop = down_valid & down_ready; 28 | 29 | flip_flop_fifo 30 | # (.width (width), .depth (depth)) 31 | fifo 32 | ( 33 | .clk ( clk ), 34 | .rst ( rst ), 35 | .push ( fifo_push ), 36 | .pop ( fifo_pop ), 37 | .write_data ( up_data ), 38 | .read_data ( down_data ), 39 | .empty ( fifo_empty ), 40 | .full ( fifo_full ) 41 | ); 42 | 43 | endmodule 44 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_05_2_a_plus_b_using_fifos/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_05_2_a_plus_b_using_fifos/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "%1" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_05_2_a_plus_b_using_fifos/wave_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "-wave" 23 | 24 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_05_a_plus_b_using_fifos_and_double_buffer/double_buffer_from_dally_harting.sv: -------------------------------------------------------------------------------- 1 | // This solution is a Yuri Panchul's edition 2 | // of the code derived from: 3 | // 4 | // Digital Design: A Systems Approach 5 | // by William James Dally and R. Curtis Harting 6 | // 2012 7 | 8 | module double_buffer_from_dally_harting 9 | # ( 10 | parameter width = 0 11 | ) 12 | ( 13 | input clk, 14 | input rst, 15 | 16 | input up_valid, 17 | output logic up_ready, 18 | input [width - 1:0] up_data, 19 | 20 | output logic down_valid, 21 | input down_ready, 22 | output logic [width - 1:0] down_data 23 | ); 24 | 25 | logic buf_valid; 26 | logic [width - 1:0] buf_data; 27 | 28 | always_ff @ (posedge clk) 29 | begin 30 | if (up_ready & ~ down_ready) 31 | buf_data <= up_data; 32 | 33 | if (down_ready) 34 | down_data <= up_ready ? up_data : buf_data; 35 | end 36 | 37 | always_ff @ (posedge clk or posedge rst) 38 | if (rst) 39 | begin 40 | buf_valid <= 1'b0; 41 | down_valid <= 1'b0; 42 | up_ready <= 1'b1; 43 | end 44 | else 45 | begin 46 | if (up_ready & ~ down_ready) 47 | buf_valid <= up_valid; 48 | 49 | if (down_ready) 50 | down_valid <= up_ready ? up_valid : buf_valid; 51 | 52 | up_ready <= down_ready; 53 | end 54 | 55 | endmodule 56 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_05_a_plus_b_using_fifos_and_double_buffer/lint_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --lint 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_05_a_plus_b_using_fifos_and_double_buffer/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_05_a_plus_b_using_fifos_and_double_buffer/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "%1" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_05_a_plus_b_using_fifos_and_double_buffer/wave_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --wave 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_05_a_plus_b_using_fifos_and_double_buffer/wave_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "-wave" 23 | 24 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_06_sqrt_formula_pipe/04_07_formula_1_pipe.sv: -------------------------------------------------------------------------------- 1 | module formula_1_pipe 2 | ( 3 | input clk, 4 | input rst, 5 | 6 | input arg_vld, 7 | input [31:0] a, 8 | input [31:0] b, 9 | input [31:0] c, 10 | 11 | output res_vld, 12 | output [31:0] res 13 | ); 14 | 15 | // NOTHING TO DO HERE 16 | 17 | 18 | endmodule 19 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_06_sqrt_formula_pipe/04_08_formula_1_pipe_aware_fsm.sv: -------------------------------------------------------------------------------- 1 | module formula_1_pipe_aware_fsm 2 | ( 3 | input clk, 4 | input rst, 5 | 6 | input arg_vld, 7 | input [31:0] a, 8 | input [31:0] b, 9 | input [31:0] c, 10 | 11 | output logic res_vld, 12 | output logic [31:0] res, 13 | 14 | // isqrt interface 15 | 16 | output logic isqrt_x_vld, 17 | output logic [31:0] isqrt_x, 18 | 19 | input isqrt_y_vld, 20 | input [15:0] isqrt_y 21 | ); 22 | // NOTHING TO DO HERE 23 | 24 | 25 | endmodule 26 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_06_sqrt_formula_pipe/04_10_formula_2_pipe.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Task 3 | //---------------------------------------------------------------------------- 4 | 5 | module formula_2_pipe 6 | ( 7 | input clk, 8 | input rst, 9 | 10 | input arg_vld, 11 | input [31:0] a, 12 | input [31:0] b, 13 | input [31:0] c, 14 | 15 | output res_vld, 16 | output [31:0] res 17 | ); 18 | 19 | // NOTHING TO DO HERE 20 | 21 | 22 | endmodule 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_06_sqrt_formula_pipe/black_boxes/isqrt_slice_comb.sv: -------------------------------------------------------------------------------- 1 | module isqrt_slice_comb 2 | # ( 3 | parameter [31:0] m = 32'h4000_0000 4 | ) 5 | ( 6 | input [31:0] ix, 7 | input [31:0] iy, 8 | output [31:0] ox, 9 | output [31:0] oy 10 | ); 11 | 12 | wire [31:0] b = iy | m; 13 | wire x_ge_b = ix >= b; 14 | 15 | assign ox = x_ge_b ? ix - b : ix; 16 | assign oy = (iy >> 1) | (x_ge_b ? m : 0); 17 | 18 | endmodule 19 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_06_sqrt_formula_pipe/black_boxes/isqrt_slice_reg.sv: -------------------------------------------------------------------------------- 1 | module isqrt_slice_reg 2 | # ( 3 | parameter [31:0] m = 32'h4000_0000 4 | ) 5 | ( 6 | input clk, 7 | input rst, 8 | 9 | input ivld, 10 | input [31:0] ix, 11 | input [31:0] iy, 12 | 13 | output logic ovld, 14 | output logic [31:0] ox, 15 | output logic [31:0] oy 16 | ); 17 | 18 | wire [31:0] cox, coy; 19 | 20 | isqrt_slice_comb # (.m (m)) inst 21 | ( 22 | .ix ( ix ), 23 | .iy ( iy ), 24 | .ox ( cox ), 25 | .oy ( coy ) 26 | ); 27 | 28 | always_ff @ (posedge clk) 29 | if (rst) 30 | ovld <= 1'b0; 31 | else 32 | ovld <= ivld; 33 | 34 | always_ff @ (posedge clk) 35 | if (ivld) 36 | begin 37 | ox <= cox; 38 | oy <= coy; 39 | end 40 | 41 | endmodule 42 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_06_sqrt_formula_pipe/formula_1_fn.svh: -------------------------------------------------------------------------------- 1 | `ifndef FORMULA_1_FN_SVH 2 | `define FORMULA_1_FN_SVH 3 | 4 | //---------------------------------------------------------------------------- 5 | // Header file defining the formula. DO NOT MODIFY 6 | //---------------------------------------------------------------------------- 7 | 8 | `include "isqrt_fn.svh" 9 | 10 | function [31:0] formula_1_fn 11 | ( 12 | input [31:0] a, 13 | input [31:0] b, 14 | input [31:0] c 15 | ); 16 | return 32' (isqrt_fn (a)) + 32' (isqrt_fn (b)) + 32' (isqrt_fn (c)); 17 | 18 | endfunction 19 | 20 | `endif 21 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_06_sqrt_formula_pipe/formula_1_pipe_aware_fsm_top.sv: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Top file wiring everything together. DO NOT MODIFY 3 | //---------------------------------------------------------------------------- 4 | 5 | module formula_1_pipe_aware_fsm_top 6 | ( 7 | input clk, 8 | input rst, 9 | 10 | input arg_vld, 11 | input [31:0] a, 12 | input [31:0] b, 13 | input [31:0] c, 14 | 15 | output res_vld, 16 | output [31:0] res 17 | ); 18 | 19 | wire isqrt_x_vld; 20 | wire [31:0] isqrt_x; 21 | 22 | wire isqrt_y_vld; 23 | wire [15:0] isqrt_y; 24 | 25 | formula_1_pipe_aware_fsm i_formula_1_pipe_aware_fsm (.*); 26 | 27 | isqrt # (.n_pipe_stages (4)) i_isqrt 28 | ( 29 | .clk ( clk ), 30 | .rst ( rst ), 31 | .x_vld ( isqrt_x_vld ), 32 | .x ( isqrt_x ), 33 | .y_vld ( isqrt_y_vld ), 34 | .y ( isqrt_y ) 35 | ); 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_06_sqrt_formula_pipe/formula_2_fn.svh: -------------------------------------------------------------------------------- 1 | `ifndef FORMULA_2_FN_SVH 2 | `define FORMULA_2_FN_SVH 3 | 4 | //---------------------------------------------------------------------------- 5 | // Header file defining the formula. DO NOT MODIFY 6 | //---------------------------------------------------------------------------- 7 | 8 | `include "isqrt_fn.svh" 9 | 10 | function [31:0] formula_2_fn 11 | ( 12 | input [31:0] a, 13 | input [31:0] b, 14 | input [31:0] c 15 | ); 16 | return 32' (isqrt_fn (a + 32' (isqrt_fn (b + 32' (isqrt_fn (c) ) ) ) ) ); 17 | 18 | endfunction 19 | 20 | `endif 21 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_06_sqrt_formula_pipe/lint_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --lint 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_06_sqrt_formula_pipe/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_06_sqrt_formula_pipe/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "%1" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_06_sqrt_formula_pipe/testbenches/isqrt_fn.svh: -------------------------------------------------------------------------------- 1 | // This example is written by Yuri Panchul 2 | // The algorithm is from Hacker's Delight by Henry Warren 3 | 4 | `ifndef ISQRT_FN_SVH 5 | `define ISQRT_FN_SVH 6 | 7 | function [15:0] isqrt_fn (input [31:0] x); 8 | 9 | logic [31:0] m, tx, ty, b; 10 | 11 | m = 32'h4000_0000; 12 | tx = x; 13 | ty = 0; 14 | 15 | repeat (16) 16 | begin 17 | b = ty | m; 18 | ty = ty >> 1; 19 | 20 | if (tx >= b) 21 | begin 22 | tx = tx - b; 23 | ty = ty | m; 24 | end 25 | 26 | m = m >> 2; 27 | end 28 | 29 | return ty [15:0]; 30 | 31 | endfunction 32 | 33 | `endif 34 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_06_sqrt_formula_pipe/wave_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --wave 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_06_sqrt_formula_pipe/wave_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "-wave" 23 | 24 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_07_cpu_baseline/gtkwave.tcl: -------------------------------------------------------------------------------- 1 | # gtkwave::loadFile "dump.vcd" 2 | 3 | set all_signals [list] 4 | 5 | lappend all_signals tb.clk 6 | lappend all_signals tb.rst 7 | lappend all_signals tb.cpu.pc 8 | lappend all_signals tb.imAddr 9 | lappend all_signals tb.imData 10 | lappend all_signals tb.regAddr 11 | lappend all_signals tb.regData 12 | 13 | set num_added [ gtkwave::addSignalsFromList $all_signals ] 14 | 15 | gtkwave::/Time/Zoom/Zoom_Full 16 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_07_cpu_baseline/instruction_rom.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | module instruction_rom 14 | #( 15 | parameter SIZE = 64, 16 | parameter ADDR_W = $clog2(SIZE) 17 | ) 18 | ( 19 | input [ADDR_W - 1:0] a, 20 | output [ 31:0] rd 21 | ); 22 | reg [31:0] rom [0:SIZE - 1]; 23 | assign rd = rom [a]; 24 | 25 | initial $readmemh ("program.hex", rom); 26 | 27 | endmodule 28 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_07_cpu_baseline/lint_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --lint 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_07_cpu_baseline/program.s: -------------------------------------------------------------------------------- 1 | # li pseudo-instruction 2 | 3 | li t0, 0x123 4 | li t1, 0x12345678 5 | li t2, 0x12345000 6 | li t3, -0x123 7 | 8 | # RISC-V fibonacci program 9 | # 10 | # Stanislav Zhelnio, 2020 11 | # Amended by Yuri Panchul, 2024 12 | 13 | fibonacci: 14 | 15 | mv a0, zero 16 | li t0, 1 17 | 18 | loop: add t1, a0, t0 19 | mv a0, t0 20 | mv t0, t1 21 | beqz zero, loop 22 | 23 | # RISC-V factorial program 24 | # Uncomment it when necessary 25 | 26 | # factorial: 27 | # 28 | # li a0, 1 29 | # li t0, 2 30 | # 31 | # loop: mul a0, a0, t0 32 | # addi t0, t0, 1 33 | # b loop 34 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_07_cpu_baseline/register_with_rst.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | module register_with_rst 14 | ( 15 | input clk, 16 | input rst, 17 | input [31:0] d, 18 | output logic [31:0] q 19 | ); 20 | 21 | always_ff @ (posedge clk) 22 | if (rst) 23 | q <= '0; 24 | else 25 | q <= d; 26 | 27 | endmodule 28 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_07_cpu_baseline/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_07_cpu_baseline/run_rars_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_07_cpu_baseline/run_rars_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_rars_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_07_cpu_baseline/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "%1" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_07_cpu_baseline/sr_alu.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | `include "sr_cpu.svh" 14 | 15 | module sr_alu 16 | ( 17 | input [31:0] srcA, 18 | input [31:0] srcB, 19 | input [ 2:0] oper, 20 | output zero, 21 | output logic [31:0] result 22 | ); 23 | 24 | always_comb 25 | case (oper) 26 | default : result = srcA + srcB; 27 | `ALU_ADD : result = srcA + srcB; 28 | `ALU_OR : result = srcA | srcB; 29 | `ALU_SRL : result = srcA >> srcB [4:0]; 30 | `ALU_SLTU : result = (srcA < srcB) ? 32'd1 : 32'd0; 31 | `ALU_SUB : result = srcA - srcB; 32 | endcase 33 | 34 | assign zero = (result == '0); 35 | 36 | endmodule 37 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_07_cpu_baseline/sr_cpu.svh: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | `ifndef SR_CPU_SVH 14 | `define SR_CPU_SVH 15 | 16 | // ALU commands 17 | 18 | `define ALU_ADD 3'b000 19 | `define ALU_OR 3'b001 20 | `define ALU_SRL 3'b010 21 | `define ALU_SLTU 3'b011 22 | `define ALU_SUB 3'b100 23 | 24 | // Instruction opcode 25 | 26 | `define RVOP_ADDI 7'b0010011 27 | `define RVOP_BEQ 7'b1100011 28 | `define RVOP_LUI 7'b0110111 29 | `define RVOP_BNE 7'b1100011 30 | `define RVOP_ADD 7'b0110011 31 | `define RVOP_OR 7'b0110011 32 | `define RVOP_SRL 7'b0110011 33 | `define RVOP_SLTU 7'b0110011 34 | `define RVOP_SUB 7'b0110011 35 | 36 | // Instruction funct3 37 | 38 | `define RVF3_ADDI 3'b000 39 | `define RVF3_BEQ 3'b000 40 | `define RVF3_BNE 3'b001 41 | `define RVF3_ADD 3'b000 42 | `define RVF3_OR 3'b110 43 | `define RVF3_SRL 3'b101 44 | `define RVF3_SLTU 3'b011 45 | `define RVF3_SUB 3'b000 46 | `define RVF3_ANY 3'b??? 47 | 48 | // Instruction funct7 49 | 50 | `define RVF7_ADD 7'b0000000 51 | `define RVF7_OR 7'b0000000 52 | `define RVF7_SRL 7'b0000000 53 | `define RVF7_SLTU 7'b0000000 54 | `define RVF7_SUB 7'b0100000 55 | `define RVF7_ANY 7'b??????? 56 | 57 | `endif // `ifndef SR_CPU_SVH 58 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_07_cpu_baseline/sr_register_file.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | `include "sr_cpu.svh" 14 | 15 | module sr_register_file 16 | ( 17 | input clk, 18 | input [ 4:0] a0, 19 | input [ 4:0] a1, 20 | input [ 4:0] a2, 21 | input [ 4:0] a3, 22 | output [31:0] rd0, 23 | output [31:0] rd1, 24 | output [31:0] rd2, 25 | input [31:0] wd3, 26 | input we3 27 | ); 28 | logic [31:0] rf [0:31]; 29 | 30 | assign rd0 = (a0 != 0) ? rf [a0] : 32'b0; 31 | assign rd1 = (a1 != 0) ? rf [a1] : 32'b0; 32 | assign rd2 = (a2 != 0) ? rf [a2] : 32'b0; 33 | 34 | always_ff @ (posedge clk) 35 | if(we3) rf [a3] <= wd3; 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_07_cpu_baseline/wave_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --wave 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_07_cpu_baseline/wave_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "-wave" 23 | 24 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_08_cpu_with_comb_mul_instr/gtkwave.tcl: -------------------------------------------------------------------------------- 1 | # gtkwave::loadFile "dump.vcd" 2 | 3 | set all_signals [list] 4 | 5 | lappend all_signals tb.clk 6 | lappend all_signals tb.rst 7 | lappend all_signals tb.cpu.pc 8 | lappend all_signals tb.imAddr 9 | lappend all_signals tb.imData 10 | lappend all_signals tb.regAddr 11 | lappend all_signals tb.regData 12 | 13 | set num_added [ gtkwave::addSignalsFromList $all_signals ] 14 | 15 | gtkwave::/Time/Zoom/Zoom_Full 16 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_08_cpu_with_comb_mul_instr/instruction_rom.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | module instruction_rom 14 | #( 15 | parameter SIZE = 64, 16 | parameter ADDR_W = $clog2(SIZE) 17 | ) 18 | ( 19 | input [ADDR_W - 1:0] a, 20 | output [ 31:0] rd 21 | ); 22 | reg [31:0] rom [0:SIZE - 1]; 23 | assign rd = rom [a]; 24 | 25 | initial $readmemh ("program.hex", rom); 26 | 27 | endmodule 28 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_08_cpu_with_comb_mul_instr/lint_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --lint 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_08_cpu_with_comb_mul_instr/program.s: -------------------------------------------------------------------------------- 1 | # RISC-V factorial program 2 | 3 | factorial: 4 | 5 | li a0, 1 6 | li t0, 2 7 | 8 | loop: mul a0, a0, t0 9 | addi t0, t0, 1 10 | beqz zero, loop 11 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_08_cpu_with_comb_mul_instr/register_with_rst.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | module register_with_rst 14 | ( 15 | input clk, 16 | input rst, 17 | input [31:0] d, 18 | output logic [31:0] q 19 | ); 20 | 21 | always_ff @ (posedge clk) 22 | if (rst) 23 | q <= '0; 24 | else 25 | q <= d; 26 | 27 | endmodule 28 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_08_cpu_with_comb_mul_instr/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_08_cpu_with_comb_mul_instr/run_rars_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_08_cpu_with_comb_mul_instr/run_rars_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_rars_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_08_cpu_with_comb_mul_instr/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "%1" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_08_cpu_with_comb_mul_instr/sr_alu.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | `include "sr_cpu.svh" 14 | 15 | module sr_alu 16 | ( 17 | input [31:0] srcA, 18 | input [31:0] srcB, 19 | input [ 2:0] oper, 20 | output zero, 21 | output logic [31:0] result 22 | ); 23 | 24 | always_comb 25 | case (oper) 26 | default : result = srcA + srcB; 27 | `ALU_ADD : result = srcA + srcB; 28 | `ALU_OR : result = srcA | srcB; 29 | `ALU_SRL : result = srcA >> srcB [4:0]; 30 | `ALU_SLTU : result = (srcA < srcB) ? 32'd1 : 32'd0; 31 | `ALU_SUB : result = srcA - srcB; 32 | endcase 33 | 34 | assign zero = (result == '0); 35 | 36 | endmodule 37 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_08_cpu_with_comb_mul_instr/sr_cpu.svh: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | `ifndef SR_CPU_SVH 14 | `define SR_CPU_SVH 15 | 16 | // ALU commands 17 | 18 | `define ALU_ADD 3'b000 19 | `define ALU_OR 3'b001 20 | `define ALU_SRL 3'b010 21 | `define ALU_SLTU 3'b011 22 | `define ALU_SUB 3'b100 23 | 24 | // Instruction opcode 25 | 26 | `define RVOP_ADDI 7'b0010011 27 | `define RVOP_BEQ 7'b1100011 28 | `define RVOP_LUI 7'b0110111 29 | `define RVOP_BNE 7'b1100011 30 | `define RVOP_ADD 7'b0110011 31 | `define RVOP_OR 7'b0110011 32 | `define RVOP_SRL 7'b0110011 33 | `define RVOP_SLTU 7'b0110011 34 | `define RVOP_SUB 7'b0110011 35 | 36 | // Instruction funct3 37 | 38 | `define RVF3_ADDI 3'b000 39 | `define RVF3_BEQ 3'b000 40 | `define RVF3_BNE 3'b001 41 | `define RVF3_ADD 3'b000 42 | `define RVF3_OR 3'b110 43 | `define RVF3_SRL 3'b101 44 | `define RVF3_SLTU 3'b011 45 | `define RVF3_SUB 3'b000 46 | `define RVF3_ANY 3'b??? 47 | 48 | // Instruction funct7 49 | 50 | `define RVF7_ADD 7'b0000000 51 | `define RVF7_OR 7'b0000000 52 | `define RVF7_SRL 7'b0000000 53 | `define RVF7_SLTU 7'b0000000 54 | `define RVF7_SUB 7'b0100000 55 | `define RVF7_ANY 7'b??????? 56 | 57 | `endif // `ifndef SR_CPU_SVH 58 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_08_cpu_with_comb_mul_instr/sr_register_file.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | `include "sr_cpu.svh" 14 | 15 | module sr_register_file 16 | ( 17 | input clk, 18 | input [ 4:0] a0, 19 | input [ 4:0] a1, 20 | input [ 4:0] a2, 21 | input [ 4:0] a3, 22 | output [31:0] rd0, 23 | output [31:0] rd1, 24 | output [31:0] rd2, 25 | input [31:0] wd3, 26 | input we3 27 | ); 28 | logic [31:0] rf [0:31]; 29 | 30 | assign rd0 = (a0 != 0) ? rf [a0] : 32'b0; 31 | assign rd1 = (a1 != 0) ? rf [a1] : 32'b0; 32 | assign rd2 = (a2 != 0) ? rf [a2] : 32'b0; 33 | 34 | always_ff @ (posedge clk) 35 | if(we3) rf [a3] <= wd3; 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_08_cpu_with_comb_mul_instr/wave_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --wave 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_08_cpu_with_comb_mul_instr/wave_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "-wave" 23 | 24 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_09_cpu_mul_with_latency/gtkwave.tcl: -------------------------------------------------------------------------------- 1 | # gtkwave::loadFile "dump.vcd" 2 | 3 | set all_signals [list] 4 | 5 | lappend all_signals tb.clk 6 | lappend all_signals tb.rst 7 | lappend all_signals tb.cpu.pc 8 | lappend all_signals tb.imAddr 9 | lappend all_signals tb.imData 10 | lappend all_signals tb.regAddr 11 | lappend all_signals tb.regData 12 | 13 | set num_added [ gtkwave::addSignalsFromList $all_signals ] 14 | 15 | gtkwave::/Time/Zoom/Zoom_Full 16 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_09_cpu_mul_with_latency/instruction_rom.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | module instruction_rom 14 | #( 15 | parameter SIZE = 64, 16 | parameter ADDR_W = $clog2(SIZE) 17 | ) 18 | ( 19 | input [ADDR_W - 1:0] a, 20 | output [ 31:0] rd 21 | ); 22 | reg [31:0] rom [0:SIZE - 1]; 23 | assign rd = rom [a]; 24 | 25 | initial $readmemh ("program.hex", rom); 26 | 27 | endmodule 28 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_09_cpu_mul_with_latency/lint_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --lint 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_09_cpu_mul_with_latency/program.s: -------------------------------------------------------------------------------- 1 | # RISC-V factorial program 2 | 3 | factorial: 4 | 5 | li a0, 1 6 | li t0, 2 7 | 8 | loop: mul a0, a0, t0 9 | addi t0, t0, 1 10 | beqz zero, loop 11 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_09_cpu_mul_with_latency/register_with_rst_and_en.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | module register_with_rst_and_en 14 | ( 15 | input clk, 16 | input rst, 17 | input en, 18 | input [31:0] d, 19 | output logic [31:0] q 20 | ); 21 | 22 | always_ff @ (posedge clk) 23 | if (rst) 24 | q <= '0; 25 | else if (en) 26 | q <= d; 27 | 28 | endmodule 29 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_09_cpu_mul_with_latency/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_09_cpu_mul_with_latency/run_rars_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_09_cpu_mul_with_latency/run_rars_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_rars_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_09_cpu_mul_with_latency/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "%1" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_09_cpu_mul_with_latency/sr_alu.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | `include "sr_cpu.svh" 14 | 15 | module sr_alu 16 | ( 17 | input [31:0] srcA, 18 | input [31:0] srcB, 19 | input [ 2:0] oper, 20 | output zero, 21 | output logic [31:0] result 22 | ); 23 | 24 | always_comb 25 | case (oper) 26 | default : result = srcA + srcB; 27 | `ALU_ADD : result = srcA + srcB; 28 | `ALU_OR : result = srcA | srcB; 29 | `ALU_SRL : result = srcA >> srcB [4:0]; 30 | `ALU_SLTU : result = (srcA < srcB) ? 32'd1 : 32'd0; 31 | `ALU_SUB : result = srcA - srcB; 32 | endcase 33 | 34 | assign zero = (result == '0); 35 | 36 | endmodule 37 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_09_cpu_mul_with_latency/sr_cpu.svh: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | `ifndef SR_CPU_SVH 14 | `define SR_CPU_SVH 15 | 16 | // ALU commands 17 | 18 | `define ALU_ADD 3'b000 19 | `define ALU_OR 3'b001 20 | `define ALU_SRL 3'b010 21 | `define ALU_SLTU 3'b011 22 | `define ALU_SUB 3'b100 23 | 24 | // Instruction opcode 25 | 26 | `define RVOP_ADDI 7'b0010011 27 | `define RVOP_BEQ 7'b1100011 28 | `define RVOP_LUI 7'b0110111 29 | `define RVOP_BNE 7'b1100011 30 | `define RVOP_ADD 7'b0110011 31 | `define RVOP_OR 7'b0110011 32 | `define RVOP_SRL 7'b0110011 33 | `define RVOP_SLTU 7'b0110011 34 | `define RVOP_SUB 7'b0110011 35 | 36 | // Instruction funct3 37 | 38 | `define RVF3_ADDI 3'b000 39 | `define RVF3_BEQ 3'b000 40 | `define RVF3_BNE 3'b001 41 | `define RVF3_ADD 3'b000 42 | `define RVF3_OR 3'b110 43 | `define RVF3_SRL 3'b101 44 | `define RVF3_SLTU 3'b011 45 | `define RVF3_SUB 3'b000 46 | `define RVF3_ANY 3'b??? 47 | 48 | // Instruction funct7 49 | 50 | `define RVF7_ADD 7'b0000000 51 | `define RVF7_OR 7'b0000000 52 | `define RVF7_SRL 7'b0000000 53 | `define RVF7_SLTU 7'b0000000 54 | `define RVF7_SUB 7'b0100000 55 | `define RVF7_ANY 7'b??????? 56 | 57 | `endif // `ifndef SR_CPU_SVH 58 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_09_cpu_mul_with_latency/sr_mdu.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | `include "sr_cpu.svh" 14 | 15 | module sr_mdu 16 | # ( 17 | parameter n_delay = 2 18 | ) 19 | ( 20 | input clk, 21 | input rst, 22 | 23 | input i_vld, 24 | input [31:0] srcA, 25 | input [31:0] srcB, 26 | output o_vld, 27 | output logic [31:0] result, 28 | output busy 29 | ); 30 | 31 | endmodule 32 | 33 | //---------------------------------------------------------------------------- 34 | 35 | module shift_register 36 | # ( 37 | parameter width = 8, depth = 8 38 | ) 39 | ( 40 | input clk, 41 | input [width - 1:0] in_data, 42 | output [width - 1:0] out_data 43 | ); 44 | logic [width - 1:0] data [0:depth - 1]; 45 | 46 | always_ff @ (posedge clk) 47 | begin 48 | data [0] <= in_data; 49 | 50 | for (int i = 1; i < depth; i ++) 51 | data [i] <= data [i - 1]; 52 | end 53 | 54 | assign out_data = data [depth - 1]; 55 | 56 | endmodule 57 | 58 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_09_cpu_mul_with_latency/sr_register_file.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | `include "sr_cpu.svh" 14 | 15 | module sr_register_file 16 | ( 17 | input clk, 18 | input [ 4:0] a0, 19 | input [ 4:0] a1, 20 | input [ 4:0] a2, 21 | input [ 4:0] a3, 22 | output [31:0] rd0, 23 | output [31:0] rd1, 24 | output [31:0] rd2, 25 | input [31:0] wd3, 26 | input we3 27 | ); 28 | logic [31:0] rf [0:31]; 29 | 30 | assign rd0 = (a0 != 0) ? rf [a0] : 32'b0; 31 | assign rd1 = (a1 != 0) ? rf [a1] : 32'b0; 32 | assign rd2 = (a2 != 0) ? rf [a2] : 32'b0; 33 | 34 | always_ff @ (posedge clk) 35 | if(we3) rf [a3] <= wd3; 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_09_cpu_mul_with_latency/wave_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --wave 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_09_cpu_mul_with_latency/wave_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "-wave" 23 | 24 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_10_cpu_with_b_instr/gtkwave.tcl: -------------------------------------------------------------------------------- 1 | # gtkwave::loadFile "dump.vcd" 2 | 3 | set all_signals [list] 4 | 5 | lappend all_signals tb.clk 6 | lappend all_signals tb.rst 7 | lappend all_signals tb.cpu.pc 8 | lappend all_signals tb.imAddr 9 | lappend all_signals tb.imData 10 | lappend all_signals tb.regAddr 11 | lappend all_signals tb.regData 12 | 13 | set num_added [ gtkwave::addSignalsFromList $all_signals ] 14 | 15 | gtkwave::/Time/Zoom/Zoom_Full 16 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_10_cpu_with_b_instr/instruction_rom.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | module instruction_rom 14 | #( 15 | parameter SIZE = 64, 16 | parameter ADDR_W = $clog2(SIZE) 17 | ) 18 | ( 19 | input [ADDR_W - 1:0] a, 20 | output [ 31:0] rd 21 | ); 22 | reg [31:0] rom [0:SIZE - 1]; 23 | assign rd = rom [a]; 24 | 25 | initial $readmemh ("program.hex", rom); 26 | 27 | endmodule 28 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_10_cpu_with_b_instr/lint_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --lint 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_10_cpu_with_b_instr/program.s: -------------------------------------------------------------------------------- 1 | # li pseudo-instruction 2 | 3 | li t0, 0x123 4 | li t1, 0x12345678 5 | li t2, 0x12345000 6 | li t3, -0x123 7 | 8 | # RISC-V fibonacci program 9 | # 10 | # Stanislav Zhelnio, 2020 11 | # Amended by Yuri Panchul, 2024 12 | 13 | fibonacci: 14 | 15 | mv a0, zero 16 | li t0, 1 17 | 18 | loop: add t1, a0, t0 19 | mv a0, t0 20 | mv t0, t1 21 | 22 | # We use b instead of beqz 23 | 24 | # beqz zero, loop 25 | b loop 26 | 27 | # RISC-V factorial program 28 | # Uncomment it when necessary 29 | 30 | # factorial: 31 | # 32 | # li a0, 1 33 | # li t0, 2 34 | # 35 | # loop: mul a0, a0, t0 36 | # addi t0, t0, 1 37 | # b loop 38 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_10_cpu_with_b_instr/register_with_rst.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | module register_with_rst 14 | ( 15 | input clk, 16 | input rst, 17 | input [31:0] d, 18 | output logic [31:0] q 19 | ); 20 | 21 | always_ff @ (posedge clk) 22 | if (rst) 23 | q <= '0; 24 | else 25 | q <= d; 26 | 27 | endmodule 28 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_10_cpu_with_b_instr/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_10_cpu_with_b_instr/run_rars_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_10_cpu_with_b_instr/run_rars_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_rars_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_10_cpu_with_b_instr/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "%1" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_10_cpu_with_b_instr/sr_alu.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | `include "sr_cpu.svh" 14 | 15 | module sr_alu 16 | ( 17 | input [31:0] srcA, 18 | input [31:0] srcB, 19 | input [ 2:0] oper, 20 | output zero, 21 | output logic [31:0] result 22 | ); 23 | 24 | always_comb 25 | case (oper) 26 | default : result = srcA + srcB; 27 | `ALU_ADD : result = srcA + srcB; 28 | `ALU_OR : result = srcA | srcB; 29 | `ALU_SRL : result = srcA >> srcB [4:0]; 30 | `ALU_SLTU : result = (srcA < srcB) ? 32'd1 : 32'd0; 31 | `ALU_SUB : result = srcA - srcB; 32 | endcase 33 | 34 | assign zero = (result == '0); 35 | 36 | endmodule 37 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_10_cpu_with_b_instr/sr_cpu.svh: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | `ifndef SR_CPU_SVH 14 | `define SR_CPU_SVH 15 | 16 | // ALU commands 17 | 18 | `define ALU_ADD 3'b000 19 | `define ALU_OR 3'b001 20 | `define ALU_SRL 3'b010 21 | `define ALU_SLTU 3'b011 22 | `define ALU_SUB 3'b100 23 | 24 | // Instruction opcode 25 | 26 | `define RVOP_ADDI 7'b0010011 27 | `define RVOP_BEQ 7'b1100011 28 | `define RVOP_LUI 7'b0110111 29 | `define RVOP_BNE 7'b1100011 30 | `define RVOP_ADD 7'b0110011 31 | `define RVOP_OR 7'b0110011 32 | `define RVOP_SRL 7'b0110011 33 | `define RVOP_SLTU 7'b0110011 34 | `define RVOP_SUB 7'b0110011 35 | 36 | // Instruction funct3 37 | 38 | `define RVF3_ADDI 3'b000 39 | `define RVF3_BEQ 3'b000 40 | `define RVF3_BNE 3'b001 41 | `define RVF3_ADD 3'b000 42 | `define RVF3_OR 3'b110 43 | `define RVF3_SRL 3'b101 44 | `define RVF3_SLTU 3'b011 45 | `define RVF3_SUB 3'b000 46 | `define RVF3_ANY 3'b??? 47 | 48 | // Instruction funct7 49 | 50 | `define RVF7_ADD 7'b0000000 51 | `define RVF7_OR 7'b0000000 52 | `define RVF7_SRL 7'b0000000 53 | `define RVF7_SLTU 7'b0000000 54 | `define RVF7_SUB 7'b0100000 55 | `define RVF7_ANY 7'b??????? 56 | 57 | `endif // `ifndef SR_CPU_SVH 58 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_10_cpu_with_b_instr/sr_register_file.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | `include "sr_cpu.svh" 14 | 15 | module sr_register_file 16 | ( 17 | input clk, 18 | input [ 4:0] a0, 19 | input [ 4:0] a1, 20 | input [ 4:0] a2, 21 | input [ 4:0] a3, 22 | output [31:0] rd0, 23 | output [31:0] rd1, 24 | output [31:0] rd2, 25 | input [31:0] wd3, 26 | input we3 27 | ); 28 | logic [31:0] rf [0:31]; 29 | 30 | assign rd0 = (a0 != 0) ? rf [a0] : 32'b0; 31 | assign rd1 = (a1 != 0) ? rf [a1] : 32'b0; 32 | assign rd2 = (a2 != 0) ? rf [a2] : 32'b0; 33 | 34 | always_ff @ (posedge clk) 35 | if(we3) rf [a3] <= wd3; 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_10_cpu_with_b_instr/wave_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --wave 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_10_cpu_with_b_instr/wave_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "-wave" 23 | 24 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_11_cpu_fetch_with_latency/gtkwave.tcl: -------------------------------------------------------------------------------- 1 | # gtkwave::loadFile "dump.vcd" 2 | 3 | set all_signals [list] 4 | 5 | lappend all_signals tb.clk 6 | lappend all_signals tb.rst 7 | lappend all_signals tb.cpu.pc 8 | lappend all_signals tb.imAddr 9 | lappend all_signals tb.imData 10 | lappend all_signals tb.regAddr 11 | lappend all_signals tb.regData 12 | 13 | set num_added [ gtkwave::addSignalsFromList $all_signals ] 14 | 15 | gtkwave::/Time/Zoom/Zoom_Full 16 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_11_cpu_fetch_with_latency/instruction_rom.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | module instruction_rom 14 | #( 15 | parameter SIZE = 64, 16 | parameter ADDR_W = $clog2(SIZE) 17 | ) 18 | ( 19 | input clk, 20 | input [ADDR_W - 1:0] a, 21 | output logic [ 31:0] rd 22 | ); 23 | reg [31:0] rom [0:SIZE - 1]; 24 | 25 | // We intentionally introduce latency here 26 | 27 | always_ff @ (posedge clk) 28 | rd <= rom [a]; 29 | 30 | initial $readmemh ("program.hex", rom); 31 | 32 | endmodule 33 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_11_cpu_fetch_with_latency/lint_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --lint 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_11_cpu_fetch_with_latency/program.s: -------------------------------------------------------------------------------- 1 | # li pseudo-instruction 2 | 3 | li t0, 0x123 4 | li t1, 0x12345678 5 | li t2, 0x12345000 6 | li t3, -0x123 7 | 8 | # RISC-V fibonacci program 9 | # 10 | # Stanislav Zhelnio, 2020 11 | # Amended by Yuri Panchul, 2024 12 | 13 | fibonacci: 14 | 15 | mv a0, zero 16 | li t0, 1 17 | 18 | loop: add t1, a0, t0 19 | mv a0, t0 20 | mv t0, t1 21 | beqz zero, loop 22 | 23 | # RISC-V factorial program 24 | # Uncomment it when necessary 25 | 26 | # factorial: 27 | # 28 | # li a0, 1 29 | # li t0, 2 30 | # 31 | # loop: mul a0, a0, t0 32 | # addi t0, t0, 1 33 | # b loop 34 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_11_cpu_fetch_with_latency/register_with_rst_and_en.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | module register_with_rst_and_en 14 | ( 15 | input clk, 16 | input rst, 17 | input en, 18 | input [31:0] d, 19 | output logic [31:0] q 20 | ); 21 | 22 | always_ff @ (posedge clk) 23 | if (rst) 24 | q <= '0; 25 | else if (en) 26 | q <= d; 27 | 28 | endmodule 29 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_11_cpu_fetch_with_latency/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_11_cpu_fetch_with_latency/run_rars_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_11_cpu_fetch_with_latency/run_rars_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_rars_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_11_cpu_fetch_with_latency/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "%1" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_11_cpu_fetch_with_latency/sr_alu.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | `include "sr_cpu.svh" 14 | 15 | module sr_alu 16 | ( 17 | input [31:0] srcA, 18 | input [31:0] srcB, 19 | input [ 2:0] oper, 20 | output zero, 21 | output logic [31:0] result 22 | ); 23 | 24 | always_comb 25 | case (oper) 26 | default : result = srcA + srcB; 27 | `ALU_ADD : result = srcA + srcB; 28 | `ALU_OR : result = srcA | srcB; 29 | `ALU_SRL : result = srcA >> srcB [4:0]; 30 | `ALU_SLTU : result = (srcA < srcB) ? 32'd1 : 32'd0; 31 | `ALU_SUB : result = srcA - srcB; 32 | endcase 33 | 34 | assign zero = (result == '0); 35 | 36 | endmodule 37 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_11_cpu_fetch_with_latency/sr_cpu.svh: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | `ifndef SR_CPU_SVH 14 | `define SR_CPU_SVH 15 | 16 | // ALU commands 17 | 18 | `define ALU_ADD 3'b000 19 | `define ALU_OR 3'b001 20 | `define ALU_SRL 3'b010 21 | `define ALU_SLTU 3'b011 22 | `define ALU_SUB 3'b100 23 | 24 | // Instruction opcode 25 | 26 | `define RVOP_ADDI 7'b0010011 27 | `define RVOP_BEQ 7'b1100011 28 | `define RVOP_LUI 7'b0110111 29 | `define RVOP_BNE 7'b1100011 30 | `define RVOP_ADD 7'b0110011 31 | `define RVOP_OR 7'b0110011 32 | `define RVOP_SRL 7'b0110011 33 | `define RVOP_SLTU 7'b0110011 34 | `define RVOP_SUB 7'b0110011 35 | 36 | // Instruction funct3 37 | 38 | `define RVF3_ADDI 3'b000 39 | `define RVF3_BEQ 3'b000 40 | `define RVF3_BNE 3'b001 41 | `define RVF3_ADD 3'b000 42 | `define RVF3_OR 3'b110 43 | `define RVF3_SRL 3'b101 44 | `define RVF3_SLTU 3'b011 45 | `define RVF3_SUB 3'b000 46 | `define RVF3_ANY 3'b??? 47 | 48 | // Instruction funct7 49 | 50 | `define RVF7_ADD 7'b0000000 51 | `define RVF7_OR 7'b0000000 52 | `define RVF7_SRL 7'b0000000 53 | `define RVF7_SLTU 7'b0000000 54 | `define RVF7_SUB 7'b0100000 55 | `define RVF7_ANY 7'b??????? 56 | 57 | `endif // `ifndef SR_CPU_SVH 58 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_11_cpu_fetch_with_latency/sr_register_file.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | `include "sr_cpu.svh" 14 | 15 | module sr_register_file 16 | ( 17 | input clk, 18 | input [ 4:0] a0, 19 | input [ 4:0] a1, 20 | input [ 4:0] a2, 21 | input [ 4:0] a3, 22 | output [31:0] rd0, 23 | output [31:0] rd1, 24 | output [31:0] rd2, 25 | input [31:0] wd3, 26 | input we3 27 | ); 28 | logic [31:0] rf [0:31]; 29 | 30 | assign rd0 = (a0 != 0) ? rf [a0] : 32'b0; 31 | assign rd1 = (a1 != 0) ? rf [a1] : 32'b0; 32 | assign rd2 = (a2 != 0) ? rf [a2] : 32'b0; 33 | 34 | always_ff @ (posedge clk) 35 | if(we3) rf [a3] <= wd3; 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_11_cpu_fetch_with_latency/wave_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --wave 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_11_cpu_fetch_with_latency/wave_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "-wave" 23 | 24 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_12_three_cpus_sharing_instr_memory/cpu_cluster.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | module cpu_cluster 14 | #( 15 | parameter nCPUs = 3 16 | ) 17 | ( 18 | input clk, // clock 19 | input rst, // reset 20 | 21 | input [nCPUs - 1:0][31:0] rstPC, // program counter set on reset 22 | input [nCPUs - 1:0][ 4:0] regAddr, // debug access reg address 23 | output [nCPUs - 1:0][31:0] regData // debug access reg data 24 | ); 25 | 26 | 27 | endmodule 28 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_12_three_cpus_sharing_instr_memory/gtkwave.tcl: -------------------------------------------------------------------------------- 1 | # gtkwave::loadFile "dump.vcd" 2 | 3 | set all_signals [list] 4 | 5 | lappend all_signals tb.clk 6 | lappend all_signals tb.rst 7 | lappend all_signals tb.cluster.imDataVld 8 | lappend all_signals tb.cluster.romAddr 9 | lappend all_signals tb.cluster.imData 10 | lappend all_signals tb.cluster.g_cpu\[0\].cpu.pc 11 | lappend all_signals tb.cluster.g_cpu\[0\].cpu.imDataVld 12 | lappend all_signals tb.cluster.g_cpu\[0\].cpu.regData 13 | lappend all_signals tb.cluster.g_cpu\[1\].cpu.pc 14 | lappend all_signals tb.cluster.g_cpu\[2\].cpu.pc 15 | lappend all_signals tb.cluster.g_cpu\[2\].cpu.imDataVld 16 | lappend all_signals tb.cluster.g_cpu\[2\].cpu.regData 17 | 18 | set num_added [ gtkwave::addSignalsFromList $all_signals ] 19 | 20 | gtkwave::/Time/Zoom/Zoom_Full 21 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_12_three_cpus_sharing_instr_memory/instruction_rom.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | module instruction_rom 14 | #( 15 | parameter SIZE = 64, 16 | parameter ADDR_W = $clog2(SIZE) 17 | ) 18 | ( 19 | input [ADDR_W - 1:0] a, 20 | output [ 31:0] rd 21 | ); 22 | reg [31:0] rom [0:SIZE - 1]; 23 | assign rd = rom [a]; 24 | 25 | initial $readmemh ("program.hex", rom); 26 | 27 | endmodule 28 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_12_three_cpus_sharing_instr_memory/lint_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --lint 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_12_three_cpus_sharing_instr_memory/program.s: -------------------------------------------------------------------------------- 1 | # li pseudo-instruction 2 | 3 | li t0, 0x123 4 | li t1, 0x12345678 5 | li t2, 0x12345000 6 | li t3, -0x123 7 | 8 | # RISC-V fibonacci program 9 | # 10 | # Stanislav Zhelnio, 2020 11 | # Amended by Yuri Panchul, 2024 12 | 13 | fibonacci: 14 | 15 | mv a0, zero 16 | li t0, 1 17 | 18 | loop: add t1, a0, t0 19 | mv a0, t0 20 | mv t0, t1 21 | beqz zero, loop 22 | 23 | # RISC-V factorial program 24 | # Uncomment it when necessary 25 | 26 | factorial: 27 | 28 | li a0, 1 29 | li t0, 2 30 | 31 | loop2: mul a0, a0, t0 32 | addi t0, t0, 1 33 | beqz zero, loop2 34 | # b loop 35 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_12_three_cpus_sharing_instr_memory/register_with_rst_value_and_enable.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | module register_with_rst_value_and_enable 14 | ( 15 | input clk, 16 | input rst, 17 | input [31:0] rstValue, 18 | input en, 19 | input [31:0] d, 20 | output logic [31:0] q 21 | ); 22 | 23 | always_ff @ (posedge clk) 24 | if (rst) 25 | q <= rstValue; 26 | else if (en) 27 | q <= d; 28 | 29 | endmodule 30 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_12_three_cpus_sharing_instr_memory/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_12_three_cpus_sharing_instr_memory/run_rars_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_12_three_cpus_sharing_instr_memory/run_rars_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_rars_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_12_three_cpus_sharing_instr_memory/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "%1" 23 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_12_three_cpus_sharing_instr_memory/sr_alu.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | `include "sr_cpu.svh" 14 | 15 | module sr_alu 16 | ( 17 | input [31:0] srcA, 18 | input [31:0] srcB, 19 | input [ 2:0] oper, 20 | output zero, 21 | output logic [31:0] result 22 | ); 23 | 24 | always_comb 25 | case (oper) 26 | default : result = srcA + srcB; 27 | `ALU_ADD : result = srcA + srcB; 28 | `ALU_OR : result = srcA | srcB; 29 | `ALU_SRL : result = srcA >> srcB [4:0]; 30 | `ALU_SLTU : result = (srcA < srcB) ? 32'd1 : 32'd0; 31 | `ALU_SUB : result = srcA - srcB; 32 | endcase 33 | 34 | assign zero = (result == '0); 35 | 36 | endmodule 37 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_12_three_cpus_sharing_instr_memory/sr_cpu.svh: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | `ifndef SR_CPU_SVH 14 | `define SR_CPU_SVH 15 | 16 | // ALU commands 17 | 18 | `define ALU_ADD 3'b000 19 | `define ALU_OR 3'b001 20 | `define ALU_SRL 3'b010 21 | `define ALU_SLTU 3'b011 22 | `define ALU_SUB 3'b100 23 | 24 | // Instruction opcode 25 | 26 | `define RVOP_ADDI 7'b0010011 27 | `define RVOP_BEQ 7'b1100011 28 | `define RVOP_LUI 7'b0110111 29 | `define RVOP_BNE 7'b1100011 30 | `define RVOP_ADD 7'b0110011 31 | `define RVOP_OR 7'b0110011 32 | `define RVOP_SRL 7'b0110011 33 | `define RVOP_SLTU 7'b0110011 34 | `define RVOP_SUB 7'b0110011 35 | 36 | // Instruction funct3 37 | 38 | `define RVF3_ADDI 3'b000 39 | `define RVF3_BEQ 3'b000 40 | `define RVF3_BNE 3'b001 41 | `define RVF3_ADD 3'b000 42 | `define RVF3_OR 3'b110 43 | `define RVF3_SRL 3'b101 44 | `define RVF3_SLTU 3'b011 45 | `define RVF3_SUB 3'b000 46 | `define RVF3_ANY 3'b??? 47 | 48 | // Instruction funct7 49 | 50 | `define RVF7_ADD 7'b0000000 51 | `define RVF7_OR 7'b0000000 52 | `define RVF7_SRL 7'b0000000 53 | `define RVF7_SLTU 7'b0000000 54 | `define RVF7_SUB 7'b0100000 55 | `define RVF7_ANY 7'b??????? 56 | 57 | `endif // `ifndef SR_CPU_SVH 58 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_12_three_cpus_sharing_instr_memory/sr_register_file.sv: -------------------------------------------------------------------------------- 1 | // 2 | // schoolRISCV - small RISC-V CPU 3 | // 4 | // Originally based on Sarah L. Harris MIPS CPU 5 | // & schoolMIPS project. 6 | // 7 | // Copyright (c) 2017-2020 Stanislav Zhelnio & Aleksandr Romanov. 8 | // 9 | // Modified in 2024 by Yuri Panchul & Mike Kuskov 10 | // for systemverilog-homework project. 11 | // 12 | 13 | `include "sr_cpu.svh" 14 | 15 | module sr_register_file 16 | ( 17 | input clk, 18 | input [ 4:0] a0, 19 | input [ 4:0] a1, 20 | input [ 4:0] a2, 21 | input [ 4:0] a3, 22 | output [31:0] rd0, 23 | output [31:0] rd1, 24 | output [31:0] rd2, 25 | input [31:0] wd3, 26 | input we3 27 | ); 28 | logic [31:0] rf [0:31]; 29 | 30 | assign rd0 = (a0 != 0) ? rf [a0] : 32'b0; 31 | assign rd1 = (a1 != 0) ? rf [a1] : 32'b0; 32 | assign rd2 = (a2 != 0) ? rf [a2] : 32'b0; 33 | 34 | always_ff @ (posedge clk) 35 | if (we3) rf [a3] <= wd3; 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_12_three_cpus_sharing_instr_memory/wave_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --wave 4 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/05_12_three_cpus_sharing_instr_memory/wave_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "-wave" 23 | 24 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/README.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/05_fifo_and_single_cycle_cpu/README.pdf -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/README_ru.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/05_fifo_and_single_cycle_cpu/README_ru.pdf -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for d in */ ; 4 | do 5 | echo $d 6 | cd $d 7 | 8 | ./run_linux_mac.sh 9 | 10 | cd .. 11 | done 12 | -------------------------------------------------------------------------------- /05_fifo_and_single_cycle_cpu/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=scripts 4 | set targetFile=run_windows.bat 5 | set dir=%~dp0 6 | 7 | :loop 8 | if %dir:~-1% == "\" ( 9 | echo Directory %targetDir% not found in the path 10 | exit /b 11 | ) 12 | 13 | if exist "%dir%\%targetDir%" ( 14 | set "ScriptPath=%dir%\%targetDir%\%targetFile%" 15 | goto :end 16 | ) 17 | 18 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 19 | goto :loop 20 | :end 21 | 22 | call "%ScriptPath%" "%1" 23 | -------------------------------------------------------------------------------- /06_cache/06_1_testing_cache_patterson_hennessy/dm_cache_data.sv: -------------------------------------------------------------------------------- 1 | // Code from David A. Patterson and John L. Hennessy. 2 | // Computer Organization and Design: The Hardware/Software Interface, 5th Edition 3 | // Section 5.12. Advanced Material: Implementing Cache Controllers 4 | // https://booksite.elsevier.com/9780124077263/downloads/advance_contents_and_appendices/section_5.12.pdf 5 | 6 | // cache: data memory, single port, 1024 blocks 7 | 8 | module dm_cache_data 9 | import cache_def::*; 10 | ( 11 | input bit clk, 12 | input cache_req_type data_req, // data request/command, e.g. RW, valid 13 | input cache_data_type data_write, // write port (128-bit line) 14 | output cache_data_type data_read // read port 15 | ); 16 | 17 | timeunit 1ns; 18 | timeprecision 1ps; 19 | 20 | cache_data_type [0:1023] data_mem; 21 | 22 | initial begin 23 | for (int i = 0; i < 1024; i ++) 24 | data_mem [i] = '0; 25 | end 26 | 27 | assign data_read = data_mem [data_req.index]; 28 | 29 | always_ff @ (posedge clk) begin 30 | if (data_req.we) 31 | data_mem [data_req.index] <= data_write; 32 | end 33 | 34 | endmodule 35 | -------------------------------------------------------------------------------- /06_cache/06_1_testing_cache_patterson_hennessy/dm_cache_tag.sv: -------------------------------------------------------------------------------- 1 | // Code from David A. Patterson and John L. Hennessy. 2 | // Computer Organization and Design: The Hardware/Software Interface, 5th Edition 3 | // Section 5.12. Advanced Material: Implementing Cache Controllers 4 | // https://booksite.elsevier.com/9780124077263/downloads/advance_contents_and_appendices/section_5.12.pdf 5 | 6 | // cache: tag memory, single port, 1024 blocks 7 | 8 | module dm_cache_tag 9 | import cache_def::*; 10 | ( 11 | input bit clk, // write clock 12 | input cache_req_type tag_req, // tag request/command, e.g. RW, valid 13 | input cache_tag_type tag_write, // write port 14 | output cache_tag_type tag_read // read port 15 | ); 16 | 17 | timeunit 1ns; 18 | timeprecision 1ps; 19 | 20 | cache_tag_type [0:1023] tag_mem; 21 | 22 | initial begin 23 | for (int i = 0; i < 1024; i ++) 24 | tag_mem [i] = '0; 25 | end 26 | 27 | assign tag_read = tag_mem [tag_req.index]; 28 | 29 | always_ff @ (posedge clk) begin 30 | if (tag_req.we) 31 | tag_mem [tag_req.index] <= tag_write; 32 | end 33 | 34 | endmodule 35 | -------------------------------------------------------------------------------- /06_cache/06_1_testing_cache_patterson_hennessy/runme.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | iverilog -I../../common -g2005-sv *.sv 4 | ./a.out | tee log.txt 5 | -------------------------------------------------------------------------------- /06_cache/lint_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./run_linux_mac.sh --lint 4 | -------------------------------------------------------------------------------- /06_cache/run_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | script=$(basename "$0") 4 | dir_source_script=../scripts/$script 5 | 6 | i=0 7 | 8 | while [ "$i" -lt 3 ] 9 | do 10 | [ -f "$dir_source_script" ] && break 11 | dir_source_script=../$dir_source_script 12 | i=$((i + 1)) 13 | done 14 | 15 | if ! [ -f "$dir_source_script" ] 16 | then 17 | printf "$script: cannot find \"%s\"\n" "$script" 18 | exit 1 19 | fi 20 | 21 | dir_source_script="$(cd "$(dirname "$dir_source_script")" && pwd)/$(basename "$dir_source_script")" 22 | . "$dir_source_script" -------------------------------------------------------------------------------- /06_cache/run_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | if not exist "C:\Program Files\Git\bin\bash.exe" ( 4 | echo "Starting from Homework 3, this Windows batch script invokes" 5 | echo "a Bash shell interpreter from the Git for Windows package." 6 | echo "This is necessary for more flexible checking of the results." 7 | echo "Please install Git for Windows from https://gitforwindows.org/ and re-run this batch again." 8 | 9 | exit /b 10 | ) 11 | 12 | "C:\Program Files\Git\bin\bash.exe" run_linux_mac.sh 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020-2023 Yuri Panchul, Mike Kuskov, Digital Design School. 4 | 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/README.pdf -------------------------------------------------------------------------------- /bin/rars1_6.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/bin/rars1_6.jar -------------------------------------------------------------------------------- /common/isqrt/isqrt_slice_comb.sv: -------------------------------------------------------------------------------- 1 | module isqrt_slice_comb 2 | # ( 3 | parameter [31:0] m = 32'h4000_0000 4 | ) 5 | ( 6 | input [31:0] ix, 7 | input [31:0] iy, 8 | output [31:0] ox, 9 | output [31:0] oy 10 | ); 11 | 12 | wire [31:0] b = iy | m; 13 | wire x_ge_b = ix >= b; 14 | 15 | assign ox = x_ge_b ? ix - b : ix; 16 | assign oy = (iy >> 1) | (x_ge_b ? m : 0); 17 | 18 | endmodule 19 | -------------------------------------------------------------------------------- /common/isqrt/isqrt_slice_reg.sv: -------------------------------------------------------------------------------- 1 | module isqrt_slice_reg 2 | # ( 3 | parameter [31:0] m = 32'h4000_0000 4 | ) 5 | ( 6 | input clk, 7 | input rst, 8 | 9 | input ivld, 10 | input [31:0] ix, 11 | input [31:0] iy, 12 | 13 | output logic ovld, 14 | output logic [31:0] ox, 15 | output logic [31:0] oy 16 | ); 17 | 18 | wire [31:0] cox, coy; 19 | 20 | isqrt_slice_comb # (.m (m)) inst 21 | ( 22 | .ix ( ix ), 23 | .iy ( iy ), 24 | .ox ( cox ), 25 | .oy ( coy ) 26 | ); 27 | 28 | always_ff @ (posedge clk) 29 | if (rst) 30 | ovld <= 1'b0; 31 | else 32 | ovld <= ivld; 33 | 34 | always_ff @ (posedge clk) 35 | if (ivld) 36 | begin 37 | ox <= cox; 38 | oy <= coy; 39 | end 40 | 41 | endmodule 42 | -------------------------------------------------------------------------------- /common/util.svh: -------------------------------------------------------------------------------- 1 | `define PD(SYMBOL) $sformatf("SYMBOL:%0d", SYMBOL) 2 | `define PB(SYMBOL) $sformatf("SYMBOL:%b", SYMBOL) 3 | `define PH(SYMBOL) $sformatf("SYMBOL:%h", SYMBOL) 4 | `define PF(SYMBOL) $sformatf("SYMBOL:%f", SYMBOL) 5 | 6 | `define PF_BITS(SYMBOL) $sformatf("SYMBOL:%f", $bitstoreal(SYMBOL)) 7 | `define PG_BITS(SYMBOL) $sformatf("SYMBOL:%g", $bitstoreal(SYMBOL)) 8 | 9 | `ifdef __ICARUS__ 10 | `define ISUNKNOWN(a) ((^ a) === 1'bx) 11 | `else 12 | `define ISUNKNOWN(a) $isunknown(a) 13 | `endif 14 | -------------------------------------------------------------------------------- /common/wally_fpu/test_fpu.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | iverilog -g2012 -D LOCAL_TB \ 4 | -I .. \ 5 | -I ../../import/preprocessed/cvw \ 6 | ../../import/preprocessed/cvw/config.vh \ 7 | ../../import/preprocessed/cvw/*.sv \ 8 | *.sv \ 9 | -s fpu_tb \ 10 | 2>&1 | grep -v sorry 11 | 12 | ./a.out > z 13 | rm -rf a.out 14 | -------------------------------------------------------------------------------- /doc/discriminant/discriminant_fsm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/discriminant/discriminant_fsm.jpg -------------------------------------------------------------------------------- /doc/discriminant/discriminant_fsm.wave: -------------------------------------------------------------------------------- 1 | {signal: [ 2 | {name: 'clk' , wave: 'p................'}, 3 | {name: 'arg_vld' , wave: '010....10....10..'}, 4 | {name: 'a' , wave: 'x3x....4x....5x..', data: "a1 a2 a3"}, 5 | {name: 'b' , wave: 'x3x....4x....5x..', data: "b1 b2 b3"}, 6 | {name: 'c' , wave: 'x3x....4x....5x..', data: "c1 c2 c3"}, 7 | {name: 'res_vld' , wave: '0.....10....10...'}, 8 | {name: 'b²-4*a*c' , wave: '....x.3x....4x...', data: "D1 D2"}, 9 | ]} 10 | -------------------------------------------------------------------------------- /doc/discriminant/discriminant_fsm.wave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/discriminant/discriminant_fsm.wave.png -------------------------------------------------------------------------------- /doc/discriminant/discriminant_pipeline.wave: -------------------------------------------------------------------------------- 1 | {signal: [ 2 | {name: 'clk' , wave: 'p................'}, 3 | {name: 'arg_vld' , wave: '0101....01.0.....'}, 4 | {name: 'a' , wave: 'x3x45678x95x.....', data: "a1 a2 a3 a4 a5"}, 5 | {name: 'b' , wave: 'x3x45678x95x.....', data: "b1 b2 b3 b4 b5"}, 6 | {name: 'c' , wave: 'x3x45678x95x.....', data: "c1 c2 c3 c4 c5"}, 7 | {name: 'res_vld' , wave: '0.....101....01.0'}, 8 | {name: 'b²-4*a*c' , wave: '....x.3x45678x95x', data: "D1 D2 D3 D4 D5"}, 9 | ]} 10 | -------------------------------------------------------------------------------- /doc/discriminant/discriminant_pipeline.wave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/discriminant/discriminant_pipeline.wave.png -------------------------------------------------------------------------------- /doc/discriminant/discriminant_pipeline_fifo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/discriminant/discriminant_pipeline_fifo.jpg -------------------------------------------------------------------------------- /doc/discriminant/discriminant_pipeline_shift_register.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/discriminant/discriminant_pipeline_shift_register.jpg -------------------------------------------------------------------------------- /doc/homework2/02_07_01_halve_tokens.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/homework2/02_07_01_halve_tokens.png -------------------------------------------------------------------------------- /doc/homework2/02_07_01_halve_tokens.wave: -------------------------------------------------------------------------------- 1 | {signal: [ 2 | {name: 'clk' , wave: 'p...............'}, 3 | {name: 'a' , wave: 'x3.04.5050.6.7.x'}, 4 | {name: 'b' , wave: 'x030.40.50..607x'}, 5 | ]} 6 | -------------------------------------------------------------------------------- /doc/homework2/02_08_01_double_tokens.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/homework2/02_08_01_double_tokens.png -------------------------------------------------------------------------------- /doc/homework2/02_08_01_double_tokens.wave: -------------------------------------------------------------------------------- 1 | {signal: [ 2 | {name: 'clk' , wave: 'p...................'}, 3 | {name: 'a' , wave: 'x30.40.560..70890..x'}, 4 | {name: 'b' , wave: 'x3.04.05.6.07.8.9.0x'}, 5 | ]} 6 | -------------------------------------------------------------------------------- /doc/homework2/02_09_01_rr_arbiter_2_req.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/homework2/02_09_01_rr_arbiter_2_req.png -------------------------------------------------------------------------------- /doc/homework2/02_09_01_rr_arbiter_2_req.wave: -------------------------------------------------------------------------------- 1 | {signal: [ 2 | {name: 'clk' , wave: 'p.................'}, 3 | {name: 'requests' , wave: 'x3.x4x56..x7x6896x', data: '01 00 10 11 10 11 01 10 11'}, 4 | {name: 'grants' , wave: 'x3.x4x5666x7x6896x', data: '01 00 10 01 10 01 10 01 01 10 01'}, 5 | ]} 6 | -------------------------------------------------------------------------------- /doc/homework2/02_10_01_serial_to_parallel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/homework2/02_10_01_serial_to_parallel.png -------------------------------------------------------------------------------- /doc/homework2/02_10_01_serial_to_parallel.wave: -------------------------------------------------------------------------------- 1 | {signal: [ 2 | {name: 'clk' , wave: 'p.................'}, 3 | {name: 'serial_valid' , wave: 'x0.101..0...1...0x'}, 4 | {name: 'serial_data' , wave: 'x1030333010133330x', data: 'a0 a1 a2 a3 a4 a5 a6 a7'}, 5 | {name: 'parallel_valid' , wave: 'x0.............10x'}, 6 | {name: 'parallel_data' , wave: 'x0.............30x', data: 'a'}, 7 | ]} 8 | -------------------------------------------------------------------------------- /doc/homework2/02_10_01_serial_to_parallel_with_combinational_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/homework2/02_10_01_serial_to_parallel_with_combinational_output.png -------------------------------------------------------------------------------- /doc/homework2/02_10_01_serial_to_parallel_with_registered_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/homework2/02_10_01_serial_to_parallel_with_registered_output.png -------------------------------------------------------------------------------- /doc/homework4/04_11_fix_latency.json: -------------------------------------------------------------------------------- 1 | {signal: [ 2 | {name: 'N', wave: '7.............', data: ['4']}, 3 | {name: 'clk', wave: 'p.............'}, 4 | {name: 'rst', wave: '10............'}, 5 | {name: 'abc', wave: 'x.345x7x3457x.', data: ['1', '2', '3', '4','1', '2', '3', '4']}, 6 | {name: 'arg_vld', wave: 'x01..0101...0.'}, 7 | {name: 'abc_reg', wave: 'x..345x7x3457x', data: ['1', '2', '3', '4','1', '2', '3', '4']}, 8 | {name: 'arg_vld_reg', wave: 'x0.1..0101...0'}, 9 | {name: 'index', wave: 'x8..88.8.8888.',data: ['0', '1', '2', '3', '0', '1', '2', '3']}, 10 | {name: 'isqrt_y_1', wave: 'x.....3x....3x',data: ['1','1']}, 11 | {name: 'isqrt_y_vld_1', wave: 'x0....10....10'}, 12 | {name: 'isqrt_y_2', wave: 'x......4x....4',data: ['2','2']}, 13 | {name: 'isqrt_y_vld_2', wave: 'x0.....10....1'}, 14 | {name: 'isqrt_y_3', wave: 'x.......5x....',data: ['3']}, 15 | {name: 'isqrt_y_vld_3', wave: 'x0......10....'}, 16 | {name: 'isqrt_y_4', wave: 'x.........7x..',data: ['4']}, 17 | {name: 'isqrt_y_vld_4', wave: 'x0........10..'}, 18 | {name: 'res', wave: 'x.....345x7x34',data: ['1', '2', '3', '4', '1', '2']}, 19 | {name: 'res_vld', wave: 'x0....1..0101.',} 20 | ]} 21 | -------------------------------------------------------------------------------- /doc/homework4/04_11_fix_latency.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/homework4/04_11_fix_latency.png -------------------------------------------------------------------------------- /doc/homework4/04_11_fix_latency_wave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/homework4/04_11_fix_latency_wave.png -------------------------------------------------------------------------------- /doc/homework4/4_13_home_work_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/homework4/4_13_home_work_diagram.png -------------------------------------------------------------------------------- /doc/homework4/4_13_wave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/homework4/4_13_wave.png -------------------------------------------------------------------------------- /doc/isqrt/01_isqrt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/isqrt/01_isqrt.png -------------------------------------------------------------------------------- /doc/isqrt/01_isqrt.wave: -------------------------------------------------------------------------------- 1 | {signal: [ 2 | {name: 'clk' , wave: 'p...............'}, 3 | {name: 'x_vld' , wave: '0101....01.0....'}, 4 | {name: 'x' , wave: 'x3x45678x95x....', data: "n m p" }, 5 | {name: 'y_vld' , wave: '0....101....01.0'}, 6 | {name: 'y' , wave: '...x.3x45678x95x', data: "√n √m √p" }, 7 | ]} 8 | -------------------------------------------------------------------------------- /doc/isqrt/01_isqrt.wave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/isqrt/01_isqrt.wave.png -------------------------------------------------------------------------------- /doc/isqrt/01_isqrt_alt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/isqrt/01_isqrt_alt.png -------------------------------------------------------------------------------- /doc/isqrt/02_fa_fb_fc_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/isqrt/02_fa_fb_fc_3.png -------------------------------------------------------------------------------- /doc/isqrt/02_fa_fb_fc_3.wave: -------------------------------------------------------------------------------- 1 | {signal: [ 2 | {name: 'clk' , wave: 'p................'}, 3 | {name: 'arg_vld' , wave: '0101....01.0.....'}, 4 | {name: 'a' , wave: 'x3x45678x95x.....', data: "a1 a2 a3 a4 a5"}, 5 | {name: 'b' , wave: 'x3x45678x95x.....', data: "b1 b2 b3 b4 b5"}, 6 | {name: 'c' , wave: 'x3x45678x95x.....', data: "c1 c2 c3 c4 c5"}, 7 | {name: 'a_res_vld' , wave: '0....101....01.0.'}, 8 | {name: '√a' , wave: '...x.3x45678x95x.', data: "√a1 √a2 √a3 √a4 √a5"}, 9 | {name: '√b' , wave: '...x.3x45678x95x.', data: "√b1 √b2 √b3 √b4 √b5"}, 10 | {name: '√c' , wave: '...x.3x45678x95x.', data: "√c1 √c2 √c3 √c4 √c5"}, 11 | {name: 'res_vld' , wave: '0.....101....01.0'}, 12 | {name: '√a + √b + √c' , wave: '....x.3x45678x95x', data: "∑1 ∑2 ∑3 ∑4 ∑5"}, 13 | ]} 14 | -------------------------------------------------------------------------------- /doc/isqrt/02_fa_fb_fc_3.wave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/isqrt/02_fa_fb_fc_3.wave.png -------------------------------------------------------------------------------- /doc/isqrt/03_fsm_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/isqrt/03_fsm_1.png -------------------------------------------------------------------------------- /doc/isqrt/03_fsm_1.vcd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/isqrt/03_fsm_1.vcd.png -------------------------------------------------------------------------------- /doc/isqrt/04_fsm_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/isqrt/04_fsm_2.png -------------------------------------------------------------------------------- /doc/isqrt/05_f_a_f_b_fc_incorrect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/isqrt/05_f_a_f_b_fc_incorrect.png -------------------------------------------------------------------------------- /doc/isqrt/06_shift_reg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/isqrt/06_shift_reg.png -------------------------------------------------------------------------------- /doc/isqrt/06_shift_reg_alt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/isqrt/06_shift_reg_alt.png -------------------------------------------------------------------------------- /doc/isqrt/07_f_a_f_b_fc_pipe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/isqrt/07_f_a_f_b_fc_pipe.png -------------------------------------------------------------------------------- /doc/isqrt/08_f_a_f_b_fc_pipe_with_fifo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/isqrt/08_f_a_f_b_fc_pipe_with_fifo.png -------------------------------------------------------------------------------- /doc/isqrt/09_valid_ready_wide.wave: -------------------------------------------------------------------------------- 1 | {signal: [ 2 | {name: 'clk' , wave: 'p...P.p.Pp.Pp...P.P.Pp.Pp..P.P.Pp.Pp..P.P.Pp.P'}, 3 | {name: 'rst' , wave: 'x10..........10.........10.........10.........'}, 4 | {name: 'vld' , wave: 'x0.1....0.10...1....0.10..1....0.10..1....0.10'}, 5 | {name: 'rdy' , wave: 'x1...0.10.10.1......0.101......0.101......0.10'}, 6 | {name: 'data' , wave: 'x..345..x.7x...345689..x..345689..x..345689..x', data: "A B C D E F G H I J K L M N O P Q R T U V W"}, 7 | ]} 8 | -------------------------------------------------------------------------------- /doc/quadratic/01_parts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/quadratic/01_parts.png -------------------------------------------------------------------------------- /doc/quadratic/02_quadratic_equation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/quadratic/02_quadratic_equation.png -------------------------------------------------------------------------------- /doc/quadratic/03_quadratic_equation_valid_ready.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/quadratic/03_quadratic_equation_valid_ready.png -------------------------------------------------------------------------------- /doc/quadratic/04_quadratic_equation_individual_valid_ready.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipdesignschool/systemverilog-homework/f52ffb5ccf8162f4de031e3de0af442dad3edd62/doc/quadratic/04_quadratic_equation_individual_valid_ready.png -------------------------------------------------------------------------------- /scripts/run_rars_linux_mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | rars_jar=rars1_6.jar 4 | 5 | if command -v rars >/dev/null 2>&1 6 | then 7 | rars_cmd=rars 8 | else 9 | if ! command -v java >/dev/null 2>&1 10 | then 11 | echo "ERROR: java is not in the path or cannot be run." \ 12 | "java is needed to run RARS," \ 13 | "a RISC-V instruction set simulator." \ 14 | "You can install it using" \ 15 | "'sudo apt-get install default-jre'" \ 16 | 2>&1 17 | 18 | echo "Press enter" 19 | read enter 20 | exit 1 21 | fi 22 | 23 | rars_cmd="java -jar ../../bin/$rars_jar" 24 | fi 25 | 26 | $rars_cmd & 27 | -------------------------------------------------------------------------------- /scripts/run_rars_windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set targetDir=bin 4 | set targetFile=rars1_6.jar 5 | set dir=%~dp0 6 | 7 | where java > nul 2>&1 8 | 9 | if errorlevel 1 ( 10 | echo ERROR: java.exe is not in the path. It is needed to run RARS, a RISC-V instruction set simulator." 11 | pause 12 | exit /b 1 13 | ) 14 | 15 | :loop 16 | if %dir:~-1% == "\" ( 17 | echo Directory %targetDir% not found in the path 18 | exit /b 19 | ) 20 | 21 | if exist "%dir%\%targetDir%" ( 22 | set PathToBin="%dir%\%targetDir%\%targetFile%" 23 | goto :end 24 | ) 25 | 26 | for %%i in ("%dir:~0,-1%") do set "dir=%%~dpi" 27 | goto :loop 28 | :end 29 | 30 | start "" java -jar "%PathToBin%" --------------------------------------------------------------------------------