Добрый день!
По учебе поставили задачу реализовать 2-х битый синхронный счетчик, на двух JK-триггерах (см. рис 1).
Решил сначала сделать сам триггер, получилось что то вроде:
JKTriggerSync.h
Кликните здесь для просмотра всего текста
C++ |
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
| #pragma once
#include <systemc.h>
SC_MODULE(JKTriggerSync)
{
//get in ...
sc_in_clk CLK_pin;
sc_in<bool> J_pin;
sc_in<bool> K_pin;
//and get out!
sc_out<bool> Q_pin;
sc_out<bool> NQ_pin;
//inside
bool state = false;
void clock() {
Q_pin.write(state);
NQ_pin.write(!state);
uint8_t pin_state = 0b0, j_state = 0b0, k_state = 0b0;
k_state = K_pin.read();
j_state = J_pin.read();
pin_state = k_state + (j_state << 1);
switch (pin_state) {
case 0b00:
break;
case 0b01:
state = false;
break;
case 0b10:
state = true;
break;
case 0b11:
state = !state;
break;
}
}
SC_CTOR(JKTriggerSync) : J_pin(), K_pin(), Q_pin(), NQ_pin()
{
SC_METHOD(clock);
sensitive << CLK_pin.neg();
}
}; |
|
main.cpp
Кликните здесь для просмотра всего текста
C++ |
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
| #include <windows.h>
#include <debugapi.h>
#include "systemc.h"
#include "JKTriggerSync.h"
#include "SignalControl.h"
int sc_main(int argc, char* argv[]) {
sc_signal<bool> clock;
sc_signal<bool> j;
sc_signal<bool> k;
sc_signal<bool> q;
sc_signal<bool> nq;
JKTriggerSync trigger("trigger");
trigger.CLK_pin(clock);
trigger.J_pin(j);
trigger.K_pin(k);
trigger.Q_pin(q);
trigger.NQ_pin(nq);
SignalControl j_ctl(j, j.read(), 5, 20, 2);
SignalControl k_ctl(k, k.read(), 5, 20, 12);
SignalControl clk_ctl(clock, clock.read(),3, 3);
sc_start();
sc_trace_file* trace_file = sc_create_vcd_trace_file("jk-trigger");
sc_trace(trace_file, clock, "clock");
sc_trace(trace_file, j, "j");
sc_trace(trace_file, k, "k");
sc_trace(trace_file, q, "q");
sc_trace(trace_file, nq, "nq");
clock = true;
for (size_t i = 0; i < 200; i++)
{
j_ctl.stage(i);
k_ctl.stage(i);
clk_ctl.stage(i);
sc_start(1, SC_PS);
}
sc_close_vcd_trace_file(trace_file);
return 0;
} |
|
Который в общем и целом выдает достойный похожий на правду результат (см. рис 2). Важно отметить, что срабаывает код clock() при negative edge на пине clock - так поставлено задание. При последующей реализации уже всей схемы счетчика на основе двух триггеров -
TwoBitSyncCounter.h
Кликните здесь для просмотра всего текста
C++ |
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
| #pragma once
#include <systemc.h>
#include "../SystemC JK-Trigger/JKTriggerSync.h"
SC_MODULE(TwoBitSyncCounter)
{
//get in ...
sc_in_clk CLK_pin;
//and get out!
sc_out<bool> JK0_Q;
sc_out<bool> JK1_Q;
sc_out<sc_uint<2>> OUT_set;
//inside
JKTriggerSync c0, c1;
sc_uint<2> counterState;
//signals
sc_signal<bool> JK_CLK;
sc_signal<bool> JK0_CLK_sig;
sc_signal<bool> JK0_J_sig;
sc_signal<bool> JK0_K_sig;
sc_signal<bool> JK0_Q_sig;
sc_signal<bool> JK0_NQ_sig;
sc_signal<bool> JK1_CLK_sig;
sc_signal<bool> JK1_J_sig;
sc_signal<bool> JK1_K_sig;
sc_signal<bool> JK1_Q_sig;
sc_signal<bool> JK1_NQ_sig;
void clock() {
JK_CLK.write(CLK_pin.read());
//reading state
counterState = (JK1_Q_sig.read() << 1) + JK0_Q_sig.read();
OUT_set.write(counterState);
JK0_Q.write(JK0_Q_sig.read());
JK1_Q.write(JK1_Q_sig.read());
}
SC_CTOR(TwoBitSyncCounter) : c0("bit0"), c1("bit1")
{
//bind signals to pins
//triggers clock pins both attached to CLK signal
c0.CLK_pin(JK_CLK);
c0.J_pin(JK_CLK);
c0.K_pin(JK_CLK);
c0.Q_pin(JK0_Q_sig);
c0.NQ_pin(JK0_NQ_sig);
c1.CLK_pin(JK_CLK);
c1.J_pin(JK0_Q_sig);
c1.K_pin(JK0_Q_sig);
c1.Q_pin(JK1_Q_sig);
c1.NQ_pin(JK1_NQ_sig);
SC_METHOD(clock);
sensitive << CLK_pin;
}
}; |
|
main.cpp
Кликните здесь для просмотра всего текста
C++ |
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
| #include <windows.h>
#include <debugapi.h>
#include "systemc.h"
#include "TwoBitCounterSync.h"
#include "../SystemC JK-Trigger/SignalControl.cpp" //no way
int sc_main(int argc, char* argv[]) {
sc_signal<bool> CTR_CLK_sig;
sc_signal<sc_uint<2>> CTR_OUT_sig;
sc_signal<bool> CTR_JK0_Q;
sc_signal<bool> CTR_JK1_Q;
TwoBitSyncCounter counter("counter");
counter.CLK_pin(CTR_CLK_sig);
counter.OUT_set(CTR_OUT_sig);
counter.JK0_Q(CTR_JK0_Q);
counter.JK1_Q(CTR_JK1_Q);
SignalControl clk_ctl(CTR_CLK_sig, CTR_CLK_sig.read(), 2, 2);
sc_start();
sc_trace_file* trace_file = sc_create_vcd_trace_file("TwoBitCounter");
sc_trace(trace_file, CTR_CLK_sig, "clock");
sc_trace(trace_file, CTR_OUT_sig, "out");
sc_trace(trace_file, CTR_JK0_Q, "q0");
sc_trace(trace_file, CTR_JK1_Q, "q1");
CTR_CLK_sig = true;
for (size_t i = 0; i < 100; i++)
{
clk_ctl.stage(i);
sc_start(1, SC_PS);
}
sc_close_vcd_trace_file(trace_file);
return 0;
} |
|
- при открытии трассировки на выходах из обоих триггеров (порты JK0_Q и JK1_Q) вечный ноль (см. рис 3).
Мои соображения: поскольку по заданию на одной линии в схеме счетчика висит как clk обоих триггеров, так и входные порты J и K первого триггера (сигнал JK_CLK), внутри модуля триггера:
C++ |
1
2
| k_state = K_pin.read();
j_state = J_pin.read(); |
|
все время считывается ноль, т.к. триггер срабатывает при переходе JK_CLK в ноль. Я, к сожалению, в HDL новичек, и не особо понимаю, почему так работает и в чем я не прав. Пожалуйста, подскажите, в чем моя ошибка.
Вспомогательный класс для тактирования
Кликните здесь для просмотра всего текста
C++ |
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
| #include "SignalControl.h"
void SignalControl::setState(bool state) {
if (state != _sigState) {
_sig.write(state);
_sigState = state;
}
}
SignalControl::SignalControl(sc_signal<bool>& sig, bool sigState, int wavelength, int interval, int delay)
: _sig(sig), _sigState(sigState), _wavelength(wavelength), _delay(delay), _interval(interval)
{
}
void SignalControl::stage(int step)
{
if (step < _delay) return;
int realstep = step - _delay;
int periodLen = _wavelength + _interval;
int periodIndex = realstep % periodLen;
if (periodIndex < _wavelength) {
setState(true);
}
else {
setState(false);
}
} |
|