Page 1 of 1

Оптимизация кода для CPLD

Posted: 04 Apr 2017, 21:19
by R2R
Собственно, пишу код для XC9572XL. Сначала тренировался на XC6SLX9 - все работало и занимало меньше макроячеек, чем есть в упомянутом CPLD. В процессе переноса выяснилось, что ресурсов все-таки не хватает. Путем сокращения функционала удалось разместить код, однако любой шаг в сторону приводит к невозможности синтеза схемы.
Сейчас задействовано 32/72 макроячеек, 251/360 product terms (кстати, как это называется по-русски?) и 27/72 регистров. Если увеличить разрядность регистра cnt с 15 до 17 бит, будет задействовано на 2 регистра больше и на 6 термов меньше, а если поднять до 19 бит, то для синтеза внезапно не будет хватать 234 термов! Где здесь логичная и понятная закономерность? Подобное происходит при минимальном изменении условия в конструкции if или замене цепочки if на case (вроде как и то, и то другое в последовательность мультиплексоров должно синтезироваться, но не прокатывает). В общем, я запутался и не знаю, как тут оптимизировать.
 Код

Code: Select all

module ETCC
	(
	input wire clk,
	input wire fb,
	input wire mode,		
	input wire ocd,		
  	output wire [3:0] out_sgn
    );

localparam		DT = 5,
				T = 128,
				PW = 400;

reg [14:0]	cnt = 0;			
reg [8:0]	cnt_int = 0;
reg [4:0]	cnt_dt = 0;
reg [3:0]	sharm = 4'b1111;
reg [0:0]	fb_pre = 0,
		cnt_dt_inc_en = 0,
		inter_fb = 0,
		inter_gen = 0,
		fb_cx = 0,
		phase = 0,
		start = 0,
		ocd_s = 1;
			
always @ (posedge clk)
begin

cnt = cnt + 1;

if ((cnt_dt == 1)&&(fb_pre == 0)) cnt_int = cnt_int + 1;
if ((cnt >= (0-1))&&(cnt < T)) start = 1;
else start = 0;

if (cnt_int == PW) inter_fb = inter_fb ^ 1;
if (cnt == 1000) inter_gen = inter_gen ^ 1;

if (mode == 1) fb_cx = ((phase ^ fb) || cnt[6]) && inter_gen && ocd_s;
else fb_cx = cnt[6] && inter_gen && ocd_s;

if (fb_cx != fb_pre) cnt_dt_inc_en = 1;
if (cnt_dt_inc_en == 1) cnt_dt = cnt_dt + 1;

if (fb_cx > fb_pre)
	begin
	if ((cnt_dt >= 0)&&(cnt_dt < 5))
		begin
		if (start == 0) sharm = 4'b1110;
		else sharm = 4'b1111;
		end
	if ((cnt_dt >= 5)&&(cnt_dt < 15)) sharm = 4'b1111;
	if ((cnt_dt >= 15)&&(cnt_dt < 20)) sharm = 4'b1011;
	if ((cnt_dt >= 20)&&(cnt_dt < 32))
		begin
		sharm = 4'b0011;
		cnt_dt_inc_en = 0;
		cnt_dt = 0;
		fb_pre = fb_cx;
		end
	end 
if (fb_cx < fb_pre)
	begin
	if ((cnt_dt >= 0)&&(cnt_dt < 5)) sharm = 4'b1011;
	if ((cnt_dt >= 5)&&(cnt_dt < 15)) 
		begin
		sharm = 4'b1111;
		if ((start == 1)||(inter_gen == 0))
			begin
			cnt_dt_inc_en = 0;
			cnt_dt = 0;
			fb_pre = fb_cx;
			end
		end
	if ((cnt_dt >= 15)&&(cnt_dt < 20)) sharm = 4'b1110;
	if ((cnt_dt >= 20)&&(cnt_dt < 32))
		begin
		sharm = 4'b1100;
		cnt_dt_inc_en = 0;
		cnt_dt = 0;
		fb_pre = fb_cx;
		end
		
	end  

end

assign out_sgn = sharm;

endmodule

Re: Оптимизация кода для CPLD

Posted: 05 Apr 2017, 15:56
by iEugene0x7CA
Хм, не подскажу насчет термов — Xilinx'ы не прогал ни разу, но насчет XC9572 — это мега-крохотная и супер-древняя(1998-й год :)) микрушка, я бы не использовал их для новых дизайнов или даже обучения.
Мы сейчас на EPM240 перешли, даже есть мысли поставить её в SimpleDriver, в одной из следующих версий.

Re: Оптимизация кода для CPLD

Posted: 05 Apr 2017, 19:57
by R2R
Хм, XC9572 действительно старая, но проектов на ней в сети мало. Видать, их только как замену нескольким корпусам комбинаторной логики юзать можно. Ну ладно, попробую домучить хильку, а в следующий раз буду делать контроллер для теслы на EPM240, благо уже затарился ими :) .

Re: Оптимизация кода для CPLD

Posted: 08 Apr 2017, 00:04
by iEugene0x7CA
R2R wrote:только как замену нескольким корпусам комбинаторной логики
Вроде, CPLD и не претендуют ни на что большее. :)
Это не замена микроконтроллеру, как многим иногда кажется, её цели — экономия пространства на платке(помещение логики в один чип) и обработка быстрых процессов, с которыми простой микроконтроллер не справится.
В жирные FPGA да, можно залить софткорный процессор, но на практике большие FPGA дороги и всегда дешевле поставить мелкую CPLD в связке с железным MCU. Менее гемморней, тоже.