Перейти к содержанию
    

Проблема с синтезом. Память под Synplify 8.2.1

Уже крыша едет!!

В двух словах: есть набор регистров 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 ни при чем.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

я с Simplify не работал но попробуйте расставить begin и end, где это нужно, компилятор похоже с ума сходит. Было такое в ISE, после того как, расставил все заработало.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

я с Simplify не работал но попробуйте расставить begin и end, где это нужно, компилятор похоже с ума сходит. Было такое в ISE, после того как, расставил все заработало.

Попробую, чем черт не шутит...

{MEM[A_MEM],MEM[A_MEM+1]}=DIN - тоже не радует.

Самого не радует, но это можно разбить

MEM[A_MEM]=DIN[15:8];

MEM[A_MEM+1]=DIN[7:0];

В модуле always@(posedge GCLK) куча "=" - это неправильно.

А вот как обойти это?

ну,

if (nWR_MEM==0)

{MEM[A_MEM],MEM[A_MEM+1]}=DIN;

можно отнести в отдельный always @(GCLK)

а все остальное нельзя: тогда изменение одних регистров окажется в разных олвайзах, чего синтезаторы просто не переваривают... Я, конечно, бывало, изголялся... но сейчас не хочется...

В модуле always@(posedge GCLK) куча "=" - это неправильно.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

всё запихать в один большой олвайз желательно примерно так (логику не проверял):

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

MEM[A_MEM]=DIN[15:8]; MEM[A_MEM+1]=DIN[7:0];

Это дела не меняет - надо отдельным модулем явно описать, как в память записываются 2 байта. ИМХО.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В соответствии с советами и собственным домыслием изменил код так:

`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 из под меня хочет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

always @(POSEDGE GCLK)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

always @(posedge GCLK)

begin

...

MEM[A_MEM+1]<=DIN[7:0];

...

end

always @(negedge GCLK)

MEM[A_MEM] <=DIN[15:8];

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

RARM[33]<=A_MEM1+2;

nWR_MEM_C=nWR_MEM;

и не смешивайте блокирующие и неблокирующие присвоения в одном always -блоке.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

у Synplify, по крайней мере до v7.7, всегда крыша ехала с упаковкой двухпортовой памяти.

 

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

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

always @(POSEDGE GCLK)

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

 

always @(posedge GCLK)

begin

...

MEM[A_MEM+1]<=DIN[7:0];

...

end

always @(negedge GCLK)

MEM[A_MEM] <=DIN[15:8];

 

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

Примерно так я уже попытался сделать в предыдущем примере.

А вот Ваш код синтезатор вряд ли проглотит: менять одну переменную в разных олвайзах для него кощунство.

RARM[33]<=A_MEM1+2;

nWR_MEM_C=nWR_MEM;

и не смешивайте блокирующие и неблокирующие присвоения в одном always -блоке.

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

Вы все правильно говорите, если бы не одна деталь...

Если поставить nWR_MEM_C<=nWR_MEM;, то код просто работать не должен :)

у Synplify, по крайней мере до v7.7, всегда крыша ехала с упаковкой двухпортовой памяти.

 

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

 

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

 

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

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

 

Тем не менее, в отношении RARM ворнинг остался.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

он же вам черным по белому пишет что он сделал вместо тригеров ЗАЩЕЛКИ, такое возможно ТОЛЬКО в том случе если:

1. У вас не полный список чувствительности

2. У вас не указан используемый фронт сигнала (см. стандарт на верилог)

3. не расписанны все возможные альтернативы в АСИНХРННОМ процессе (о чем ИМХО и твердит вам симплифай и правильно делает)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

он же вам черным по белому пишет что он сделал вместо тригеров ЗАЩЕЛКИ,

...это я, как раз, понял...

такое возможно ТОЛЬКО в том случе если:

1. У вас не полный список чувствительности

Признаю свое полное невежество, никогда не понимал, что подразумевается под "списком чувствительности".

2. У вас не указан используемый фронт сигнала (см. стандарт на верилог)

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

3. не расписанны все возможные альтернативы в АСИНХРННОМ процессе (о чем ИМХО и твердит вам симплифай и правильно делает)

Ну, это, простите, детский сад, до такого я не опускаюсь... Хоть Вы и считате, что она мне об этом сейчас и говорит, я правильно понял?

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

ИМХО always@(GCLK) по уровню :) (сколько себя помню всегда так было),

а если по фронту то always@(posedge GCLK)

это не ВХДЛ,

 

насчет списка чувствительности, это из симуляторов, то что у казанно в алвейса и есть sensivity list, т.е. те сигнал по изменению которых запускаеться процесс

удачи

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...