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

параметризация условия if

есть такая задачка:

есть N входных и N выходных портов, пришедшую на любой порт часть первого слова надо запомнить как адрес(номер) выходного порта и все приходящие в этот порт далее слова отправлять по запомненному адресу, до неважно какого события. При этом нужно удостовериться что выходной порт свободен(!), те по такому адресу не идет отправки ни из одного входного порта(если идет то подождать)

Соответственно все порты должны работать независимо, те если из 1го порта что-то отсылается в 2й, то это не должно влиять на отправку допустим из 3го в 4й. Такой вот прототип роутера.

Количество портов должно задаваться через параметр N.

Не могу понять как мне параметризовать сравнение одного защелкнутого адреса со всеми другими, чтобы исключить совпадения?

 

reg [8:0] data_in_r [N-1:0];

reg [8:0] data_out [N-1:0];

reg [4:0] adr_reg [N-1:0];

 

always @(posedge clk or posedge reset)

begin

for (i=0; i<N; i=i+1)

begin

if (reset) begin

..;

end

else

 

begin

 

if(слово первое)

adr_reg <= #T data_in_r ;

else

 

for (k=0; k<N; k=k+1)

begin

if (adr_reg== k ) // выбираем номер выходного порта

if (adr_reg != ???) // вот здесь надо как-то сравнить адрес со всеми остальными(!)

 

data_out[k] <= #T data_in_r ;

 

end

end

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


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

Приветствую!

 

Заведите регистр занятых выходных каналов

 

reg [N-1:0] rOutBusy;

 

соответсвующий бит которого устанавливается в 1 если выходной порт занят.

тогда проверка

 

if (rOutBusy[adr_reg] ==0 ) //выход свободен

...

 

Вобще при этом еще надо предусматривать возможность одновременного запроса одного выхода двумя и более входами.

 

Успехов! Rob.

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


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

соответственно возможность одновременного запроса можно предусмотреть только последовательно перебирая входы??

или есть какой-то еще способ?

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


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

или есть какой-то еще способ?

Одним циклом for можно описать комбинационную логику приоритезации - и при наличии 2 одновременных запросов всегда обрабатываться будет только пришедший по каналу с большим (или меньшим - как опишете) номером.

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


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

если не затруднит можно пример?

 

 

пользуйтесь поиском

 

http://electronix.ru/forum/index.php?showt...mp;#entry348464

 

Удачи !!!

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


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

Используем вышеупомянутый rOutBusy, считаем, что функция clog2 вернёт необходимый (старший индекс+1) для хранения (числа-1). Напр. clog2(16) = 4, clog2 (17) = 5).

 reg [8:0] data_in_r [N-1:0];
integer i, j;
lovcalparam W = clog2(N);
reg [N-1:0] asking [W-1:0]  //Номер канала, с которого запрашивается данный; напр. 
reg ifAsking [N-1:0]  //Признак того, что канал запрашивается
always @ (*)
  for (i = N; i > 0; i = i-1) begin
    ifAsking[i] = 1'b0;
    asking[i] = 1'b0; //Или 1'bx - в смысле don't care.
    if (~rOutBusy[i] && какие-ещё-условия-возможности-занятия-общие-для-номера-запрашиваемого)
      for (j = N; j > 0; j = j-1) //Направление счёта в этом цикле и определит приоритет; сейчас - у МЛАДЩИХ, т. е. если s-ый запросят одновременно t-ый и t+3-ый, то доступ получит t-ый
      if (i == data_in_r[W-1:0] && какие-ещё-условия-для-пары-"запрашивающий-запрашиваемый") begin
        ifAsking[i] = 1'b1;
        asking[i] = j; //Можно поколдовать с дополнительной переменной типа reg[] или с индексацией, чтоб не появлялось предупреждение о потере разрядности.
   end
  end

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

При большом числе каналов синтезируется в немаленький куст логики.

Что дальше делать с полученными (комбинационными) значениями asking (номера) и ifAsking (флаги запросов), решайте сами.

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


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

спасибо, разобрался

приведу код который получился, все по сути тоже самое, но есть одна вещь с которой не разобрался - когда во внутреннем цикле j=0 условие * не срабатывает и ifAsking[j], asking[j] не поднимаются кроме как когда i=0?..

те ситуация что на 0й выход не обратиться ни с какого входа кроме как с нулевого.

 

+ добавил вектор выбранных входов - ничего умнее не придумал как после прохождения всего большого цикла i==0 проверить состояние вектора ifAsking и далее вытащить из asking[k] номера задействованных входов...мб можно проще?

 

always @(*)

begin

for (i = N-1; i >= 0; i = i-1) begin

if (reset)

begin

ifAsking = 1'b0;

asking = 5'd0;

ifSelected= 1'b0; //вектор выбранных входов

end

else

begin

ifAsking = 1'b0;

asking = 5'd0;

ifSelected= 1'b0;

if (~rOutBusy & adr_set )

begin

for (j = N-1; j>=0; j = j-1)

begin

if (j == adr_reg) //*

begin

ifAsking[j] = 1'b1;

asking[j] = i;

 

end

end

if(i==0) //

for(k=N-1;k>=0; k= k-1)

if (ifAsking[k])

ifSelected[asking[k]]= 1'b1;

end

end

end

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


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

0) Пожалуйста, оформляйте код как код - иначе отступы отображаются только при цитировании.

1) Поразили строчки

ifAsking[j] = 1'b1;
asking[j] = i

(Сейчас понял - да, наверное было правильней назвать isAsked и ifIsAsked...)

по-моему, мы друг друга не совсем поняли; в моём примере i - абстрактный номер канала, на который в настоящий момент (точнее - в текущей части конструкции, так как работает всё, естественно, параллельно) производится проверка "не запросил ли кто его?", а j - номер канала, запрос с которого анализируется в текущий (опять-таки, условно, см. предыдущее замечание) момент. ifAsking - признак того, что канал кем-то запрашиваетСЯ (значение этого регистра, отфильтрованное условиями, аккумулируется в rOutBusy, если так понятнее).

Тогда мой вариант

asking[i] = j;

работал так: допустим, тестируется (i) номер 5 и обнаруживается в канале (j) номер 7. Тогда, если он не занят, он занимается, устанавливается единица в ifAsking[5] - "канал 5 кому-то нужен" и в asking[5] помещается 111b (=7) - "а конкретно - нужен седьмому".

С учётом вышеизложенного, ИМХО, одна из 3 переменных и один цикл у Вас лишние.

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


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

i - абстрактный номер канала, на который в настоящий момент (точнее - в текущей части конструкции, так как работает всё, естественно, параллельно) производится проверка "не запросил ли кто его?", а j - номер канала, запрос с которого анализируется в текущий (опять-таки, условно, см. предыдущее замечание) момент.

 

в моем примере почти тоже самое но i- номер входа, а j- номер выхода:

во внешнем цикле я перебираю входы и если адрес на входе совпадает со значением j, то

 ifAsking[j] = 1'b1;
asking[j] = i;

соответственно в asking[j] будут сохраняться номера входов запрашивающих j-й выход

ifAsking[j] защелкиваем в регистр rOutBusy

сейчас заметил в примере ошибку - проверку на ~rOutBusy надо перенести во внутренний цикл и сделать ее по j.

 

А что касается 3го цикла - логично защелкнуть в отдельный регистр номера выбранных входов, иначе как их использовать из массива векторов? передатчикам надо указать что их выбрали и можно гнать данные. Ничего умнее не придумал как после завершения формирования массива asking выбрать оттуда задействованные входы.

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


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

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

приведу итоговый код переключающей матрицы роутера:

//priority
always @(rOutBusy or adr_set  or  adr_reg[1]or adr_reg[2]or adr_reg[3]or adr_reg[4]or adr_reg[5] )
begin
for (i = N; i >= 0; i = i-1) begin              
       
      if ( adr_set [i])  //сигнал из регистра информирующий о том что по i-му входу выставлен адрес.
       
      begin
      for (j = N; j>=0; j = j-1)
         begin
           
           
            asking[j] = 5'd0;   // матрица, связывающая выходы и входы (*)
            ifAsking[j] = 1'b0; //сигналы запроса выходов (*)

            begin
              if ((j == adr_reg[i]) & (~rOutBusy[j]))
               
                
               begin
               ifAsking[j] = 1'b1;
               asking[j] = i;     
               end
            end 
            
                        
                       
           
         end   
       end
      
       
     
      if(i==1)
       for(k=N;k>-1; k= k-1)
         begin
          ifSelected[k]= 1'b0; 
         if  (ifAsking[k]==1'b1 )  
         begin
          ifSelected[asking[k]]= 1'b1;   
        end
         end
      
      
           

end
end

 

 

 

 

и вкратце глубокую мысль этого модуля-роутера:

есть i входов и j выходов, во внешнем цикле берем i-ый вход и если на нем выставлен адрес adr_set ищем в j-м цикле какому выходу соответствует этот адрес. После прохождения полностью 2х циклов в

asking[j] будут находится номера всех запрашивающих выходы входов

ifAsking[j] вектор запрашиваемых выходов

 

3й цикл служит для извлечения из матрицы asking вектора входов ifSelected, выбранных для передачи.

Далее эти комбинаторные сигналы защелкиваются в регистры (в частности ifAsking[j] защелкивается в rOutBusy[j])

 

Если не вводить обнуление сигналов(*), то синтезируются латчи и меня в этом случае это не устраивает, если его вводить, то по непонятной мне причине после прохождения обоих циклов то в сигналах ifAsking[j] и asking[j] после прохождения циклов сохраняется только одно значение(роутится один вход на один выход, при наличии нескольких установленных адресов и соответствующих им выходов), те не работает параллельно..(по крайней мере в моем симуляторе ModelSim 6.0c)

Может быть есть предположения почему??

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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