├── Lecture_1_slides.pdf ├── Lecture_2_slides.pdf ├── Lecture_3_slides.pdf ├── Lecture_4_slides.pdf ├── README.md ├── lecture_2 ├── README.md ├── counter.sv ├── make_sim.do └── top_tb.sv ├── lecture_3 ├── README.md ├── debouncer │ ├── debouncer.sv │ └── debouncer_tb │ │ ├── debouncer_tb.sv │ │ └── make.do ├── fifo │ ├── fifo.sv │ ├── fifo_example │ │ ├── fifo_top.qpf │ │ ├── fifo_top.qsf │ │ ├── fifo_top.sdc │ │ └── fifo_top.sv │ └── fifo_tb │ │ ├── fifo_tb.sv │ │ └── make.do ├── fsm │ ├── fsm.sv │ └── fsm_example │ │ ├── fsm_top.qpf │ │ ├── fsm_top.qsf │ │ ├── fsm_top.sdc │ │ └── fsm_top.sv ├── memory │ ├── memory.sv │ └── memory_example │ │ ├── memory_top.qpf │ │ ├── memory_top.qsf │ │ ├── memory_top.sdc │ │ └── memory_top.sv ├── mux_demux │ ├── demux.sv │ ├── demux_example │ │ ├── demux_top.qpf │ │ ├── demux_top.qsf │ │ ├── demux_top.sdc │ │ └── demux_top.sv │ ├── mux.sv │ └── mux_example │ │ ├── mux_top.qpf │ │ ├── mux_top.qsf │ │ ├── mux_top.sdc │ │ └── mux_top.sv └── posedge_detector │ ├── posedge_detector.sv │ └── posedge_detector_example │ ├── posedge_detector_top.qpf │ ├── posedge_detector_top.qsf │ ├── posedge_detector_top.sdc │ └── posedge_detector_top.sv └── project ├── README.md ├── img ├── lfsr_9bit.png ├── nback.png └── nback_logic_fsm.png ├── quartus_prj ├── nback_top.qpf ├── nback_top.qsf └── nback_top.sdc ├── rtl ├── debouncer.sv ├── led_driver.sv ├── lfsr_9bit.sv ├── nback_logic.sv ├── nback_top.sv └── posedge_detector.sv └── tb ├── nback_logic_tb ├── make.do └── nback_logic_tb.sv └── prbs_tb ├── lsfr_9b_gen.py ├── make.do ├── prbs_tb.sv └── ref_results.txt /Lecture_1_slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcmtk/fpga-webinar-2020/bfbbfe2e8874b52a0cf192fc6725038a6f43f3d2/Lecture_1_slides.pdf -------------------------------------------------------------------------------- /Lecture_2_slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcmtk/fpga-webinar-2020/bfbbfe2e8874b52a0cf192fc6725038a6f43f3d2/Lecture_2_slides.pdf -------------------------------------------------------------------------------- /Lecture_3_slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcmtk/fpga-webinar-2020/bfbbfe2e8874b52a0cf192fc6725038a6f43f3d2/Lecture_3_slides.pdf -------------------------------------------------------------------------------- /Lecture_4_slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcmtk/fpga-webinar-2020/bfbbfe2e8874b52a0cf192fc6725038a6f43f3d2/Lecture_4_slides.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fpga-webinar-2020 2 | 3 | * Страница с описанием курса: https://metrotek.center/fpga-webinar.html 4 | * Записи лекций: https://www.youtube.com/playlist?list=PLOiK7Vmp7kf-YmjuuJKvDvmJdxKs826kx 5 | 6 | Репозиторий наполняется по мере выхода лекций. 7 | 8 | ## Структура репозитория 9 | 10 | * Слайды лекци: 11 | * Lecture_1_slides.pdf -- слайды к первой лекции. 12 | * Lecture_2_slides.pdf -- слайды ко второй лекции. 13 | * Lecture_3_slides.pdf -- слайды к третьей лекции. 14 | * Lecture_4_slides.pdf -- слайды к четвертой лекции. 15 | * Материалы лекций: 16 | * lecture_2/ -- материалы к лекции 2. 17 | * lecture_3/ -- материалы к лекции 3. 18 | * project/ -- проект к лекции 4. 19 | -------------------------------------------------------------------------------- /lecture_2/README.md: -------------------------------------------------------------------------------- 1 | # Пример просто тесбенча на языку SystemVerilog 2 | 3 | Для запуска симуляции в ModelSim: 4 | 1. Запустите ModelSim 5 | 2. В консоли ModelSim переместитесь в это папку: 6 | # cd <путь_до_папки> 7 | 3. Выполните: 8 | # do make_sim.do 9 | 4. Если временные диаграммы не появились, откройте окно Wave: 10 | View -> Wave 11 | -------------------------------------------------------------------------------- /lecture_2/counter.sv: -------------------------------------------------------------------------------- 1 | module counter ( 2 | input clock_i, 3 | input reset_i, 4 | output [3:0] data_o 5 | ); 6 | 7 | logic [3:0] cnt; 8 | 9 | always_ff @( posedge clock_i ) 10 | begin 11 | if( reset_i ) 12 | cnt <= '0; 13 | else 14 | cnt <= cnt + 1; 15 | end 16 | 17 | assign data_o = cnt; 18 | 19 | endmodule 20 | -------------------------------------------------------------------------------- /lecture_2/make_sim.do: -------------------------------------------------------------------------------- 1 | vlib work 2 | 3 | vlog -sv counter.sv 4 | vlog -sv top_tb.sv 5 | 6 | vsim -novopt top_tb 7 | 8 | add log -r /* 9 | add wave -r * 10 | run -all 11 | -------------------------------------------------------------------------------- /lecture_2/top_tb.sv: -------------------------------------------------------------------------------- 1 | module top_tb; 2 | bit clk; 3 | bit reset; 4 | initial 5 | forever 6 | #5 clk = !clk; 7 | 8 | logic [3:0] cnt_from_dut; 9 | 10 | counter DUT ( 11 | .clock_i ( clk ), 12 | .reset_i ( reset ), 13 | .data_o ( cnt_from_dut ) 14 | ); 15 | 16 | initial 17 | begin 18 | reset <= 1'b0; 19 | #99; 20 | @( posedge clk ); 21 | reset <= 1'b1; 22 | @( posedge clk ); 23 | reset <= 1'b0; 24 | $display( cnt_from_dut ); 25 | @( posedge clk ); 26 | $display( cnt_from_dut ); 27 | end 28 | endmodule 29 | 30 | -------------------------------------------------------------------------------- /lecture_3/README.md: -------------------------------------------------------------------------------- 1 | # Материалы к лекции 3 курса "FPGA для начинающих" 2 | 3 | В папках исходники Quartus проектов, которые были рассмотрены на лекции. 4 | 5 | ## Структура папок: 6 | 7 | * debouncer/ -- модуль фильтрации сигнала 8 | * debouncer/debouncer_tb/ -- тестбенч для debouncer 9 | 10 | * fifo/ -- очередь fifo 11 | * fifo/fifo_example/ -- Quartus проект fifo 12 | * fifo/tb/ -- тестбенч для fifo 13 | 14 | * fsm/ -- пример простого конечного автомата 15 | * fsm/fsm_example/ -- Quartus проект fsm 16 | 17 | * memory/ -- пример памяти 18 | * memory/memory_example/ -- Quartus проект памяти 19 | 20 | * mux_demux/ -- пример простых мультиплексоров и демультиплексоров 21 | * mux_demux/mux_example/ -- Quartus проект мультиплексора 22 | 23 | * posedge_detector/ -- выделитель фронта 24 | * posedge_detector/posedge_detector_example/ -- Quartus проект памяти 25 | 26 | ## Как собрать проект Quartus 27 | 28 | Открыть в Quartus файл <имя_проекта>.qpf 29 | 30 | Нажать Start Compilation 31 | 32 | ## Как запустить симуляцию 33 | 34 | 1. Запустите ModelSim 35 | 2. В консоли ModelSim переместитесь в эту папку: 36 | # cd <путь_до_папки> 37 | 3. Выполните: 38 | # do make_sim.do 39 | 4. Если временные диаграммы не появились, откройте окно Wave: 40 | View -> Wave 41 | -------------------------------------------------------------------------------- /lecture_3/debouncer/debouncer.sv: -------------------------------------------------------------------------------- 1 | module debouncer #( 2 | // Счетчик, который будет считать время, которое сигнал вел себя стабильно 3 | // Если это время достигнет 2**DB_CNT_W - 1 -- им можно пользоваться. 4 | parameter DB_CNT_W = 20 5 | )( 6 | input logic clk_i, 7 | input logic s_rst_i, 8 | 9 | input logic pin_i, 10 | output logic pin_state_o 11 | ); 12 | 13 | // pin_i асинхронный сигнал. Нужно его пересинхронизировать: 14 | 15 | logic [2:0] pin_d; 16 | 17 | always_ff @( posedge clk_i ) 18 | begin 19 | pin_d[0] <= pin_i; 20 | pin_d[1] <= pin_d[0]; 21 | pin_d[2] <= pin_d[1]; 22 | end 23 | 24 | logic [DB_CNT_W-1:0] db_counter; 25 | logic pin_differ; 26 | 27 | logic db_counter_max; 28 | 29 | // 1 только когда счетчик станет '1111...11 30 | assign db_counter_max = ( &db_counter ); 31 | 32 | // 0 -- когда пин не меняется за 2 такта 33 | // 1 -- пин на двух тактах имеет разное значение 34 | assign pin_differ = pin_d[2] ^ pin_d[1]; 35 | 36 | always_ff @( posedge clk_i ) 37 | if( s_rst_i ) 38 | db_counter <= '0; 39 | else 40 | begin 41 | if( db_counter_max || pin_differ ) 42 | db_counter <= '0; 43 | else 44 | db_counter <= db_counter + (DB_CNT_W)'(1); 45 | end 46 | 47 | always_ff @( posedge clk_i ) 48 | if( s_rst_i ) 49 | pin_state_o <= 1'b0; 50 | else 51 | if( db_counter_max ) 52 | pin_state_o <= pin_d[2]; 53 | 54 | endmodule 55 | -------------------------------------------------------------------------------- /lecture_3/debouncer/debouncer_tb/debouncer_tb.sv: -------------------------------------------------------------------------------- 1 | module debouncer_tb; 2 | 3 | parameter PULSE_LENGTH = 10000; 4 | parameter TASKS_CNT = 100; 5 | 6 | parameter CLEAR_TASK_CNT = TASKS_CNT/2; 7 | parameter NOISE_TASK_CNT = TASKS_CNT - CLEAR_TASK_CNT; 8 | 9 | bit clk; 10 | bit rst; 11 | bit rst_done; 12 | 13 | logic pin; 14 | logic pin_state; 15 | 16 | typedef struct { 17 | int before_stable_duration; 18 | int stable_duration; 19 | int after_stable_duration; 20 | int pause_duration; 21 | } task_t; 22 | 23 | typedef struct { 24 | int cnt; 25 | int max_duration; 26 | int min_duration; 27 | int total_duration; 28 | } pulse_stat_t; 29 | 30 | task generate_tasks ( mailbox #( task_t ) gt, 31 | int task_cnt, 32 | int stable_duration, 33 | bit clear_signal = 0 34 | ); 35 | for (int i = 0; i < task_cnt; i++ ) 36 | begin 37 | task_t new_task; 38 | if( clear_signal ) 39 | begin 40 | new_task.before_stable_duration = 0; 41 | new_task.after_stable_duration = 0; 42 | end 43 | else 44 | begin 45 | new_task.before_stable_duration = $urandom_range(stable_duration/4,1); 46 | new_task.after_stable_duration = $urandom_range(stable_duration/4,1); 47 | end 48 | new_task.stable_duration = stable_duration; 49 | new_task.pause_duration = stable_duration; 50 | gt.put( new_task ); 51 | end 52 | endtask 53 | 54 | task recieve_tasks( int timeout, output pulse_stat_t signal_stat ); 55 | automatic int tick_counter = 0; 56 | automatic int duration = 0; 57 | 58 | signal_stat.cnt = 0; 59 | signal_stat.total_duration = 0; 60 | signal_stat.max_duration = 0; 61 | signal_stat.min_duration = 2**31 - 1; 62 | 63 | while( tick_counter < timeout ) 64 | begin 65 | while ( pin_state == 1'b0 ) 66 | begin 67 | tick_counter += 1; 68 | ##1; 69 | if( tick_counter > timeout ) 70 | return; 71 | end 72 | 73 | duration = 0; 74 | 75 | while ( pin_state ) 76 | begin 77 | duration += 1; 78 | tick_counter += 1; 79 | ##1; 80 | if( tick_counter > timeout ) 81 | return; 82 | end 83 | 84 | signal_stat.cnt += 1; 85 | signal_stat.total_duration += duration; 86 | 87 | if( duration > signal_stat.max_duration ) 88 | signal_stat.max_duration = duration; 89 | 90 | if( duration < signal_stat.min_duration ) 91 | signal_stat.min_duration = duration; 92 | end 93 | 94 | endtask 95 | 96 | task send_tasks( mailbox #( task_t ) st ); 97 | while ( st.num != 0 ) 98 | begin 99 | task_t send_task; 100 | 101 | st.get( send_task ); 102 | for ( int i = 0; i < send_task.before_stable_duration; i++ ) 103 | begin 104 | ##1; 105 | pin <= $urandom_range(1,0); 106 | end 107 | 108 | for ( int i = 0; i < send_task.stable_duration; i++ ) 109 | begin 110 | ##1; 111 | pin <= 1'b1; 112 | end 113 | 114 | for ( int i = 0; i < send_task.after_stable_duration; i++ ) 115 | begin 116 | ##1; 117 | pin <= $urandom_range(1,0); 118 | end 119 | 120 | for ( int i = 0; i < send_task.pause_duration; i++ ) 121 | begin 122 | ##1; 123 | pin <= 1'b0; 124 | end 125 | end 126 | endtask 127 | 128 | initial 129 | forever 130 | #5 clk = !clk; 131 | 132 | default clocking cb 133 | @ (posedge clk); 134 | endclocking 135 | 136 | initial 137 | begin 138 | rst <= 1'b0; 139 | ##1; 140 | rst <= 1'b1; 141 | ##1; 142 | rst <= 1'b0; 143 | rst_done = 1'b1; 144 | end 145 | 146 | debouncer #( 147 | .DB_CNT_W ( 10 ) 148 | ) db_inst ( 149 | .clk_i ( clk ), 150 | .s_rst_i ( rst ), 151 | 152 | .pin_i ( pin ), 153 | .pin_state_o ( pin_state ) 154 | ); 155 | 156 | mailbox #( task_t ) gen_tasks = new(); 157 | pulse_stat_t clear_signal_stat; 158 | pulse_stat_t noise_signal_stat; 159 | 160 | initial 161 | begin 162 | wait( rst_done ); 163 | $display( "Starint tests. Config:"); 164 | $display( "\t PULSE_LENGTH (stable time for each input pulse) = %d", 165 | PULSE_LENGTH); 166 | 167 | $display( "\t TASKS_CNT (count of task to send) = %d", 168 | TASKS_CNT); 169 | 170 | $display( "Starting with sending %d clear signals with no noise" , 171 | CLEAR_TASK_CNT); 172 | 173 | generate_tasks( gen_tasks, CLEAR_TASK_CNT, PULSE_LENGTH, 1 ); 174 | 175 | fork 176 | send_tasks( gen_tasks ); 177 | recieve_tasks( PULSE_LENGTH * CLEAR_TASK_CNT * 2, clear_signal_stat ); 178 | join 179 | 180 | if( clear_signal_stat.cnt != CLEAR_TASK_CNT ) 181 | $error( "Not all pulses were recieved in clear test!" ); 182 | 183 | $display( "### Test 1 with clear signal done ###" ); 184 | $display( "\t Send pulses: %d" , CLEAR_TASK_CNT ); 185 | $display( "\t Recieved pulses: %d", clear_signal_stat.cnt ); 186 | $display( "\t Max pulse duration: %d", clear_signal_stat.max_duration ); 187 | $display( "\t Min pulse duration: %d", clear_signal_stat.min_duration ); 188 | $display( "\t Average pulse duration: %f", clear_signal_stat.total_duration / clear_signal_stat.cnt); 189 | 190 | $display( "Starting test #2: sending %d signals with noise" , 191 | NOISE_TASK_CNT); 192 | 193 | generate_tasks( gen_tasks, NOISE_TASK_CNT, PULSE_LENGTH, 0 ); 194 | 195 | fork 196 | send_tasks( gen_tasks ); 197 | recieve_tasks( PULSE_LENGTH * NOISE_TASK_CNT * 2, noise_signal_stat ); 198 | join 199 | 200 | if( noise_signal_stat.cnt != NOISE_TASK_CNT ) 201 | $error( "Not all pulses were recieved in clear test!" ); 202 | 203 | $display( "### Test 2 with clear signal done ###" ); 204 | $display( "\t Send pulses: %d" , NOISE_TASK_CNT ); 205 | $display( "\t Recieved pulses: %d", clear_signal_stat.cnt ); 206 | $display( "\t Max pulse duration: %d", clear_signal_stat.max_duration ); 207 | $display( "\t Min pulse duration: %d", clear_signal_stat.min_duration ); 208 | $display( "\t Average pulse duration: %f", clear_signal_stat.total_duration / clear_signal_stat.cnt); 209 | 210 | $stop(); 211 | end 212 | 213 | endmodule 214 | -------------------------------------------------------------------------------- /lecture_3/debouncer/debouncer_tb/make.do: -------------------------------------------------------------------------------- 1 | vlib work 2 | 3 | vlog -sv ../debouncer.sv 4 | vlog -sv debouncer_tb.sv 5 | 6 | vsim -novopt debouncer_tb 7 | add log -r /* 8 | add wave -r * 9 | run -all 10 | 11 | -------------------------------------------------------------------------------- /lecture_3/fifo/fifo.sv: -------------------------------------------------------------------------------- 1 | module fifo #( 2 | parameter DATA_W = 5, 3 | parameter ADDR_W = 4 4 | )( 5 | input logic clk_i, 6 | input logic s_rst_i, 7 | 8 | input logic wr_req_i, 9 | input logic [DATA_W-1:0] wr_data_i, 10 | output logic full_o, 11 | 12 | input logic rd_req_i, 13 | output logic [DATA_W-1:0] rd_data_o, 14 | output logic empty_o 15 | ); 16 | 17 | localparam PTR_W = ADDR_W+1; 18 | 19 | logic [PTR_W-1:0] rd_ptr; 20 | logic [PTR_W-1:0] wr_ptr; 21 | 22 | logic [DATA_W-1:0] mem [2**ADDR_W-1:0]; 23 | 24 | always_ff @( posedge clk_i or posedge s_rst_i ) 25 | if( s_rst_i ) 26 | begin 27 | rd_ptr <= '0; 28 | wr_ptr <= '0; 29 | end 30 | else 31 | begin 32 | if( rd_req_i && !empty_o ) 33 | rd_ptr <= rd_ptr + (PTR_W)'(1); 34 | if( wr_req_i && !full_o ) 35 | wr_ptr <= wr_ptr + (PTR_W)'(1); 36 | end 37 | 38 | always_ff @( posedge clk_i ) 39 | if( wr_req_i ) 40 | mem[wr_ptr[ADDR_W-1:0]] <= wr_data_i; 41 | 42 | always_ff @( posedge clk_i ) 43 | if( rd_req_i ) 44 | rd_data_o <= mem[rd_ptr[ADDR_W-1:0]]; 45 | 46 | assign empty_o = ( rd_ptr == wr_ptr ); 47 | assign full_o = ( rd_ptr[ADDR_W-1:0] == wr_ptr[ADDR_W-1:0] ) && 48 | ( rd_ptr[PTR_W-1] != wr_ptr[PTR_W-1] ); 49 | endmodule 50 | -------------------------------------------------------------------------------- /lecture_3/fifo/fifo_example/fifo_top.qpf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 2017 Intel Corporation. All rights reserved. 4 | # Your use of Intel Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Intel Program License 10 | # Subscription Agreement, the Intel Quartus Prime License Agreement, 11 | # the Intel FPGA IP License Agreement, or other applicable license 12 | # agreement, including, without limitation, that your use is for 13 | # the sole purpose of programming logic devices manufactured by 14 | # Intel and sold by Intel or its authorized distributors. Please 15 | # refer to the applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus Prime 20 | # Version 17.1.0 Build 590 10/25/2017 SJ Lite Edition 21 | # Date created = 23:04:34 мая 12, 2020 22 | # 23 | # -------------------------------------------------------------------------- # 24 | 25 | QUARTUS_VERSION = "17.1" 26 | DATE = "23:04:34 мая 12, 2020" 27 | 28 | # Revisions 29 | 30 | PROJECT_REVISION = "fifo_top" 31 | -------------------------------------------------------------------------------- /lecture_3/fifo/fifo_example/fifo_top.qsf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 2017 Intel Corporation. All rights reserved. 4 | # Your use of Intel Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Intel Program License 10 | # Subscription Agreement, the Intel Quartus Prime License Agreement, 11 | # the Intel FPGA IP License Agreement, or other applicable license 12 | # agreement, including, without limitation, that your use is for 13 | # the sole purpose of programming logic devices manufactured by 14 | # Intel and sold by Intel or its authorized distributors. Please 15 | # refer to the applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus Prime 20 | # Version 17.1.0 Build 590 10/25/2017 SJ Lite Edition 21 | # Date created = 23:04:34 мая 12, 2020 22 | # 23 | # -------------------------------------------------------------------------- # 24 | # 25 | # Notes: 26 | # 27 | # 1) The default values for assignments are stored in the file: 28 | # mux_top_assignment_defaults.qdf 29 | # If this file doesn't exist, see file: 30 | # assignment_defaults.qdf 31 | # 32 | # 2) Altera recommends that you do not modify this file. This 33 | # file is updated automatically by the Quartus Prime software 34 | # and any changes you make may be lost or overwritten. 35 | # 36 | # -------------------------------------------------------------------------- # 37 | 38 | 39 | set_global_assignment -name FAMILY "Cyclone IV E" 40 | set_global_assignment -name DEVICE EP4CE22F17C6 41 | set_global_assignment -name TOP_LEVEL_ENTITY fifo_top 42 | set_global_assignment -name ORIGINAL_QUARTUS_VERSION 17.1.0 43 | set_global_assignment -name PROJECT_CREATION_TIME_DATE "23:04:34 мая 12, 2020" 44 | set_global_assignment -name LAST_QUARTUS_VERSION "17.1.0 Lite Edition" 45 | set_global_assignment -name SYSTEMVERILOG_FILE ../fifo.sv 46 | set_global_assignment -name SYSTEMVERILOG_FILE fifo_top.sv 47 | set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files 48 | set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 49 | set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 50 | set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1 51 | set_global_assignment -name NOMINAL_CORE_SUPPLY_VOLTAGE 1.2V 52 | set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top 53 | set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top 54 | set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top 55 | set_global_assignment -name SDC_FILE fifo_top.sdc 56 | set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" 57 | set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" 58 | set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON 59 | set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL 60 | 61 | set_instance_assignment -name VIRTUAL_PIN ON -to s_rst_i 62 | set_instance_assignment -name VIRTUAL_PIN ON -to wr_req_i 63 | set_instance_assignment -name VIRTUAL_PIN ON -to wr_data_i 64 | set_instance_assignment -name VIRTUAL_PIN ON -to full_o 65 | set_instance_assignment -name VIRTUAL_PIN ON -to rd_req_i 66 | set_instance_assignment -name VIRTUAL_PIN ON -to rd_data_o 67 | set_instance_assignment -name VIRTUAL_PIN ON -to empty_o 68 | 69 | set_location_assignment PIN_R8 -to clk_i 70 | 71 | 72 | 73 | 74 | 75 | set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top -------------------------------------------------------------------------------- /lecture_3/fifo/fifo_example/fifo_top.sdc: -------------------------------------------------------------------------------- 1 | set_time_format -unit ns -decimal_places 3 2 | 3 | create_clock -name {clk_100} -period 10.000 -waveform { 0.000 5.000 } [get_ports {clk_i}] 4 | 5 | derive_clock_uncertainty 6 | -------------------------------------------------------------------------------- /lecture_3/fifo/fifo_example/fifo_top.sv: -------------------------------------------------------------------------------- 1 | module fifo_top( 2 | input logic clk_i, 3 | input logic s_rst_i, 4 | 5 | input logic wr_req_i, 6 | input logic [7:0] wr_data_i, 7 | output logic full_o, 8 | 9 | input logic rd_req_i, 10 | output logic [7:0] rd_data_o, 11 | output logic empty_o 12 | ); 13 | 14 | logic s_rst; 15 | logic wr_req; 16 | logic [7:0] wr_data; 17 | logic rd_req; 18 | 19 | logic full; 20 | logic [7:0] rd_data; 21 | logic empty; 22 | 23 | always_ff @( posedge clk_i ) 24 | begin 25 | s_rst <= s_rst_i; 26 | wr_req <= wr_req_i; 27 | wr_data <= wr_data_i; 28 | rd_req <= rd_req_i; 29 | end 30 | 31 | fifo #( 32 | .ADDR_W ( 4 ), 33 | .DATA_W ( 8 ) 34 | ) fifo_ins ( 35 | .clk_i ( clk_i ), 36 | .s_rst_i ( s_rst ), 37 | 38 | .wr_req_i ( wr_req ), 39 | .wr_data_i ( wr_data ), 40 | .full_o ( full ), 41 | 42 | .rd_req_i ( rd_req ), 43 | .rd_data_o ( rd_data ), 44 | .empty_o ( empty ) 45 | ); 46 | 47 | always_ff @( posedge clk_i ) 48 | begin 49 | full_o <= full; 50 | rd_data_o <= rd_data; 51 | empty_o <= empty; 52 | end 53 | 54 | endmodule 55 | -------------------------------------------------------------------------------- /lecture_3/fifo/fifo_tb/fifo_tb.sv: -------------------------------------------------------------------------------- 1 | module fifo_tb; 2 | 3 | parameter DATA_W = 30; 4 | parameter ADDR_W = 5; 5 | parameter TEST_CNT = 100; 6 | 7 | bit clk; 8 | bit rst; 9 | bit rst_done; 10 | 11 | logic wr_req; 12 | logic [DATA_W-1:0] wr_data; 13 | logic full; 14 | 15 | logic rd_req; 16 | logic [DATA_W-1:0] rd_data; 17 | logic empty; 18 | 19 | initial 20 | forever 21 | #5 clk = !clk; 22 | 23 | default clocking cb 24 | @ (posedge clk); 25 | endclocking 26 | 27 | initial 28 | begin 29 | rst <= 1'b0; 30 | ##1; 31 | rst <= 1'b1; 32 | ##1; 33 | rst <= 1'b0; 34 | rst_done = 1'b1; 35 | end 36 | 37 | fifo #( 38 | .DATA_W ( DATA_W ), 39 | .ADDR_W ( ADDR_W ) 40 | ) fifo_ins ( 41 | .clk_i ( clk ), 42 | .s_rst_i ( rst ), 43 | 44 | .wr_req_i ( wr_req ), 45 | .wr_data_i ( wr_data ), 46 | .full_o ( full ), 47 | 48 | .rd_req_i ( rd_req ), 49 | .rd_data_o ( rd_data ), 50 | .empty_o ( empty ) 51 | ); 52 | 53 | int cnt; 54 | mailbox #( logic [DATA_W-1:0] ) generated_data = new(); 55 | mailbox #( logic [DATA_W-1:0] ) sended_data = new(); 56 | mailbox #( logic [DATA_W-1:0] ) read_data = new(); 57 | 58 | task gen_data( input int cnt, 59 | mailbox #( logic [DATA_W-1:0] ) data ); 60 | 61 | logic [DATA_W-1:0] data_to_send; 62 | 63 | for( int i = 0; i < cnt; i++ ) 64 | begin 65 | data_to_send = $urandom_range(2**DATA_W-1,0); 66 | data.put( data_to_send ); 67 | end 68 | 69 | endtask 70 | 71 | task fifo_wr( mailbox #( logic [DATA_W-1:0] ) data, 72 | mailbox #( logic [DATA_W-1:0] ) sended_data, 73 | input bit burst = 0 74 | ); 75 | 76 | logic [DATA_W-1:0] word_to_wr; 77 | int pause; 78 | while( data.num() ) 79 | begin 80 | data.get(word_to_wr); 81 | if( burst ) 82 | pause = 0; 83 | else 84 | pause = $urandom_range(10,0); 85 | 86 | wr_data <= word_to_wr; 87 | wr_req <= 1'b1; 88 | ##1; 89 | 90 | if( !full ) 91 | sended_data.put( word_to_wr ); 92 | 93 | if( pause != 0 ) 94 | begin 95 | wr_req <= 1'b0; 96 | ##pause; 97 | end 98 | end 99 | wr_req <= 1'b0; 100 | endtask 101 | 102 | task fifo_rd( mailbox #( logic [DATA_W-1:0] ) read_data, 103 | input int empty_timeout, 104 | input bit burst = 0 105 | ); 106 | 107 | int no_empty_counter; 108 | int pause; 109 | 110 | forever 111 | begin 112 | if( !empty ) 113 | begin 114 | if( burst ) 115 | pause = 0; 116 | else 117 | pause = $urandom_range(10,0); 118 | 119 | no_empty_counter = 0; 120 | 121 | rd_req <= 1'b1; 122 | ##1; 123 | read_data.put( rd_data ); 124 | if( pause != 0 ) 125 | begin 126 | rd_req <= 0; 127 | ##pause; 128 | end 129 | end 130 | else 131 | begin 132 | 133 | if( no_empty_counter == empty_timeout ) 134 | return; 135 | else 136 | no_empty_counter += 1; 137 | 138 | ##1; 139 | end 140 | end 141 | endtask 142 | 143 | task compare_data( mailbox #( logic [DATA_W-1:0] ) ref_data, 144 | mailbox #( logic [DATA_W-1:0] ) dut_data 145 | ); 146 | 147 | logic [DATA_W-1:0] ref_data_tmp; 148 | logic [DATA_W-1:0] dut_data_tmp; 149 | 150 | if( ref_data.num() != dut_data.num() ) 151 | begin 152 | $display( "Size of ref data: %d", ref_data.num() ); 153 | $display( "And sized of dut data: %d", dut_data.num() ); 154 | $display( "Do not match" ); 155 | $stop(); 156 | end 157 | else 158 | begin 159 | for( int i = 0; i < dut_data.num(); i++ ) 160 | begin 161 | dut_data.get( dut_data_tmp ); 162 | ref_data.get( ref_data_tmp ); 163 | if( ref_data_tmp != dut_data_tmp ) 164 | begin 165 | $display( "Error! Data do not match!" ); 166 | $display( "Reference data: %x", ref_data_tmp ); 167 | $display( "Read data: %x", dut_data_tmp ); 168 | $stop(); 169 | end 170 | end 171 | end 172 | 173 | endtask 174 | 175 | initial 176 | begin 177 | wr_data <= '0; 178 | wr_req <= 1'b0; 179 | rd_req <= 1'b0; 180 | 181 | gen_data( TEST_CNT, generated_data ); 182 | 183 | wait( rst_done ); 184 | 185 | fork 186 | fifo_wr(generated_data, sended_data); 187 | fifo_rd(read_data, 1000); 188 | join 189 | 190 | compare_data(sended_data, read_data); 191 | $display( "Test done! No errors!" ); 192 | $stop(); 193 | end 194 | 195 | 196 | endmodule 197 | -------------------------------------------------------------------------------- /lecture_3/fifo/fifo_tb/make.do: -------------------------------------------------------------------------------- 1 | vlib work 2 | 3 | vlog -sv ../fifo.sv 4 | vlog -sv fifo_tb.sv 5 | 6 | vsim -novopt fifo_tb 7 | add log -r /* 8 | add wave -r * 9 | run -all 10 | 11 | -------------------------------------------------------------------------------- /lecture_3/fsm/fsm.sv: -------------------------------------------------------------------------------- 1 | module fsm( 2 | input logic clk_i, 3 | input logic s_rst_i, 4 | 5 | input logic next_state_stb_i, 6 | output logic [1:0] value_o 7 | ); 8 | 9 | enum logic [1:0] { 10 | IDLE_S, 11 | STATE_1, 12 | STATE_2 13 | } state, next_state; 14 | 15 | always_ff @( posedge clk_i ) 16 | if( s_rst_i ) 17 | state <= IDLE_S; 18 | else 19 | state <= next_state; 20 | 21 | always_comb 22 | begin 23 | next_state = state; 24 | case( state ) 25 | IDLE_S: 26 | begin 27 | if( next_state_stb_i ) 28 | next_state = STATE_1; 29 | end 30 | STATE_1: 31 | begin 32 | if( next_state_stb_i ) 33 | next_state = STATE_2; 34 | end 35 | STATE_2: 36 | begin 37 | if( next_state_stb_i ) 38 | next_state = IDLE_S; 39 | end 40 | default: 41 | begin 42 | next_state = IDLE_S; 43 | end 44 | endcase 45 | end 46 | 47 | always_comb 48 | begin 49 | value_o = '0; 50 | case( state ) 51 | IDLE_S: 52 | begin 53 | value_o = 2'd0; 54 | end 55 | STATE_1: 56 | begin 57 | value_o = 2'd2; 58 | end 59 | STATE_2: 60 | begin 61 | value_o = 2'd1; 62 | end 63 | default: 64 | begin 65 | value_o = 2'd0; 66 | end 67 | endcase 68 | end 69 | 70 | endmodule 71 | -------------------------------------------------------------------------------- /lecture_3/fsm/fsm_example/fsm_top.qpf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 2017 Intel Corporation. All rights reserved. 4 | # Your use of Intel Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Intel Program License 10 | # Subscription Agreement, the Intel Quartus Prime License Agreement, 11 | # the Intel FPGA IP License Agreement, or other applicable license 12 | # agreement, including, without limitation, that your use is for 13 | # the sole purpose of programming logic devices manufactured by 14 | # Intel and sold by Intel or its authorized distributors. Please 15 | # refer to the applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus Prime 20 | # Version 17.1.0 Build 590 10/25/2017 SJ Lite Edition 21 | # Date created = 23:04:34 мая 12, 2020 22 | # 23 | # -------------------------------------------------------------------------- # 24 | 25 | QUARTUS_VERSION = "17.1" 26 | DATE = "23:04:34 мая 12, 2020" 27 | 28 | # Revisions 29 | 30 | PROJECT_REVISION = "fsm_top" 31 | -------------------------------------------------------------------------------- /lecture_3/fsm/fsm_example/fsm_top.qsf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 2017 Intel Corporation. All rights reserved. 4 | # Your use of Intel Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Intel Program License 10 | # Subscription Agreement, the Intel Quartus Prime License Agreement, 11 | # the Intel FPGA IP License Agreement, or other applicable license 12 | # agreement, including, without limitation, that your use is for 13 | # the sole purpose of programming logic devices manufactured by 14 | # Intel and sold by Intel or its authorized distributors. Please 15 | # refer to the applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus Prime 20 | # Version 17.1.0 Build 590 10/25/2017 SJ Lite Edition 21 | # Date created = 23:04:34 мая 12, 2020 22 | # 23 | # -------------------------------------------------------------------------- # 24 | # 25 | # Notes: 26 | # 27 | # 1) The default values for assignments are stored in the file: 28 | # mux_top_assignment_defaults.qdf 29 | # If this file doesn't exist, see file: 30 | # assignment_defaults.qdf 31 | # 32 | # 2) Altera recommends that you do not modify this file. This 33 | # file is updated automatically by the Quartus Prime software 34 | # and any changes you make may be lost or overwritten. 35 | # 36 | # -------------------------------------------------------------------------- # 37 | 38 | 39 | set_global_assignment -name FAMILY "Cyclone IV E" 40 | set_global_assignment -name DEVICE EP4CE22F17C6 41 | set_global_assignment -name TOP_LEVEL_ENTITY fsm_top 42 | set_global_assignment -name ORIGINAL_QUARTUS_VERSION 17.1.0 43 | set_global_assignment -name PROJECT_CREATION_TIME_DATE "23:04:34 мая 12, 2020" 44 | set_global_assignment -name LAST_QUARTUS_VERSION "17.1.0 Lite Edition" 45 | set_global_assignment -name SYSTEMVERILOG_FILE ../fsm.sv 46 | set_global_assignment -name SYSTEMVERILOG_FILE fsm_top.sv 47 | set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files 48 | set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 49 | set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 50 | set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1 51 | set_global_assignment -name NOMINAL_CORE_SUPPLY_VOLTAGE 1.2V 52 | set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top 53 | set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top 54 | set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top 55 | set_global_assignment -name SDC_FILE fsm_top.sdc 56 | set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" 57 | set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" 58 | set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON 59 | set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL 60 | 61 | set_instance_assignment -name VIRTUAL_PIN ON -to s_rst_i 62 | set_instance_assignment -name VIRTUAL_PIN ON -to next_state_stb_i 63 | set_instance_assignment -name VIRTUAL_PIN ON -to value_o 64 | 65 | set_location_assignment PIN_R8 -to clk_i 66 | 67 | 68 | 69 | 70 | 71 | 72 | set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top -------------------------------------------------------------------------------- /lecture_3/fsm/fsm_example/fsm_top.sdc: -------------------------------------------------------------------------------- 1 | set_time_format -unit ns -decimal_places 3 2 | 3 | create_clock -name {clk_100} -period 10.000 -waveform { 0.000 5.000 } [get_ports {clk_i}] 4 | 5 | derive_clock_uncertainty 6 | -------------------------------------------------------------------------------- /lecture_3/fsm/fsm_example/fsm_top.sv: -------------------------------------------------------------------------------- 1 | module fsm_top( 2 | input logic clk_i, 3 | input logic s_rst_i, 4 | 5 | input logic next_state_stb_i, 6 | output logic [1:0] value_o 7 | ); 8 | 9 | logic s_rst; 10 | logic next_state_stb; 11 | logic [1:0] value; 12 | 13 | always_ff @( posedge clk_i ) 14 | begin 15 | s_rst <= s_rst_i; 16 | next_state_stb <= next_state_stb_i; 17 | end 18 | 19 | fsm fsm_ins( 20 | .clk_i ( clk_i ), 21 | .s_rst_i ( s_rst ), 22 | 23 | .next_state_stb_i ( next_state_stb ), 24 | .value_o ( value ) 25 | ); 26 | 27 | always_ff @( posedge clk_i ) 28 | value_o <= value; 29 | 30 | endmodule 31 | -------------------------------------------------------------------------------- /lecture_3/memory/memory.sv: -------------------------------------------------------------------------------- 1 | module memory #( 2 | parameter ADDR_W = 5, 3 | parameter DATA_W = 10 4 | )( 5 | input logic clk_i, 6 | input logic [DATA_W-1:0] d_i, 7 | input logic [ADDR_W-1:0] write_address_i, 8 | input logic [ADDR_W-1:0] read_address_i, 9 | input logic we_i, 10 | 11 | output logic [DATA_W-1:0] q_o 12 | ); 13 | 14 | logic [DATA_W-1:0] mem [2**ADDR_W-1:0]; 15 | 16 | always_ff @( posedge clk_i ) 17 | begin 18 | 19 | if( we_i ) 20 | mem[write_address_i] <= d_i; 21 | 22 | q_o <= mem[read_address_i]; 23 | end 24 | 25 | endmodule 26 | -------------------------------------------------------------------------------- /lecture_3/memory/memory_example/memory_top.qpf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 2017 Intel Corporation. All rights reserved. 4 | # Your use of Intel Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Intel Program License 10 | # Subscription Agreement, the Intel Quartus Prime License Agreement, 11 | # the Intel FPGA IP License Agreement, or other applicable license 12 | # agreement, including, without limitation, that your use is for 13 | # the sole purpose of programming logic devices manufactured by 14 | # Intel and sold by Intel or its authorized distributors. Please 15 | # refer to the applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus Prime 20 | # Version 17.1.0 Build 590 10/25/2017 SJ Lite Edition 21 | # Date created = 23:04:34 мая 12, 2020 22 | # 23 | # -------------------------------------------------------------------------- # 24 | 25 | QUARTUS_VERSION = "17.1" 26 | DATE = "23:04:34 мая 12, 2020" 27 | 28 | # Revisions 29 | 30 | PROJECT_REVISION = "memory_top" 31 | -------------------------------------------------------------------------------- /lecture_3/memory/memory_example/memory_top.qsf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 2017 Intel Corporation. All rights reserved. 4 | # Your use of Intel Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Intel Program License 10 | # Subscription Agreement, the Intel Quartus Prime License Agreement, 11 | # the Intel FPGA IP License Agreement, or other applicable license 12 | # agreement, including, without limitation, that your use is for 13 | # the sole purpose of programming logic devices manufactured by 14 | # Intel and sold by Intel or its authorized distributors. Please 15 | # refer to the applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus Prime 20 | # Version 17.1.0 Build 590 10/25/2017 SJ Lite Edition 21 | # Date created = 23:04:34 мая 12, 2020 22 | # 23 | # -------------------------------------------------------------------------- # 24 | # 25 | # Notes: 26 | # 27 | # 1) The default values for assignments are stored in the file: 28 | # mux_top_assignment_defaults.qdf 29 | # If this file doesn't exist, see file: 30 | # assignment_defaults.qdf 31 | # 32 | # 2) Altera recommends that you do not modify this file. This 33 | # file is updated automatically by the Quartus Prime software 34 | # and any changes you make may be lost or overwritten. 35 | # 36 | # -------------------------------------------------------------------------- # 37 | 38 | 39 | set_global_assignment -name FAMILY "Cyclone IV E" 40 | set_global_assignment -name DEVICE EP4CE22F17C6 41 | set_global_assignment -name TOP_LEVEL_ENTITY memory_top 42 | set_global_assignment -name ORIGINAL_QUARTUS_VERSION 17.1.0 43 | set_global_assignment -name PROJECT_CREATION_TIME_DATE "23:04:34 мая 12, 2020" 44 | set_global_assignment -name LAST_QUARTUS_VERSION "17.1.0 Lite Edition" 45 | set_global_assignment -name SYSTEMVERILOG_FILE ../memory.sv 46 | set_global_assignment -name SYSTEMVERILOG_FILE memory_top.sv 47 | set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files 48 | set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 49 | set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 50 | set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1 51 | set_global_assignment -name NOMINAL_CORE_SUPPLY_VOLTAGE 1.2V 52 | set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top 53 | set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top 54 | set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top 55 | set_global_assignment -name SDC_FILE memory_top.sdc 56 | set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" 57 | set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" 58 | set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON 59 | set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL 60 | 61 | set_instance_assignment -name VIRTUAL_PIN ON -to d_i 62 | set_instance_assignment -name VIRTUAL_PIN ON -to write_address_i 63 | set_instance_assignment -name VIRTUAL_PIN ON -to read_address_i 64 | set_instance_assignment -name VIRTUAL_PIN ON -to we_i 65 | set_instance_assignment -name VIRTUAL_PIN ON -to q_o 66 | 67 | set_location_assignment PIN_R8 -to clk_i 68 | 69 | 70 | 71 | 72 | set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top -------------------------------------------------------------------------------- /lecture_3/memory/memory_example/memory_top.sdc: -------------------------------------------------------------------------------- 1 | set_time_format -unit ns -decimal_places 3 2 | 3 | create_clock -name {clk_100} -period 10.000 -waveform { 0.000 5.000 } [get_ports {clk_i}] 4 | 5 | derive_clock_uncertainty 6 | -------------------------------------------------------------------------------- /lecture_3/memory/memory_example/memory_top.sv: -------------------------------------------------------------------------------- 1 | module memory_top( 2 | input logic clk_i, 3 | input logic [9:0] d_i, 4 | input logic [4:0] write_address_i, 5 | input logic [4:0] read_address_i, 6 | input logic we_i, 7 | 8 | output logic [9:0] q_o 9 | ); 10 | 11 | logic [9:0] d; 12 | logic [4:0] write_address; 13 | logic [4:0] read_address; 14 | logic we; 15 | 16 | logic [9:0] q; 17 | 18 | always_ff @( posedge clk_i ) 19 | begin 20 | d <= d_i; 21 | write_address <= write_address_i; 22 | read_address <= read_address_i; 23 | we <= we_i; 24 | end 25 | 26 | memory #( 27 | .ADDR_W ( 5 ), 28 | .DATA_W ( 10 ) 29 | ) mem_ins ( 30 | .clk_i ( clk_i ), 31 | .d_i ( d ), 32 | .write_address_i ( write_address ), 33 | .read_address_i ( read_address ), 34 | .we_i ( we ), 35 | 36 | .q_o ( q ) 37 | ); 38 | 39 | always_ff @( posedge clk_i ) 40 | q_o <= q; 41 | 42 | endmodule 43 | -------------------------------------------------------------------------------- /lecture_3/mux_demux/demux.sv: -------------------------------------------------------------------------------- 1 | module demux #( 2 | parameter OUT_CNT = 2, 3 | parameter DATA_W = 7 4 | )( 5 | input logic [DATA_W-1:0] data_i, 6 | input logic [$clog2(OUT_CNT)-1:0] sel_i, 7 | output logic [OUT_CNT-1:0][DATA_W-1:0] demuxed_out_o 8 | ); 9 | 10 | always_comb 11 | begin 12 | demuxed_out_o = '0; 13 | demuxed_out_o[ sel_i ] = data_i; 14 | end 15 | 16 | endmodule 17 | -------------------------------------------------------------------------------- /lecture_3/mux_demux/demux_example/demux_top.qpf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 2017 Intel Corporation. All rights reserved. 4 | # Your use of Intel Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Intel Program License 10 | # Subscription Agreement, the Intel Quartus Prime License Agreement, 11 | # the Intel FPGA IP License Agreement, or other applicable license 12 | # agreement, including, without limitation, that your use is for 13 | # the sole purpose of programming logic devices manufactured by 14 | # Intel and sold by Intel or its authorized distributors. Please 15 | # refer to the applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus Prime 20 | # Version 17.1.0 Build 590 10/25/2017 SJ Lite Edition 21 | # Date created = 23:04:34 мая 12, 2020 22 | # 23 | # -------------------------------------------------------------------------- # 24 | 25 | QUARTUS_VERSION = "17.1" 26 | DATE = "23:04:34 мая 12, 2020" 27 | 28 | # Revisions 29 | 30 | PROJECT_REVISION = "demux_top" 31 | -------------------------------------------------------------------------------- /lecture_3/mux_demux/demux_example/demux_top.qsf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 2017 Intel Corporation. All rights reserved. 4 | # Your use of Intel Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Intel Program License 10 | # Subscription Agreement, the Intel Quartus Prime License Agreement, 11 | # the Intel FPGA IP License Agreement, or other applicable license 12 | # agreement, including, without limitation, that your use is for 13 | # the sole purpose of programming logic devices manufactured by 14 | # Intel and sold by Intel or its authorized distributors. Please 15 | # refer to the applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus Prime 20 | # Version 17.1.0 Build 590 10/25/2017 SJ Lite Edition 21 | # Date created = 23:04:34 мая 12, 2020 22 | # 23 | # -------------------------------------------------------------------------- # 24 | # 25 | # Notes: 26 | # 27 | # 1) The default values for assignments are stored in the file: 28 | # mux_top_assignment_defaults.qdf 29 | # If this file doesn't exist, see file: 30 | # assignment_defaults.qdf 31 | # 32 | # 2) Altera recommends that you do not modify this file. This 33 | # file is updated automatically by the Quartus Prime software 34 | # and any changes you make may be lost or overwritten. 35 | # 36 | # -------------------------------------------------------------------------- # 37 | 38 | 39 | set_global_assignment -name FAMILY "Cyclone IV E" 40 | set_global_assignment -name DEVICE EP4CE22F17C6 41 | set_global_assignment -name TOP_LEVEL_ENTITY demux_top 42 | set_global_assignment -name ORIGINAL_QUARTUS_VERSION 17.1.0 43 | set_global_assignment -name PROJECT_CREATION_TIME_DATE "23:04:34 мая 12, 2020" 44 | set_global_assignment -name LAST_QUARTUS_VERSION "19.1.0 Lite Edition" 45 | set_global_assignment -name SYSTEMVERILOG_FILE ../demux.sv 46 | set_global_assignment -name SYSTEMVERILOG_FILE demux_top.sv 47 | set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files 48 | set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 49 | set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 50 | set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1 51 | set_global_assignment -name NOMINAL_CORE_SUPPLY_VOLTAGE 1.2V 52 | set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top 53 | set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top 54 | set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top 55 | set_global_assignment -name SDC_FILE demux_top.sdc 56 | set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" 57 | set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" 58 | set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON 59 | set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL 60 | 61 | set_instance_assignment -name VIRTUAL_PIN ON -to sel_i 62 | set_instance_assignment -name VIRTUAL_PIN ON -to data_in_i 63 | set_instance_assignment -name VIRTUAL_PIN ON -to data_0_o 64 | set_instance_assignment -name VIRTUAL_PIN ON -to data_1_o 65 | 66 | set_location_assignment PIN_R8 -to clk_i 67 | 68 | 69 | set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top -------------------------------------------------------------------------------- /lecture_3/mux_demux/demux_example/demux_top.sdc: -------------------------------------------------------------------------------- 1 | set_time_format -unit ns -decimal_places 3 2 | 3 | create_clock -name {clk_100} -period 10.000 -waveform { 0.000 5.000 } [get_ports {clk_i}] 4 | 5 | derive_clock_uncertainty 6 | -------------------------------------------------------------------------------- /lecture_3/mux_demux/demux_example/demux_top.sv: -------------------------------------------------------------------------------- 1 | module demux_top( 2 | input logic clk_i, 3 | 4 | input logic sel_i, 5 | 6 | input logic [7:0] data_in_i, 7 | output logic [7:0] data_0_o, 8 | output logic [7:0] data_1_o 9 | ); 10 | 11 | logic [7:0] data_in; 12 | logic sel_in; 13 | logic [1:0][7:0] data_out; 14 | 15 | always_ff @( posedge clk_i ) 16 | begin 17 | data_in <= data_in_i; 18 | sel_in <= sel_i; 19 | end 20 | 21 | demux #( 22 | .OUT_CNT ( 2 ), 23 | .DATA_W ( 8 ) 24 | ) mux_ins ( 25 | .data_i ( data_in ), 26 | .sel_i ( sel_in ), 27 | .demuxed_out_o ( data_out ) 28 | ); 29 | 30 | always_ff @( posedge clk_i ) 31 | begin 32 | data_0_o <= data_out[0]; 33 | data_1_o <= data_out[1]; 34 | end 35 | 36 | endmodule 37 | -------------------------------------------------------------------------------- /lecture_3/mux_demux/mux.sv: -------------------------------------------------------------------------------- 1 | module mux #( 2 | parameter IN_CNT = 2, 3 | parameter DATA_W = 7 4 | )( 5 | input logic [IN_CNT-1:0][DATA_W-1:0] data_i, 6 | input logic [$clog2(IN_CNT)-1:0] sel_i, 7 | output logic [DATA_W-1:0] muxed_out_o 8 | ); 9 | 10 | assign muxed_out_o = data_i[ sel_i ]; 11 | 12 | endmodule 13 | -------------------------------------------------------------------------------- /lecture_3/mux_demux/mux_example/mux_top.qpf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 2017 Intel Corporation. All rights reserved. 4 | # Your use of Intel Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Intel Program License 10 | # Subscription Agreement, the Intel Quartus Prime License Agreement, 11 | # the Intel FPGA IP License Agreement, or other applicable license 12 | # agreement, including, without limitation, that your use is for 13 | # the sole purpose of programming logic devices manufactured by 14 | # Intel and sold by Intel or its authorized distributors. Please 15 | # refer to the applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus Prime 20 | # Version 17.1.0 Build 590 10/25/2017 SJ Lite Edition 21 | # Date created = 23:04:34 мая 12, 2020 22 | # 23 | # -------------------------------------------------------------------------- # 24 | 25 | QUARTUS_VERSION = "17.1" 26 | DATE = "23:04:34 мая 12, 2020" 27 | 28 | # Revisions 29 | 30 | PROJECT_REVISION = "mux_top" 31 | -------------------------------------------------------------------------------- /lecture_3/mux_demux/mux_example/mux_top.qsf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 2017 Intel Corporation. All rights reserved. 4 | # Your use of Intel Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Intel Program License 10 | # Subscription Agreement, the Intel Quartus Prime License Agreement, 11 | # the Intel FPGA IP License Agreement, or other applicable license 12 | # agreement, including, without limitation, that your use is for 13 | # the sole purpose of programming logic devices manufactured by 14 | # Intel and sold by Intel or its authorized distributors. Please 15 | # refer to the applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus Prime 20 | # Version 17.1.0 Build 590 10/25/2017 SJ Lite Edition 21 | # Date created = 23:04:34 мая 12, 2020 22 | # 23 | # -------------------------------------------------------------------------- # 24 | # 25 | # Notes: 26 | # 27 | # 1) The default values for assignments are stored in the file: 28 | # mux_top_assignment_defaults.qdf 29 | # If this file doesn't exist, see file: 30 | # assignment_defaults.qdf 31 | # 32 | # 2) Altera recommends that you do not modify this file. This 33 | # file is updated automatically by the Quartus Prime software 34 | # and any changes you make may be lost or overwritten. 35 | # 36 | # -------------------------------------------------------------------------- # 37 | 38 | 39 | set_global_assignment -name FAMILY "Cyclone IV E" 40 | set_global_assignment -name DEVICE EP4CE22F17C6 41 | set_global_assignment -name TOP_LEVEL_ENTITY mux_top 42 | set_global_assignment -name ORIGINAL_QUARTUS_VERSION 17.1.0 43 | set_global_assignment -name PROJECT_CREATION_TIME_DATE "23:04:34 мая 12, 2020" 44 | set_global_assignment -name LAST_QUARTUS_VERSION "17.1.0 Lite Edition" 45 | set_global_assignment -name SYSTEMVERILOG_FILE ../mux.sv 46 | set_global_assignment -name SYSTEMVERILOG_FILE mux_top.sv 47 | set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files 48 | set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 49 | set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 50 | set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1 51 | set_global_assignment -name NOMINAL_CORE_SUPPLY_VOLTAGE 1.2V 52 | set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top 53 | set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top 54 | set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top 55 | set_global_assignment -name SDC_FILE mux_top.sdc 56 | set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" 57 | set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" 58 | set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON 59 | set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL 60 | 61 | set_instance_assignment -name VIRTUAL_PIN ON -to sel_i 62 | set_instance_assignment -name VIRTUAL_PIN ON -to data_0_i 63 | set_instance_assignment -name VIRTUAL_PIN ON -to data_1_i 64 | set_instance_assignment -name VIRTUAL_PIN ON -to data_out_o 65 | 66 | set_location_assignment PIN_R8 -to clk_i 67 | 68 | 69 | 70 | set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top -------------------------------------------------------------------------------- /lecture_3/mux_demux/mux_example/mux_top.sdc: -------------------------------------------------------------------------------- 1 | set_time_format -unit ns -decimal_places 3 2 | 3 | create_clock -name {clk_100} -period 10.000 -waveform { 0.000 5.000 } [get_ports {clk_i}] 4 | 5 | derive_clock_uncertainty 6 | -------------------------------------------------------------------------------- /lecture_3/mux_demux/mux_example/mux_top.sv: -------------------------------------------------------------------------------- 1 | module mux_top( 2 | input logic clk_i, 3 | 4 | input logic sel_i, 5 | 6 | input logic [7:0] data_0_i, 7 | input logic [7:0] data_1_i, 8 | output logic [7:0] data_out_o 9 | ); 10 | 11 | logic [1:0][7:0] data_in; 12 | logic sel_in; 13 | logic [7:0] data_out; 14 | 15 | always_ff @( posedge clk_i ) 16 | begin 17 | data_in[0] <= data_0_i; 18 | data_in[1] <= data_1_i; 19 | end 20 | 21 | always_ff @( posedge clk_i ) 22 | sel_in <= sel_i; 23 | 24 | mux #( 25 | .IN_CNT ( 2 ), 26 | .DATA_W ( 8 ) 27 | ) mux_ins ( 28 | .data_i ( data_in ), 29 | .sel_i ( sel_in ), 30 | .muxed_out_o ( data_out ) 31 | ); 32 | 33 | always_ff @( posedge clk_i ) 34 | data_out_o <= data_out; 35 | 36 | endmodule 37 | -------------------------------------------------------------------------------- /lecture_3/posedge_detector/posedge_detector.sv: -------------------------------------------------------------------------------- 1 | module posedge_detector ( 2 | input clk_i, 3 | input d_i, 4 | output posedge_stb_o 5 | ); 6 | 7 | logic d_delay; 8 | 9 | always_ff @( posedge clk_i ) 10 | d_delay <= d_i; 11 | 12 | assign posedge_stb_o = d_i && !d_delay; 13 | 14 | endmodule 15 | -------------------------------------------------------------------------------- /lecture_3/posedge_detector/posedge_detector_example/posedge_detector_top.qpf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 2017 Intel Corporation. All rights reserved. 4 | # Your use of Intel Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Intel Program License 10 | # Subscription Agreement, the Intel Quartus Prime License Agreement, 11 | # the Intel FPGA IP License Agreement, or other applicable license 12 | # agreement, including, without limitation, that your use is for 13 | # the sole purpose of programming logic devices manufactured by 14 | # Intel and sold by Intel or its authorized distributors. Please 15 | # refer to the applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus Prime 20 | # Version 17.1.0 Build 590 10/25/2017 SJ Lite Edition 21 | # Date created = 23:04:34 мая 12, 2020 22 | # 23 | # -------------------------------------------------------------------------- # 24 | 25 | QUARTUS_VERSION = "17.1" 26 | DATE = "23:04:34 мая 12, 2020" 27 | 28 | # Revisions 29 | 30 | PROJECT_REVISION = "posedge_detector_top" 31 | -------------------------------------------------------------------------------- /lecture_3/posedge_detector/posedge_detector_example/posedge_detector_top.qsf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 2017 Intel Corporation. All rights reserved. 4 | # Your use of Intel Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Intel Program License 10 | # Subscription Agreement, the Intel Quartus Prime License Agreement, 11 | # the Intel FPGA IP License Agreement, or other applicable license 12 | # agreement, including, without limitation, that your use is for 13 | # the sole purpose of programming logic devices manufactured by 14 | # Intel and sold by Intel or its authorized distributors. Please 15 | # refer to the applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus Prime 20 | # Version 17.1.0 Build 590 10/25/2017 SJ Lite Edition 21 | # Date created = 23:04:34 мая 12, 2020 22 | # 23 | # -------------------------------------------------------------------------- # 24 | # 25 | # Notes: 26 | # 27 | # 1) The default values for assignments are stored in the file: 28 | # mux_top_assignment_defaults.qdf 29 | # If this file doesn't exist, see file: 30 | # assignment_defaults.qdf 31 | # 32 | # 2) Altera recommends that you do not modify this file. This 33 | # file is updated automatically by the Quartus Prime software 34 | # and any changes you make may be lost or overwritten. 35 | # 36 | # -------------------------------------------------------------------------- # 37 | 38 | 39 | set_global_assignment -name FAMILY "Cyclone IV E" 40 | set_global_assignment -name DEVICE EP4CE22F17C6 41 | set_global_assignment -name TOP_LEVEL_ENTITY posedge_detector_top 42 | set_global_assignment -name ORIGINAL_QUARTUS_VERSION 17.1.0 43 | set_global_assignment -name PROJECT_CREATION_TIME_DATE "23:04:34 мая 12, 2020" 44 | set_global_assignment -name LAST_QUARTUS_VERSION "17.1.0 Lite Edition" 45 | set_global_assignment -name SYSTEMVERILOG_FILE ../posedge_detector.sv 46 | set_global_assignment -name SYSTEMVERILOG_FILE posedge_detector_top.sv 47 | set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files 48 | set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 49 | set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 50 | set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1 51 | set_global_assignment -name NOMINAL_CORE_SUPPLY_VOLTAGE 1.2V 52 | set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top 53 | set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top 54 | set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top 55 | set_global_assignment -name SDC_FILE posedge_detector_top.sdc 56 | set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" 57 | set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" 58 | set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON 59 | set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL 60 | 61 | set_instance_assignment -name VIRTUAL_PIN ON -to d_i 62 | set_instance_assignment -name VIRTUAL_PIN ON -to d_o 63 | 64 | set_location_assignment PIN_R8 -to clk_i 65 | 66 | 67 | set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top -------------------------------------------------------------------------------- /lecture_3/posedge_detector/posedge_detector_example/posedge_detector_top.sdc: -------------------------------------------------------------------------------- 1 | set_time_format -unit ns -decimal_places 3 2 | 3 | create_clock -name {clk_100} -period 10.000 -waveform { 0.000 5.000 } [get_ports {clk_i}] 4 | 5 | derive_clock_uncertainty 6 | -------------------------------------------------------------------------------- /lecture_3/posedge_detector/posedge_detector_example/posedge_detector_top.sv: -------------------------------------------------------------------------------- 1 | module posedge_detector_top( 2 | input logic clk_i, 3 | 4 | input logic d_i, 5 | output logic d_o 6 | ); 7 | 8 | logic data_in; 9 | logic data_out; 10 | 11 | always_ff @( posedge clk_i ) 12 | data_in <= d_i; 13 | 14 | posedge_detector pd_ins ( 15 | .clk_i ( clk_i ), 16 | .d_i ( data_in ), 17 | .posedge_stb_o ( data_out ) 18 | ); 19 | 20 | always_ff @( posedge clk_i ) 21 | d_o <= data_out; 22 | 23 | endmodule 24 | -------------------------------------------------------------------------------- /project/README.md: -------------------------------------------------------------------------------- 1 | # Demo-проект игры N-back на отладочной плате DE0-Nano 2 | 3 | ## Правила игры 4 | 5 | Нужно нажать KEY0 в тот момент, когда состояние светодиодов соответствуют тем, 6 | что были 3 символа назад. 7 | 8 | Игра начинается с того, что все светодиоды не горят 4 секунды. 9 | После этого 4 секунды показывается символ №0. 10 | Потом все светодиоды гаснут и через 4 секунды загорается символ №1 и так далее. 11 | 12 | Игра завершается, когда показывается символ, который был показан 3 символа 13 | назад. 14 | 15 | Если во время показа этого символа нажать KEY0 -- это считается победой и 16 | светодиоды будут последовательно загораться друг за другом. 17 | Если не нажать ничего (или нажать KEY0 во время показа другого символа), 18 | то это считается поражением и светодиоды будут мигать и гаснуть все одновременно. 19 | 20 | Перед началом игры нужно нажать KEY1 чтобы сбросить счетчик генератора ПСП. 21 | 22 | ## Схема проекта 23 | 24 | ![](img/nback.png) 25 | 26 | ## Особенности: 27 | 28 | * Для генерации случайных чисел используется LFSR x^9 + x^4 + 1. Но чтобы игра 29 | была интереснее -- после показа первых 4 символов игры с вероятностью 25% новый 30 | символ будет повторять тот, который был 3 символа назад (то есть игра 31 | завершится). 32 | * Перед стартом игры её обязательно нужно сбросить клавишей KEY1. 33 | * N можно поменять, изменив параметр N модуля nback_logic. 34 | -------------------------------------------------------------------------------- /project/img/lfsr_9bit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcmtk/fpga-webinar-2020/bfbbfe2e8874b52a0cf192fc6725038a6f43f3d2/project/img/lfsr_9bit.png -------------------------------------------------------------------------------- /project/img/nback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcmtk/fpga-webinar-2020/bfbbfe2e8874b52a0cf192fc6725038a6f43f3d2/project/img/nback.png -------------------------------------------------------------------------------- /project/img/nback_logic_fsm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcmtk/fpga-webinar-2020/bfbbfe2e8874b52a0cf192fc6725038a6f43f3d2/project/img/nback_logic_fsm.png -------------------------------------------------------------------------------- /project/quartus_prj/nback_top.qpf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 2017 Intel Corporation. All rights reserved. 4 | # Your use of Intel Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Intel Program License 10 | # Subscription Agreement, the Intel Quartus Prime License Agreement, 11 | # the Intel FPGA IP License Agreement, or other applicable license 12 | # agreement, including, without limitation, that your use is for 13 | # the sole purpose of programming logic devices manufactured by 14 | # Intel and sold by Intel or its authorized distributors. Please 15 | # refer to the applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus Prime 20 | # Version 17.1.0 Build 590 10/25/2017 SJ Lite Edition 21 | # Date created = 23:04:34 мая 12, 2020 22 | # 23 | # -------------------------------------------------------------------------- # 24 | 25 | QUARTUS_VERSION = "17.1" 26 | DATE = "23:04:34 мая 12, 2020" 27 | 28 | # Revisions 29 | 30 | PROJECT_REVISION = "nback_top" 31 | -------------------------------------------------------------------------------- /project/quartus_prj/nback_top.qsf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 2017 Intel Corporation. All rights reserved. 4 | # Your use of Intel Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Intel Program License 10 | # Subscription Agreement, the Intel Quartus Prime License Agreement, 11 | # the Intel FPGA IP License Agreement, or other applicable license 12 | # agreement, including, without limitation, that your use is for 13 | # the sole purpose of programming logic devices manufactured by 14 | # Intel and sold by Intel or its authorized distributors. Please 15 | # refer to the applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus Prime 20 | # Version 17.1.0 Build 590 10/25/2017 SJ Lite Edition 21 | # Date created = 23:04:34 мая 12, 2020 22 | # 23 | # -------------------------------------------------------------------------- # 24 | # 25 | # Notes: 26 | # 27 | # 1) The default values for assignments are stored in the file: 28 | # mux_top_assignment_defaults.qdf 29 | # If this file doesn't exist, see file: 30 | # assignment_defaults.qdf 31 | # 32 | # 2) Altera recommends that you do not modify this file. This 33 | # file is updated automatically by the Quartus Prime software 34 | # and any changes you make may be lost or overwritten. 35 | # 36 | # -------------------------------------------------------------------------- # 37 | 38 | 39 | set_global_assignment -name FAMILY "Cyclone IV E" 40 | set_global_assignment -name DEVICE EP4CE22F17C6 41 | set_global_assignment -name TOP_LEVEL_ENTITY nback_top 42 | set_global_assignment -name ORIGINAL_QUARTUS_VERSION 17.1.0 43 | set_global_assignment -name PROJECT_CREATION_TIME_DATE "23:04:34 мая 12, 2020" 44 | set_global_assignment -name LAST_QUARTUS_VERSION "19.1.0 Lite Edition" 45 | 46 | set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/debouncer.sv 47 | set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/led_driver.sv 48 | set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/lfsr_9bit.sv 49 | set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/nback_logic.sv 50 | set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/posedge_detector.sv 51 | 52 | set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/nback_top.sv 53 | set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files 54 | set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 55 | set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 56 | set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1 57 | set_global_assignment -name NOMINAL_CORE_SUPPLY_VOLTAGE 1.2V 58 | set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top 59 | set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top 60 | set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top 61 | set_global_assignment -name SDC_FILE nback_top.sdc 62 | set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" 63 | set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" 64 | set_global_assignment -name TIMING_ANALYZER_MULTICORNER_ANALYSIS ON 65 | set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL 66 | 67 | set_location_assignment PIN_R8 -to clk_50_mhz_i 68 | set_location_assignment PIN_J15 -to key_0_i 69 | set_location_assignment PIN_E1 -to key_1_i 70 | 71 | set_location_assignment PIN_A15 -to leds_o[0] 72 | set_location_assignment PIN_A13 -to leds_o[1] 73 | set_location_assignment PIN_B13 -to leds_o[2] 74 | set_location_assignment PIN_A11 -to leds_o[3] 75 | set_location_assignment PIN_D1 -to leds_o[4] 76 | set_location_assignment PIN_F3 -to leds_o[5] 77 | set_location_assignment PIN_B1 -to leds_o[6] 78 | set_location_assignment PIN_L3 -to leds_o[7] 79 | 80 | set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top 81 | -------------------------------------------------------------------------------- /project/quartus_prj/nback_top.sdc: -------------------------------------------------------------------------------- 1 | set_time_format -unit ns -decimal_places 3 2 | 3 | create_clock -name {clk_50} -period 20.000 -waveform { 0.000 10.000 } [get_ports {clk_50_mhz_i}] 4 | 5 | derive_clock_uncertainty 6 | -------------------------------------------------------------------------------- /project/rtl/debouncer.sv: -------------------------------------------------------------------------------- 1 | module debouncer #( 2 | // Счетчик, который будет считать время, которое сигнал вел себя стабильно 3 | // Если это время достигнет 2**DB_CNT_W - 1 -- им можно пользоваться. 4 | parameter DB_CNT_W = 20 5 | )( 6 | input logic clk_i, 7 | input logic s_rst_i, 8 | 9 | input logic pin_i, 10 | output logic pin_state_o 11 | ); 12 | 13 | // pin_i асинхронный сигнал. Нужно его пересинхронизировать: 14 | 15 | logic [2:0] pin_d; 16 | 17 | always_ff @( posedge clk_i ) 18 | begin 19 | pin_d[0] <= pin_i; 20 | pin_d[1] <= pin_d[0]; 21 | pin_d[2] <= pin_d[1]; 22 | end 23 | 24 | logic [DB_CNT_W-1:0] db_counter; 25 | logic pin_differ; 26 | 27 | logic db_counter_max; 28 | 29 | // 1 только когда счетчик станет '1111...11 30 | assign db_counter_max = ( &db_counter ); 31 | 32 | // 0 -- когда пин не меняется за 2 такта 33 | // 1 -- пин на двух тактах имеет разное значение 34 | assign pin_differ = pin_d[2] ^ pin_d[1]; 35 | 36 | always_ff @( posedge clk_i ) 37 | if( s_rst_i ) 38 | db_counter <= '0; 39 | else 40 | begin 41 | if( db_counter_max || pin_differ ) 42 | db_counter <= '0; 43 | else 44 | db_counter <= db_counter + (DB_CNT_W)'(1); 45 | end 46 | 47 | always_ff @( posedge clk_i ) 48 | if( s_rst_i ) 49 | pin_state_o <= 1'b0; 50 | else 51 | if( db_counter_max ) 52 | pin_state_o <= pin_d[2]; 53 | 54 | endmodule 55 | -------------------------------------------------------------------------------- /project/rtl/led_driver.sv: -------------------------------------------------------------------------------- 1 | module led_driver #( 2 | parameter SYMBOL_W = 8, 3 | parameter LEDS_CNT = 8 4 | )( 5 | input logic clk_i, 6 | input logic s_rst_i, 7 | 8 | input logic [SYMBOL_W-1:0] current_symbol_i, 9 | input logic user_in_game_i, 10 | 11 | // 1 -- user win, 0 -- user lost. 12 | // valid only when user_in_game_o is 0. 13 | input logic user_win_nlost_i, 14 | output logic [LEDS_CNT-1:0] leds_o 15 | ); 16 | 17 | localparam WIN_LOOSE_PAUSE = 6250000; 18 | localparam WIN_LOOSE_PAUSE_W = $clog2(WIN_LOOSE_PAUSE); 19 | 20 | logic [LEDS_CNT-1:0] leds; 21 | logic [WIN_LOOSE_PAUSE_W-1:0] win_cnt_period; 22 | logic [WIN_LOOSE_PAUSE_W-1:0] loose_cnt_period; 23 | 24 | logic [LEDS_CNT-1:0] win_cnt; 25 | logic [LEDS_CNT-1:0] loose_cnt; 26 | 27 | 28 | always_ff @( posedge clk_i ) 29 | begin 30 | if( s_rst_i ) 31 | begin 32 | win_cnt_period <= '0; 33 | loose_cnt_period <= '0; 34 | end 35 | else 36 | if( win_cnt_period == ( WIN_LOOSE_PAUSE - 1 ) ) 37 | begin 38 | win_cnt_period <= '0; 39 | loose_cnt_period <= '0; 40 | end 41 | else 42 | begin 43 | win_cnt_period <= win_cnt_period + (WIN_LOOSE_PAUSE_W)'(1); 44 | loose_cnt_period <= loose_cnt_period + (WIN_LOOSE_PAUSE_W)'(1); 45 | end 46 | end 47 | 48 | always_ff @( posedge clk_i ) 49 | begin 50 | if( s_rst_i ) 51 | win_cnt <= (LEDS_CNT)'(1); 52 | if( win_cnt_period == ( WIN_LOOSE_PAUSE - 1 ) ) 53 | begin 54 | if( win_cnt[LEDS_CNT-1] ) 55 | begin 56 | win_cnt[0] <= 1'b1; 57 | win_cnt[LEDS_CNT-1:1] <= '0; 58 | end 59 | else 60 | begin 61 | win_cnt[0] <= 1'b0; 62 | win_cnt[LEDS_CNT-1:1] <= win_cnt[LEDS_CNT-2:0]; 63 | end 64 | end 65 | end 66 | 67 | always_ff @( posedge clk_i ) 68 | begin 69 | if( s_rst_i ) 70 | loose_cnt <= '1; 71 | if( win_cnt_period == ( WIN_LOOSE_PAUSE - 1 ) ) 72 | begin 73 | // Inverse all bits: 74 | loose_cnt <= ~loose_cnt; 75 | end 76 | end 77 | 78 | always_comb 79 | case( { user_in_game_i, user_win_nlost_i } ) 80 | 2'b11, 81 | 2'b10: 82 | begin 83 | leds = current_symbol_i; 84 | end 85 | 86 | 2'b01: 87 | begin 88 | leds = win_cnt; 89 | end 90 | 91 | 2'b00: 92 | begin 93 | leds = loose_cnt; 94 | end 95 | 96 | default: 97 | 98 | begin 99 | leds = '0; 100 | end 101 | endcase 102 | 103 | // Register leds to remove glitches: 104 | always_ff @( posedge clk_i ) 105 | if( s_rst_i ) 106 | leds_o <= '0; 107 | else 108 | leds_o <= leds; 109 | 110 | endmodule 111 | 112 | -------------------------------------------------------------------------------- /project/rtl/lfsr_9bit.sv: -------------------------------------------------------------------------------- 1 | module lfsr_9bit( 2 | input logic clk_i, 3 | input logic s_rst_i, 4 | 5 | input logic ack_i, 6 | 7 | output logic prbs_o 8 | ); 9 | 10 | // Полином: x^9 + x^5 + 1 11 | parameter WIDTH = 9; 12 | parameter TAP1 = WIDTH-1; 13 | parameter TAP2 = 4; 14 | 15 | logic [WIDTH-1:0] prbs_state; 16 | 17 | always_ff @( posedge clk_i ) 18 | if( s_rst_i ) 19 | prbs_state <= (WIDTH)'(1); 20 | else 21 | begin 22 | if( ack_i ) 23 | begin 24 | prbs_state[0] <= prbs_state[TAP1] ^ prbs_state[TAP2]; 25 | prbs_state[WIDTH-1:1] <= prbs_state[WIDTH-2:0]; 26 | end 27 | end 28 | 29 | assign prbs_o = prbs_state[0]; 30 | 31 | endmodule 32 | -------------------------------------------------------------------------------- /project/rtl/nback_logic.sv: -------------------------------------------------------------------------------- 1 | module nback_logic #( 2 | parameter N = 3, 3 | parameter SYMBOL_W = 7, 4 | parameter SYMBOL_DURATION_HW_TICKS = 3000, 5 | parameter PAUSE_DURATINON_HW_TICKS = 500 6 | )( 7 | input logic clk_i, 8 | input logic s_rst_i, 9 | 10 | input logic answer_stb_i, 11 | 12 | input logic prbs_i, 13 | output logic prbs_ack_o, 14 | 15 | output logic [SYMBOL_W-1:0] current_symbol_o, 16 | output logic user_in_game_o, 17 | 18 | // 1 -- user win, 0 -- user lost. 19 | // Valid only when user_in_game_o is 0. 20 | output logic user_win_nlost_o 21 | ); 22 | 23 | //// Local parameters calculation: //// 24 | localparam PAUSE_CNT_W = $clog2(PAUSE_DURATINON_HW_TICKS); 25 | localparam SYMBOL_CNT_W = $clog2( SYMBOL_W ); 26 | localparam SYMBOL_DUR_W = $clog2(SYMBOL_DURATION_HW_TICKS); 27 | 28 | //// Signals and registers: //// 29 | logic [PAUSE_CNT_W-1:0] pause_cnt; 30 | logic pause_done; 31 | 32 | logic [SYMBOL_W-1:0] collected_symbol; 33 | 34 | logic [SYMBOL_CNT_W-1:0] symbol_cnt; 35 | logic symbol_collected; 36 | 37 | logic [SYMBOL_W-1:0] next_symbol; 38 | 39 | logic [N:0][SYMBOL_W-1:0] symbols_queue; 40 | logic [$clog2(N):0] symbols_queue_size; 41 | 42 | logic [SYMBOL_DUR_W-1:0] symbol_pause_cnt; 43 | logic symbol_pause_done; 44 | 45 | //// Main game FSM: //// 46 | enum logic [2:0] { 47 | IDLE_S, 48 | PAUSE_S, 49 | COLLECT_PRBS_S, 50 | REPLACE_SYMBOL_S, 51 | SHIFT_SYMBOL_QUEUE_S, 52 | SHOW_SYNBOL_S, 53 | WIN_S, 54 | LOOSE_S 55 | } state, next_state; 56 | 57 | always_ff @( posedge clk_i ) 58 | if( s_rst_i ) 59 | state <= IDLE_S; 60 | else 61 | state <= next_state; 62 | 63 | always_comb 64 | begin 65 | next_state = state; 66 | case( state ) 67 | IDLE_S: 68 | begin 69 | if( answer_stb_i ) 70 | next_state = PAUSE_S; 71 | end 72 | PAUSE_S: 73 | begin 74 | if( pause_done ) 75 | next_state = COLLECT_PRBS_S; 76 | end 77 | 78 | COLLECT_PRBS_S: 79 | begin 80 | if( symbol_collected ) 81 | next_state = REPLACE_SYMBOL_S; 82 | end 83 | 84 | REPLACE_SYMBOL_S: 85 | begin 86 | next_state = SHIFT_SYMBOL_QUEUE_S; 87 | end 88 | 89 | SHIFT_SYMBOL_QUEUE_S: 90 | begin 91 | next_state = SHOW_SYNBOL_S; 92 | end 93 | 94 | SHOW_SYNBOL_S: 95 | begin 96 | if( answer_stb_i ) 97 | begin 98 | if( ( symbols_queue[0] == symbols_queue[N] ) && 99 | ( symbols_queue_size == N ) ) 100 | next_state = WIN_S; 101 | else 102 | next_state = LOOSE_S; 103 | end 104 | if( symbol_pause_done ) 105 | begin 106 | if( ( symbols_queue[0] == symbols_queue[N] ) && 107 | ( symbols_queue_size == N ) ) 108 | next_state = LOOSE_S; 109 | else 110 | next_state = PAUSE_S; 111 | end 112 | end 113 | 114 | WIN_S, 115 | LOOSE_S: 116 | begin 117 | if( symbol_pause_done ) 118 | next_state = IDLE_S; 119 | end 120 | 121 | default: 122 | begin 123 | next_state = IDLE_S; 124 | end 125 | endcase 126 | end 127 | 128 | // Counter for counting how log pause shuld be: 129 | always_ff @( posedge clk_i ) 130 | if( state == PAUSE_S ) 131 | pause_cnt <= pause_cnt + (PAUSE_CNT_W)'(1); 132 | else 133 | pause_cnt <= '0; 134 | 135 | assign pause_done = ( pause_cnt == ( PAUSE_DURATINON_HW_TICKS - 1 ) ); 136 | 137 | // PRBS collection process: 138 | always_ff @( posedge clk_i ) 139 | if( state == COLLECT_PRBS_S ) 140 | begin 141 | collected_symbol[0] <= prbs_i; 142 | collected_symbol[SYMBOL_W-1:1] <= collected_symbol[SYMBOL_W-2:0]; 143 | end 144 | 145 | assign prbs_ack_o = (state == COLLECT_PRBS_S); 146 | 147 | always_ff @( posedge clk_i ) 148 | if( state == COLLECT_PRBS_S ) 149 | symbol_cnt <= symbol_cnt + (SYMBOL_CNT_W)'(1); 150 | else 151 | symbol_cnt <= '0; 152 | 153 | assign symbol_collected = ( symbol_cnt == ( SYMBOL_W - 1 ) ); 154 | 155 | // Replace PRBS symbol for win one, if there is enought symbols and the last 2 156 | // bits of new symbol is 00 (this will make it 25% chance). 157 | 158 | always_ff @( posedge clk_i ) 159 | if( state == REPLACE_SYMBOL_S ) 160 | begin 161 | if( ( symbols_queue_size == N ) && ( collected_symbol[1:0] == 2'b00 ) ) 162 | next_symbol <= symbols_queue[N-1]; 163 | else 164 | next_symbol <= collected_symbol; 165 | end 166 | 167 | // Saving symbols to queue: 168 | always_ff @( posedge clk_i ) 169 | if( s_rst_i ) 170 | symbols_queue_size <= '0; 171 | else 172 | if( state == IDLE_S ) 173 | symbols_queue_size <= '0; 174 | else 175 | if( state == SHIFT_SYMBOL_QUEUE_S ) 176 | if( symbols_queue_size != N ) 177 | symbols_queue_size <= symbols_queue_size + ($clog2(N))'(1); 178 | 179 | always_ff @( posedge clk_i ) 180 | if( state == SHIFT_SYMBOL_QUEUE_S ) 181 | begin 182 | symbols_queue[0] <= next_symbol; 183 | symbols_queue[N:1] <= symbols_queue[N-1:0]; 184 | end 185 | 186 | // Counting pause for symbol: 187 | always_ff @( posedge clk_i ) 188 | if( state != next_state ) 189 | symbol_pause_cnt <= '0; 190 | else 191 | begin 192 | if( ( state == SHOW_SYNBOL_S ) || 193 | ( state == WIN_S ) || 194 | ( state == LOOSE_S ) ) 195 | symbol_pause_cnt <= symbol_pause_cnt + (SYMBOL_DUR_W)'(1); 196 | end 197 | 198 | assign symbol_pause_done = ( symbol_pause_cnt == SYMBOL_DURATION_HW_TICKS - 1 ); 199 | 200 | // Output signals logic: 201 | always_comb 202 | begin 203 | current_symbol_o = '0; 204 | user_in_game_o = 1'b0; 205 | user_win_nlost_o = 1'b0; 206 | 207 | case( state ) 208 | IDLE_S: 209 | begin 210 | user_in_game_o = 1'b0; 211 | user_win_nlost_o = 1'b0; 212 | end 213 | PAUSE_S, 214 | COLLECT_PRBS_S, 215 | REPLACE_SYMBOL_S, 216 | SHIFT_SYMBOL_QUEUE_S: 217 | begin 218 | user_in_game_o = 1'b1; 219 | current_symbol_o = '0; 220 | end 221 | 222 | SHOW_SYNBOL_S: 223 | begin 224 | user_in_game_o = 1'b1; 225 | current_symbol_o = symbols_queue[0]; 226 | end 227 | 228 | WIN_S: 229 | begin 230 | user_in_game_o = 1'b0; 231 | user_win_nlost_o = 1'b1; 232 | end 233 | 234 | LOOSE_S: 235 | begin 236 | user_in_game_o = 1'b0; 237 | user_win_nlost_o = 1'b0; 238 | end 239 | 240 | default: 241 | begin 242 | current_symbol_o = '0; 243 | user_in_game_o = 1'b0; 244 | user_win_nlost_o = 1'b0; 245 | end 246 | endcase 247 | end 248 | endmodule 249 | -------------------------------------------------------------------------------- /project/rtl/nback_top.sv: -------------------------------------------------------------------------------- 1 | module nback_top ( 2 | input logic clk_50_mhz_i, 3 | input logic key_0_i, 4 | input logic key_1_i, 5 | output logic [7:0] leds_o 6 | ); 7 | 8 | logic [1:0] pin_1_d; 9 | logic s_rst; 10 | logic user_answer; 11 | logic user_answer_stb; 12 | 13 | logic key_0_inv; 14 | logic key_1_inv; 15 | 16 | assign key_0_inv = !key_0_i; 17 | assign key_1_inv = !key_1_i; 18 | 19 | always_ff @( posedge clk_50_mhz_i ) 20 | begin 21 | pin_1_d[0] <= key_1_inv; 22 | pin_1_d[1] <= pin_1_d[0]; 23 | end 24 | 25 | assign s_rst = pin_1_d[1]; 26 | 27 | debouncer #( 28 | .DB_CNT_W ( 10 ) 29 | ) db_inst ( 30 | .clk_i ( clk_50_mhz_i ), 31 | .s_rst_i ( s_rst ), 32 | 33 | .pin_i ( key_0_inv ), 34 | .pin_state_o ( user_answer ) 35 | ); 36 | 37 | posedge_detector pd_inst( 38 | .clk_i ( clk_50_mhz_i ), 39 | .d_i ( user_answer ), 40 | .posedge_stb_o ( user_answer_stb ) 41 | ); 42 | 43 | logic prbs_ack; 44 | logic prbs; 45 | 46 | logic [7:0] current_symbol; 47 | logic user_in_game; 48 | logic user_win_nlost; 49 | 50 | nback_logic #( 51 | .N ( 3 ), 52 | .SYMBOL_W ( 8 ), 53 | .SYMBOL_DURATION_HW_TICKS ( 200000000 ), // 4 second: 4 / 20 ns 54 | .PAUSE_DURATINON_HW_TICKS ( 200000000 ) // 4 second 55 | ) nback_inst ( 56 | .clk_i ( clk_50_mhz_i ), 57 | .s_rst_i ( s_rst ), 58 | 59 | .answer_stb_i ( user_answer ), 60 | 61 | .prbs_i ( prbs ), 62 | .prbs_ack_o ( prbs_ack ), 63 | 64 | .current_symbol_o ( current_symbol ), 65 | .user_in_game_o ( user_in_game ), 66 | 67 | .user_win_nlost_o ( user_win_nlost ) 68 | ); 69 | 70 | lfsr_9bit prbs_inst( 71 | .clk_i ( clk_50_mhz_i ), 72 | .s_rst_i ( s_rst ), 73 | 74 | .ack_i ( prbs_ack ), 75 | .prbs_o ( prbs ) 76 | ); 77 | 78 | led_driver #( 79 | .SYMBOL_W ( 8 ), 80 | .LEDS_CNT ( 8 ) 81 | ) leds_inst ( 82 | .clk_i ( clk_50_mhz_i ), 83 | .s_rst_i ( s_rst ), 84 | 85 | .current_symbol_i ( current_symbol ), 86 | .user_in_game_i ( user_in_game ), 87 | 88 | .user_win_nlost_i ( user_win_nlost ), 89 | .leds_o ( leds_o ) 90 | ); 91 | 92 | 93 | endmodule 94 | -------------------------------------------------------------------------------- /project/rtl/posedge_detector.sv: -------------------------------------------------------------------------------- 1 | module posedge_detector ( 2 | input clk_i, 3 | input d_i, 4 | output posedge_stb_o 5 | ); 6 | 7 | logic d_delay; 8 | 9 | always_ff @( posedge clk_i ) 10 | d_delay <= d_i; 11 | 12 | assign posedge_stb_o = d_i && !d_delay; 13 | 14 | endmodule 15 | -------------------------------------------------------------------------------- /project/tb/nback_logic_tb/make.do: -------------------------------------------------------------------------------- 1 | vlib work 2 | 3 | vlog -sv ../../rtl/nback_logic.sv 4 | vlog -sv nback_logic_tb.sv 5 | 6 | vsim -novopt nback_logic_tb 7 | add log -r /* 8 | add wave -r * 9 | run -all 10 | 11 | -------------------------------------------------------------------------------- /project/tb/nback_logic_tb/nback_logic_tb.sv: -------------------------------------------------------------------------------- 1 | module nback_logic_tb; 2 | 3 | parameter N = 3; 4 | parameter SYMBOL_W = 7; 5 | parameter SYMBOL_DURATION_HW_TICKS = 3000; 6 | parameter PAUSE_DURATINON_HW_TICKS = 500; 7 | 8 | bit clk; 9 | bit rst; 10 | bit rst_done; 11 | 12 | logic answer_stb; 13 | logic prbs_ack; 14 | logic prbs; 15 | logic [SYMBOL_W-1:0] current_symbol; 16 | logic user_in_game; 17 | logic user_win_nlost; 18 | 19 | initial 20 | forever 21 | #5 clk = !clk; 22 | 23 | default clocking cb @ (posedge clk); 24 | endclocking 25 | 26 | initial 27 | begin 28 | rst <= 1'b0; 29 | ##1; 30 | rst <= 1'b1; 31 | ##1; 32 | rst <= 1'b0; 33 | rst_done = 1'b1; 34 | end 35 | 36 | nback_logic #( 37 | .N ( N ), 38 | .SYMBOL_W ( SYMBOL_W ), 39 | .SYMBOL_DURATION_HW_TICKS ( SYMBOL_DURATION_HW_TICKS ), 40 | .PAUSE_DURATINON_HW_TICKS ( PAUSE_DURATINON_HW_TICKS ) 41 | ) DUT ( 42 | .clk_i ( clk ), 43 | .s_rst_i ( rst ), 44 | 45 | .answer_stb_i ( answer_stb ), 46 | 47 | .prbs_i ( prbs ), 48 | .prbs_ack_o ( prbs_ack ), 49 | 50 | .current_symbol_o ( current_symbol ), 51 | .user_in_game_o ( user_in_game ), 52 | 53 | .user_win_nlost_o ( user_win_nlost ) 54 | ); 55 | 56 | initial 57 | begin 58 | prbs <= $urandom_range(1,0); 59 | forever 60 | begin 61 | ##1; 62 | if( prbs_ack ) 63 | prbs <= $urandom_range(1,0); 64 | end 65 | end 66 | 67 | initial 68 | begin 69 | answer_stb <= 1'b0; 70 | wait( rst_done ); 71 | ##100; 72 | answer_stb <= 1'b1; 73 | ##1; 74 | answer_stb <= 1'b0; 75 | end 76 | 77 | endmodule 78 | -------------------------------------------------------------------------------- /project/tb/prbs_tb/lsfr_9b_gen.py: -------------------------------------------------------------------------------- 1 | def lsfr(seed, polynom, count): 2 | result = list() 3 | 4 | data = seed 5 | poly = polynom 6 | 7 | for i in range( count - 1 ): 8 | lsb = data & 1 9 | data = data >> 1 10 | if lsb != 0: 11 | data = data ^ poly 12 | result.append( lsb ) 13 | return( result ) 14 | 15 | reference_results = lsfr( 1, 0b100010000, 1000 ) 16 | 17 | print( reference_results ) 18 | 19 | with open("ref_results.txt","w") as f: 20 | for l in reference_results: 21 | f.write( str(l) + "\n" ) 22 | 23 | # Полиномы: 24 | # 2 : 0b11, 25 | # 3 : 0b110, 26 | # 4 : 0b1100, 27 | # 5 : 0b10100, 28 | # 6 : 0b110000, 29 | # 7 : 0b1100000, 30 | # 8 : 0b10111000, 31 | # 9 : 0b100010000, 32 | # 10 : 0b1001000000, 33 | # 11 : 0b10100000000, 34 | # 12 : 0b111000001000, 35 | # 13 : 0b1110010000000, 36 | # 14 : 0b11100000000010, 37 | # 15 : 0b110000000000000, 38 | # 16 : 0b1011010000000000, 39 | # 17 : 0b10010000000000000, 40 | # 18 : 0b100000010000000000, 41 | # 19 : 0b1110010000000000000, 42 | -------------------------------------------------------------------------------- /project/tb/prbs_tb/make.do: -------------------------------------------------------------------------------- 1 | vlib work 2 | 3 | vlog -sv ../../rtl/lfsr_9bit.sv 4 | vlog -sv prbs_tb.sv 5 | 6 | vsim -novopt prbs_tb 7 | add log -r /* 8 | add wave -r * 9 | run -all 10 | 11 | -------------------------------------------------------------------------------- /project/tb/prbs_tb/prbs_tb.sv: -------------------------------------------------------------------------------- 1 | module prbs_tb; 2 | 3 | bit clk; 4 | bit rst; 5 | bit rst_done; 6 | 7 | logic ack; 8 | logic prbs; 9 | 10 | initial 11 | forever 12 | #5 clk = !clk; 13 | 14 | default clocking cb @ (posedge clk); 15 | endclocking 16 | 17 | initial 18 | begin 19 | rst <= 1'b0; 20 | ##1; 21 | rst <= 1'b1; 22 | ##1; 23 | rst <= 1'b0; 24 | rst_done = 1'b1; 25 | end 26 | 27 | lfsr_9bit prbs_inst( 28 | .clk_i ( clk ), 29 | .s_rst_i ( rst ), 30 | 31 | .ack_i ( ack ), 32 | 33 | .prbs_o ( prbs ) 34 | ); 35 | 36 | bit prbs_seq [$]; 37 | int ref_file_descr; 38 | bit ref_prbs; 39 | bit ref_prbs_seq [$]; 40 | 41 | initial 42 | begin 43 | ack <= 1'b0; 44 | wait( rst_done ); 45 | repeat(1000) 46 | begin 47 | prbs_seq.push_back( prbs ); 48 | ack <= 1'b1; 49 | ##1; 50 | ack <= 1'b0; 51 | ##1; 52 | end 53 | 54 | ref_file_descr = $fopen("ref_results.txt", "r"); 55 | 56 | if( !ref_file_descr ) 57 | begin 58 | $display("File ref_results.txt was NOT found!"); 59 | $stop(); 60 | end 61 | 62 | while( !$feof(ref_file_descr) ) 63 | begin 64 | $fscanf(ref_file_descr, "%b", ref_prbs ); 65 | ref_prbs_seq.push_back( ref_prbs ); 66 | end 67 | 68 | if( ref_prbs_seq != prbs_seq ) 69 | begin 70 | $error("Reference and DUR LSFR sequences do not match"); 71 | for( int i = 0; i < prbs_seq.size(); i++ ) 72 | if( ref_prbs_seq[i] != prbs_seq[i] ) 73 | $display("Error in bit #", i ); 74 | 75 | $display( "%d", ref_prbs_seq.size() ); 76 | $display( "%d", prbs_seq.size() ); 77 | end 78 | 79 | $stop(); 80 | end 81 | 82 | endmodule 83 | -------------------------------------------------------------------------------- /project/tb/prbs_tb/ref_results.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 0 3 | 0 4 | 0 5 | 0 6 | 1 7 | 0 8 | 0 9 | 0 10 | 1 11 | 1 12 | 0 13 | 0 14 | 0 15 | 0 16 | 1 17 | 0 18 | 0 19 | 1 20 | 1 21 | 1 22 | 0 23 | 0 24 | 1 25 | 0 26 | 1 27 | 0 28 | 1 29 | 0 30 | 1 31 | 1 32 | 0 33 | 0 34 | 0 35 | 0 36 | 1 37 | 1 38 | 0 39 | 1 40 | 1 41 | 1 42 | 1 43 | 0 44 | 1 45 | 0 46 | 0 47 | 1 48 | 1 49 | 0 50 | 1 51 | 1 52 | 1 53 | 0 54 | 0 55 | 1 56 | 0 57 | 0 58 | 0 59 | 1 60 | 0 61 | 1 62 | 0 63 | 0 64 | 0 65 | 0 66 | 1 67 | 0 68 | 1 69 | 0 70 | 1 71 | 1 72 | 0 73 | 1 74 | 0 75 | 0 76 | 1 77 | 1 78 | 1 79 | 1 80 | 1 81 | 1 82 | 0 83 | 1 84 | 1 85 | 0 86 | 0 87 | 1 88 | 0 89 | 0 90 | 1 91 | 0 92 | 0 93 | 1 94 | 0 95 | 1 96 | 1 97 | 0 98 | 1 99 | 1 100 | 1 101 | 1 102 | 1 103 | 1 104 | 0 105 | 0 106 | 1 107 | 0 108 | 0 109 | 1 110 | 1 111 | 0 112 | 1 113 | 0 114 | 1 115 | 0 116 | 0 117 | 1 118 | 1 119 | 0 120 | 0 121 | 1 122 | 1 123 | 0 124 | 0 125 | 0 126 | 0 127 | 0 128 | 0 129 | 0 130 | 1 131 | 1 132 | 0 133 | 0 134 | 0 135 | 1 136 | 1 137 | 0 138 | 0 139 | 1 140 | 0 141 | 1 142 | 0 143 | 0 144 | 0 145 | 1 146 | 1 147 | 0 148 | 1 149 | 0 150 | 0 151 | 1 152 | 0 153 | 1 154 | 1 155 | 1 156 | 1 157 | 1 158 | 1 159 | 1 160 | 0 161 | 1 162 | 0 163 | 0 164 | 0 165 | 1 166 | 0 167 | 1 168 | 1 169 | 0 170 | 0 171 | 0 172 | 1 173 | 1 174 | 1 175 | 0 176 | 1 177 | 0 178 | 1 179 | 1 180 | 0 181 | 0 182 | 1 183 | 0 184 | 1 185 | 1 186 | 0 187 | 0 188 | 1 189 | 1 190 | 1 191 | 1 192 | 0 193 | 0 194 | 0 195 | 1 196 | 1 197 | 1 198 | 1 199 | 1 200 | 0 201 | 1 202 | 1 203 | 1 204 | 0 205 | 1 206 | 0 207 | 0 208 | 0 209 | 0 210 | 0 211 | 1 212 | 1 213 | 0 214 | 1 215 | 0 216 | 1 217 | 1 218 | 0 219 | 1 220 | 1 221 | 0 222 | 1 223 | 1 224 | 1 225 | 0 226 | 1 227 | 1 228 | 0 229 | 0 230 | 0 231 | 0 232 | 0 233 | 1 234 | 0 235 | 1 236 | 1 237 | 0 238 | 1 239 | 0 240 | 1 241 | 1 242 | 1 243 | 1 244 | 1 245 | 0 246 | 1 247 | 0 248 | 1 249 | 0 250 | 1 251 | 0 252 | 1 253 | 0 254 | 0 255 | 0 256 | 0 257 | 0 258 | 0 259 | 1 260 | 0 261 | 1 262 | 0 263 | 0 264 | 1 265 | 0 266 | 1 267 | 0 268 | 1 269 | 1 270 | 1 271 | 1 272 | 0 273 | 0 274 | 1 275 | 0 276 | 1 277 | 1 278 | 1 279 | 0 280 | 1 281 | 1 282 | 1 283 | 0 284 | 0 285 | 0 286 | 0 287 | 0 288 | 0 289 | 1 290 | 1 291 | 1 292 | 0 293 | 0 294 | 1 295 | 1 296 | 1 297 | 0 298 | 1 299 | 0 300 | 0 301 | 1 302 | 0 303 | 0 304 | 1 305 | 1 306 | 1 307 | 1 308 | 0 309 | 1 310 | 0 311 | 1 312 | 1 313 | 1 314 | 0 315 | 1 316 | 0 317 | 1 318 | 0 319 | 0 320 | 0 321 | 1 322 | 0 323 | 0 324 | 1 325 | 0 326 | 0 327 | 0 328 | 0 329 | 1 330 | 1 331 | 0 332 | 0 333 | 1 334 | 1 335 | 1 336 | 0 337 | 0 338 | 0 339 | 0 340 | 1 341 | 0 342 | 1 343 | 1 344 | 1 345 | 1 346 | 0 347 | 1 348 | 1 349 | 0 350 | 1 351 | 1 352 | 0 353 | 0 354 | 1 355 | 1 356 | 0 357 | 1 358 | 0 359 | 0 360 | 0 361 | 0 362 | 1 363 | 1 364 | 1 365 | 0 366 | 1 367 | 1 368 | 1 369 | 1 370 | 0 371 | 0 372 | 0 373 | 0 374 | 1 375 | 1 376 | 1 377 | 1 378 | 1 379 | 1 380 | 1 381 | 1 382 | 1 383 | 0 384 | 0 385 | 0 386 | 0 387 | 0 388 | 1 389 | 1 390 | 1 391 | 1 392 | 0 393 | 1 394 | 1 395 | 1 396 | 1 397 | 1 398 | 0 399 | 0 400 | 0 401 | 1 402 | 0 403 | 1 404 | 1 405 | 1 406 | 0 407 | 0 408 | 1 409 | 1 410 | 0 411 | 0 412 | 1 413 | 0 414 | 0 415 | 0 416 | 0 417 | 0 418 | 1 419 | 0 420 | 0 421 | 1 422 | 0 423 | 1 424 | 0 425 | 0 426 | 1 427 | 1 428 | 1 429 | 0 430 | 1 431 | 1 432 | 0 433 | 1 434 | 0 435 | 0 436 | 0 437 | 1 438 | 1 439 | 1 440 | 1 441 | 0 442 | 0 443 | 1 444 | 1 445 | 1 446 | 1 447 | 1 448 | 0 449 | 0 450 | 1 451 | 1 452 | 0 453 | 1 454 | 1 455 | 0 456 | 0 457 | 0 458 | 1 459 | 0 460 | 1 461 | 0 462 | 1 463 | 0 464 | 0 465 | 1 466 | 0 467 | 0 468 | 0 469 | 1 470 | 1 471 | 1 472 | 0 473 | 0 474 | 0 475 | 1 476 | 1 477 | 0 478 | 1 479 | 1 480 | 0 481 | 1 482 | 0 483 | 1 484 | 0 485 | 1 486 | 1 487 | 1 488 | 0 489 | 0 490 | 0 491 | 1 492 | 0 493 | 0 494 | 1 495 | 1 496 | 0 497 | 0 498 | 0 499 | 1 500 | 0 501 | 0 502 | 0 503 | 1 504 | 0 505 | 0 506 | 0 507 | 0 508 | 0 509 | 0 510 | 0 511 | 0 512 | 1 513 | 0 514 | 0 515 | 0 516 | 0 517 | 1 518 | 0 519 | 0 520 | 0 521 | 1 522 | 1 523 | 0 524 | 0 525 | 0 526 | 0 527 | 1 528 | 0 529 | 0 530 | 1 531 | 1 532 | 1 533 | 0 534 | 0 535 | 1 536 | 0 537 | 1 538 | 0 539 | 1 540 | 0 541 | 1 542 | 1 543 | 0 544 | 0 545 | 0 546 | 0 547 | 1 548 | 1 549 | 0 550 | 1 551 | 1 552 | 1 553 | 1 554 | 0 555 | 1 556 | 0 557 | 0 558 | 1 559 | 1 560 | 0 561 | 1 562 | 1 563 | 1 564 | 0 565 | 0 566 | 1 567 | 0 568 | 0 569 | 0 570 | 1 571 | 0 572 | 1 573 | 0 574 | 0 575 | 0 576 | 0 577 | 1 578 | 0 579 | 1 580 | 0 581 | 1 582 | 1 583 | 0 584 | 1 585 | 0 586 | 0 587 | 1 588 | 1 589 | 1 590 | 1 591 | 1 592 | 1 593 | 0 594 | 1 595 | 1 596 | 0 597 | 0 598 | 1 599 | 0 600 | 0 601 | 1 602 | 0 603 | 0 604 | 1 605 | 0 606 | 1 607 | 1 608 | 0 609 | 1 610 | 1 611 | 1 612 | 1 613 | 1 614 | 1 615 | 0 616 | 0 617 | 1 618 | 0 619 | 0 620 | 1 621 | 1 622 | 0 623 | 1 624 | 0 625 | 1 626 | 0 627 | 0 628 | 1 629 | 1 630 | 0 631 | 0 632 | 1 633 | 1 634 | 0 635 | 0 636 | 0 637 | 0 638 | 0 639 | 0 640 | 0 641 | 1 642 | 1 643 | 0 644 | 0 645 | 0 646 | 1 647 | 1 648 | 0 649 | 0 650 | 1 651 | 0 652 | 1 653 | 0 654 | 0 655 | 0 656 | 1 657 | 1 658 | 0 659 | 1 660 | 0 661 | 0 662 | 1 663 | 0 664 | 1 665 | 1 666 | 1 667 | 1 668 | 1 669 | 1 670 | 1 671 | 0 672 | 1 673 | 0 674 | 0 675 | 0 676 | 1 677 | 0 678 | 1 679 | 1 680 | 0 681 | 0 682 | 0 683 | 1 684 | 1 685 | 1 686 | 0 687 | 1 688 | 0 689 | 1 690 | 1 691 | 0 692 | 0 693 | 1 694 | 0 695 | 1 696 | 1 697 | 0 698 | 0 699 | 1 700 | 1 701 | 1 702 | 1 703 | 0 704 | 0 705 | 0 706 | 1 707 | 1 708 | 1 709 | 1 710 | 1 711 | 0 712 | 1 713 | 1 714 | 1 715 | 0 716 | 1 717 | 0 718 | 0 719 | 0 720 | 0 721 | 0 722 | 1 723 | 1 724 | 0 725 | 1 726 | 0 727 | 1 728 | 1 729 | 0 730 | 1 731 | 1 732 | 0 733 | 1 734 | 1 735 | 1 736 | 0 737 | 1 738 | 1 739 | 0 740 | 0 741 | 0 742 | 0 743 | 0 744 | 1 745 | 0 746 | 1 747 | 1 748 | 0 749 | 1 750 | 0 751 | 1 752 | 1 753 | 1 754 | 1 755 | 1 756 | 0 757 | 1 758 | 0 759 | 1 760 | 0 761 | 1 762 | 0 763 | 1 764 | 0 765 | 0 766 | 0 767 | 0 768 | 0 769 | 0 770 | 1 771 | 0 772 | 1 773 | 0 774 | 0 775 | 1 776 | 0 777 | 1 778 | 0 779 | 1 780 | 1 781 | 1 782 | 1 783 | 0 784 | 0 785 | 1 786 | 0 787 | 1 788 | 1 789 | 1 790 | 0 791 | 1 792 | 1 793 | 1 794 | 0 795 | 0 796 | 0 797 | 0 798 | 0 799 | 0 800 | 1 801 | 1 802 | 1 803 | 0 804 | 0 805 | 1 806 | 1 807 | 1 808 | 0 809 | 1 810 | 0 811 | 0 812 | 1 813 | 0 814 | 0 815 | 1 816 | 1 817 | 1 818 | 1 819 | 0 820 | 1 821 | 0 822 | 1 823 | 1 824 | 1 825 | 0 826 | 1 827 | 0 828 | 1 829 | 0 830 | 0 831 | 0 832 | 1 833 | 0 834 | 0 835 | 1 836 | 0 837 | 0 838 | 0 839 | 0 840 | 1 841 | 1 842 | 0 843 | 0 844 | 1 845 | 1 846 | 1 847 | 0 848 | 0 849 | 0 850 | 0 851 | 1 852 | 0 853 | 1 854 | 1 855 | 1 856 | 1 857 | 0 858 | 1 859 | 1 860 | 0 861 | 1 862 | 1 863 | 0 864 | 0 865 | 1 866 | 1 867 | 0 868 | 1 869 | 0 870 | 0 871 | 0 872 | 0 873 | 1 874 | 1 875 | 1 876 | 0 877 | 1 878 | 1 879 | 1 880 | 1 881 | 0 882 | 0 883 | 0 884 | 0 885 | 1 886 | 1 887 | 1 888 | 1 889 | 1 890 | 1 891 | 1 892 | 1 893 | 1 894 | 0 895 | 0 896 | 0 897 | 0 898 | 0 899 | 1 900 | 1 901 | 1 902 | 1 903 | 0 904 | 1 905 | 1 906 | 1 907 | 1 908 | 1 909 | 0 910 | 0 911 | 0 912 | 1 913 | 0 914 | 1 915 | 1 916 | 1 917 | 0 918 | 0 919 | 1 920 | 1 921 | 0 922 | 0 923 | 1 924 | 0 925 | 0 926 | 0 927 | 0 928 | 0 929 | 1 930 | 0 931 | 0 932 | 1 933 | 0 934 | 1 935 | 0 936 | 0 937 | 1 938 | 1 939 | 1 940 | 0 941 | 1 942 | 1 943 | 0 944 | 1 945 | 0 946 | 0 947 | 0 948 | 1 949 | 1 950 | 1 951 | 1 952 | 0 953 | 0 954 | 1 955 | 1 956 | 1 957 | 1 958 | 1 959 | 0 960 | 0 961 | 1 962 | 1 963 | 0 964 | 1 965 | 1 966 | 0 967 | 0 968 | 0 969 | 1 970 | 0 971 | 1 972 | 0 973 | 1 974 | 0 975 | 0 976 | 1 977 | 0 978 | 0 979 | 0 980 | 1 981 | 1 982 | 1 983 | 0 984 | 0 985 | 0 986 | 1 987 | 1 988 | 0 989 | 1 990 | 1 991 | 0 992 | 1 993 | 0 994 | 1 995 | 0 996 | 1 997 | 1 998 | 1 999 | 0 1000 | --------------------------------------------------------------------------------