nedoPC.org

Electronics hobbyists community established in 2002
Atom Feed | View unanswered posts | View active topics It is currently 28 Mar 2024 05:56



Reply to topic  [ 198 posts ]  Go to page Previous  1 ... 6, 7, 8, 9, 10, 11, 12 ... 14  Next
ISA-8 SD-контроллер (SPI) на CPLD 
Author Message
Doomed

Joined: 18 Nov 2013 02:38
Posts: 662
Location: Москва
Reply with quote
Попутно выяснил причину зависаний 386 - подыхает AT блок питания. Пень вообще перестал стартовать, пока не воткнул ATX. Карта похоже работает на любой конфигурации - XT, 386, Pentium 1. Смотрю дрова.
UPD: Ага, не дожидался пока карточка снимет FF после IO. Поправил драйвер и поехало на пне.

Ну что ж, выходит работает система. Непонятно как, но здорово :mrgreen:

_________________
https://t.me/tronix_blog


10 Dec 2017 01:50
Profile
Doomed

Joined: 08 Apr 2013 04:04
Posts: 449
Location: 213.247.249.139
Reply with quote
Tronix wrote:
Чем то отличается. = вместо <= в некоторых местах, чтение из регистра не только по nCS & nRD но и по Clk. Что то еще может быть.


Для результата синтеза <= и = не различаются. Ну точнее вот так:
1.
Code:
always @(posedge clk)
 output <= input;
и
Code:
always @(posedge clk)
 output = input;

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

Но вот например:
2.
Code:
always @(posedge clk)
begin
 b <= a;
 c <= b;
end
и
Code:
always @(posedge clk)
begin
 b = a;
 c = b;
end

уже будут отличаться: в первом случае получится сдвиговый регистр из триггеров b и c со входом a, а во втором случае -- c и b будут каждый такт присваивать себе a.

Ну это я к чему -- что вряд ли разница в замене = на <=, если по первому случаю. А вот во 2ом случае может проролять.
И да, внутри always @(posedge clk) всегда надо писать <=, = допустимо только для временных переменных, например:
Code:
always @(posedge clk)
begin : named_block
 reg tmp;
 tmp = a+b+c;
 output <= tmp;
end

_________________
привет засранцу лавру :)


10 Dec 2017 03:52
Profile
Doomed

Joined: 18 Nov 2013 02:38
Posts: 662
Location: Москва
Reply with quote
Спасибо, это в принципе понятно, но трогать уже не хочу. Работает так - пускай работает :-)

_________________
https://t.me/tronix_blog


11 Dec 2017 00:15
Profile
Doomed

Joined: 18 Nov 2013 02:38
Posts: 662
Location: Москва
Reply with quote
newold86 Посмотрел немного сорцы. У вас нет флага занятости, почему? Потому что скорость SPI заведомо высокая (какая, кстати?)? А если ваш код на каком-нибудь Pentium 4 3,0 GHz с ISA слотом запустить - отработает?

_________________
https://t.me/tronix_blog


11 Dec 2017 02:49
Profile
Devil

Joined: 30 Nov 2013 11:08
Posts: 706
Location: WWW
Reply with quote
Tronix wrote:
newold86 Посмотрел немного сорцы. У вас нет флага занятости, почему?

Потому что необходимость чтения флага занятости перед каждым байтом автоматически снижает скорость раза в три. Поэтому пришлось усложнить "железо" - в случае необходимости, плата притормаживает процессор снятием сигнала READY.

Tronix wrote:
Потому что скорость SPI заведомо высокая (какая, кстати?)?

newold86 wrote:
Я где-то раньше уже писал - у меня все карты (три или четыре разные) и инициализируются, и работают на 12.5МГц - я даже перестал переключать на пониженную скорость для инициализации, Мало того - возможно, они и на 25МГц так работают, сейчас просто не помню, а взглянуть пока не могу.


Tronix wrote:
А если ваш код на каком-нибудь Pentium 4 3,0 GHz с ISA слотом запустить - отработает?

Хоть и используется сигнал READY, но реализация не совсем железобетонная (лень было в одном месте усложнять). Поэтому будет работать тогда, когда процессор проверяет сигнал готовности не РАНЬШЕ, чем через половину цикла тактовой SPI с момента обращения к SPI. 8088 проверяет этот сигнал приблизительно через полтора периода своей тактовой частоты, поэтому тактовая частота 8088 может быть не более, чем в 3 раза выше, чем тактовая SPI. Я не знаю, как Pentium работает с сигналом готовности, поэтому ничего сказать по этому поводу не могу.


11 Dec 2017 07:50
Profile
Doomed

Joined: 18 Nov 2013 02:38
Posts: 662
Location: Москва
Reply with quote
Хмхм.. А я ж тоже могу легко вывод BUSY на READY повесить. Действительно, минус чтение из порта.

_________________
https://t.me/tronix_blog


11 Dec 2017 07:58
Profile
Doomed

Joined: 18 Nov 2013 02:38
Posts: 662
Location: Москва
Reply with quote
А нет, не легко. У вас какая логика? Если чтение из порта и BUSY, тогда держим READY - верно?

_________________
https://t.me/tronix_blog


11 Dec 2017 08:13
Profile
Devil

Joined: 30 Nov 2013 11:08
Posts: 706
Location: WWW
Reply with quote
Tronix wrote:
А нет, не легко. У вас какая логика? Если чтение из порта и BUSY, тогда держим READY - верно?

Это если в совсем общем виде. Но дьявол, как известно, кроется в мелочах... Для начала, при записи у меня READY не трогается вообще в ТЕКУЩЕМ цикле - только если вдогонку послали байт, а старый еще не ушел. Просто нет смысла дожидаться отправки байта, и потом возвращать управление.
При чтении, естественно, нужно инициировать процесс чтения и одновременно сбросить READY, дождаться приема полного байта и отпустить READY. Я даже игрался с отпусканием READY после приема меньшего количества бит в зависимости от фазы тактовой частоты процессора, но на малых тактовых процессора это ощутимой прибавки быстродействия не дает.


11 Dec 2017 08:37
Profile
Doomed

Joined: 18 Nov 2013 02:38
Posts: 662
Location: Москва
Reply with quote
.

_________________
https://t.me/tronix_blog


12 Dec 2017 08:47
Profile
Doomed

Joined: 18 Nov 2013 02:38
Posts: 662
Location: Москва
Reply with quote
Убрал делитель вообще. Набросал такой код, пока не проверял, нет времени, да и не заработает наверняка :(

 Попытка управления READY
Code:
module MX2_CPLD(
    // Системные
    input    Clk,              // Входная частота 14.31818 МГц
    input    Res,              // Входной сигнал сброса, активный уровень лог.0
    input    nRD,              // Вход строба чтения
    input    nWR,              // Вход строба записи
    input    nCS,              // Вход выбора контроллера
    input    Adr,              // Вход адреса данные/управление
    inout    [7:0]Dat,         // Шина данных
    inout   Ready,
    // SPI
    output   nSEL,             // Выходной сигнал выбора карты
    output   reg SCK,          // Выход тактовой частоты SPI
    input    MISO,             // Вход данных SPI
    output   MOSI,             // Выход данных SPI
    output   nRED,             // Выход управления красным светодиодом
    input    nINS              // Вход датчика вставления карты
);
// Внутренние регистры
//reg Pre;                  // Делитель частоты
reg [1:0]Ctrl;                 // Регистр управления
reg [7:0]Data;                 // Регистр данных
reg [2:0]Bits;                 // Счетчик сдвигаемых бит
reg RMISO;                     // Защелка сигнала MISO
reg BUSY;                      // SPI занят передачей
reg MRDY;                  // Признак записи/чтения порта при сдвиге
// Комбинаторика
assign nSEL = ~Ctrl[0];        // Выбор карты
assign nRED = ~Ctrl[1];        // Красная лампочка
assign MOSI = Data[7];         // Выход MOSI SPI
assign Dat[7:0] = (~nCS & ~nRD & ~Clk) ?
                    (Adr) ? {~nINS,BUSY,4'h0,Ctrl[1:0]} : Data[7:0]
                    : 8'hZZ;
assign Ready = (MRDY) ? 1'b0 : 1'bZ;  // Если была попытка чтения/записи в порт, удерживаем READY

// Синхронная логика
always @(posedge Clk) begin
    // Запись в управление может происходить асинхронно
    if (~nCS & ~nWR & Adr) Ctrl[1:0] = Dat[1:0];
    // Сигнал сброса имеет приоритет вне зависимости от выбранной скорости
    if (Res)
      begin
         // Сброс действует на эти регистры
         Ctrl[1:0] <= 2'h0;
         Bits[2:0] <= 3'h0;
         BUSY <= 1'b0;
         SCK <= 1'b0;
         MRDY <= 1'b0;
      end
   else
      begin
         // Состояние SPI
         if (BUSY)
            begin
               // SPI работает
               if (SCK)
                  begin
                     // Сбрасываем такт
                     SCK <= 1'b0;
                     // Спад, поэтому сдвигаем
                     Data[7:0] <= {Data[6:0],RMISO};
                     // Считаем биты
                     Bits[2:0] <= Bits[2:0] + 3'h1;
                     // Это был 7й бит?
                     if (Bits[2] & Bits[1] & Bits[0])
                        begin
                           BUSY = 1'b0;   // Снимаем флаг занятости
                           MRDY <= 1'b0;   // Переводим READY в hi-Z
                        end;
                  end
               else
                  begin
                     // Устанавливаем такт
                     SCK <= 1'b1;
                     // Это фронт, поэтому сэмплируем вход
                     RMISO <= MISO;
                  end
            end
         else
            // Обнуляем счетчик бит
            Bits[2:0] <= 3'h0;
         
         // Запись в регистр данных
            if (~nCS & ~nWR & ~Adr)
            begin
            if (BUSY)
               // если продолжается сдвиг, опустим READY
               MRDY <= 1'b1;
            else
               begin
                  Data[7:0] = Dat[7:0];
                  BUSY = 1'b1;
               end;
            end

         // Чтение из регистра данных при сдвиге - опустим READY
            if (~nCS & ~nRD & ~Adr & BUSY) MRDY <= 1'b1;

      end
end
// Конец
endmodule

_________________
https://t.me/tronix_blog


14 Dec 2017 11:16
Profile
Doomed

Joined: 08 Apr 2013 04:04
Posts: 449
Location: 213.247.249.139
Reply with quote
Code:
    input    Res,              // Входной сигнал сброса, активный уровень лог.0


Code:
    if (Res)
      begin
         // Сброс действует на эти регистры
         Ctrl[1:0] <= 2'h0;

Что из этих утверждений верно?

Ну и еще посоветовал бы ресет сделать асинхронный, в этом случае может колво логики сократиться, т.к. afair в максах триггеры имеют асинхр. сброс, а синхронного не имеют, соотвно синхронный делается логикой:

Code:
always @(posedge clk, negedge arst_n) // arst_n: 0 -- сброс, 1 -- работа
if( !arst_n )
 сброс
else
 работа

_________________
привет засранцу лавру :)


14 Dec 2017 13:13
Profile
Doomed

Joined: 18 Nov 2013 02:38
Posts: 662
Location: Москва
Reply with quote
angry_troll wrote:
Code:
    input    Res,              // Входной сигнал сброса, активный уровень лог.0


Code:
    if (Res)
      begin
         // Сброс действует на эти регистры
         Ctrl[1:0] <= 2'h0;

Что из этих утверждений верно?



Из этих утверждений верно условие. Комментарий остался от "специалиста". В IBM у RESET активный логический уровень 1.

_________________
https://t.me/tronix_blog


14 Dec 2017 21:57
Profile
Doomed

Joined: 18 Nov 2013 02:38
Posts: 662
Location: Москва
Reply with quote
DimkaM wrote:
[s]
Quote:
MRDY <= 1'b0; // Переводим READY в hi-Z

точно не MRDY <= 1'bZ;
?[/s]


Точно. Из allways блока он не дает напрямую IO пин установить, поэтому пришлось ввести промежуточный тригер MRDY. А до блока allways, где синхронная логика, уже в зависимости от состояния этого регистра устанавливается сама нога Ready:

Code:
assign Ready = (MRDY) ? 1'b0 : 1'bZ;  // Если была попытка чтения/записи в порт, удерживаем READY


Костыль-с.

_________________
https://t.me/tronix_blog


14 Dec 2017 22:12
Profile
Maniac

Joined: 22 Jun 2005 04:35
Posts: 260
Location: МО Россия
Reply with quote
Quote:
if (BUSY)
// если продолжается сдвиг, опустим READY
MRDY <= 1'b1;

это условие никогда не выполнится


14 Dec 2017 22:41
Profile ICQ
Doomed

Joined: 18 Nov 2013 02:38
Posts: 662
Location: Москва
Reply with quote
DimkaM wrote:
Quote:
if (BUSY)
// если продолжается сдвиг, опустим READY
MRDY <= 1'b1;

это условие никогда не выполнится


Почему?

_________________
https://t.me/tronix_blog


14 Dec 2017 22:57
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 198 posts ]  Go to page Previous  1 ... 6, 7, 8, 9, 10, 11, 12 ... 14  Next

Who is online

Users browsing this forum: No registered users and 8 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.