Skip to content

Commit 6ad0dc2

Browse files
committed
added set/rst simulation
1 parent 53bc11a commit 6ad0dc2

2 files changed

Lines changed: 54 additions & 44 deletions

File tree

index.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,9 @@ <h1 class="center">Flip Flop Visualizer</h1>
109109
<!-- q -->
110110
<td>Q Output</td>
111111
<td>
112-
<canvas id="q_canvas"></canvas>
112+
<canvas class="toggle_canvas" toggles="q_toggles()"></canvas>
113113
</td>
114114
</tr>
115-
116115
</table>
117116
<div id="schematic" class="center">
118117
<img src="./ff_svgs/async_rst.svg" alt="blank"/>

main.js

Lines changed: 53 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ function draw_toggle_canvases() {
108108
if (togglesAttr) {
109109
const ctx = canvas.getContext('2d');
110110
let toggles = eval(togglesAttr);
111+
if (toggles === undefined)
112+
console.error(`${togglesAttr} failed`)
111113
toggles.push(STOP_TIME);
112114
ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear canvas before drawing
113115
ctx.strokeStyle = 'black';
@@ -143,62 +145,72 @@ function toggle_value_at_time(multirange, time) {
143145
return (toggle_index%2);
144146
}
145147

146-
function draw_q_canvas() {
147-
const canvas = document.getElementById("q_canvas");
148-
const ctx = canvas.getContext('2d');
149-
148+
function q_toggles() {
150149
const has_sync_rst = document.getElementById("sync_rst").checked;
151150
const has_async_rst = document.getElementById("async_rst").checked;
152151
const has_async_set = document.getElementById("async_set").checked;
153152

154-
ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear canvas before drawing
155-
156-
ctx.strokeStyle = 'black';
157-
ctx.beginPath();
158-
ctx.moveTo(0, canvas.height); // Start from the bottom of the canvas
153+
// Generate update events
154+
const set_events = multirange_to_toggles('set_slider').map(value => ({ name: 'set', value }));
155+
const rst_events = multirange_to_toggles('rst_slider').map(value => ({ name: 'rst', value }));
156+
const clk_events = clk_to_toggles().map(value => ({ name: 'clk', value }));
157+
const filtered_set_events = set_events.filter(event => event.value >= 0);
158+
const filtered_rst_events = rst_events.filter(event => event.value >= 0);
159+
const filtered_clk_events = clk_events.filter((_, index) => index % 2 === 0);
160+
const events = [...filtered_set_events, ...filtered_rst_events, ...filtered_clk_events].sort((a, b) => a.value - b.value);
159161

160-
let cycle = 0;
161-
let nextTime = 0;
162162
let value_is_1 = false;
163-
while (nextTime < STOP_TIME) {
164-
nextTime = (freq2time(CLK_FREQ)/2) + (freq2time(CLK_FREQ)*cycle);
163+
let toggles = [];
164+
165+
for (const event of events) {
165166
if (value_is_1) {
166-
nextTime += FALLING_CLKTOQ;
167-
const nextX = time2canvasX(nextTime, canvas);
168-
let value_before_setup = toggle_value_at_time("d_slider", nextTime - FALLING_SETUPTIME);
169-
let value_after_hold = toggle_value_at_time("d_slider", nextTime + FALLING_HOLDTIME);
170-
if (has_sync_rst) {
171-
value_before_setup &= toggle_value_at_time("rst_slider", nextTime - FALLING_SETUPTIME);
172-
value_after_hold &= toggle_value_at_time("rst_slider", nextTime + FALLING_HOLDTIME);
173-
}
174-
ctx.lineTo(nextX, 0);
175-
if ((value_before_setup == 0)&&(value_after_hold == 0)) {
176-
if (nextTime < STOP_TIME) ctx.lineTo(nextX, canvas.height);
177-
value_is_1 = false;
167+
if (has_async_rst && event.name == "rst" && !toggle_value_at_time("rst_slider", event.value)) {
168+
toggles.push(event.value + ASYNCRSTTIME)
169+
value_is_1 = 0;
170+
} else if (has_async_set && event.name == "set") {
171+
} else if (has_async_set && !toggle_value_at_time("set_slider", event.value - ASYNCSETTIME)) {
172+
} else if (has_async_set && event.name == "clk" && !toggle_value_at_time("set_slider", event.value - ASYNCSETTIME + FALLING_CLKTOQ)) {
173+
// maintain 1
174+
} else if (event.name == "clk") {
175+
let value_before_setup = toggle_value_at_time("d_slider", event.value - FALLING_SETUPTIME);
176+
let value_after_hold = toggle_value_at_time("d_slider", event.value + FALLING_HOLDTIME);
177+
if (has_sync_rst) {
178+
value_before_setup &= toggle_value_at_time("rst_slider", event.value - FALLING_SETUPTIME);
179+
value_after_hold &= toggle_value_at_time("rst_slider", event.value + FALLING_HOLDTIME);
180+
}
181+
if (value_before_setup == 0 && value_after_hold == 0) {
182+
toggles.push(event.value + FALLING_CLKTOQ)
183+
value_is_1 = 0;
184+
}
178185
}
179186
} else {
180-
nextTime += RISING_CLKTOQ;
181-
const nextX = time2canvasX(nextTime, canvas);
182-
let value_before_setup = toggle_value_at_time("d_slider", nextTime - RISING_SETUPTIME);
183-
let value_after_hold = toggle_value_at_time("d_slider", nextTime + RISING_HOLDTIME);
184-
if (has_sync_rst) {
185-
value_before_setup &= toggle_value_at_time("rst_slider", nextTime - RISING_SETUPTIME);
186-
value_after_hold &= toggle_value_at_time("rst_slider", nextTime + RISING_HOLDTIME);
187-
}
188-
ctx.lineTo(nextX, canvas.height);
189-
if ((value_before_setup == 1)&&(value_after_hold == 1)) {
190-
if (nextTime < STOP_TIME) ctx.lineTo(nextX, 0);
191-
value_is_1 = true;
187+
if (has_async_rst && event.name == "rst" && !toggle_value_at_time("rst_slider", event.value)) {
188+
} else if (has_async_rst && !toggle_value_at_time("rst_slider", event.value - ASYNCRSTTIME)) {
189+
} else if (has_async_rst && event.name == "clk" && !toggle_value_at_time("rst_slider", event.value - ASYNCRSTTIME + RISING_CLKTOQ)) {
190+
// maintain 0
191+
} else if (has_async_set && event.name == "set") {
192+
toggles.push(event.value + ASYNCSETTIME)
193+
value_is_1 = 1;
194+
} else if (event.name == "clk") {
195+
let value_before_setup = toggle_value_at_time("d_slider", event.value - RISING_SETUPTIME);
196+
let value_after_hold = toggle_value_at_time("d_slider", event.value + RISING_HOLDTIME);
197+
if (has_sync_rst) {
198+
value_before_setup &= toggle_value_at_time("rst_slider", event.value - RISING_SETUPTIME);
199+
value_after_hold &= toggle_value_at_time("rst_slider", event.value + RISING_HOLDTIME);
200+
}
201+
if (value_before_setup == 1 && value_after_hold == 1) {
202+
toggles.push(event.value + RISING_CLKTOQ)
203+
value_is_1 = 1;
204+
}
192205
}
193206
}
194-
cycle++;
195207
}
196-
ctx.stroke();
208+
209+
return toggles;
197210
}
198211

199212
function handle_slider() {
200-
draw_toggle_canvases();
201-
draw_q_canvas();
213+
draw_canvases();
202214
}
203215

204216
function handle_sync_rst() {
@@ -262,7 +274,6 @@ function draw_canvases() {
262274
canvas.height = parseInt(computedStyle.height);
263275
});
264276
draw_toggle_canvases();
265-
draw_q_canvas();
266277
}
267278

268279
fix_multiranges();

0 commit comments

Comments
 (0)