Skip to content

Instantly share code, notes, and snippets.

@ochaochaocha3
Last active August 29, 2015 14:07
Show Gist options
  • Save ochaochaocha3/805106a17c40c33b0cdc to your computer and use it in GitHub Desktop.
Save ochaochaocha3/805106a17c40c33b0cdc to your computer and use it in GitHub Desktop.
非同期式カウンタシミュレータ:タイムチャート描画、カウント表示
#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