-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathlab_3.tex
378 lines (279 loc) · 28.8 KB
/
lab_3.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
\chapter{Лабораторная работа №3\\Секундомер}
\par{В прошлых лабораторных работах мы изучили базовые строительные блоки цифровых устройств. Теперь у нас уже достаточно знаний для реализации несложного, но функционально законченного цифрового устройства.}
\par{В данной лабораторной работе мы познакомимся с процессом проектирования полноценного цифрового устройства на примере разработки простого секундомера. Мы подробно, поэтапно, рассмотрим процесс проектирования, проиллюстрировав каждый этап графической схемой.}
\par{Для эффективного проектирования любого цифрового устройства нужно придерживаться некоторой \quotes{канвы} проектирования. Это поможет не запутаться и последовательно разобраться с вопросами, возникающими в ходе проектирования.}
\par{\textbf{Начинать проектирование любого цифрового устройства следует с определения входов и выходов.} Нужно понять какие данные будут входными для проектируемого устройства, и какие данные нам надо выработать и подать на выход.}
\vspace{4mm}
\par{В случае секундомера справедливы такие рассуждения:}
\par{Чтобы управлять работой секундомера нам понадобятся два входа: \quotes{старт/стоп} и \quotes{сброс}.}
\par{Для отображения времени можно воспользоваться семисегментными индикаторами. Значит, для управления каждым из них понадобится семибитная шина, которая будет выходом нашего устройства.}
\par{Для отображения времени выделим 2 индикатора для отображения количества прошедших секунд и 2 индикатора для отображения количества прошедших десятых и сотых долей секунды.}
\par{Значит выходом секундомера будут четыре семибитные шины для управления индикаторами.}
\par{В основе секундомера лежит счётчик. Работая, секундомер отсчитывает время, считая количество пришедших импульсов сигнала синхронизации, частота которого заранее известна.}
\par{Т.е. нам потребуется сигнал синхронизации со стабильной частотой.}
\vspace{4mm}
\par{Больше никаких входов и выходов не требуется.}
\par{Общая схема на данный момент выглядит так:}
\begin{figure}[H]
\centering
\def\svgwidth{\columnwidth}
\includesvg{images/lab_3/blackbox}
\caption{Описание входов и выходов секундомера}
\end{figure}
\par{Начнём описывать модуль на языке \eng{Verilog}:}
\lstinputlisting[caption={Описание входов и выходов модуля на языке \eng{Verilog HDL}}, ]{./code_examples/lab_3/stopwatch_module.v}
\par{Теперь приступим к описанию \quotes{внутренностей} модуля.}
\par{Чтобы реализовать секундомер, нам необходимо отсчитывать время.}
\par{Для отсчёта времени в цифровых устройствах считают количество прошедших импульсов синхронизации (тактов). Так как тактовые импульсы генерируются кварцевым генератором со стабильной, известной нам, частотой, то мы можем рассчитать количество импульсов, которое соответствует заданному времени.}
\par{Например, если в устройстве установлен кварцевый генератор на 26 МГц, то одной секунде соответствует 26 миллионов тактовых импульсов, а одной сотой секунды соответствует 260 тысяч тактовых импульсов.}
\par{Для того, чтобы отсчитать это количество импульсов подходит единственный из известных нам \quotes{строительных блоков} - счётчик:}
\begin{figure}[H]
\centering
\def\svgwidth{\columnwidth}
\includesvg{images/lab_3/counter}
\caption{Структура счетчика}
\end{figure}
\par{Как мы уже говорили, счётчик состоит из регистра и сумматора. Чтобы счётчик циклически отсчитывал одну сотую секунды его необходимо обнулить после того, как он отсчитает 260 тысяч тактовых импульсов. В этот же момент нужно выработать сигнал для остальной схемы, что прошла одна сотая секунды.}
\par{Из всех цифровых блоков, которые мы рассмотрели, для реализации задачи сравнения текущего значения счётчика с константой подходит только компаратор. На один из входов компаратора подадим текущее значение счётчика, а на другой вход - константу 260 000.}
\begin{figure}[H]
\centering
\def\svgwidth{\columnwidth}
\includesvg{images/lab_3/count_comp}
\caption{Структура счетчика с компаратором}
\end{figure}
\par{Пока значения на входах компаратора будут отличаться, на выходе компаратора будет значение \quotes{0}. Когда значения будут равны, компаратор изменит выход с \quotes{0} на \quotes{1}, это и будет признак того, что прошло 0.01 секунды. Для того, чтобы можно было эффективно использовать сигнал \quotes{прошло 0.01с}, этот сигнал должен иметь длительность равную 1 такту.}
\par{Этот же сигнал мы будет использовать для управления сбросом счётчика.}
\par{Итак, счётчик должен после достижения значения 260 000 принять значение \quotes{0}, но переход должен случиться, как и все остальные переходы, в момент перехода тактового сигнала из \quotes{0} в \quotes{1}.}
\par{Сброс, отвечающий таким условиям, называется \quotes{синхронный сброс}.}
\par{Посмотрите, как будет выглядеть на временной диаграмме как будет работать счётчик если выход компаратора, подключить как сигнал синхронного сброса:}
\begin{figure}[H]
\centering
\begin{tikztimingtable}[%
timing/dslope=0.1,
timing/.style={x=5ex,y=2ex},
very thick,
x=3ex,
timing/rowdist=3.3ex,
timing/name/.style={font=\sffamily\scriptsize},
]
& 16{c} \\
& 0.5D{} D{259997} D{259998} D{259999} D{0} D{1} D{2} D{3} 0.5D{}\\
& 2.5L 1H 4.5L\\
\extracode
\begin{pgfonlayer}{background}
\node [align=center,scale=0.6,text width=26ex] at (-8ex, -6ex) {Выход компаратора, подключенный в виде синхронного сброса};
\begin{scope}[semitransparent ,semithick]
\end{scope}
\end{pgfonlayer}
\end{tikztimingtable}
\caption{Временная диаграмма работы синхронного счетчика}
\end{figure}
\par{А так выглядит временная диаграмма, если подключить выход компаратора к входу асинхронного сброса триггера:}
\begin{figure}[H]
\centering
\begin{tikztimingtable}[%
timing/dslope=0.1,
timing/.style={x=5ex,y=2ex},
very thick,
x=3ex,
timing/rowdist=3.3ex,
timing/name/.style={font=\sffamily\scriptsize},
]
& 16{c} \\
& 0.5D{} D{259996} D{259997} D{259998} 0.3D{} 0.7D{0} D{1} D{2} D{3}0.5D{}\\
& 3.5L 0.3H 4.2L\\
\extracode
\begin{pgfonlayer}{background}
\node [align=center,scale=0.6,text width=26ex] at (-8ex, -6ex) {Выход компаратора, подключенный в виде асинхронного сброса};
\draw [->,thick] (12ex,-8ex) to [out=50,in=190] (16ex,-5ex) to [out=10,in=-100] (18.5ex,-3.3ex);
\node [align=center,below,scale=0.6,text width=10ex] at (12ex,-8ex) {259999};
\begin{scope}[semitransparent ,semithick]
\end{scope}
\end{pgfonlayer}
\end{tikztimingtable}
\caption{Временная диаграмма работы асинхронного счетчика}
\end{figure}
\par{Выход компаратора, установившись в единицу, моментально сбросит счётчик и, так как значение счётчика изменилось, а значит, изменился и один из входов компаратора, выход компаратора сразу же перейдет в значение \quotes{0}.}
\par{Обратите внимание, что длительность сигнала с выхода компаратора должна быть равна одному такту. Ведь в дальнейшем нам необходимо будет считать события \quotes{прошла одна сотая секунды}, а значит подготовить сигнал единичной длительности, который соответствует этому событию (см. лабораторную работу №3).}
\par{Сигнал с компаратора, в случае, когда он подключен в виде синхронного сброса, полностью удовлетворяет этому условию, а значит нам не придется в дальнейшем вводить новые фрагменты схемы.}
\par{Как реализовать синхронный сброс в цифровом устройстве?}
\par{Для этого можно использовать мультиплексор. Схема будет выглядеть следующим образом:}
\begin{figure}[H]
\centering
\def\svgwidth{\columnwidth}
\includesvg{images/lab_3/sync_reset}
\caption{Схема реализации синхронного сброса}
\end{figure}
\par{Если подключить \eng{sync\_reset} к выходу компаратора, то когда счётчик достигнет порогового значения, выход компаратора изменится и переключит мультиплексор. Теперь на выход мультиплексора будет подаваться \quotes{0}. Этот сигнал будет поступать на вход триггера, но запись нового значения произойдет только во время положительного фронта сигнала синхронизации.}
\par{Для общего сброса секундомера при нажатии кнопки \quotes{сброс} как раз можно воспользоваться входом асинхронного сброса регистра. Ведь при нажатии кнопки \quotes{сброс} можно обнулять регистр мгновенно.}
\par{Теперь надо выбрать правильный сигнал управления работой счётчика - сигнал разрешения работы (\eng{Enable}, \eng{EN}). Ведь счётчик должен начинать считать после нажатия кнопки \quotes{старт/стоп}, а после её повторного нажатия должен останавливаться.}
\par{Для управления работой счётчика можно использовать сигнал, который будет единицей, пока счётчик должен работать и нулём, если отсчёт времени остановлен. Как раз такой сигнал можно подать на вход разрешения работы регистра. Назовём этот сигнал \qeng{device\_running}.}
\par{Посмотрите, как выглядит остановка и запуск счётчика в таком случае:}
\begin{figure}[H]
\centering
\begin{tikztimingtable}[%
timing/dslope=0.1,
timing/.style={x=5ex,y=2ex},
very thick,
x=3ex,
timing/rowdist=3.3ex,
timing/name/.style={font=\sffamily\scriptsize},
]
& 16{c} \\
\eng{device\_running} & 2.5H 3L 2.5H\\
Значение счетчика & 0.5D{} D{19157} D{19158} 4D{19159} D{19160} 0.5D{}\\
\extracode
\end{tikztimingtable}
\caption{Временная диаграмма работы сигнала \eng{device\_running}}
\end{figure}
\par{К проектированию и описанию схемы, которая вырабатывала бы сигнал \qeng{device\_running}, мы вернемся позднее.}
\par{Стоит обратить внимание на следующий момент: что будет, если счётчик остановить в тот момент времени, когда его значение стало равно 259999?}
\par{Взгляните на временную диаграмму:}
\begin{figure}[H]
\centering
\begin{tikztimingtable}[%
timing/dslope=0.1,
timing/.style={x=5ex,y=2ex},
very thick,
x=3ex,
timing/rowdist=3.3ex,
timing/name/.style={font=\sffamily\scriptsize},
]
& 16{c} \\
\eng{device\_running} & 2.5H 5.5L\\
& 0.5D{} D{259997} D{259998} 5.5D{259999}\\
Выход компаратора & 2.6L 5.4H \\
\extracode
\end{tikztimingtable}
\caption{Временная диаграмма работы счетчика}
\end{figure}
\par{Для того чтобы не допустить такого поведения, можно немного изменить условие, запрещающее работу счётчика. Теперь мы будем дополнительно проверять сигнал с компаратора. И если счётчик в данный момент равен 259999, то запретить его работу будет невозможно.}
\par{Для решения этой задачи подойдет вентиль \quotes{или}. Условие будет таким: \quotes{работа разрешена, если сигнал \qeng{device\_running} равен единице \textbf{ИЛИ} когда текущее значение счётчика равно 259999}.}
\par{Теперь схема счётчика выглядит следующим образом:}
\begin{figure}[H]
\centering
\def\svgwidth{\columnwidth}
\includesvg{images/lab_3/pulse_counter}
\caption{Схема счетчика тысячных долей секунды}
\end{figure}
\par{Когда мы представили схему в виде набора цифровых блоков, мы можем описать её поведение на языке \eng{Verilog}:}
\lstinputlisting[caption={Описание счетчика тактовых импульсов на языке \eng{Verilog HDL}}, ]{./code_examples/lab_3/pulse_counter.v}
\par{Теперь, когда у нас есть счетчик, отсчитывающий такты и сигнализирующий о том, что прошла сотая доля секунды, мы можем отсчитывать сотые доли секунды.}
\par{Перед нами встаёт выбор.}
\par{Первый вариант – отсчитывать количество прошедших сотых долей секунды единственным счётчиком. Значение этого счётчика мы можем дешифрировать, чтобы выделить из него количество единиц, десятков, сотен и тысяч прошедших долей секунды, чтобы подать эти значения на дешифраторы семисегментных индикаторов:}
\begin{figure}[H]
\centering
\def\svgwidth{\columnwidth}
\includesvg{images/lab_3/timer_struct_1}
\caption{Первый пример реализации секундомера}
\end{figure}
\par{Второй вариант – использовать отдельные счётчики для сотых долей секунды, десятых долей секунды, целых секунд и десятков секунд.}
\par{Т.е. первый счетчик подсчитывает количество прошедших сотых долей секунды от 0 до 9, и, затем обнуляется, вырабатывая сигнал \quotes{прошла десятая доля секунды}. Следующий счётчик, точно также считает уже десятые доли и вырабатывает сигнал \quotes{прошла одна секунда} и так далее.}
\begin{figure}[H]
\centering
\def\svgwidth{\columnwidth}
\includesvg{images/lab_3/timer_struct_2}
\caption{Второй пример реализации секундомера}
\end{figure}
\par{Второй вариант для нас проще в реализации, компактнее, удобнее и понятнее.}
\par{Поэтому выберем именно его.}
\par{В качестве счётчиков подойдет уже описанная нами схема для подсчёта тактов, но с небольшими правками.}
\par{Счетчики подойдут нам потому, что функция их идентична – подсчёт событий с ограничением диапазона. Изменить нужно будет только разрядность счётчика с 16 на 4 и верхнюю границу счёта с 260000 на 9. Тогда счётчик будет выдавать признак переполнения (достижения границы отсчёта, когда его значение будет становиться) девяткой.}
\par{Еще одним моментом, о котором нужно позаботиться – длительность выходного сигнала.}
\par{Пока счётчик считал такты, его значение менялось каждый такт. Компаратор просто не мог принять значение 1 более чем на один такт. Теперь ситуация выглядит следующим образом:}
\begin{figure}[H]
\centering
\begin{tikztimingtable}[%
timing/dslope=0.1,
timing/.style={x=3.5ex,y=2ex},
very thick,
x=3ex,
timing/rowdist=3.3ex,
timing/coldist=2pt,
timing/name/.style={font=\sffamily\scriptsize},
]
& 11{c} 2{0.5c} 11{c} \\
& 0.5D{} D{[scale=0.7]{259997}} D{[scale=0.7]{259998}} D{[scale=0.7]{259999}} D{[scale=0.7]{0}} 1D{[scale=0.7]{1}} 0.5D{} D{[scale=0.7]{259997}} D{[scale=0.7]{259998}} D{[scale=0.7]{259999}} D{[scale=0.7]{0}} D{[scale=0.7]{1}} 0.5D{}\\
& 2.5L 1H 4.5L 1H 2.5L\\
& 3.5D{[scale=0.7]{8}} 2D{[scale=0.7]{9}} 3.5D{[scale=0.7]{9}} 2.5D{[scale=0.7]{0}} \\
& 3.5L 5.5H 2.5L\\
& 8L 1H 2.5L\\
\extracode
\draw[fill=white,color=white] (20ex,-19ex) rectangle (18.8ex,4ex);
\begin{pgfonlayer}{background}
\node [align=right,scale=0.7,text width=22ex] at (-10ex, -3ex) {Счетчик тактов};
\node [align=right,scale=0.7,text width=22ex] at (-10ex, -6ex) {\quotes{Прошла 0.01с}};
\node [align=right,scale=0.7,text width=22ex] at (-10ex, -9ex) {Счетчик сотых долей};
\node [align=right,scale=0.7,text width=22ex] at (-10ex, -12ex) {Выход компаратора счетчика сотых долей};
\node [align=right,scale=0.7,text width=22ex] at (-10ex, -15ex) {\quotes{Прошла 0.1с}};
\draw [very thick, color=black] (20.15ex,4ex) -- (20.15ex,-19ex);
\draw [very thick, color=black] (18.65ex,4ex) -- (18.65ex,-19ex);
\end{pgfonlayer}
\end{tikztimingtable}
\caption{Временная диаграмма работы секундомера}
\end{figure}
\par{Счетчик будет переключаться каждую 0,01 секунды, 0,1 секунды ,1 секунду или 10 секунд. И выход компаратора будет устанавливаться в 1 на всё время, которое потребуется для переключения счётчика из 9 в ноль. Т.е. в случае счётчика сотых долей секунды потребуется 259999 тактов.}
\par{Как выделить из всего времени, пока счётчик имеет значение \quotes{9} сигнал длительностью в один такт, который возникает в нужный момент времени? На временной диаграмме этот сигнал отмечен как \quotes{прошла 0,1с.}
\par{Сигнал \quotes{прошла 0,1с} можно получить из сигналов, представленных на временной диаграмме следующим образом: \quotes{прошла 0,1с} правда, когда выход компаратора равен единице \textbf{И} \quotes{прошла 0,01с}.}
\par{Схема счётчика практически не изменилась:}
\begin{figure}[H]
\centering
\def\svgwidth{\columnwidth}
\includesvg{images/lab_3/hundredth_counter}
\caption{Схема счётчика сотых долей секунды}
\end{figure}
\par{Скорректируем описание её работы на \eng{Verilog}:}
\lstinputlisting[caption={Описание счетчика сотых долей секунды на языке \eng{Verilog HDL}}, ]{./code_examples/lab_3/hundredth_counter.v}
\par{Счётчики десятых долей секунды, целых секунд и десятков секунд устроены абсолютно также. В описаниях изменятся только названия сигналов и регистров. Единственное в чем необходимо быть внимательным – это подключение сигналов. Для правильного подключения надо свериться со схемой, которую мы выбрали ранее.}
\par{Теперь вернёмся к вопросам, которые мы отложили ранее.}
\par{В нашем устройстве пока нет описания схемы, которая вырабатывает сигнал \qeng{device\_stopped}. Сигнал должен управляться кнопкой, поэтому как мы уже говорили, в лабораторной работе №3 потребуется схема, синхронизирующая сигнал, поступающий с кнопки с внутренним сигналом \eng{clk} (тактовые импульсы).}
\par{Также сразу выделим из всего нажатия признак того, что кнопка была нажата, так, чтобы по длительности этот признак был равен одному такту.}
\par{Тогда схема будет абсолютно такой же, как и в лабораторной работе №3 и будет выглядеть следующим образом:}
\begin{figure}[H]
\centering
\def\svgwidth{\columnwidth}
\includesvg{images/lab_2/register}
\caption{Структура схемы синхронизации сигнала}
\end{figure}
\par{Поведение такой схемы описывается на языке \eng{Verilog} следующим образом:}
\lstinputlisting[caption={Описание схемы синхранизации на языке \eng{Verilog HDL}}, ]{./code_examples/lab_3/button_syncroniser.v}
\par{Эта схема и её описание подробно рассмотрены в лабораторной работе №3}
\par{Теперь нам нужно построить схему, которая по нажатию кнопки переключала бы сигнал \quotes{device\_stopped} из \quotes{0} в \quotes{1} и из \quotes{1} в \quotes{0}.}
\par{Что нам понадобится? Триггер, чтобы хранить значение \qeng{device\_stopped}. Чтобы менять значение на противоположное надо знать противоположное значение, значит, нужен инвертор. Событие должно случаться по сигналу \qeng{button\_was\_pressed}, а значит речь, скорее всего, идет о входе разрешения работы триггера.}
\par{Немного подумав над этими вводными, нетрудно составить следующую схему:}
\begin{figure}[H]
\centering
\def\svgwidth{\columnwidth}
\includesvg{images/lab_3/device_stopped}
\caption{Схема переключения сигнала \qeng{device\_running}}
\end{figure}
\par{Временная диаграмма, которая соответствует работе этого устройства:}
\begin{figure}[H]
\centering
\begin{tikztimingtable}[%
timing/dslope=0.1,
timing/.style={x=5ex,y=2ex},
very thick,
x=3ex,
timing/rowdist=3.3ex,
timing/name/.style={font=\sffamily\scriptsize},
]
& 15{c} \\
\eng{button\_was\_pressed} & 1.5L 1H 3L 1H 1L\\
\eng{device\_running} & 2.5L 4H 1L\\
\extracode
\end{tikztimingtable}
\caption{Временная диаграмма переключения сигнала \qeng{device\_running}}
\end{figure}
\par{Описание поведения этой схемы на \eng{Verilog} также не представляет сложности. Выполните его самостоятельно.}
\par{Теперь приведем полное описание секундомера (за исключением схемы, вырабатывающей сигнал \qeng{device\_stopped}), выполненное на языке \eng{Verilog}:}
\lstinputlisting[caption={Описание секундомера на языке \eng{Verilog HDL}}, ]{./code_examples/lab_3/stopwatch.v}
\section{Задание лабораторной работы:}
\par{Изучить разработку к лабораторной работе.}
\par{Самостоятельно выполнить описание схемы, вырабатывающей сигнал \qeng{device\_stopped}.}
\par{Выполнить синтез и моделирование работы счётчика.}
\par{Продемонстрировать в результатах моделирования фрагменты временных диаграмм, приведенных в заработке.}
\par{Изучить работу устройства, реализованного в ПЛИС учебного стенда.}
\par{Подготовить ответы на вопросы к защите лабораторной работы.}
\section{Вопросы к защите лабораторной работы}
\par{*in progress*}