[an error occurred while processing this directive]
|
В общем по резету на выходе дается тактовая "clka". Затем, если на "sw_a_b" подать высокий уровень, то произойдет переключение на "clkb". Если подать высокий на "sw_b_a" - то наоборот - переключение на клок "а".
ВАЖНО. Все изменения входных сигналов переключения клоков ДОЛЖНЫ производится по положительному фронту "outclk". То есть пока outclk выключен - изменение состояния sw_*_* недопустимо.
CONSTANT DLY_LINE_SIZE = 4;
subdesign clk_mux (
sw_a_b: input;
sw_b_a: input;
clka, clkb: input;
outclk: output;
reset: input;
)
variable
dly_b_a[DLY_LINE_SIZE-1..0]:dff;
dly_a_b[DLY_LINE_SIZE-1..0]:dff;
cke_a_ff:dffe;
cke_b_ff:dffe;
begin
defaults
cke_a_ff.ena=gnd;
cke_b_ff.ena=gnd;
end defaults;
outclk = global(lcell(
(clka and lcell(cke_a_ff)) or
(clkb and lcell(cke_b_ff)) ));
dly_b_a[0] = cke_b_ff;
dly_a_b[0] = cke_a_ff;
dly_b_a[DLY_LINE_SIZE-1..1] = dly_b_a[DLY_LINE_SIZE-2..0];
dly_a_b[DLY_LINE_SIZE-1..1] = dly_a_b[DLY_LINE_SIZE-2..0];
-- switch clka on after clkb off
if ((not dly_b_a[DLY_LINE_SIZE-1]) and (not cke_a_ff) and sw_b_a and (not sw_a_b) ) then
cke_a_ff = vcc;
cke_a_ff.ena=vcc;
end if;
-- switch clkb on after clka off
if ((not dly_a_b[DLY_LINE_SIZE-1]) and (not cke_b_ff) and sw_a_b and (not sw_b_a) ) then
cke_b_ff = vcc;
cke_b_ff.ena=vcc;
end if;
-- start clka->clkb process
if (sw_a_b and cke_a_ff) then
cke_a_ff = gnd;
cke_a_ff.ena=vcc;
end if;
-- start clkb->clka process
if (sw_b_a and cke_b_ff) then
cke_b_ff = gnd;
cke_b_ff.ena=vcc;
end if;
-- clock connection
dly_b_a[].clk = not clka;
cke_a_ff.clk = not clka;
dly_a_b[].clk = not clkb;
cke_b_ff.clk = not clkb;
-- reset's
dly_b_a[].clrn = reset;
cke_b_ff.clrn = reset;
dly_a_b[].prn = reset;
cke_a_ff.prn = reset;
end;
E-mail: info@telesys.ru