Last active
August 29, 2015 14:07
-
-
Save ochaochaocha3/805106a17c40c33b0cdc to your computer and use it in GitHub Desktop.
非同期式カウンタシミュレータ:タイムチャート描画、カウント表示
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
typedef struct { | |
int time; | |
int length; | |
} pulse; | |
typedef struct { | |
unsigned int negative_edge : 1; | |
unsigned int t : 1; | |
unsigned int q : 1; | |
unsigned int not_q : 1; | |
} t_ff; | |
typedef struct { | |
unsigned int negative_edge : 1; | |
unsigned int connect_not_q1_to_t2 : 1; | |
unsigned int n_bits; | |
t_ff *ff; | |
} async_counter; | |
void | |
die(const char *s) | |
{ | |
perror(s); | |
exit(1); | |
} | |
void | |
t_ff_init(t_ff *ff, int negative_edge) | |
{ | |
ff->negative_edge = negative_edge ? 1 : 0; | |
ff->t = 0; | |
ff->q = 0; | |
ff->not_q = 1; | |
} | |
void | |
t_ff_update(t_ff *ff, t_ff *prev) | |
{ | |
#define INVERT(x) ((x) ? 0 : 1); | |
ff->q = prev->q; | |
if (ff->negative_edge) { | |
if (prev->t && !ff->t) { | |
ff->q = INVERT(ff->q); | |
} | |
} else { | |
if (!prev->t && ff->t) { | |
ff->q = INVERT(ff->q); | |
} | |
} | |
ff->not_q = INVERT(ff->q); | |
} | |
void | |
print_high_or_low(int x) | |
{ | |
putchar(x ? '^' : '_'); | |
} | |
void | |
async_counter_init( | |
async_counter *counter, | |
unsigned int n_bits, | |
unsigned int negative_edge, | |
unsigned int connect_not_q1_to_t2 | |
) | |
{ | |
unsigned int i; | |
counter->negative_edge = negative_edge ? 1 : 0; | |
counter->connect_not_q1_to_t2 = connect_not_q1_to_t2 ? 1 : 0; | |
counter->n_bits = n_bits; | |
counter->ff = (t_ff*)malloc(counter->n_bits * sizeof(t_ff)); | |
if (!counter->ff) { | |
die("malloc"); | |
} | |
for (i = 0; i < counter->n_bits; i++) { | |
t_ff_init(&counter->ff[i], counter->negative_edge); | |
} | |
} | |
void | |
async_counter_update(async_counter *counter, async_counter *prev) | |
{ | |
unsigned int i; | |
t_ff_update(&counter->ff[0], &prev->ff[0]); | |
for (i = 1; i < counter->n_bits; i++) { | |
counter->ff[i].t = counter->connect_not_q1_to_t2 ? | |
counter->ff[i - 1].not_q : counter->ff[i - 1].q; | |
t_ff_update(&counter->ff[i], &prev->ff[i]); | |
} | |
} | |
void | |
async_counter_print_time_chart(async_counter counter[], unsigned int length) | |
{ | |
unsigned int n_bits = counter[0].n_bits; | |
unsigned int last = n_bits - 1; | |
unsigned int i, j; | |
printf(" T "); | |
for (i = 0; i < length; i++) { | |
print_high_or_low(counter[i].ff[0].t); | |
} | |
putchar('\n'); | |
for (i = 0; i < last; i++) { | |
printf("\n Q%u ", i); | |
for (j = 0; j < length; j++) { | |
print_high_or_low(counter[j].ff[i].q); | |
} | |
putchar('\n'); | |
printf("\n!Q%u ", i); | |
for (j = 0; j < length; j++) { | |
print_high_or_low(counter[j].ff[i].not_q); | |
} | |
putchar('\n'); | |
} | |
printf("\n Q%u ", last); | |
for (i = 0; i < length; i++) { | |
print_high_or_low(counter[i].ff[last].q); | |
} | |
putchar('\n'); | |
printf("\n "); | |
for (i = 0; i < length; i++) { | |
unsigned int x = 0; | |
for (j = 0; j < n_bits; j++) { | |
if (counter[i].ff[j].q) { | |
x |= (1 << j); | |
} | |
} | |
printf("%X", x); | |
} | |
putchar('\n'); | |
} | |
void | |
simulate_async_counter( | |
unsigned int pulse_width, | |
unsigned int interval, | |
unsigned int length, | |
unsigned int n_bits, | |
unsigned int negative_edge, | |
unsigned int connect_not_q1_to_t2 | |
) | |
{ | |
async_counter *counter; | |
unsigned int cycle = pulse_width + interval; | |
unsigned int i; | |
counter = (async_counter*)malloc(length * sizeof(async_counter)); | |
if (!counter) { | |
die("malloc"); | |
} | |
for (i = 0; i < length; i++) { | |
int j = (i - 1) % cycle; | |
async_counter_init( | |
&counter[i], | |
n_bits, | |
negative_edge, | |
connect_not_q1_to_t2 | |
); | |
if (i > 0) { | |
if (j < pulse_width) { | |
counter[i].ff[0].t = 1; | |
} | |
async_counter_update(&counter[i], &counter[i - 1]); | |
} | |
} | |
async_counter_print_time_chart(counter, length); | |
for (i = 0; i < length; i++) { | |
free(counter[i].ff); | |
} | |
free(counter); | |
} | |
int | |
main(void) | |
{ | |
unsigned int pulse_width, interval, length; | |
unsigned int n_bits, negative_edge, connect_not_q1_to_t2; | |
puts("非同期式カウンタ"); | |
printf("ビット数 (2-4): "); | |
scanf("%u", &n_bits); | |
printf("パルス幅: "); | |
scanf("%u", &pulse_width); | |
printf("間隔: "); | |
scanf("%u", &interval); | |
printf("時間: "); | |
scanf("%u", &length); | |
printf("[0]ポジティブエッジ [1]ネガティブエッジ: "); | |
scanf("%u", &negative_edge); | |
printf("[0]Q1 [1]!Q1 を T2 に接続する: "); | |
scanf("%u", &connect_not_q1_to_t2); | |
putchar('\n'); | |
simulate_async_counter( | |
pulse_width, | |
interval, | |
length, | |
n_bits, | |
negative_edge, | |
connect_not_q1_to_t2 | |
); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment