Делаю имитатор сигнала глонасс на плисе от xilinx.
Естественно в проекте нужен генератор ПСП. И вот столкнулся с проблемой, что если в проект пихнуть, например, десять таких генераторов, то из десяти два-три работать не будут. ПСП на выходе будет неправильная.
В результате чтения отчета Place & Route выяснил, что не работают те генераторы, у которых больший перекос по тактовой цепи чем у остальных. Например, если перекос всего 2 ns, то генератор может не работать. После задания ограничения MAXSKEW = "0.9 ns" вроде бы все заработало. Но меня не покидает ощущение, что это неправильный костыль.
Может подскажете в чем дело и как правильно делать?
Есть подозрения, что надо как-то описать тактовую цепь генератора ПСП, но как непонятно. Её частота поидее всего ~511 кГц, фронт естественно гуляет шагами кратными 10 ns, т.к. сделана она из старшего разряда аккумулятора обычного на 32 разряда работающего на 100 МHz.
Генераторов ПСП перепробовал кучу, результат примерно одинаков, всегда найдутся косячные.
Генератор тактовой частоты ПСП работает на 100 МГц. На неё установлен констрэйн в UCF файле PERIOD = "8.75 ns". Цепь заведена на BUFG. Больше никаких настроек не делал.
Далее код из проекта.
Генератор ПСП:
Код
module prs_sa_gl( clk, rst, prs_out, prs_sync );
(* maxskew = "0.9 ns" *)
input clk;
input rst;
output prs_out;
output prs_sync;
parameter sr_init = 9'b111111111;
reg [8:0] sr = sr_init;
reg prs_sync = 0;
assign prs_out = sr[6];
wire rst_net;
strobe s(
.clk(clk ),
.i (rst ),
.o (rst_net)
);
always @(posedge clk) begin
sr <= rst_net ? sr_init : {sr[7:0], (sr[4] ^ sr[8])};
prs_sync <= (sr == sr_init);
end
endmodule
Генератор тактовой частоты для ПСП:
Код
module prs_cnt( clk, value, wr, clk_out, phase, rst );
input clk;
input [31:0] value;
input wr;
output clk_out;
output [31:0] phase;
input rst;
reg [31:0] index = 0;
reg [31:0] incr = 32'h00000000;
reg [31:0] incr0 = 32'h00000000;
wire wr_net;
assign phase = index;
assign clk_out = index[31];
always @(posedge clk or posedge rst) begin
if (rst) begin
index <= 0;
end
else begin
index <= index + incr;
end
end
strobe s(
.clk(clk ),
.i (wr ),
.o (wr_net)
);
always @(posedge clk) begin
incr0 <= wr_net ? value : incr0;
incr <= incr0;
end
endmodule
Синхронизатор импульсов сброса/записи:
Код
module strobe( clk, i, o );
input clk;
input i;
output o;
reg clr = 0;
reg o = 0;
always @(posedge i or posedge o) begin
clr <= o ? 0 : 1;
end
always @(negedge clk) begin
o <= clr;
end
endmodule