Приложение 1.
Программы для ПЛИС.
Основная рабочая программа
TITLE "interferometr";
INCLUDE DIV10.inc
FUNCTION DIV10 (CLK, RES) RETURN (f)
FUNCTION lpm_add_sub (dataa[LPM_WIDTH-1..0], datab[LPM_WIDTH-1..0], clock)
WITH (LPM_WIDTH,
LPM_REPRESENTATION,
LPM_DIRECTION,
LPM_PIPELINE,
)
RETURNS (result[LPM_WIDTH-1..0], cout, overflow);
FUNCTION lpm_counter (data[LPM_WIDTH-1..0], clock, cnt_en, updown, cin, aclr, aset, aconst, aload, sload)
WITH (LPM_WIDTH, LPM_DIRECTION, LPM_MODULUS, LPM_AVALUE)
RETURNS (q[LPM_WIDTH-1..0], cout);
FUNCTION lpm_clshift (data[LPM_WIDTH-1..0], distance[LPM_WIDTHDIST-1..0], direction)
WITH (LPM_WIDTH, LPM_WIDTHDIST, LPM_SHIFTTYPE)
RETURNS (result[LPM_WIDTH-1..0]);
FUNCTION lpm_ff (data[LPM_WIDTH-1..0], clock, enable, sclr, sset, sload, aclr, aset, aload)
WITH (LPM_WIDTH, LPM_AVALUE, LPM_PVALUE, LPM_SVALUE, LPM_FFTYPE)
RETURNS (q[LPM_WIDTH-1..0]);
FUNCTION lpm_mux (data[LPM_SIZE-1..0][LPM_WIDTH-1..0], sel[LPM_WIDTHS-1..0], clock, aclr)
WITH (LPM_WIDTH, LPM_SIZE, LPM_WIDTHS, LPM_PIPELINE)
RETURNS (result[LPM_WIDTH-1..0]);
FUNCTION lpm_constant ()
WITH (LPM_WIDTH, LPM_CVALUE)
RETURNS (result[LPM_WIDTH-1..0]);
FUNCTION lpm_compare (dataa[LPM_WIDTH-1..0], datab[LPM_WIDTH-1..0], clock, aclr)
WITH (LPM_WIDTH, LPM_PIPELINE, ONE_INPUT_IS_CONSTANT)
RETURNS (alb);
FUNCTION lpm_ram_io (address[LPM_WIDTHAD-1..0], we, inclock, outclock, outenab, memenab)
WITH (LPM_WIDTH, LPM_WIDTHAD, LPM_NUMWORDS, LPM_FILE, LPM_INDATA, LPM_ADDRESS_CONTROL, LPM_OUTDATA)
RETURNS (dio[LPM_WIDTH-1..0]);
PARAMETERS (LENGTH_1 = 16,
LENGTH_2 = 4
LENGTH_3 = 3 -- 2^LENGTH_3
LENGHT_4 = 7);
SUBDESIGN interferometr (
sin: INPUT; --вход sin, ножка 3
cos: input; -- входcos, ножка 4
CLK: INPUT; -- вход опорной частоты, ножка 5
noise [0..LENGTH_2]:input; --вход, задающий уровень величины шума, т.е. задает по скольким отсчетам проводим усреднение
out_range:input; --вход принудительной установки частоты дискретизации
OUT_dist [LENGTH_1-1..0]:output; --с этого выхода получаем код перемещения
way:output; -- выход кода направления перемещения
out_all[0..7]: output; -- выход полного отсчета (дистанция, дискретизация, направление)пачками по 8
out_sel[0..2]:input; -- управление выходом отсчетов
reset_addr:input; -- внешний сброс счетчика адреса
addr:input; -- внешний доступ к счетчику адреса
out_data: input;
write_data: input;)
VARIABLE
f[0..LENGHT_4 - 1]: NODE; --шина частот дискретизации от 100Мгц до 10кГц
g[0..LENGTH_2 - 1]: NODE;
tg1: DFF; --триггер выделения направления
tg2: DFF; -- триггер выделения направления
tg3: DFF; --триггер выделения направления
tg4: DFF; -- триггер для счетчика диапазонов
trg1, trg2, trg3, trg4: DFF;
memories:lpm_ram_io WITH (LPM_WIDTH = LENGTH_1 + LENGTH_3 + 1,
LPM_WIDTHAD = 2^16,
LPM_NUMWORDS = 2^16
);
outmux: lpm_muxWITH (LPM_WIDTH = 8,
LPM_SIZE = 3,
LPM_WIDTHS = 4,
LPM_PIPELINE = 1);
rangemux1: lpm_mux WITH (LPM_WIDTH = 1, LPM_SIZE = LENGHTH_4,
LPM_WIDTHS = LENGHTH_3,
LPM_PIPELINE = 1);
rangemux2: lpm_mux WITH (LPM_WIDTH = 1, LPM_SIZE = LENGHTH_4,
LPM_WIDTHS = LENGHTH_3,
LPM_PIPELINE = 1);
cnt_addr:lpm_counter WITH (LPM_WIDTH = 16,
LPM_DIRECTION = "UP"
);
cnt_rangefind:lpm_counter WITH (LPM_WIDTH = LENGTH_3, --счетчикдо 100 дляоценки fд
LPM_DIRECTION = "UP",
LPM_MODULUS = 100
);
cnt_measure:lpm_counter WITH (LPM_WIDTH = LENGHTH_1, -- измерительныйсчетчикна 16 разрядов
LPM_AVALUE = 2^(LENGHT_1 - 1));
sum_range:lpm_add_sub WITH (LPM_WIDTH = LENGHTH_4,
LPM_REPRESENTATION = "UNSIGNED",
LPM_DIRECTION = "ADD",
LPM_PIPELINE = 1,);
shifter:lpm_clshift WITH (LPM_WIDTH = LENGHTH_4, LPM_WIDTHDIST = LENGHTH_2);
cnt_range:lpm_counter WITH (LPM_WIDTH = LENGHTH_3);
cnt_medium:lpm_counter WITH (LPM_WIDTH = LENGHTH_3, LPM_DIRECTION = "DOWN");
rg1:lpm_ff WITH (LPM_WIDTH = LENGHTH_4,
LPM_PVALUE = 0);
z1:lpm_constant WITH (LPM_WIDTH = 3, LPM_CVALUE = 1);
z2:lpm_constant WITH (LPM_WIDTH = 3, LPM_CVALUE = 2);
z3:lpm_constant WITH (LPM_WIDTH = 3, LPM_CVALUE = 4);
z4:lpm_constant WITH (LPM_WIDTH = 3, LPM_CVALUE = 8);
mux_noise:lpm_mux WITH (LPM_WIDTH = 3, LPM_SIZE = 4,
LPM_WIDTHS = 3,
LPM_PIPELINE = 1);
lower_10:lpm_compare WITH (LPM_WIDTH = LENGHT_4, LPM_PIPELINE = 1,
ONE_INPUT_IS_CONSTANT = "YES")
BEGIN
tg1.d = sin;
tg2.d = cos;
tg1.CLK = cos;
tg2.CLK = sin;
tg3.PRN =!tg1.q;
tg3.CLRN =!tg2.q;
cnt_measure.updown = tg3.q;
cnt_measure.clock = sin;
f[0] = CLK;
FOR i IN 1 TO LENGHTH_4 - 1 GENERATE
f[i] = DIV10(f[i-1]);
rangemux1.DATA[i][] = f[i];
END GENERATE;
FOR i IN 1 TO LENGHTH_4 - 2 GENERATE
rangemux2.DATA[i][] = f[i+1];
END GENERATE;
cnt_rangefind.clock = sin;
cnt_rangefind.cnt_en = rangemux2.result[];
--усреднитель
shifter.data[]=cnt_rangefind.q[];
shifter.distance[] = noise[];
sum_range.dataa[] = shifter.result[];
sum_range.datab[] = rg1.q[];
sum_range.clock = rangemux2.result[];
rg1.data[] = sum_range.result[];
rg1.clock = rangemux2.result[];
lower_10.dataa[] =!g[LENGHTH_2] AND rg1.q[];
lower_10.datab[] = 10;
lower_10.clock = rangemux2.result[];
tg4.PRN =!lower_10.alb; --
tg4.clrn =!cnt_rangefind.cout;
cnt_range.updown = tg4.q;
cnt_range.clock=!!!!(lower_10.alb OR cnt_rangefind.cout);
rangemux1.sel[] = cnt_range.q[];
rangemux2.sel[] = cnt_range.q[];
cnt_medium.data =!g[LENGHTH_2] AND mux_noise.result[];
cnt_medium.clock = rangemux2.result[];
g[0]=cnt_medium.q[0]&cnt_medium.q[1]
FOR i IN 1 TO LENGHTH_2 GENERATE
g[i]=g[i-1]&cnt_medium.q[i+1]
END GENERATE;
mux_noise.data[0][] = z1.result[];
mux_noise.data[1][] = z2.result[];
mux_noise.data[2][] = z3.result[];
mux_noise.data[3][] = z4.result[];
mux_noise.sel[] = noise[];
cnt_addr.clock = rangemux1.result[] OR addr;
cnt_addr.aclr = reset_addr;
memories.address[] = cnt_addr.q[];
memories.inclock = rangemux1.result[];
memories.outclock=!!!!addr;
memories.we = write_data;
memories.outenab = out_data;
memories.memenab=!addr OR rangemux1.result[]
FOR i IN 0 TO LENGTH_1 - 1 GENERATE
memories.dio[] = cnt_measure.q[i]
END GENERATE;
memories.dio [LENGTH_1..LENGTH_1 + LENGTH_3 - 1] = cnt_range.q[];
memories.dio [LENGTH_1 + LENGTH_3 + 1] = tg3.q;
FOR j IN 0 TO 1 GENERATE
FOR i IN 0 TO 7 GENERATE
outmux.data [j][i] = memories.dio[i+j*8] AND out_data;
END GENERATE;
END GENERATE;
outmux.data [2][0..2] = memories.dio[LENGTH_1..LENGTH_1 + LENGTH_3 - 1];
outmux.data [2][3] = memories.[LENGTH_1 + LENGTH_3 + 1];
outmux.sel[] = out_sel[];
out_all [] = outmux.result [];
end
Делитель частоты на 10
TITLE "DIV10";
SUBDESIGN DIV10(
CLK: input;
RES: input;
f: output;)
VARIABLE
trg1, trg2, trg3, trg4: DFF;
BEGIN
trg1.CLK = CLK; --делитель частоты на 10, вход trg1.CLK, выход trg4.Q
trg1.D =!trg1.Q;
trg2.CLK =!trg1.Q;
trg3.CLK =!trg1.Q;
trg4.CLK =!trg1.Q;
trg1.PRN = VCC;
trg2.PRN = VCC;
trg3.PRN = VCC;
trg4.PRN = VCC;
trg1.CLRN =!RES;
trg2.CLRN =!RES;
trg3.CLRN =!RES;
trg4.CLRN = trg3.Q;
trg2.D =!trg4.Q;
trg3.D = trg2.Q;
trg4.D = trg3.Q;
f = trg4.q;
end;