1
0
mirror of https://github.com/aap/pdp6.git synced 2026-02-09 09:51:33 +00:00
Files
aap.pdp6/verilog/core164.v
2019-10-26 16:49:04 +02:00

363 lines
9.3 KiB
Verilog

module core164(
input wire clk,
input wire reset,
input wire power,
input wire sw_single_step,
input wire sw_restart,
input wire membus_wr_rs_p0,
input wire membus_rq_cyc_p0,
input wire membus_rd_rq_p0,
input wire membus_wr_rq_p0,
input wire [21:35] membus_ma_p0,
input wire [18:21] membus_sel_p0,
input wire membus_fmc_select_p0,
input wire [0:35] membus_mb_in_p0,
output wire membus_addr_ack_p0,
output wire membus_rd_rs_p0,
output wire [0:35] membus_mb_out_p0,
input wire membus_wr_rs_p1,
input wire membus_rq_cyc_p1,
input wire membus_rd_rq_p1,
input wire membus_wr_rq_p1,
input wire [21:35] membus_ma_p1,
input wire [18:21] membus_sel_p1,
input wire membus_fmc_select_p1,
input wire [0:35] membus_mb_in_p1,
output wire membus_addr_ack_p1,
output wire membus_rd_rs_p1,
output wire [0:35] membus_mb_out_p1,
input wire membus_wr_rs_p2,
input wire membus_rq_cyc_p2,
input wire membus_rd_rq_p2,
input wire membus_wr_rq_p2,
input wire [21:35] membus_ma_p2,
input wire [18:21] membus_sel_p2,
input wire membus_fmc_select_p2,
input wire [0:35] membus_mb_in_p2,
output wire membus_addr_ack_p2,
output wire membus_rd_rs_p2,
output wire [0:35] membus_mb_out_p2,
input wire membus_wr_rs_p3,
input wire membus_rq_cyc_p3,
input wire membus_rd_rq_p3,
input wire membus_wr_rq_p3,
input wire [21:35] membus_ma_p3,
input wire [18:21] membus_sel_p3,
input wire membus_fmc_select_p3,
input wire [0:35] membus_mb_in_p3,
output wire membus_addr_ack_p3,
output wire membus_rd_rs_p3,
output wire [0:35] membus_mb_out_p3,
// 36 bit Avalon Master
output wire [17:0] m_address,
output reg m_write,
output reg m_read,
output wire [35:0] m_writedata,
input wire [35:0] m_readdata,
input wire m_waitrequest
);
/* Jumpers */
parameter memsel_p0 = 4'b0;
parameter memsel_p1 = 4'b0;
parameter memsel_p2 = 4'b0;
parameter memsel_p3 = 4'b0;
// TODO: SP
wire cmc_sp = 0;
reg [22:35] cma;
reg cma_rd_rq, cma_wr_rq;
reg [0:35] cmb;
// TODO: interleave
wire cmpc_p0_rq = (membus_sel_p0 == memsel_p0) &
~membus_fmc_select_p0 &
membus_rq_cyc_p0 &
cmc_await_rq;
wire cmpc_p1_rq = (membus_sel_p1 == memsel_p1) &
~membus_fmc_select_p1 &
membus_rq_cyc_p1 &
cmc_await_rq;
wire cmpc_p2_rq = (membus_sel_p2 == memsel_p2) &
~membus_fmc_select_p2 &
membus_rq_cyc_p2 &
cmc_await_rq;
wire cmpc_p3_rq = (membus_sel_p3 == memsel_p3) &
~membus_fmc_select_p3 &
membus_rq_cyc_p3 &
cmc_await_rq;
wire [22:35] ma_in =
{14{cmc_p0_sel}}&membus_ma_p0 |
{14{cmc_p1_sel}}&membus_ma_p1 |
{14{cmc_p2_sel}}&membus_ma_p2 |
{14{cmc_p3_sel}}&membus_ma_p3;
wire rd_rq_in =
cmc_p0_sel&membus_rd_rq_p0 |
cmc_p1_sel&membus_rd_rq_p1 |
cmc_p2_sel&membus_rd_rq_p2 |
cmc_p3_sel&membus_rd_rq_p3;
wire wr_rq_in =
cmc_p0_sel&membus_wr_rq_p0 |
cmc_p1_sel&membus_wr_rq_p1 |
cmc_p2_sel&membus_wr_rq_p2 |
cmc_p3_sel&membus_wr_rq_p3;
wire [0:35] mb_in =
{36{cmc_p0_sel}}&membus_mb_in_p0 |
{36{cmc_p1_sel}}&membus_mb_in_p1 |
{36{cmc_p2_sel}}&membus_mb_in_p2 |
{36{cmc_p3_sel}}&membus_mb_in_p3;
pa cmpc_pa0(clk, reset, cmc_t1b&cmc_p0_sel, membus_addr_ack_p0);
pa cmpc_pa1(clk, reset, cmc_t1b&cmc_p1_sel, membus_addr_ack_p1);
pa cmpc_pa2(clk, reset, cmc_t1b&cmc_p2_sel, membus_addr_ack_p2);
pa cmpc_pa3(clk, reset, cmc_t1b&cmc_p3_sel, membus_addr_ack_p3);
assign membus_rd_rs_p0 = cmc_rd_rs&cmc_p0_sel;
assign membus_rd_rs_p1 = cmc_rd_rs&cmc_p1_sel;
assign membus_rd_rs_p2 = cmc_rd_rs&cmc_p2_sel;
assign membus_rd_rs_p3 = cmc_rd_rs&cmc_p3_sel;
assign membus_mb_out_p0 = sa & {36{strobe_sense & cmc_p0_sel}};
assign membus_mb_out_p1 = sa & {36{strobe_sense & cmc_p1_sel}};
assign membus_mb_out_p2 = sa & {36{strobe_sense & cmc_p2_sel}};
assign membus_mb_out_p3 = sa & {36{strobe_sense & cmc_p3_sel}};
wire cmpc_rs_set = membus_wr_rs_p0 & cmc_p0_sel |
membus_wr_rs_p1 & cmc_p1_sel |
membus_wr_rs_p2 & cmc_p2_sel |
membus_wr_rs_p3 & cmc_p3_sel;
// TODO: this is all wrong
wire pwr_t1, pwr_t2, pwr_t3;
wire cmc_await_rq_reset, cmc_pwr_clr, cmc_pwr_start;
pg pg0(clk, reset, power, pwr_t1);
// 200ms
ldly1us dly0(clk, reset, pwr_t1, pwr_t2, cmc_await_rq_reset);
// 100μs
ldly1us dly1(clk, reset, pwr_t2, pwr_t3, cmc_pwr_clr);
pa pa0(clk, reset, pwr_t3, cmc_pwr_start);
// core control, we don't really have a use for it
reg cmc_read, cmc_write, cmc_inh;
reg cmc_rq_sync, cmc_cyc_done;
reg cmc_await_rq, cmc_pse_sync, cmc_proc_rs, cmc_stop;
reg cmc_p0_act, cmc_p1_act, cmc_p2_act, cmc_p3_act;
reg cmc_last_proc;
// TODO: SP
wire cmc_p0_sel = cmc_p0_act;
wire cmc_p1_sel = cmc_p1_act;
wire cmc_p2_sel = cmc_p2_act;
wire cmc_p3_sel = cmc_p3_act;
wire cmc_t0, cmc_t1b, cmc_t1a, cmc_t2, cmc_t3;
wire cmc_t4, cmc_t5, cmc_t6, cmc_t6p;
wire cmc_t0_D, cmc_t1b_D, cmc_t1a_D1, cmc_t2_D1, cmc_t2_D2;
wire cmc_t3_D1, cmc_t3_D2;
wire cmc_restart;
wire cmc_start;
wire cmc_state_clr;
wire cmc_pn_act = cmc_p0_act | cmc_p1_act | cmc_p2_act | cmc_p3_act;
wire cmc_aw_rq_set = cmc_t0_D & ~cmc_pn_act;
wire cmc_rq_sync_set = cmc_t0_D & ~cmc_sp & cmc_pn_act;
wire cmc_jam_cma = cmc_t1b;
wire cmc_cmb_clr;
wire cmc_read_off;
wire cmc_pse_sync_set;
wire strobe_sense;
wire cmc_rd_rs;
wire cmpc_rs_set_D;
wire cmc_proc_rs_pulse;
pa pa1(clk, reset,
(cmpc_p0_rq | cmpc_p1_rq | cmpc_p2_rq | cmpc_p3_rq),
cmc_t0);
pa pa2(clk, reset, cmc_restart | cmc_pwr_start, cmc_start);
pa pa3(clk, reset, cmc_start | cmc_t3_D1, cmc_t5);
pa pa4(clk, reset, cmc_start | cmc_t3_D2, cmc_t6p);
pa pa5(clk, reset,
cmc_start | cmc_t3 & ~cma_wr_rq | cmc_proc_rs_pulse,
cmc_state_clr);
pa pa6(clk, reset, cmc_rq_sync&cmc_cyc_done, cmc_t1b);
pa pa7(clk, reset, cmc_t1b, cmc_t1b_D);
pa pa8(clk, reset, cmc_t1b_D, cmc_t1a);
pa pa9(clk, reset,
cmc_t1b | cmc_t2_D2&cma_rd_rq&cma_wr_rq,
cmc_cmb_clr);
pa pa10(clk, reset, cmc_t1a_D1, cmc_t2);
pa pa11(clk, reset, cmc_t2_D1&cma_rd_rq, strobe_sense);
pa pa12(clk, reset, strobe_sense, cmc_rd_rs);
pa pa13(clk, reset, cmc_pse_sync&(cmc_proc_rs | ~cma_wr_rq), cmc_t3);
pa pa14(clk, reset, cmc_proc_rs, cmc_proc_rs_pulse);
// probably wrong
pa pa15(clk, reset, sw_restart, cmc_restart);
dly250ns dly2(clk, reset, cmc_t6p, cmc_t6);
dly100ns dly3(clk, reset, cmc_t0, cmc_t0_D);
dly250ns dly4(clk, reset, cmc_t1a, cmc_t1a_D1);
dly450ns dly5(clk, reset, cmc_t1a, cmc_read_off);
dly550ns dly6(clk, reset, cmc_t1a, cmc_pse_sync_set);
// Variable 35-100ns
dly70ns dly7(clk, reset, cmc_t2, cmc_t2_D1);
dly300ns dly8(clk, reset, cmc_t2, cmc_t2_D2);
dly50ns dly9(clk, reset, cmc_t3, cmc_t4);
dly550ns dly10(clk, reset, cmc_t3, cmc_t3_D1);
dly750ns dly11(clk, reset, cmc_t3, cmc_t3_D2);
dly50ns dly12(clk, reset, cmpc_rs_set, cmpc_rs_set_D);
reg [0:35] sa; // "sense amplifiers"
wire [13:0] core_addr = cma[22:35];
assign m_address = { 4'b0, core_addr };
assign m_writedata = cmb;
always @(posedge clk or posedge reset) begin
if(reset) begin
m_read <= 0;
m_write <= 0;
sa <= 0;
// value doesn't matter
cmc_last_proc <= 0;
// these should probably be reset but aren't
cmc_proc_rs <= 0;
cmc_pse_sync <= 0;
end else begin
if(m_write & ~m_waitrequest) begin
m_write <= 0;
end
if(m_read & ~m_waitrequest) begin
m_read <= 0;
sa <= m_readdata;
end
if(cmc_state_clr) begin
cmc_p0_act <= 0;
cmc_p1_act <= 0;
cmc_p2_act <= 0;
cmc_p3_act <= 0;
end
if(cmpc_p0_rq | cmpc_p1_rq | cmpc_p2_rq | cmpc_p3_rq) begin
if(cmpc_p0_rq) begin
cmc_p0_act <= 1;
cmc_p1_act <= 0;
cmc_p2_act <= 0;
cmc_p3_act <= 0;
end else if(cmpc_p1_rq) begin
cmc_p0_act <= 0;
cmc_p1_act <= 1;
cmc_p2_act <= 0;
cmc_p3_act <= 0;
end else if(cmpc_p2_rq & cmpc_p3_rq) begin
cmc_p0_act <= 0;
cmc_p1_act <= 0;
cmc_p2_act <= cmc_last_proc;
cmc_p3_act <= ~cmc_last_proc;
cmc_last_proc <= ~cmc_last_proc;
end else if(cmpc_p2_rq) begin
cmc_p0_act <= 0;
cmc_p1_act <= 0;
cmc_p2_act <= 1;
cmc_p3_act <= 0;
end else if(cmpc_p3_rq) begin
cmc_p0_act <= 0;
cmc_p1_act <= 0;
cmc_p2_act <= 0;
cmc_p3_act <= 1;
end
end
if(cmc_t2) begin
if(cmc_p2_act)
cmc_last_proc <= 0;
if(cmc_p3_act)
cmc_last_proc <= 1;
end
if(cmc_t0 | cmc_await_rq_reset)
cmc_await_rq <= 0;
if(cmc_t5 | cmc_aw_rq_set)
cmc_await_rq <= 1;
if(cmc_start | cmc_pwr_clr)
cmc_rq_sync <= 0;
if(cmc_rq_sync_set | cmc_t0 & cmc_sp)
cmc_rq_sync <= 1;
if(cmc_pwr_clr)
cmc_cyc_done <= 0;
if(cmc_t6 & ~cmc_stop)
cmc_cyc_done <= 1;
if(cmc_t1b) begin
cmc_pse_sync <= 0;
cmc_proc_rs <= 0;
cmc_stop <= 0;
end
// actually through another PA
if(cmc_pse_sync_set)
cmc_pse_sync <= 1;
if(cmpc_rs_set_D)
cmc_proc_rs <= 1;
if(cmc_start)
cmc_stop <= 0;
if(cmc_t2 & sw_single_step)
cmc_stop <= 1;
if(cmc_t2) begin
cmc_rq_sync <= 0;
cmc_cyc_done <= 0;
end
if(cmc_jam_cma) begin
cma <= ma_in;
cma_rd_rq <= rd_rq_in;
cma_wr_rq <= wr_rq_in;
end
cmb <= cmb | mb_in;
if(cmc_cmb_clr)
cmb <= 0;
if(strobe_sense)
cmb <= cmb | sa;
/* Core */
if(cmc_pwr_clr | cmc_t5) begin
cmc_read <= 0;
cmc_write <= 0;
cmc_inh <= 0;
end
if(cmc_t1a) begin
cmc_read <= 1;
m_read <= 1;
cmc_write <= 0;
end
if(cmc_read_off)
cmc_read <= 0;
if(cmc_t3)
cmc_inh <= 1;
if(cmc_t4) begin
cmc_write <= 1;
m_write <= 1;
cmc_read <= 0;
end
end
end
endmodule