Альтернативная система на 68000 :)
Moderator: Shaos
-
- Doomed
- Posts: 662
- Joined: 18 Nov 2013 02:38
- Location: Москва
Re: Альтернативная система на 68000 :)
Имхо, надо же приляпать ethernet, завести линупс, поднять сервак с хояком и камерой и выставить в инет.
-
- Senior
- Posts: 137
- Joined: 30 Mar 2017 00:55
Re: Альтернативная система на 68000 :)
Ну припаять эзернет и камеру можно, если сделать для этого отдельную платку и установить этажеркой на эту сверху. А дальше, линукс, сервер там и всё такое - это уже не ко мне 

-
- Doomed
- Posts: 662
- Joined: 18 Nov 2013 02:38
- Location: Москва
Re: Альтернативная система на 68000 :)
Не, ну на 68к я где-то видел люди свободно поднимают линупс. Это все-таки не 6502. На 6502 придется веб сервер свой писать -)
-
- Doomed
- Posts: 449
- Joined: 08 Apr 2013 04:04
- Location: 213.247.249.139
-
- Doomed
- Posts: 662
- Joined: 18 Nov 2013 02:38
- Location: Москва
Re: Альтернативная система на 68000 :)
Да... 3.7: http://mc68k.blogspot.ru/angry_troll wrote:если на 68000, то наверное uClinux?
-
- Senior
- Posts: 137
- Joined: 30 Mar 2017 00:55
Re: Альтернативная система на 68000 :)
Уфффф. Оно работало четверо суток, и наконец-то грохнулось. Проблема повторяется всё та же. Как-то мистически выпадает всё та же ловушка на последнем (выключенном!!) IRQ19. Какой-то глубоко закопанный глюк в схеме формирования вектора, или в микроцикле опроса флагов прерываний. Переписать его заново чтоли... Всё остальное - замечательно, при снятии исключения вручную и перезапуске юзерского кода - код запускается как ни в чем ни бывало без перезагрузки. Крутит зеленый тор, переписывая видеопамять 

You do not have the required permissions to view the files attached to this post.
-
- Doomed
- Posts: 481
- Joined: 25 Aug 2009 07:02
- Location: Москва
Re: Альтернативная система на 68000 :)
То есть, взводятся какие-то IPL тогда, когда они должны вместе молчать? Цикл приема вектора нормально же обрабатывается, судя по тому, что во вменяемое место проц вываливается ? (заглушка на 83-м векторе, как я понял). Ну да, тогда косяк. Или чужой вектор подставляется?
А зачем линии прерываний в цикле автоматом опрашиваются? Не проще выбрать нужную по приоритетному шифратору, зафиксировать запрос, стать глухим к изменениям на линиях и выдать нужный вектор?
А зачем линии прерываний в цикле автоматом опрашиваются? Не проще выбрать нужную по приоритетному шифратору, зафиксировать запрос, стать глухим к изменениям на линиях и выдать нужный вектор?
-
- Senior
- Posts: 137
- Joined: 30 Mar 2017 00:55
Re: Альтернативная система на 68000 :)
Сами по себе IPL взводятся правильно. (там взводится только /IPL=6 всегда при любом прерывании, а в остальное время /IPL=7).
Выдача вектора и прием его в ЦП производится тоже правильно. Процессор приходит куда нужно, никаких таймаутов шины, нарушений ОЗУ и прочих совсем плохих неприятностей не происходит.
53-й вектор - это IRQ19. Вектора размещаются с 0x40 (IRQ0) по 0x53 (IRQ19).
При считывании флага и маски IRQ19 - там всё чисто и спокойно, везде 0. Значит само прерывание не виновато.
Похоже, что 0x53 вектор изредка (раз в несколько часов или суток) подставляется вместо какого-то "легального" вектора прерывания, которое при этом конечно же теряется (скорее всего это один из двух работающих таймеров). Где-то точно есть мой косяк
Приоритетный шифратор я делала раньше, когда было 5 прерываний.
И что-то мне тогда не понравилось
Но можно попробовать сделать это снова как-нибудь 
Выдача вектора и прием его в ЦП производится тоже правильно. Процессор приходит куда нужно, никаких таймаутов шины, нарушений ОЗУ и прочих совсем плохих неприятностей не происходит.
53-й вектор - это IRQ19. Вектора размещаются с 0x40 (IRQ0) по 0x53 (IRQ19).
При считывании флага и маски IRQ19 - там всё чисто и спокойно, везде 0. Значит само прерывание не виновато.
Похоже, что 0x53 вектор изредка (раз в несколько часов или суток) подставляется вместо какого-то "легального" вектора прерывания, которое при этом конечно же теряется (скорее всего это один из двух работающих таймеров). Где-то точно есть мой косяк

Приоритетный шифратор я делала раньше, когда было 5 прерываний.
И что-то мне тогда не понравилось


-
- Doomed
- Posts: 481
- Joined: 25 Aug 2009 07:02
- Location: Москва
Re: Альтернативная система на 68000 :)
Ну да, более всего похоже на подставной вектор. На процессор по сути идет как будто бы одна линия запроса прерывания, IPL0. Процессор отвечает циклом IACK, который комбинационным образом надежно и без потенциальных глюков собирается из сигналов AS, FC[2:0], A[19:16], A[2:0]. В данной схеме адреса 0-2 даже и не нужны. По получении IACK девайс (контроллер) реагирует снятием IPL и выдачей кода на шину даных в сопровождении DTACK.
Пофантазирую на тему контроллера прерываний. Может быть, циклический опрос и вполне себе ничего в данном случае. Приоритет прерывания становится понятием условным, потому что процессор видит только один уровень, маскировать своими средствами себе может либо ничего, либо сразу все. Маска в контроллер вынесена. Как вариант, контроллер по кругу опрашивает регистр, фиксирующий запросы. Пусть сканирование обеспечивается счетчиком от 0 до 19 (5 разрядов). Если запрос есть - опрос приостанавливается, выполняется обмен по IACK с процессором, код вектора при этом конструируется как лог. ИЛИ 7'b1000000 с содержимым счетчика. По окончании IACK сканирование возобновляется. Такой бесприоритетный round-robin с гарантией того, что все запросы будут обслужены, и ни один запрос не сможет блокировать остальные. Все хорошо, но в таком варианте не получается представить, как вектор 7'b1010011 взамен другого может выдаваться.
Пофантазирую на тему контроллера прерываний. Может быть, циклический опрос и вполне себе ничего в данном случае. Приоритет прерывания становится понятием условным, потому что процессор видит только один уровень, маскировать своими средствами себе может либо ничего, либо сразу все. Маска в контроллер вынесена. Как вариант, контроллер по кругу опрашивает регистр, фиксирующий запросы. Пусть сканирование обеспечивается счетчиком от 0 до 19 (5 разрядов). Если запрос есть - опрос приостанавливается, выполняется обмен по IACK с процессором, код вектора при этом конструируется как лог. ИЛИ 7'b1000000 с содержимым счетчика. По окончании IACK сканирование возобновляется. Такой бесприоритетный round-robin с гарантией того, что все запросы будут обслужены, и ни один запрос не сможет блокировать остальные. Все хорошо, но в таком варианте не получается представить, как вектор 7'b1010011 взамен другого может выдаваться.

-
- Senior
- Posts: 137
- Joined: 30 Mar 2017 00:55
Re: Альтернативная система на 68000 :)
Ага. Всё почти так и есть.
Только я сделала не циклический опрос 0..1..2......19..0...1...2..
У меня там идет опрос до первого взведенного флага, а дальше, после прохождения IACK - происходит возврат и опрос снова с 0. Так что приоритет "как бы есть"
И вот где-то в этом месте и есть какая-то беда.
-------
А почему бы действительно не попробовать просто по кругу... еще проще же.
Ну будут они все равноправные... и ладна:)
Только я сделала не циклический опрос 0..1..2......19..0...1...2..
У меня там идет опрос до первого взведенного флага, а дальше, после прохождения IACK - происходит возврат и опрос снова с 0. Так что приоритет "как бы есть"

-------
А почему бы действительно не попробовать просто по кругу... еще проще же.

Ну будут они все равноправные... и ладна:)
-
- Doomed
- Posts: 449
- Joined: 08 Apr 2013 04:04
- Location: 213.247.249.139
Re: Альтернативная система на 68000 :)
по началу цикла чтения вектора от 68к залатчить (не позволять меняться) вектор, который выдается. Вдоуг он меняется как раз тогда, когда проц его читает.
А вообще, без схем и сорцов это всё одни гадания от нас
А вообще, без схем и сорцов это всё одни гадания от нас

привет засранцу лавру :)
-
- Senior
- Posts: 137
- Joined: 30 Mar 2017 00:55
Re: Альтернативная система на 68000 :)
Если выберусь из депры и приведу в порядок остаток схем и исходники - выложу всё.
Совсем что-то хреново сейчас.
Совсем что-то хреново сейчас.
-
- Senior
- Posts: 137
- Joined: 30 Mar 2017 00:55
Re: Альтернативная система на 68000 :)
module interrupt_controller(IRQ,CLK16M,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 CLK16M;
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;
//output wire T1,T2,T3,T4;
reg RST;
reg [4:0] COUNTER; //IRQ scan counter
reg [4:0] DRCNT; //AUTO-EOI delay counter
reg [31:0] IDC; //IRQ scan decoder output lines
reg [19:0] MASK; //IRQ mask reg
reg IPD,IPLF, DRS;
reg [4:0] IRQ_NUM; //IRQ num buffer register
wire XDS, WDS, WWSTB, RWSTB, MHWSTB, MLWSTB, MHRSTB, MLRSTB, PHRSTB, PLRSTB, CHWSTB;
wire CLWSTB, FSCLK, SETCNT, IACK, XFLAG,DRCLK;
wire [19:0] CLR;
wire [19:0] POLL;
wire [19:0] FLAG;
wire [7:0] VECTOR;
always@(negedge CLK16M) RST <= (~nRESET); //synchronize reset pulse to system clock
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 posedge RST)
begin
if (RST) MASK[19:16] <= 4'd0;
else MASK[19:16] <= DIN[3:0];
end
always@(negedge MLWSTB or posedge RST)
begin
if (RST) 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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.IACK(IACK),.IDC(IDC[0]),.MASK(MASK[0]),
.POLL(POLL[0]),.FLAG(FLAG[0]));
assign XFLAG = ~(FLAG == 20'h0);
always@(negedge FSCLK or posedge RST or posedge IACK)
begin
if (RST) IPLF <= 0;
else
begin
if (IACK) IPLF <= 0;
else IPLF <= XFLAG;
end
end
always@(posedge DRS or posedge IPLF or posedge RST)
begin
if (RST) IPD <= 0;
else
begin
if (IPLF) IPD <=1;
else IPD <= 0;
end
end
assign SETCNT = IACK | RST;
assign FSCLK = CLK16M & (~IPD);
always@(posedge FSCLK or posedge SETCNT)
begin
if (SETCNT) COUNTER <= 5'd19;
else
begin
if (COUNTER == 5'd19) COUNTER <= 5'd0;
else COUNTER <= COUNTER + 1'd1;
end
end
always@(negedge FSCLK) IRQ_NUM <=COUNTER;
assign VECTOR[7:5] = 3'b010; //vector = 0x40 + irq_num
assign VECTOR[4:0] = IRQ_NUM;
//auto EOI delay counter
always@(negedge CLK16M or posedge RST)
begin
if (RST) DRS <=1;
else
begin
if (IACK) DRS <= 0;
else DRS <= (DRCNT == 5'h1F);
end
end
assign DRCLK = CLK16M & (~DRS);
always@(posedge DRCLK or posedge IACK or posedge RST)
begin
if (RST) DRCNT <= 5'h1F;
else
begin
if (IACK) DRCNT <= 5'h0;
else DRCNT <= DRCNT + 1'h1;
end
end
// assign T1 = FSCLK;
// assign T2 = XFLAG;
// assign T3 = IPD;
// assign T4 = DRS;
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
RS_CTRL,RS_PCH,RS_PCL,RS_MH,RS_ML,
IPL, DOUT, DTEN, DTA);
input wire [19:0] IRQ;
input wire CLK16M;
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;
//output wire T1,T2,T3,T4;
reg RST;
reg [4:0] COUNTER; //IRQ scan counter
reg [4:0] DRCNT; //AUTO-EOI delay counter
reg [31:0] IDC; //IRQ scan decoder output lines
reg [19:0] MASK; //IRQ mask reg
reg IPD,IPLF, DRS;
reg [4:0] IRQ_NUM; //IRQ num buffer register
wire XDS, WDS, WWSTB, RWSTB, MHWSTB, MLWSTB, MHRSTB, MLRSTB, PHRSTB, PLRSTB, CHWSTB;
wire CLWSTB, FSCLK, SETCNT, IACK, XFLAG,DRCLK;
wire [19:0] CLR;
wire [19:0] POLL;
wire [19:0] FLAG;
wire [7:0] VECTOR;
always@(negedge CLK16M) RST <= (~nRESET); //synchronize reset pulse to system clock
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 posedge RST)
begin
if (RST) MASK[19:16] <= 4'd0;
else MASK[19:16] <= DIN[3:0];
end
always@(negedge MLWSTB or posedge RST)
begin
if (RST) 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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.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(RST),.IACK(IACK),.IDC(IDC[0]),.MASK(MASK[0]),
.POLL(POLL[0]),.FLAG(FLAG[0]));
assign XFLAG = ~(FLAG == 20'h0);
always@(negedge FSCLK or posedge RST or posedge IACK)
begin
if (RST) IPLF <= 0;
else
begin
if (IACK) IPLF <= 0;
else IPLF <= XFLAG;
end
end
always@(posedge DRS or posedge IPLF or posedge RST)
begin
if (RST) IPD <= 0;
else
begin
if (IPLF) IPD <=1;
else IPD <= 0;
end
end
assign SETCNT = IACK | RST;
assign FSCLK = CLK16M & (~IPD);
always@(posedge FSCLK or posedge SETCNT)
begin
if (SETCNT) COUNTER <= 5'd19;
else
begin
if (COUNTER == 5'd19) COUNTER <= 5'd0;
else COUNTER <= COUNTER + 1'd1;
end
end
always@(negedge FSCLK) IRQ_NUM <=COUNTER;
assign VECTOR[7:5] = 3'b010; //vector = 0x40 + irq_num
assign VECTOR[4:0] = IRQ_NUM;
//auto EOI delay counter
always@(negedge CLK16M or posedge RST)
begin
if (RST) DRS <=1;
else
begin
if (IACK) DRS <= 0;
else DRS <= (DRCNT == 5'h1F);
end
end
assign DRCLK = CLK16M & (~DRS);
always@(posedge DRCLK or posedge IACK or posedge RST)
begin
if (RST) DRCNT <= 5'h1F;
else
begin
if (IACK) DRCNT <= 5'h0;
else DRCNT <= DRCNT + 1'h1;
end
end
// assign T1 = FSCLK;
// assign T2 = XFLAG;
// assign T3 = IPD;
// assign T4 = DRS;
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
-
- Doomed
- Posts: 481
- Joined: 25 Aug 2009 07:02
- Location: Москва
Re: Альтернативная система на 68000 :)
Потенциальная засада может быть тут:
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, но при этом его поведение чуть поменять нужно.
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, но при этом его поведение чуть поменять нужно.
-
- Senior
- Posts: 137
- Joined: 30 Mar 2017 00:55
Re: Альтернативная система на 68000 :)
С больной головы, греясь в ванной и грызя шоколадку, нарисовала вот такой вариант.
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, возобновляя работу счетчика.
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, возобновляя работу счетчика.
You do not have the required permissions to view the files attached to this post.