|
mt32 под EP3C25 не работает в режиме Burst, Проблема организации пакетного режима |
|
|
|
Jun 19 2012, 13:25
|
Участник

Группа: Участник
Сообщений: 49
Регистрация: 28-03-12
Из: Санкт-Петербург
Пользователь №: 71 050

|
Здравствуйте
У меня такая проблема: Сделал программу на Verilog, которая принимает данные из вне, а потом перекидывает их на сторону PCI(работал, как таргет, считывали с меня по прерыванию)... но такой вариант был слишком затратен по времени, т.к. верхнее ПО было написано под Linux, а сам чипсет компа не давал возможности с меня считывать пакетно... что только не пробовал, ничего не выходило, прочитал на форуме ELECTRONIX, подсказали, что придется реализовывать мастера...
Так вот поставил mt32 core для Альтеры с возможностью работы в режиме 66Мгц...
Прога под Linux пока не подправлена, но я попробовал выходить на шину мастером и писать данные в меня... я увидел, что я пишу так же, т.е. одиночными посылками, а не пакетно....
Вопрос: что необходимо указать в установках core(я пробовал менять конфигурацию баров с non - prefetchable на prefetchable), либо как организовывать обмен по PCI так, чтобы я работал в пакетном режиме???
Спасибо...
|
|
|
|
|
Jun 20 2012, 05:30
|
Знающий
   
Группа: Свой
Сообщений: 721
Регистрация: 23-10-08
Из: next to Odessa
Пользователь №: 41 112

|
Цитата(xxxmatrixxx @ Jun 19 2012, 16:25)  ...я увидел, что я пишу так же, т.е. одиночными посылками, а не пакетно.... Похоже, что Ваш FSM не верно обслуживает mt32 с локальной стороны. Чтобы разобраться, выложите *.pdf PCI Megacore с которым работаете (их много), и ссылку на страницу и диаграмму. А также кратко, что выдается с локальной стороны в mt32 и что по диаграмме не так получается. Есть еще и SignalTap II Logic Analyzer, который всегда поможет разобраться, покажите и его диаграммы. Какой QII применяете?
|
|
|
|
|
Jun 21 2012, 05:53
|
Участник

Группа: Участник
Сообщений: 49
Регистрация: 28-03-12
Из: Санкт-Петербург
Пользователь №: 71 050

|
Цитата(Serhiy_UA @ Jun 20 2012, 09:30)  Похоже, что Ваш FSM не верно обслуживает mt32 с локальной стороны. Чтобы разобраться, выложите *.pdf PCI Megacore с которым работаете (их много), и ссылку на страницу и диаграмму. А также кратко, что выдается с локальной стороны в mt32 и что по диаграмме не так получается. Есть еще и SignalTap II Logic Analyzer, который всегда поможет разобраться, покажите и его диаграммы. Какой QII применяете? Спасибо, что откликнулись))) Применяю Quartus 9.1 Описание Core и диаграммы с SignalTab тоже выложил... не смотрите на сигналы lt_ackn и lt_dxfrn, похоже неправильно нарисовал сигналтаб, т.к. lt_rdyn выставляется на них... Адрес БАР0 именно 0xF8F0_0000 // выставление готовности при совпадении бар0 always @(posedge ClkPCI or negedge Reset) begin if(Reset == 0) ltrdyn <= 1; else ltrdyn <= !(( bar0_hit) & cycle_start ); end ////////////// выставление с локальной стороны lt_framen //////////// reg lt_framen_q; always @ (posedge ClkPCI or negedge Reset) begin if (!Reset) lt_framen_q <= 1'b1; else lt_framen_q <= !lt_framen; end ////////////////////////////////////////////////////////////////////////////// //установившийся сигнал обмена wire cycle_start = (lt_framen_q & !lt_framen); wire bar0_hit = lt_tsr[0]; // отслеживаем бит 0 // сигнал ответа готовности к обмену reg ltrdyn; assign lt_rdyn = ltrdyn;
Эскизы прикрепленных изображений
Прикрепленные файлы
ug_pci.zip ( 1.51 мегабайт )
Кол-во скачиваний: 28
|
|
|
|
|
Jun 22 2012, 06:12
|
Участник

Группа: Участник
Сообщений: 49
Регистрация: 28-03-12
Из: Санкт-Петербург
Пользователь №: 71 050

|
Цитата(Serhiy_UA @ Jun 21 2012, 13:10)  lm_tsr[9..0] от SignalTap показывает, что что-то не так...
Однако, этого не достаточно: wire bar0_hit = lt_tsr[0]; // отслеживаем бит 0
Повторюсь "...и ссылку на страницу и диаграмму", с которой работаете... стр 188 данного руководства... насчет выставления lt_rdyn вы правы... я принимаю данные на чтение или запись вот так // запись wire wrFromPci = (!lt_dxfrn & (l_cmdo[3:0] == 4'h7) & bar0_hit); // запись информации //чтение служебной информации wire rdWorkInf = (!lt_ackn & (l_cmdo[3:0] == 4'h6) & bar1_hit); //чтение служебной инфы похоже кора просто не выставляет сигналы lt_dxfrn и lt_ackn... надо будет разбираться почему...
|
|
|
|
|
Jun 28 2012, 12:23
|
Участник

Группа: Участник
Сообщений: 49
Регистрация: 28-03-12
Из: Санкт-Петербург
Пользователь №: 71 050

|
Цитата(Serhiy_UA @ Jun 22 2012, 13:08)  на стр.188 (Burst Memory Write) нет сигналов l_cmdo[3:0]. Возможно, надо привязаться к чему-то другому... например, l_cbeni[3..0]... l_cbeni[3..0] - сигналы выдачи команды с локальной стороны во время фазы адреса, а так же признаки разрешения байтов во время чтения/записи по PCI, т.е. это входной сигнал с локальной стороны PCIcore... Изучая этут тему и когда с отпуска вернулся программист под Linux обнаружились следующие результаты... Когда я выхожу как мастер на шину и пишу в себя.... Здесь моя таргет сторона выставляет сигнал STOP и прекращает обмен, хотя по статусу видно, что мастер ведет именно мультизапись(статусный регистр lt_tsr[9] = 1)... после более подробного изучения спецификации и документации на шину PCI, выяснил, что если мастер ведет обмен с мультизаписью или мультичтением, а устройство, с которым оно связывается не поддерживает мультизапись (мультичтение), то это устройство выставляет сигнал STOP для окончания транзакции... т.е. вынужденно передается все по одному слову.... Вопрос: получается, что сторона target в megacore вообще не поддерживает мультизапись или мультичтение, либо это результат того, что я пишу сам в себя, либо в настройках не так что-то ставлю(выделяю 2 бар prefecheable) Сейчас обмен между мною и ПК осуществляется следующим образом: в момент инициализации(вкл модуля) ПК пишет в меня физический адрес памяти на шине PCI, который выделяет в процессе загрузки драйвера под Linux... при обращении к ней все виснет))) выяснилось, что я выставляю адрес на шину, а затем пытаюсь передать данные... причем ответа от устройства я не могу дождаться(сигнал trdy висит в 1), но и сигналы Framen и Irdy висят в 0, т.е. я занимаю шину PCI постоянно, поэтому виснет вся система..... Вопрос: как необходимо вести обмен между мною и ПК? какой адрес памяти ПК, выделенный для меня, должен передаваться мне(просто там 64 бита, а мне передается старшая часть 64го слова) Может у кого-нибудь есть опыт по разработке мастера для реализации мультизаписи??? 1я картинка(слева направо) попытка обмена с ПК, после чего все виснет)))) 2я картинка работа меня, как мастера, и запись в меня, кстати, комп при этом не виснет...
Сообщение отредактировал xxxmatrixxx - Jun 28 2012, 12:27
Эскизы прикрепленных изображений
|
|
|
|
|
Jun 29 2012, 08:35
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата Вопрос: как необходимо вести обмен между мною и ПК? какой адрес памяти ПК, выделенный для меня, должен передаваться мне(просто там 64 бита, а мне передается старшая часть 64го слова) Если там 64 бита, то вы и должны передавать 64 бита. Т.е. у вас должна быть PCI64. Если же у вас PCI32, то со стороны Linux'а вы должны заказывать себе буфер для обмена в нижней части памяти (в 32х битах) Скажите своему програмисту, что бы позвал pci_set_dma_mask(pdev, DMA_32BIT_MASK) перед pci_alloc_consistent Отдавать на плату нужно будет младшую часть 64х битного адреса (от pci_alloc_consistent)
|
|
|
|
|
Jul 4 2012, 09:11
|
Участник

Группа: Участник
Сообщений: 49
Регистрация: 28-03-12
Из: Санкт-Петербург
Пользователь №: 71 050

|
Цитата(XVR @ Jun 29 2012, 12:35)  Если там 64 бита, то вы и должны передавать 64 бита. Т.е. у вас должна быть PCI64. Если же у вас PCI32, то со стороны Linux'а вы должны заказывать себе буфер для обмена в нижней части памяти (в 32х битах)
Скажите своему програмисту, что бы позвал pci_set_dma_mask(pdev, DMA_32BIT_MASK) перед pci_alloc_consistent Отдавать на плату нужно будет младшую часть 64х битного адреса (от pci_alloc_consistent) Спасибо, за помощь, но такой вариант так же не помог... Может у кого-нибудь есть проект под Q9.1 для реализации мастера для записи от меня во внешнее устройство по шине PCI, если можно код, как конкретно и когда выставляете сигналы... Просто ситуация для меня совсем не понятная, по экспериментам получается, что PCIcore работает нормально, когда я обращаюсь сам на себя, т.е. выхожу мастером и пишу по адресу, который соответствует моему Bar0, но в данной ситуации обнаруживается мультизапись, но PCIcore останавливает обмен сама... т.е. заставлят работать не в мультизаписи, а одиночными записями... Когда пишу в память ПК, выделенную программистом под Linux, все виснет... причем я не понимаю, почему сигналы framen и irdy остаются постоянно в активном уровне(фиически 0) и не реагирует на сигналы с локальной стороны(lm_last - по утому сигналу должен заершаться обмен(framen должен выстависться физически в 1), lm_rdyn - сигнал готовности с моей стороны, который управляет сигналом irdy на шине PCI ), хотя по стандарту обмена по шине PCI я должен ждать сигнал trdy максимум 4 такта после выставления irdy c моей стороны(кстати, по этим тактам определяем насколько быстрое устройство)... Вот код, который управляет стороной мастера и таргета с моей стороны, может идеи будут, я очень буду рад любым... CODE //==========================================================================
////////////// выставление с локальной стороны lt_framen //////////// reg lt_framen_q; always @ (posedge ClkPCI or negedge Reset) begin if (!Reset) lt_framen_q <= 1'b1; else lt_framen_q <= !lt_framen; end ////////////////////////////////////////////////////////////////////////////// //установившийся сигнал обмена wire cycle_start = (lt_framen_q & !lt_framen); wire bar0_hit = lt_tsr[0]; // отслеживаем бит 0 wire bar1_hit = lt_tsr[1]; // отслеживаем бит 1 // сигнал ответа готовности к обмену reg ltrdyn; assign lt_rdyn = ltrdyn; // выставление готовности при совпадении бар0 и always @(posedge ClkPCI or negedge Reset) begin if(Reset == 0) ltrdyn <= 1; else ltrdyn <= !(( bar0_hit | bar1_hit) & cycle_start ); end //reg ltdiscn; assign lt_discn = 1'b1;//ltdiscn;
wire [31:0] WorkDataForPCI; wire [31:0] DataForPCI; reg [31:0] SumOfCountForPCI;
// запись wire wrFromPci = (!lt_dxfrn & (l_cmdo[3:0] == 4'h7) & bar0_hit); // запись информации //чтение служебной информации wire rdWorkInf = (!lt_ackn & (l_cmdo[3:0] == 4'h6) & bar1_hit); //чтение служебной инфы //прерывание reg set_irq; // регистр отвечающий за выставление прерывания assign lirqn = !set_irq;//выставляем прерывание
reg [11:0] CountOfData; reg [11:0] CountOfWorkData;
wire DataWrfull; wire DataRdempty; wire WorkDataWrfull; wire WorkDataDataRdempty; //Очередь для данных, считанных с шины Е, для записи по шине PCI //Очередь для данных, считанных с шины Е, для записи по шине PCI dcfifo FifoData( .wrclk (Clk50), .rdreq (rdreqFifoData), .aclr (~Res), .rdclk (ClkPCI), .wrreq (SI_EN), .data (data), .rdempty (DataRdempty), .wrfull (DataWrfull), .wrusedw (CountOfData), .q (DataForPCI) // synopsys translate_off , .rdfull (), .rdusedw (), .wrempty () // synopsys translate_on ); defparam FifoData.intended_device_family = "Cyclone III", FifoData.lpm_numwords = 4096, FifoData.lpm_showahead = "ON", FifoData.lpm_type = "dcfifo", FifoData.lpm_width = 32, FifoData.lpm_widthu = 12, FifoData.overflow_checking = "ON", FifoData.rdsync_delaypipe = 4, FifoData.underflow_checking = "ON", FifoData.use_eab = "ON", FifoData.write_aclr_synch = "OFF", FifoData.wrsync_delaypipe = 4; //Очередь для чтения на шину PCI и записи с шины МПИ dcfifo FifoWorkData ( .wrclk (Clk50),//+ .rdreq (rdreqFifoWorkData),//+ .aclr (~Res),//+ .rdclk (ClkPCI),//со стороны мпи .wrreq (fldone_en), //+ .data (workdata),//+ .rdempty (WorkDataDataRdempty), .wrfull (WorkDataWrfull), .wrusedw (CountOfWorkData), .q (WorkDataForPCI)//+ // synopsys translate_off , .rdfull (), .rdusedw (), .wrempty () // synopsys translate_on ); defparam FifoWorkData.intended_device_family = "Cyclone III", FifoWorkData.lpm_numwords = 4096, FifoWorkData.lpm_showahead = "ON", FifoWorkData.lpm_type = "dcfifo", FifoWorkData.lpm_width = 32, FifoWorkData.lpm_widthu = 12, FifoWorkData.overflow_checking = "ON", FifoWorkData.rdsync_delaypipe = 4, FifoWorkData.underflow_checking = "ON", FifoWorkData.use_eab = "ON", FifoWorkData.write_aclr_synch = "OFF", FifoWorkData.wrsync_delaypipe = 4;
//---------------------------------------------------- reg ResetFromPci; reg InitFromPci; wire Res; //общий сброс assign Res = Reset & ResetFromPci & InitFromPci;
localparam ns40 = 2'h2; reg [1:0] kk; // генерация внутреннего сброса при приеме соответствующего пакета по PCI always @(posedge ClkPCI or negedge Reset) begin if (Reset == 0) ResetFromPci <= 1; else if(wrFromPci && l_dato[15:0] == 16'hE00F) ResetFromPci <= 0; else if(kk == ns40) ResetFromPci <= 1; end
always @(posedge Clk50 or negedge Reset) begin if (Reset == 0) kk <= 0; else if(ResetFromPci == 0) kk <= kk + 1'b1; else kk <= 0; end ///---------------------------------------------------
//отключение и включение модуля always @(posedge ClkPCI or negedge Reset) begin if (Reset == 0) InitFromPci <= 0; else if(wrFromPci && l_dato[15:0] == 16'hE000) InitFromPci <= 0; else if(wrFromPci && l_dato[15:0] == 16'hE001) InitFromPci <= 1; end
//----------------------------------------------------- reg set_irq_clear; // флаг снятия прерывания со стороны PCI //снятие прерывания always @(posedge ClkPCI or negedge Reset) begin if (Reset == 0) set_irq_clear <= 0; else if(wrFromPci && l_dato[15:0] == 16'hE00C) //если производится запись с PCI set_irq_clear <= 1; else if(set_irq == 0) set_irq_clear <= 0; end
reg mode_r; //выбор режима //0 - прерывание выставляется при окончании одиночной пачки //1 - при достижении очереди > 4000 отсчетов(т.е. зафиксировали, дождались конца всей пачки, выдали прерывание) always @(posedge ClkPCI or negedge Reset) begin if (Reset == 0) mode_r <= 0; else if(wrFromPci && l_dato[15:0] == 16'hE00E) if (l_dato[31:16] == 16'h0000) mode_r <= 0; else mode_r <= 1; end
//регистр статуса reg [31:0] RegStatus; always @(posedge ClkPCI or negedge Res) begin if (Res == 0) RegStatus <= 32'hF0F0_0F00; else begin RegStatus[0] <= set_irq; // прерывание end end
//формирование служебных пакетов на сторону PCI reg [31:0] WorkInf; always @(posedge ClkPCI or negedge Res) begin if (Res == 0) WorkInf <= 32'h0000_0000; else if(rdWorkInf) case (l_adro[15:0]) 16'h0000: WorkInf <= CountOfData; 16'h0004: WorkInf <= CountOfWorkData; 16'h0030: WorkInf <= RegStatus; 16'h0034: WorkInf <= ver; 16'h0038: WorkInf <= date; endcase end
//сигнал разрешения записи по PCI со стороны мастера wire EnableWritePCIMaster = WriteEnableFromE & EnableMaster;
// разрешение записи на стороне PCI reg EnableMaster; always @(posedge ClkPCI or negedge Res) begin if(Res == 0) EnableMaster <= 1'b1; else if(set_irq_posedge == 1) EnableMaster <= 1'b0; //выставили прерывание else if(wrFromPci && l_dato[15:0] == 16'hE00D) EnableMaster <= 1'b1; //получили команду на разрешение работы как мастера end
//фиксируем перепад для выставления прерывания wire set_irq_posedge = set_irq & ! set_irqN;
reg set_irqN; always @(posedge Clk50 or negedge Res) begin if(Res == 0) set_irqN <= 1'b0; else set_irqN <= set_irq; end
//выставление прерывания always @(posedge Clk50 or negedge Res) begin if(Res == 0) set_irq <= 1'b0; else if(StatePCI == 6) set_irq <= 1'b1; else if(set_irq_clear == 1) set_irq <= 1'b0; end //общее количество отсчетов в очередях always @(posedge Clk50 or negedge Res) begin if(Res == 0) SumOfCount <= 32'h0000_0000; else if(fldone_en_2T_negedge) SumOfCount <= CountOfData + CountOfWorkData; end
//ресинхронизируем для шины PCI количества сформированных пачек always @(posedge ClkPCI or negedge Res) begin if (Res == 0) SumOfCountForPCI <= 32'h0000_0000; else SumOfCountForPCI <= SumOfCount; end
//*****************************____PCI_MASTER____********************************* * //промежуточные регистры для передачи данных reg [31:0] localMaxSumOfCount;// количество передаваемых на шину PCI отсчетов за одну транзакцию reg [31:0] localIndexSumOfCounting; // текущий индекс отсчетов относительно пачек reg [31:0] localMaxCounting; // количество отсчетов в текущей пачке reg [31:0] CurrentIndexOfCounting; // текущий индекс отсчета в пачке
//сигналы разрешения выталкивания отсчетов из очередей reg rdreqFifoWorkData; reg rdreqFifoData; reg rdrFifoWorkData; // промежуточный сигнал для машины автомата
//присвоение текущего количества отсчетов за транзакцию always @(posedge ClkPCI or negedge Res) begin if(Res == 0) localMaxSumOfCount <= 32'h0000_0000; else if(StatePCI_Wr == 4 && StatePCI == 0) localMaxSumOfCount <= SumOfCountForPCI; end
//отслеживание текущего индекса внутри пачки always @(posedge ClkPCI or negedge Res) begin if(Res == 0) localIndexSumOfCounting <= 32'h0000_0000; else if(StatePCI == 3) localIndexSumOfCounting <= localIndexSumOfCounting + WorkDataForPCI + 4; else if(StatePCI == 6) localIndexSumOfCounting <= 32'h0000_0000; end
//отслеживание текущего индекса внутри пачки always @(posedge ClkPCI or negedge Res) begin if(Res == 0) localMaxCounting <= 32'h0000_0000; else if(StatePCI == 3) localMaxCounting <= WorkDataForPCI; end
//импульс выталкивания из очереди, где данные always @(posedge ClkPCI or negedge Res) begin if(Res == 0) rdreqFifoData <= 0; else if(StatePCI == 4 && CurrentIndexOfCounting >= localMaxCounting) rdreqFifoData <= 0; else if(StatePCI == 4 || StatePCI == 5/*&& lm_ackn == 0*/ ) rdreqFifoData <= 1; else rdreqFifoData <= 0; end
//отслеживание текущего индекса отсчетов относительно пачек always @(posedge ClkPCI or negedge Res) begin if(Res == 0) CurrentIndexOfCounting <= 32'h0000_0000; else if(StatePCI != 4 /* && lm_ackn == 0*/) CurrentIndexOfCounting <= 32'h0000_0001; else CurrentIndexOfCounting <= CurrentIndexOfCounting + 1'b1; end
//сигнал выталкивания из очереди рабочих данных always @(posedge ClkPCI or negedge Res) begin if(Res == 0) rdreqFifoWorkData <= 0; else /*if( lm_ackn == 0)*/ case (StatePCI) //передача служебной инфы (не обращаем внимание на цифры, главное последовательность) // т.к. работаем по синхросигналу сразу, то начинаем работать на опережение 1: if(localIndexSumOfCounting < localMaxSumOfCount) rdreqFifoWorkData <= 1; // передаем номер кадра из служебной очереди 7: rdreqFifoWorkData <= 1; // передаем номер пачки из служебной очереди 2: rdreqFifoWorkData <= 1; // передаем количество отсчетов в данной пачке из служебной очереди 3: rdreqFifoWorkData <= 1; // передаем количество ошибок ЗИНП default: rdreqFifoWorkData <= 0; endcase /*else rdreqFifoWorkData <= 0;*/ end
//выставление данных на шину АД PCI assign l_adi = (rdWorkInf == 1)? WorkInf: (fl_adr == 1)? adress: (EnableWritePCIMaster == 1 && StatePCI == 0)? SumOfCountForPCI: (StatePCI == 4)? DataForPCI:(StatePCI == 6)? 32'hFACE_DEAD: ( StatePCI == 7 || StatePCI == 2 || StatePCI == 3 || StatePCI == 5)? WorkDataForPCI: 32'h0000_0000; //************************************************************************** //********Работа автомата по шине PCI при записи от меня******************** //**************************************************************************
//переход в 32битный режим reg lm_req32r; assign lm_req32n = lm_req32r;
//выставление запроса работы по 32й шине always @(posedge ClkPCI or negedge Res) begin if(Res == 0) lm_req32r <= 1; else if(StatePCI_Wr == 0 && EnableWritePCIMaster == 1) lm_req32r <= 0; // пытаемся перейти в 32битный режим else lm_req32r <= 1; end
//задержка перед проверкой, в каком режиме работаем reg [4:0] delay; always @(posedge ClkPCI or negedge Res) begin if(Res == 0) delay <= 0; else if(StatePCI_Wr == 1) delay <= delay + 1'b1; // пытаемся перейти в 64битный режим else delay <= 0; end
//адрес записи с моей стороны reg [31:0] adress ; //команда для записи по PCI localparam comand = 4'h07; assign l_cbeni = comand;
//определяем адрес always @(posedge ClkPCI or negedge Reset) begin if(Reset == 0) adress = 32'h0000_0000; else if(wrFromPci && l_dato[15:0] == 16'hE00A) adress[31:16] <= l_dato[31:16]; //старшее слово else if(wrFromPci && l_dato[15:0] == 16'hE00B) adress[15:0] <= l_dato[31:16]; //младшее слово end
//флаг выставления адреса или данных reg fl_adr; always @(posedge ClkPCI or negedge Res) begin if(Res == 0) fl_adr <= 0; else case(StatePCI_Wr) 0: if (EnableWritePCIMaster == 1) fl_adr <= 1;// выставляем адрес 3: if (lm_adr_ackn_ne == 1) fl_adr <= 0; //выставляем данные endcase end
reg lm_adr_acknN; always @(posedge ClkPCI or negedge Res) begin if(Res == 0) lm_adr_acknN <= 1; else lm_adr_acknN <= lm_adr_ackn; end
wire lm_adr_ackn_ne = !lm_adr_ackn & lm_adr_acknN;
localparam t2 = 1; // считаем количество тактов
//выставление сигнала готовности на стороне мастера PCI
assign lm_rdyn = (StatePCI == 1 )? 1'b1: (StatePCI_Wr == 4)? 1'b0: 1'b1; /*reg lmrdyn;
// выставление сигнала готовности на стороне мастера always @(posedge ClkPCI or negedge Res) begin if(Res == 0) lmrdyn <= 1; else if(StatePCI == 1) lmrdyn <= 1; // ставим задержку в передаче при передаче на сторону PCI else case(StatePCI_Wr) 0: lmrdyn <= 1; // в самом начале неактивно устройство(на всякий случай) 3: if(lm_adr_ackn_ne == 1) lmrdyn <= 0; // начала обмена после выставления адреса 4: if(StatePCI == 7) lmrdyn <= 0; else if(StatePCI == 6) lmrdyn <= 1; endcase end */
//выставление сигнала, определяющего последний переданный пакет(извещение о последней посылке) reg lmlastn; assign lm_lastn = lmlastn; always @(posedge ClkPCI or negedge Res) begin if(Res == 0) lmlastn <= 1; else case(StatePCI) 1: if(localIndexSumOfCounting >= localMaxSumOfCount) lmlastn <= 0; //последняя пачка default: lmlastn <= 1; endcase end
// автомат для передачи данных на сторону PCI (обслуживание стороны мастера) reg [3:0] StatePCI_Wr; always @(posedge ClkPCI or negedge Res) begin if(Res == 0) StatePCI_Wr <= 0; else case(StatePCI_Wr) 0: if(EnableWritePCIMaster == 1) StatePCI_Wr <= 1; //сформировали пачку начинаем ее передавать 1: if(delay >= t2) StatePCI_Wr <= 2; // ставим задержку 2: if ( lm_tsr[0] == 1) StatePCI_Wr <= 3; // если подтвердился обмен по 32битной шине else StatePCI_Wr <= 0; // отправили адрес 3: if (lm_adr_ackn_ne == 1) StatePCI_Wr <= 4; //работа по 32битной шине //собственно передача управления для работы алгоритма выдачи информации 4: if(StatePCI == 6) StatePCI_Wr <= 0; endcase end
//алгоритм работы выставления данных на шину АД шины PCI reg [2:0] StatePCI; always @(posedge ClkPCI or negedge Res) begin if(Res == 0) StatePCI <= 0; else case (StatePCI) 0: if(StatePCI_Wr == 4) StatePCI <= 1; // передаем количество считываемых пакетов за 1 цикл обмена 1: if(localIndexSumOfCounting >= localMaxSumOfCount) StatePCI <= 6; else StatePCI <= 7; //передача служебной инфы (не обращаем внимание на цифры, главное последовательность) 7: StatePCI <= 2; // передаем номер кадра из служебной очереди 2: StatePCI <= 3; // передаем номер пачки из служебной очереди 3: StatePCI <= 5; // передаем количество отсчетов в данной пачке из служебной очереди 5: StatePCI <= 4; // передаем количество ошибок ЗИНП //сами отсчеты 4: if(CurrentIndexOfCounting >= localMaxCounting) StatePCI <= 1;// передаем данные //передаем концевик 6: StatePCI <= 0; //после окончания транзакции( п) endcase end
endmodule
Причина редактирования: используйте теги для форматирования кода (с) модератор
|
|
|
|
|
Jul 4 2012, 12:38
|
Участник

Группа: Участник
Сообщений: 70
Регистрация: 8-05-07
Пользователь №: 27 604

|
А запись одного слова в память компьютера, по выделенному адресу, получается?
|
|
|
|
|
Jul 4 2012, 14:38
|
Участник

Группа: Участник
Сообщений: 49
Регистрация: 28-03-12
Из: Санкт-Петербург
Пользователь №: 71 050

|
Цитата(608 @ Jul 4 2012, 16:38)  А запись одного слова в память компьютера, по выделенному адресу, получается? Нет, сразу виснет
|
|
|
|
|
Jul 6 2012, 09:25
|
Участник

Группа: Участник
Сообщений: 49
Регистрация: 28-03-12
Из: Санкт-Петербург
Пользователь №: 71 050

|
Цитата(XVR @ Jun 29 2012, 12:35)  Если там 64 бита, то вы и должны передавать 64 бита. Т.е. у вас должна быть PCI64. Если же у вас PCI32, то со стороны Linux'а вы должны заказывать себе буфер для обмена в нижней части памяти (в 32х битах)
Скажите своему програмисту, что бы позвал pci_set_dma_mask(pdev, DMA_32BIT_MASK) перед pci_alloc_consistent Отдавать на плату нужно будет младшую часть 64х битного адреса (от pci_alloc_consistent) XVR, Не мог бы скинуть код под Линукс, если есть конечно, где ты работаешь как таргет, а в тебя пишут.... буду очень признателен мыло: petrov3372@yandex.ru
|
|
|
|
|
Jul 9 2012, 07:50
|
Участник

Группа: Участник
Сообщений: 49
Регистрация: 28-03-12
Из: Санкт-Петербург
Пользователь №: 71 050

|
Цитата(XVR @ Jul 6 2012, 17:57)  Запись в таргет под управлением CPU возможна только словами. Для записи блоками нужен мастер. Так комп работает как таргет, а я со стороны своего модуля как мастер... У меня виснет, когда я захватываю шину, становлюсь мастером на шине и пишу в ПК... вероятнее всего, что проблема в работе со стороны ПК, либо адрес, который определяет linux и мне выдает, неверный, либо сконфигурирована память на стороне ПК не правильно... Просто я грешу на неправильную работу проги под Linux...
|
|
|
|
|
Jul 9 2012, 09:01
|
Знающий
   
Группа: Свой
Сообщений: 721
Регистрация: 23-10-08
Из: next to Odessa
Пользователь №: 41 112

|
У меня mt32 на Cyclone III работает как в Линук, так и в ДОС. BAR0 и BAR1 проецируются на память ПК, а BAR2 и BAR3 на регистры ввода-вывода в mt32. Один из последних используется для приема начального адреса (через запрос на прерывание), по которому потом в память ПК начинает записываться массив. Правда я записываю в память ПК последовательно по слову, может быть и для того, чтобы не занимать надолго PCI-шину, были сомнения, что иначе ограничивается производительность программы на ПК… Заметил, что Ваша программа работает с ClkPCI и Clk50. У меня тоже две частоты, обошел коллизии тем, что работаю с внутренним ОЗУ на одной более высокой в процессе подготовки данных, а потом при работе с шиной переключаю на ClkPCI. Ну и соответственно два банка для подготовки данных, работающих по принципу «пинг-понг»…
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|