Код:
//----------------------------------------------------------------------
//
// Модуль управления внешней шиной
//
//----------------------------------------------------------------------
module Bus_control(
input clk, // Тактовый сигнал
input res, // Сигнал сброса
input [98:0] pla, // Шина ПЛМ
input m1, // Машинный цикл M1
input t1, // Такт T1
input t3, // Такт T3
input t3_del, // Такт T3 с задержкой
input t4, // Такт T4
input grp_io, // Сигнал GRP_IO
input int_ack, // Сигнал INT_ACK
input dis_bus, // Сигнал DIS_BUS
input bus_z, // Сигнал BUS_Z
input req_write, // Сигнал запроса записи
input [15:0] pcr, // Регистр PCR
output mreq, // Сигнал запроса памяти MREQ
output rd, // Сигнал чтение памяти или портов ввода-вывода RD
output reg p_m1, // Сигнал машинного цикла M1
output reg rfsh, // Сигнал рефреша памяти RFSH
output reg [15:0] adr // Шина адреса (16 бит)
);
wire start_mem_cycle; // Сигнал запуска цикла чтения/записи MREQ, RD
reg mreq_rs; // Триггер сигнала MREQ
reg rd_rs; // Триггер сигнала RD
reg disable_rd_port; // Триггер запрета вывода в порт RD (для циклов записи, холостых циклов и прерываний)
//----------------------------------------------------------------------
assign stop_rd_cycle = ((!m1) & t3) | t4 | res; // Сигнал окончания циклов MREQ, IORQ, RD для чтения/записи данных
// По сигналу RES
// По T4 любого цикла
// По Т3 любого цикла кроме M1
// Сигнал нначала цикла памяти
assign start_mem_cycle = ((!m1) & t1 & (!grp_io) | // По сигналу GRP_IO и T1 любого цикла, кроме M1
(m1 & t1 & (!int_ack))) & // По M1.T1, кроме INT_ACK (цикл чтения кода команды)
(!dis_bus); // При этом сигнал DIS_BUS не должен быть активен
// Вспомогательные сигналы
assign m1_t3_mask = t3_del & m1 & t3; // Сигнал маски по M1.T3.2
always @ (negedge clk) // Управление триггером mreq_rs (/CLK)
begin
if (stop_rd_cycle) // Если сигнал окончания записи,
mreq_rs <= 0; // то mreq_rs = 0 (высший приоритет),
else if (start_mem_cycle) // Иначе, если сигнал начала цикла памяти,
mreq_rs <= 1; // то mreq_rs = 1
end
assign mreq = mreq_rs & (!m1_t3_mask); // Внешний сигнал запроса памяти формируется с учетом врезки окончания цикла чтения кода операции
always @ (posedge clk) // Управление разрешением RD (CLK)
begin
disable_rd_port <= (int_ack & m1) | // В m1.int_ack,
req_write | // В цикле записи
dis_bus; // В цикле без доступа к памяти
end
always @ (negedge clk) // Управление триггером rd_rs (/CLK)
begin
if (stop_rd_cycle | // Если сигнал окончания чтения,
(m1 & t3)) // или начало цикла регенерации памяти M1.T3,
rd_rs <= 0; // то mreq_rs = 0 (высший приоритет),
else if (start_mem_cycle & (!disable_rd_port)) // Иначе, если сигнал начала цикла памяти и сигнал RD не запрещен,
rd_rs <= 1; // то mreq_rs = 1
end
assign rd = rd_rs & (!(t3_del & m1)); // Внешний сигнал чтения памяти формируется с учетом удлиненной врезки окончания цикла чтения кода операции
always @ (posedge clk) // Управление портом M1 (CLK)
begin
if (t3 | bus_z) // В такте T3 любого цикла (а на самом деле в M1.T3) или же по сигналу BUS_Z
p_m1 <= 0; // порт M1 переводится в 0
else if (m1 & t1) // В такте M1.T1 порт M1 переводится в 1, что означает начало цикла M1
p_m1 <= 1; //
end
always @ (posedge clk) // Управление портом RFSH (CLK)
begin
rfsh <= m1 & (t3 | t4); // Цикл рефреша памяти в тактах M1.T3 и M1.T4
end
always @ (posedge clk) // Управление шиной адреса (CLK)
begin
if (((m1 & t3) | t1) & (!dis_bus)) // Если нет сигнала запрета чтения/записи (dis_bus), то
adr <= pcr; // в такте T1 любого цила активен общий цикл чтения/записи,
// либо в такте M1.T3 активен цикл записи IR на шину адреса
end
endmodule