nedoPC.org

Community of electronics hobbyists established in 2002

...
Atom Feed | View unanswered posts | View active topics It is currently 12 Dec 2017 10:25



Reply to topic  [ 150 posts ]  Go to page Previous  1 ... 6, 7, 8, 9, 10  Next
Альтернативная система на 68000 :) 
Author Message
Maniac

Joined: 25 Aug 2009 10:02
Posts: 237
Location: Москва
Reply with quote
Потенциальная засада может быть тут:

assign SETCNT = IACK | RST;
assign FSCLK = CLK16M & (~IPD);

always@(posedge FSCLK or posedge SETCNT)
begin
if (SETCNT) COUNTER <= 5'd19;
...
always@(negedge FSCLK) IRQ_NUM <=COUNTER;

assign VECTOR[7:5] = 3'b010; //vector = 0x40 + irq_num
assign VECTOR[4:0] = IRQ_NUM;


COUNTER по активному IACK асинхронно переводится в 19 и там удерживается.
В регистр IRQ_NUM, по которому формируется вектор, по спаду FSCLK заносится содержимое COUNTER. Подразумевается, что FSCLK это не "чистая" синхра, а замаскированная сигналом IPD, который, в свою очередь как-то очень замороченно формируется, без временных диаграмм разобраться непросто, а их рисовать лень. Вот может IPD в какой-то момент не поспевает во-время, синхроимпульс проскакивает и в IRQ_NUM переносится содержимое COUNTER тогда, когда это не предполагается.
Возможно, общую логику как-то можно упростить, потому что IRQ_NUM кажется лишним, можно было бы брать вектор из COUNTER, но при этом его поведение чуть поменять нужно.


01 May 2017 14:16
Profile
Senior

Joined: 30 Mar 2017 03:55
Posts: 137
Reply with quote
С больной головы, греясь в ванной и грызя шоколадку, нарисовала вот такой вариант.
Mixa64, спасибо :)

Теперь вроде бы не так заморочено :) И синхронизация прозрачная.
Как-нибудь на днях закодю это счастье :)
Эх.. мне нужно приучаться делать везде прозрачную синхронизацию...
---------------

COUNTER -просто считает от 0 до 19, и дальше снова перепрыгивает в 0. При системном сбросе будет сбрасываться в 0.
XFLAG - это результат проверки текущего флага IRQ
IN_PROC - флаг IRQ_IN_PROCESS, который запрещает инкремент счетчика
IPLF - триггер прерывания, выдает /IPL
IACK - асинхронный строб дешифрованного цикла IACK от ЦП, по нему мы выдаем вектор (COUNTER+$40) и DTACK, а также асинхронно сбрасываем IPL и текущий флаг IRQ (через дешифратор, по номеру из COUNTER)

IACK_SYNCn - задержанный синхронный вариант IACK, из него формируем сигнал завершения IRDY, которым синхронно сбрасываем флаг IN_PROC, возобновляя работу счетчика.


Attachments:
ictc1.jpg
ictc1.jpg [ 406.1 KiB | Viewed 1193 times ]
01 May 2017 19:17
Profile
Senior

Joined: 30 Mar 2017 03:55
Posts: 137
Reply with quote
Закодила по вчерашней времянке.
Делает вид что работает...

Code:
module interrupt_controller(IRQ,CLK,FC,ADDR,DIN,nAS,nUDS,nLDS,RW,nRESET,
                            RS_CTRL,RS_PCH,RS_PCL,RS_MH,RS_ML,
                            IPL, DOUT, DTEN, DTA);
input wire [19:0] IRQ;
input wire CLK;
input wire [2:0] FC;
input wire [23:1] ADDR;
input wire [15:0] DIN;
input wire nAS, nUDS, nLDS, RW, nRESET, RS_CTRL, RS_PCH, RS_PCL, RS_MH, RS_ML;
output wire [2:0] IPL;
output wire [15:0] DOUT;
output wire DTEN,DTA;

reg [19:0] MASK;                            //IRQ mask reg
reg [4:0] COUNTER;                              //IRQ scan counter
reg [31:0] IDC;                             //IRQ scan decoder output lines
reg IN_PROC,IPLF;
reg [2:0] IACK_SYNC;                          //synchronized and delayed IACK
wire XDS, WDS, WWSTB, RWSTB, MHWSTB, MLWSTB, MHRSTB, MLRSTB, PHRSTB, PLRSTB, CHWSTB;
wire CLWSTB, IACK, XFLAG;
wire [19:0] CLR;
wire [19:0] POLL;
wire [19:0] FLAG;
wire [7:0]  VECTOR;

assign XDS = (~nUDS) | (~nLDS);
assign WDS = (~nUDS) & (~nLDS);

assign IACK = (ADDR[23:8] == 16'hFFFF) & (~nAS) & RW & (~nLDS) &
               (ADDR[3] & ADDR[2] & (~ADDR[1])) & (FC[2] & FC[1] & FC[0]);

assign WWSTB = (~RW) & WDS;                 //write_word strobe
assign RWSTB =  RW & WDS;                   //read_word strobe
assign MHWSTB = RS_MH & WWSTB;           //mask reg H write strobe
assign MLWSTB = RS_ML & WWSTB;            //mask reg L write strobe
assign MHRSTB = RS_MH & RWSTB;              //mask reg H read strobe
assign MLRSTB = RS_ML & RWSTB;              //mask reg L read strobe
assign PHRSTB = RS_PCH & RWSTB;             //polling reg H read strobe
assign PLRSTB = RS_PCL & RWSTB;             //polling reg L read strobe
assign CHWSTB = RS_PCH & WWSTB;             //flag clr reg H write strobe
assign CLWSTB = RS_PCL & WWSTB;             //flag clr reg L write strobe

assign CLR[15:0]  = DIN[15:0] & {16{CLWSTB}}; // generate flag clear strobes
assign CLR[19:16] = DIN[3:0] & {4{CHWSTB}};

//load IRQ mask register
always@(negedge MHWSTB or negedge nRESET)   
  begin
    if (~nRESET) MASK[19:16] <= 4'd0;
    else MASK[19:16] <=  DIN[3:0];
  end
always@(negedge MLWSTB or negedge nRESET)
  begin
    if (~nRESET) MASK[15:0] <= 16'd0;
    else MASK[15:0] <=  DIN[15:0];
  end
//generate output data
assign DOUT[15:8] = (POLL[15:8]&{8{PLRSTB}}) | (MASK[15:8]&{8{MLRSTB}});
assign DOUT[7:0] =  (POLL[7:0] &{8{PLRSTB}}) | (POLL[19:16]&{4{PHRSTB}}) |
                    (MASK[7:0]&{8{MLRSTB}})  | (MASK[19:16]&{4{MHRSTB}}) |
                    (VECTOR[7:0]&{8{IACK}});

//sys data bus drive enable strobe (read cycle)
assign DTEN = (RW & XDS & (RS_CTRL | RS_PCH | RS_PCL | RS_MH | RS_ML)) | IACK; 

//generate DTACK signal
assign DTA = (XDS & (RS_CTRL | RS_PCH | RS_PCL | RS_MH | RS_ML)) | IACK;

//generate IPL code for CPU
assign IPL[0] = 1;
assign IPL[1] = ~IPLF;
assign IPL[2] = ~IPLF;

//===========================================================

IRQ_channel IFLAG_19 (.IRQ(IRQ[19]),.CLR(CLR[19]),.RST(nRESET),.IACK(IACK),.IDC(IDC[19]),.MASK(MASK[19]),
                     .POLL(POLL[19]),.FLAG(FLAG[19]));
IRQ_channel IFLAG_18 (.IRQ(IRQ[18]),.CLR(CLR[18]),.RST(nRESET),.IACK(IACK),.IDC(IDC[18]),.MASK(MASK[18]),
                     .POLL(POLL[18]),.FLAG(FLAG[18]));
IRQ_channel IFLAG_17 (.IRQ(IRQ[17]),.CLR(CLR[17]),.RST(nRESET),.IACK(IACK),.IDC(IDC[17]),.MASK(MASK[17]),
                     .POLL(POLL[17]),.FLAG(FLAG[17]));
IRQ_channel IFLAG_16 (.IRQ(IRQ[16]),.CLR(CLR[16]),.RST(nRESET),.IACK(IACK),.IDC(IDC[16]),.MASK(MASK[16]),
                     .POLL(POLL[16]),.FLAG(FLAG[16]));
IRQ_channel IFLAG_15 (.IRQ(IRQ[15]),.CLR(CLR[15]),.RST(nRESET),.IACK(IACK),.IDC(IDC[15]),.MASK(MASK[15]),
                     .POLL(POLL[15]),.FLAG(FLAG[15]));
IRQ_channel IFLAG_14 (.IRQ(IRQ[14]),.CLR(CLR[14]),.RST(nRESET),.IACK(IACK),.IDC(IDC[14]),.MASK(MASK[14]),
                     .POLL(POLL[14]),.FLAG(FLAG[14]));
IRQ_channel IFLAG_13 (.IRQ(IRQ[13]),.CLR(CLR[13]),.RST(nRESET),.IACK(IACK),.IDC(IDC[13]),.MASK(MASK[13]),
                     .POLL(POLL[13]),.FLAG(FLAG[13]));
IRQ_channel IFLAG_12 (.IRQ(IRQ[12]),.CLR(CLR[12]),.RST(nRESET),.IACK(IACK),.IDC(IDC[12]),.MASK(MASK[12]),
                     .POLL(POLL[12]),.FLAG(FLAG[12]));
IRQ_channel IFLAG_11 (.IRQ(IRQ[11]),.CLR(CLR[11]),.RST(nRESET),.IACK(IACK),.IDC(IDC[11]),.MASK(MASK[11]),
                     .POLL(POLL[11]),.FLAG(FLAG[11]));
IRQ_channel IFLAG_10 (.IRQ(IRQ[10]),.CLR(CLR[10]),.RST(nRESET),.IACK(IACK),.IDC(IDC[10]),.MASK(MASK[10]),
                     .POLL(POLL[10]),.FLAG(FLAG[10]));
IRQ_channel IFLAG_9  (.IRQ(IRQ[9]),.CLR(CLR[9]),.RST(nRESET),.IACK(IACK),.IDC(IDC[9]),.MASK(MASK[9]),
                     .POLL(POLL[9]),.FLAG(FLAG[9]));
IRQ_channel IFLAG_8  (.IRQ(IRQ[8]),.CLR(CLR[8]),.RST(nRESET),.IACK(IACK),.IDC(IDC[8]),.MASK(MASK[8]),
                     .POLL(POLL[8]),.FLAG(FLAG[8]));
IRQ_channel IFLAG_7  (.IRQ(IRQ[7]),.CLR(CLR[7]),.RST(nRESET),.IACK(IACK),.IDC(IDC[7]),.MASK(MASK[7]),
                     .POLL(POLL[7]),.FLAG(FLAG[7]));
IRQ_channel IFLAG_6  (.IRQ(IRQ[6]),.CLR(CLR[6]),.RST(nRESET),.IACK(IACK),.IDC(IDC[6]),.MASK(MASK[6]),
                     .POLL(POLL[6]),.FLAG(FLAG[6]));
IRQ_channel IFLAG_5  (.IRQ(IRQ[5]),.CLR(CLR[5]),.RST(nRESET),.IACK(IACK),.IDC(IDC[5]),.MASK(MASK[5]),
                     .POLL(POLL[5]),.FLAG(FLAG[5]));
IRQ_channel IFLAG_4  (.IRQ(IRQ[4]),.CLR(CLR[4]),.RST(nRESET),.IACK(IACK),.IDC(IDC[4]),.MASK(MASK[4]),
                      .POLL(POLL[4]),.FLAG(FLAG[4]));
IRQ_channel IFLAG_3  (.IRQ(IRQ[3]),.CLR(CLR[3]),.RST(nRESET),.IACK(IACK),.IDC(IDC[3]),.MASK(MASK[3]),
                      .POLL(POLL[3]),.FLAG(FLAG[3]));
IRQ_channel IFLAG_2  (.IRQ(IRQ[2]),.CLR(CLR[2]),.RST(nRESET),.IACK(IACK),.IDC(IDC[2]),.MASK(MASK[2]),
                     .POLL(POLL[2]),.FLAG(FLAG[2]));
IRQ_channel IFLAG_1  (.IRQ(IRQ[1]),.CLR(CLR[1]),.RST(nRESET),.IACK(IACK),.IDC(IDC[1]),.MASK(MASK[1]),
                     .POLL(POLL[1]),.FLAG(FLAG[1]));
IRQ_channel IFLAG_0  (.IRQ(IRQ[0]),.CLR(CLR[0]),.RST(nRESET),.IACK(IACK),.IDC(IDC[0]),.MASK(MASK[0]),
                     .POLL(POLL[0]),.FLAG(FLAG[0]));

assign XFLAG = ~(FLAG == 20'h0);

always@(negedge CLK or posedge IACK or negedge nRESET)
  begin
    if (~nRESET) IPLF <= 0;
    else
      begin
        if (IACK) IPLF <= 0;
        else IPLF <= XFLAG;
      end
  end

always@(negedge CLK or posedge IPLF or negedge nRESET)
  begin
    if (~nRESET) IN_PROC <= 0;
    else 
      begin
        if (IPLF) IN_PROC <=1;
        else IN_PROC <= IN_PROC & (IACK_SYNC[1] | (~IACK_SYNC[2]));   //synchronous IN_PROC clear
      end
  end

always@(posedge CLK or negedge nRESET)
  begin
    if (~nRESET) COUNTER <= 5'd0;
    else
      begin
        if (~IN_PROC)
          begin
            if (COUNTER == 5'd19) COUNTER <= 5'd0;
            else COUNTER <= COUNTER + 1'd1;
          end
      end
  end

assign VECTOR[7:5] = 3'b010;       //vector = 0x40 + irq_num
assign VECTOR[4:0] = COUNTER;

always@(posedge CLK or negedge nRESET)      //IACK synchronizer and delay
  begin
    if (~nRESET) IACK_SYNC <= 3'd0;
    else
      begin
        IACK_SYNC[2:1] <= IACK_SYNC[1:0];
        IACK_SYNC[0] <= IACK;
      end
  end
 
always@*
begin
  case(COUNTER[4:0])
        5'h0:  IDC=32'b00000000000000000000000000000001;
        5'h1:  IDC=32'b00000000000000000000000000000010;
        5'h2:  IDC=32'b00000000000000000000000000000100;
        5'h3:  IDC=32'b00000000000000000000000000001000;
        5'h4:  IDC=32'b00000000000000000000000000010000;
        5'h5:  IDC=32'b00000000000000000000000000100000;
        5'h6:  IDC=32'b00000000000000000000000001000000;
        5'h7:  IDC=32'b00000000000000000000000010000000;
        5'h8:  IDC=32'b00000000000000000000000100000000;
        5'h9:  IDC=32'b00000000000000000000001000000000;
        5'hA:  IDC=32'b00000000000000000000010000000000;
        5'hB:  IDC=32'b00000000000000000000100000000000;
        5'hC:  IDC=32'b00000000000000000001000000000000;
        5'hD:  IDC=32'b00000000000000000010000000000000;
        5'hE:  IDC=32'b00000000000000000100000000000000;
        5'hF:  IDC=32'b00000000000000001000000000000000;
        5'h10: IDC=32'b00000000000000010000000000000000;
        5'h11: IDC=32'b00000000000000100000000000000000;
        5'h12: IDC=32'b00000000000001000000000000000000;
        5'h13: IDC=32'b00000000000010000000000000000000;
        5'h14: IDC=32'b00000000000100000000000000000000;
        5'h15: IDC=32'b00000000001000000000000000000000;
        5'h16: IDC=32'b00000000010000000000000000000000;
        5'h17: IDC=32'b00000000100000000000000000000000;
        5'h18: IDC=32'b00000001000000000000000000000000;
        5'h19: IDC=32'b00000010000000000000000000000000;
        5'h1A: IDC=32'b00000100000000000000000000000000;
        5'h1B: IDC=32'b00001000000000000000000000000000;
        5'h1C: IDC=32'b00010000000000000000000000000000;
        5'h1D: IDC=32'b00100000000000000000000000000000;
        5'h1E: IDC=32'b01000000000000000000000000000000;
        5'h1F: IDC=32'b10000000000000000000000000000000;
  endcase
end
endmodule

//---------------------------------------------------------------------------------

module IRQ_channel(IRQ,CLR,RST,IACK,IDC,MASK,  POLL,FLAG);
input wire IRQ;
input wire CLR;
input wire RST;
input wire IACK;
input wire IDC;
input wire MASK;
output wire POLL;
output wire FLAG;

reg IFLG;
wire FCLR;

assign FCLR = (~RST) | CLR | (IACK & IDC);
always@(posedge IRQ or posedge FCLR)
  begin
    if (FCLR) IFLG<= 0;
    else IFLG <= 1;
  end
assign POLL = IFLG;
assign FLAG = IFLG & IDC & MASK;
endmodule


02 May 2017 03:21
Profile
Maniac

Joined: 25 Aug 2009 10:02
Posts: 237
Location: Москва
Reply with quote
Annett wrote:
С больной головы, греясь в ванной и грызя шоколадку, нарисовала вот такой вариант.
Mixa64, спасибо :)

Да не за что, это всё шоколадка :)
Мне-то эта тема интересна тем, что у самого в коробочке лежат и ждут несколько разных из серии m68k (68008, 68000, 68010 и 68020).
Опять же, не настаиваю, но для чего задерживать сброс IN_PROC ? Я бы его вообще сформировал D-триггером с IPLF | IACK на D-входе. IPLF сбрасывается IACK-ом, они с перекрытием, сигнал чистый.

Code:
always@(posedge CLK or negedge nRESET)
    if (~nRESET) IN_PROC <= 0;
    else IN_PROC <= (IPLF | IACK);


А вообще, похоже, даже и он не нужен, если счетчиком управлять непосредственно:
Code:
always@(posedge CLK or negedge nRESET)
  begin
    if (~nRESET) COUNTER <= 5'd0;
    else
      begin
        if (IPLF | IACK) COUNTER <= COUNTER;
        else COUNTER <= COUNTER + 1;
      end
  end


Это всё стиль, привитый мелкой логикой и стремлением сэкономить корпуса, стиль для FPGA может отличатся.


02 May 2017 11:36
Profile
Senior

Joined: 30 Mar 2017 03:55
Posts: 137
Reply with quote
Mixa64 wrote:
Мне-то эта тема интересна тем, что у самого в коробочке лежат и ждут несколько разных из серии m68k (68008, 68000, 68010 и 68020).

А на каком из них хочется сделать? :)


03 May 2017 14:25
Profile
Senior

Joined: 30 Mar 2017 03:55
Posts: 137
Reply with quote
Да что же накрывает-то так... совсем что-то хреново...


03 May 2017 15:21
Profile
Senior

Joined: 30 Mar 2017 03:55
Posts: 137
Reply with quote
Причина задержки IACK.

Что-то мне подсказывает, что 68К не любит, чтобы приходило подряд два одинаковых IPL, и что между ними должна быть пауза минимум в 2 такта, чтобы он успел засинхрить и схватить новый IPL. А ведь у меня здесь именно такой нестандартный вариант - приходят всегда одинаковые IPL.

Не знаю, может быть всё это - результат моих глюков из-за пограничного психического состояния. А может быть, уже начинается паранойя. Но оно прекрасно работает вот так, с задержкой. Она не делает ничего такого плохого, разве что "съедает" 2 триггера плисы...

Кстати, сейчас вот подумала... если использовать ЦП не на 16МГц, а например на 6 или 8, то нужно еще и удлинить эту паузу в 2.5 раза :)


04 May 2017 13:59
Profile
Senior

Joined: 30 Mar 2017 03:55
Posts: 137
Reply with quote
Нет, похоже это мой глюк, и 68К принимает IPL просто по уровню. Тогда эти паузы действительно ненужны.
Что-то вот этот момент немножко мутноватый а даташитах...


05 May 2017 06:11
Profile
Maniac

Joined: 25 Aug 2009 10:02
Posts: 237
Location: Москва
Reply with quote
Annett wrote:
Mixa64 wrote:
Мне-то эта тема интересна тем, что у самого в коробочке лежат и ждут несколько разных из серии m68k (68008, 68000, 68010 и 68020).

А на каком из них хочется сделать? :)

Да на каждом. :) 68000 и 68010, правда, мало отличаются, но 68000 у меня в варианте керамический PGA от Тошибы, TMP68HC000, просто симпатичный.

Про IPL, из даташита я усвоил, что воспринимаются уровнями, внутри то ли двойная, то ли тройная привязка к такту, рекомендуется держать уровень до цикла IACK, проц переходит в режим супервизора и свой приоритет устанавливает равным пришедшему запросу. Что позволяет его принять повторно, если он тут же возникнет снова. Но это так, абстрактные рассуждения, все же нужно сверять даташит с реальным поведением.


05 May 2017 18:07
Profile
Senior

Joined: 18 Nov 2013 18:15
Posts: 176
Location: все оттуда ;)
Reply with quote
Вот такое для 6800 было ;)

Image

Можно прикручивать ;) к сделанному !


16 May 2017 17:01
Profile
Senior

Joined: 30 Mar 2017 03:55
Posts: 137
Reply with quote
Не. Не подойдет. это же под 6800, а не 68000...


17 May 2017 11:58
Profile
Senior

Joined: 30 Mar 2017 03:55
Posts: 137
Reply with quote
В общем теперь эта радость больше не падает.
Выключила пока. Ненавижу уже эти мигающие диоды.
Хорошо еще что удержалась и не разбила ее о стену...

Что-то снова накрывает пустота и безнадега какая-то
Никому кроме меня это всё ненужно


18 May 2017 18:01
Profile
Senior

Joined: 30 Mar 2017 03:55
Posts: 137
Reply with quote
Проект закрыт.
Всё.
Прошу прощения за беспокойство у всех.


27 May 2017 14:03
Profile
Maniac
User avatar

Joined: 05 Oct 2006 07:45
Posts: 266
Location: Moscow
Reply with quote
Хаха, вступайте в клуб! Тут у каждого есть никому не интересный проект, а то и несколько, и не менее сложных. И ничо, никто голову об стену не разбил, живем как-то, общаемся. :rotate: Серьезно, времена дефицита информации давно канули, народ пересыщен и балован, никто не кинется потреблять контент и тем повышать ЧСВ автора. Тем более в сложных для мгновенного включения вещах - это ж не "веселая ферма". Так что эндорфинчики надо генерировать себе самому, уже только фактом собственного творчества, а не ждать их извне в ответ на. А это уже совсем другой уровень нашего ботанского кунг-фу, такскзть - черный пояс. :)

_________________
Всем добра!


28 May 2017 05:02
Profile
Senior

Joined: 30 Mar 2017 03:55
Posts: 137
Reply with quote
Да тут дело не в этом. Это-то ясно-понятно.
Здесь так сказать внутренняя проблема...
---------

Основные дозы эндорфинчиков я получаю совсем другими способами...


28 May 2017 07:46
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 150 posts ]  Go to page Previous  1 ... 6, 7, 8, 9, 10  Next

Who is online

Users browsing this forum: No registered users and 1 guest


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.