Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблема с синтезом. Память под Synplify 8.2.1
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
stalko
Уже крыша едет!!
В двух словах: есть набор регистров 16х256 "на улицу" + двухпортовая память для передачи данных другому модулю + вход от такой же памяти того самого модуля... Память адресуется регистрами 32 и 33, регистры с автоинкрементом. Все остальное неважно, далее код в студию...
`timescale 1ms / 1us
////////////////////////////////////////////////////////////////////////////////
// Create Date: 10:12:22 07/27/05
// Module Name: REG_ARM_DUAL_PORT
////////////////////////////////////////////////////////////////////////////////
module REG_ARM_DUAL_PORT(A, CS_FPGA, nWR, nRD, NLB, NUB, HFCC, HFCD, DIN, DOUT, TxHALEn,
RECEIVE, TOUT, MARKER, HAL_HDWL, NSS_MODE, GCLK, SHARE_A, SHARE_D, TOSHARE_A,
TOSHARE_D, CS4_MEM, CS5_MEM);
parameter DEEP=256;
parameter MEM_DEEP=1024;
input [7:0] A;
input CS_FPGA;
input nWR;
input nRD;
input NLB;
input NUB;
input HFCC;
input [7:0] HFCD;
input [15:0] DIN;
input GCLK;
input [10:0] SHARE_A;
input [15:0] TOSHARE_D;
input CS4_MEM;
input CS5_MEM;
output [15:0] DOUT;
output TxHALEn;
output RECEIVE;
output [15:0] TOUT;
output MARKER;
output HAL_HDWL;
output NSS_MODE;
output [7:0] SHARE_D;
output [10:0] TOSHARE_A;
// Собственно регистры
reg [15:0] RARM [DEEP-1:0]/* synthesis syn_ramstyle="registers"*/;
reg [7:0] MEM [MEM_DEEP-1:0]/* synthesis syn_ramstyle="select_ram"*/;
reg [15:0] R3;
reg MARKER;
wire nWR_EN;
wire [10:0] A_MEM;
reg nWR_MEM_C, nRD_MEM_C;

assign TxHALEn = RARM[0][0];
assign NSS_MODE = RARM[0][1];
assign RECEIVE = RARM[1][0];
assign HAL_HDWL = RARM[1][2];
assign TOUT=RARM[2];
assign nWR_EN=nWR | CS_FPGA;
assign TOSHARE_A=RARM[33];
assign nWR_MEM=nWR|CS4_MEM;
assign nRD_MEM=nRD|CS5_MEM;
assign A_MEM=RARM[32];
assign A_MEM1=RARM[33];

assign SHARE_D=MEM[SHARE_A];

// Регистр RARM3 - вход HAL Freq Control
always @(posedge HFCC)
R3={8'b0,HFCD};

always @(posedge GCLK)
begin
// Маркер
if ((nWR_EN==0)&&(A==8'h02)&&(DIN!=8'h00))
MARKER=!MARKER;
// Локальные регистры
if (nWR_EN==0) //negedge nWR_EN
RARM[A]=DIN;
// Память обмена (запись)
if (nWR_MEM==0)
{MEM[A_MEM],MEM[A_MEM+1]}=DIN;
// Автоинкремент указателей
if ({nWR_MEM,nWR_MEM_C}==2'b10) //posedge nWR_MEM
RARM[32]=A_MEM+2;
nWR_MEM_C=nWR_MEM;
if ({nRD_MEM,nRD_MEM_C}==2'b10) //posedge nRD_MEM
RARM[33]=A_MEM1+2;
nRD_MEM_C=nRD_MEM;
end

assign DOUT=((CS5_MEM==0)?TOSHARE_D:((A==3)?R3:RARM[A]));

endmodule

Так вот: при синтезе Synplify 8.2.1 просто зависает (возможно, она и не висит в прямом смысле этого слова, но я так и не дождался)...
Подобная ситуация и с тем самым "другим модулем", он написан немного по другому. Он по логу проходит чуть дальше и выдает в .srr чудную ошибку:
Latch generated from always block for signal MEM_1018_[7:0], probably caused by a missing assignment in an if or case stmt. И так для каждого бита памяти...
Я, честно, так и не понял ее смысла... Но синтезирует его... вот только Latch-ей после этого в проекте столько, что они в ПЛИС не лезут...
Ответы сводящиеся только к "я бы сделал совсем по другому" просьба не писать, либо уж пишите, как бы Вы сделали...
Заранее спасибо.
P.S. Думаю, это у меня ручки кривоваты, а Synplify ни при чем.
tegumay
я с Simplify не работал но попробуйте расставить begin и end, где это нужно, компилятор похоже с ума сходит. Было такое в ISE, после того как, расставил все заработало.
Leka
В модуле always@(posedge GCLK) куча "=" - это неправильно.
{MEM[A_MEM],MEM[A_MEM+1]}=DIN - тоже не радует.
stalko
Цитата(tegumay @ Nov 28 2005, 20:31) *
я с Simplify не работал но попробуйте расставить begin и end, где это нужно, компилятор похоже с ума сходит. Было такое в ISE, после того как, расставил все заработало.

Попробую, чем черт не шутит...
Цитата(Leka @ Nov 28 2005, 22:24) *
{MEM[A_MEM],MEM[A_MEM+1]}=DIN - тоже не радует.

Самого не радует, но это можно разбить
MEM[A_MEM]=DIN[15:8];
MEM[A_MEM+1]=DIN[7:0];

Цитата(Leka @ Nov 28 2005, 22:24) *
В модуле always@(posedge GCLK) куча "=" - это неправильно.

А вот как обойти это?
ну,
if (nWR_MEM==0)
{MEM[A_MEM],MEM[A_MEM+1]}=DIN;

можно отнести в отдельный always @(GCLK)
а все остальное нельзя: тогда изменение одних регистров окажется в разных олвайзах, чего синтезаторы просто не переваривают... Я, конечно, бывало, изголялся... но сейчас не хочется...
Цитата(Leka @ Nov 28 2005, 22:24) *
В модуле always@(posedge GCLK) куча "=" - это неправильно.

Кстати, данная фраза меня очень удивила: обычно, наоборот, мне советовали всё запихать в один большой олвайз. smile.gif
Leka
всё запихать в один большой олвайз желательно примерно так (логику не проверял):

assign clk_MARKER = ((nWR_EN==0)&&(A==8'h02)&&(DIN!=8'h00));
assign clk_RARM_32 = ({nWR_MEM,nWR_MEM_C}==2'b10);
assign clk_RARM_33 = ({nRD_MEM,nRD_MEM_C}==2'b10);

always @(posedge GCLK)
begin
if (clk_MARKER)
MARKER<=!MARKER;
if (nWR_EN==0)
RARM[A]<=DIN;
if (clk_RARM_32)
RARM[32]<=A_MEM+2;
if (clk_RARM_33)
RARM[33]<=A_MEM1+2;
...
nWR_MEM_C<=nWR_MEM;
nRD_MEM_C<=nRD_MEM;
end
Leka
MEM[A_MEM]=DIN[15:8]; MEM[A_MEM+1]=DIN[7:0];
Это дела не меняет - надо отдельным модулем явно описать, как в память записываются 2 байта. ИМХО.
stalko
В соответствии с советами и собственным домыслием изменил код так:
`timescale 1ms / 1us
////////////////////////////////////////////////////////////////////////////////
// Create Date: 10:12:22 07/27/05
// Module Name: REG_ARM_DUAL_PORT
////////////////////////////////////////////////////////////////////////////////
module REG_ARM_DUAL_PORT(A, CS_FPGA, nWR, nRD, NLB, NUB, HFCC, HFCD, DIN, DOUT, TxHALEn,
RECEIVE, TOUT, MARKER, HAL_HDWL, NSS_MODE, GCLK, SHARE_A, SHARE_D, TOSHARE_A, TOSHARE_D,
CS4_MEM, CS5_MEM);
parameter DEEP=256;
parameter MEM_DEEP=1024;
input [7:0] A;
input CS_FPGA;
input nWR;
input nRD;
input NLB;
input NUB;
input HFCC;
input [7:0] HFCD;
input [15:0] DIN;
input GCLK;
input [9:0] SHARE_A;
input [15:0] TOSHARE_D;
input CS4_MEM;
input CS5_MEM;
output [15:0] DOUT;
output TxHALEn;
output RECEIVE;
output [15:0] TOUT;
output MARKER;
output HAL_HDWL;
output NSS_MODE;
output [7:0] SHARE_D;
output [9:0] TOSHARE_A;
// Собственно регистры
reg [15:0] RARM [DEEP-1:0]/* synthesis syn_ramstyle="registers"*/;
reg [7:0] MEM [MEM_DEEP-1:0]/* synthesis syn_ramstyle="select_ram"*/;
reg [15:0] R3;
reg MARKER;
wire nWR_EN;
wire [9:0] A_MEM;
wire [9:0] A_MEM1;
reg nWR_MEM_C, nRD_MEM_C;
wire clk_MARKER, clk_nWR_MEM, clk_nRD_MEM;

assign TxHALEn = RARM[0][0];
assign NSS_MODE = RARM[0][1];
assign RECEIVE = RARM[1][0];
assign HAL_HDWL = RARM[1][2];
assign TOUT=RARM[2];
assign nWR_EN=nWR | CS_FPGA;
assign TOSHARE_A=RARM[33];
assign SHARE_D=MEM[SHARE_A];
assign nWR_MEM=nWR|CS4_MEM;
assign nRD_MEM=nRD|CS5_MEM;
assign A_MEM=RARM[32][9:0];
assign A_MEM1=RARM[33][9:0];
assign clk_MARKER=((nWR_EN==0)&&(A==8'h02)&&(DIN!=8'h00))?1:0;
assign clk_nWR_MEM=({nWR_MEM,nWR_MEM_C}==2'b10)?1:0;
assign clk_nRD_MEM=({nRD_MEM,nRD_MEM_C}==2'b10)?1:0;


// Регистр RARM3 - вход HAL Freq Control
always @(posedge HFCC)
R3<={8'b0,HFCD};

always @(GCLK)
begin
// Маркер
if (clk_MARKER==1)
MARKER<=!MARKER;
// Локальные регистры
if (nWR_EN==0) //negedge nWR_EN
begin
RARM[A]<=DIN;
end
// Память обмена (запись)
if (nWR_MEM==0)
if (GCLK==0)
MEM[A_MEM] <=DIN[15:8];
else
MEM[A_MEM+1]<=DIN[7:0];
// Автоинкремент указателей
if (clk_nWR_MEM==1) //posedge nWR_MEM
RARM[32]<=A_MEM+2;
if (clk_nRD_MEM==1) //posedge nRD_MEM
RARM[33]<=A_MEM1+2;
nWR_MEM_C=nWR_MEM;
nRD_MEM_C=nRD_MEM;
end

assign DOUT=((CS5_MEM==0)?TOSHARE_D:((A==3)?R3:RARM[A]));

endmodule


Стал синтезироваться, но одна из проблем осталась:
прет ворнинг

@W: CL118 :"...\REG_ARM_DUAL_PORT.v":82:1:82:6|Latch generated from always block for signal MEM_1023_[7:0], probably caused by a missing assignment in an if or case stmt
@W: CL118 :"...\REG_ARM_DUAL_PORT.v":82:1:82:6|Latch generated from always block for signal MEM_1022_[7:0], probably caused by a missing assignment in an if or case stmt
...

и никак я не пойму, что Synplify из под меня хочет?
des00
Цитата(stalko @ Nov 29 2005, 03:30) *
и никак я не пойму, что Synplify из под меня хочет?


always @(POSEDGE GCLK)
Leka
always @(posedge GCLK)
begin
...
MEM[A_MEM+1]<=DIN[7:0];
...
end
always @(negedge GCLK)
MEM[A_MEM] <=DIN[15:8];

Хотя не рекомендуется использовать оба фронта глобального клока.
id_gene
Цитата
RARM[33]<=A_MEM1+2;
nWR_MEM_C=nWR_MEM;

и не смешивайте блокирующие и неблокирующие присвоения в одном always -блоке.
Используйте неблокирующие для триггеров @(posedge gclk) и блокирующие для комбинаторной логики @* .
lutik
у Synplify, по крайней мере до v7.7, всегда крыша ехала с упаковкой двухпортовой памяти.

на "родном" сайте есть очень занятный документ, который показывает как надыть писать код чтобы синтезатор его понял именно как дуал порт рам.

я на vhdl работаю, но точно помню что не смотря на все рекомендации и примеры от ментора или альдека или еще кого - пока не описал так как в этом документе - нихера не понимал синтезатор дуал порт.

я потому, помнится, и перешел на явное обьявление примитива что там очень неудобный код был.
stalko
Цитата(des00 @ Nov 29 2005, 11:47) *
Цитата(stalko @ Nov 29 2005, 03:30) *

и никак я не пойму, что Synplify из под меня хочет?


always @(POSEDGE GCLK)

а ему не по...? Хотя, всеравно не по... могает...

Цитата(Leka @ Nov 29 2005, 12:39) *
always @(posedge GCLK)
begin
...
MEM[A_MEM+1]<=DIN[7:0];
...
end
always @(negedge GCLK)
MEM[A_MEM] <=DIN[15:8];

Хотя не рекомендуется использовать оба фронта глобального клока.

Примерно так я уже попытался сделать в предыдущем примере.
А вот Ваш код синтезатор вряд ли проглотит: менять одну переменную в разных олвайзах для него кощунство.
Цитата(id_gene @ Nov 29 2005, 12:56) *
Цитата
RARM[33]<=A_MEM1+2;
nWR_MEM_C=nWR_MEM;

и не смешивайте блокирующие и неблокирующие присвоения в одном always -блоке.
Используйте неблокирующие для триггеров @(posedge gclk) и блокирующие для комбинаторной логики @* .

Вы все правильно говорите, если бы не одна деталь...
Если поставить nWR_MEM_C<=nWR_MEM;, то код просто работать не должен smile.gif
Цитата(lutik @ Nov 29 2005, 14:32) *
у Synplify, по крайней мере до v7.7, всегда крыша ехала с упаковкой двухпортовой памяти.

на "родном" сайте есть очень занятный документ, который показывает как надыть писать код чтобы синтезатор его понял именно как дуал порт рам.

я на vhdl работаю, но точно помню что не смотря на все рекомендации и примеры от ментора или альдека или еще кого - пока не описал так как в этом документе - нихера не понимал синтезатор дуал порт.

я потому, помнится, и перешел на явное обьявление примитива что там очень неудобный код был.

Вот и я сейчас не пожалел времени, сделал отдельный элемент RAM512X16D при этом, как видите, перейдя на 16-тибитную память, так получается лучше.

Тем не менее, в отношении RARM ворнинг остался.
des00
Цитата(stalko @ Nov 29 2005, 08:02) *
а ему не по...? Хотя, всеравно не по... могает...


он же вам черным по белому пишет что он сделал вместо тригеров ЗАЩЕЛКИ, такое возможно ТОЛЬКО в том случе если:
1. У вас не полный список чувствительности
2. У вас не указан используемый фронт сигнала (см. стандарт на верилог)
3. не расписанны все возможные альтернативы в АСИНХРННОМ процессе (о чем ИМХО и твердит вам симплифай и правильно делает)
stalko
Цитата(des00 @ Nov 29 2005, 16:46) *
он же вам черным по белому пишет что он сделал вместо тригеров ЗАЩЕЛКИ,

...это я, как раз, понял...
Цитата(des00 @ Nov 29 2005, 16:46) *
такое возможно ТОЛЬКО в том случе если:
1. У вас не полный список чувствительности

Признаю свое полное невежество, никогда не понимал, что подразумевается под "списком чувствительности".
Цитата(des00 @ Nov 29 2005, 16:46) *
2. У вас не указан используемый фронт сигнала (см. стандарт на верилог)

Получается, что тут тот самый случай. Но верилог разрешает использование обоих фронтов для запуска олвайза!! Или я не прав..?
Цитата(des00 @ Nov 29 2005, 16:46) *
3. не расписанны все возможные альтернативы в АСИНХРННОМ процессе (о чем ИМХО и твердит вам симплифай и правильно делает)

Ну, это, простите, детский сад, до такого я не опускаюсь... Хоть Вы и считате, что она мне об этом сейчас и говорит, я правильно понял?
Или Вы хотите сказать, что у меня окончательно стекла крыша, и always@(GCLK) указывает, что работать по уровню, а не по обоим фронтам? Ну, в таком случае, мне самому уже пора звонить на "скорую"... Либо, наконец, выбить хоть маленький, крохотный отпуск...
des00
Цитата(stalko @ Nov 29 2005, 09:04) *
Или Вы хотите сказать, что у меня окончательно стекла крыша, и always@(GCLK) указывает, что работать по уровню, а не по обоим фронтам? Ну, в таком случае, мне самому уже пора звонить на "скорую"... Либо, наконец, выбить хоть маленький, крохотный отпуск...


ИМХО always@(GCLK) по уровню smile.gif (сколько себя помню всегда так было),
а если по фронту то always@(posedge GCLK)
это не ВХДЛ,

насчет списка чувствительности, это из симуляторов, то что у казанно в алвейса и есть sensivity list, т.е. те сигнал по изменению которых запускаеться процесс
удачи
id_gene
Цитата
Но верилог разрешает использование обоих фронтов для запуска олвайза!! Или я не прав..?


верилог разрешает, а синтез - нет. Синтезируемое подмножество использует небольшое количество всех возможных конструкций.
В частности, always@(posedge clk) синтезируется в триггер.
always @ (clk) реагирует на уровень.

Насчет смешивания блокирующих/неблокирующих- это я поторопился. Для разных сигналов такое возможно. Только очень осторожно, и блокрирующие присвоения в триггерах не рекомендуются.
stalko
Цитата(des00 @ Nov 29 2005, 17:19) *
ИМХО always@(GCLK) по уровню smile.gif (сколько себя помню всегда так было),

Нафиг все, работа без выходных на голову таки воздействует!!
Покажу это сообщение начальнику, пусть в отпуск пускает.
Цитата(des00 @ Nov 29 2005, 17:19) *
а если по фронту то always@(posedge GCLK)
это не ВХДЛ,

это по ПЕРЕДНЕМУ фронту smile.gif . А мне хотелось бы по обоим, а Synplify конструкцию posedge GCLK or negedge GCLK не любит. sad.gif
Цитата(des00 @ Nov 29 2005, 17:19) *
насчет списка чувствительности, это из симуляторов, то что у казанно в алвейса и есть sensivity list, т.е. те сигнал по изменению которых запускаеться процесс удачи

Смысл простой... зато название какое!! biggrin.gif


Цитата(id_gene @ Nov 29 2005, 17:35) *
Насчет смешивания блокирующих/неблокирующих- это я поторопился. Для разных сигналов такое возможно. Только очень осторожно, и блокрирующие присвоения в триггерах не рекомендуются.

Смешать разные присвоения не даст синтезатор и тут он прав, он вообще не любит смешения синхронности и асинхронности.
Дело в том, что в том случае мы проверяем {A,A_C}, а потом делаем A_C=A;
Если мы запишем A_C<=A, то они уже на момент проверки будут равны. Значит, либо нужно унести присвоение в границы результата проверки, что в данном случае некоректно, либо ставить небокирующие.
Поправьте меня, если я заблуждаюсь.

P.S. Сказал про ассинхронность, и вспомнил: как-то он нефиг делать попробовал сделать RS-триггер с помощью assign-ов, только на wire-ах. И ведь получилось!! smile.gif
andrew_b
Цитата(stalko @ Nov 29 2005, 22:21) *
Цитата(des00 @ Nov 29 2005, 17:19) *

а если по фронту то always@(posedge GCLK)
это не ВХДЛ,

это по ПЕРЕДНЕМУ фронту smile.gif . А мне хотелось бы по обоим, а Synplify конструкцию posedge GCLK or negedge GCLK не любит. sad.gif

Вы в праве хотеть все, что угодно. Однако ваше желание упирается в возможности FPGA. Как вы себе представляете реализацию
Код
always (GCLK)
       if (GCLK == 0)
          MEM[A_MEM] <= DIN[15:8];
       else
          MEM[A_MEM+1]<= DIN[7:0];

Память не работает по двум фронтам.
dxp
Цитата(des00 @ Nov 29 2005, 20:19) *
Цитата(stalko @ Nov 29 2005, 09:04) *

Или Вы хотите сказать, что у меня окончательно стекла крыша, и always@(GCLK) указывает, что работать по уровню, а не по обоим фронтам? Ну, в таком случае, мне самому уже пора звонить на "скорую"... Либо, наконец, выбить хоть маленький, крохотный отпуск...


ИМХО always@(GCLK) по уровню smile.gif (сколько себя помню всегда так было),
а если по фронту то always@(posedge GCLK)
это не ВХДЛ,

always@(GCLK) - это по любому событию. По факту это соответствует комбинационной логике.

Цитата(des00 @ Nov 29 2005, 20:19) *
насчет списка чувствительности, это из симуляторов, то что у казанно в алвейса и есть sensivity list, т.е. те сигнал по изменению которых запускаеться процесс

В Верилог-2001 задавать список для комбинационных схем не требуется, можно просто писать always @(*) или always @*. Компилятор дальше сам разберется, что к чему исходя из контекста описания тела блока.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.