From fb47930b1b212ca94ccdbeb16ad8a2c6a2117940 Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 9 Nov 2016 19:21:09 +0100 Subject: [PATCH] started to write a verilog simulation --- verilog/Makefile | 5 + verilog/apr.v | 565 ++++++++++++++++++++++++++++++++++++++++++++++ verilog/coremem.v | 255 +++++++++++++++++++++ verilog/fastmem.v | 195 ++++++++++++++++ verilog/modules.v | 173 ++++++++++++++ verilog/test.gtkw | 303 +++++++++++++++++++++++++ verilog/test.v | 219 ++++++++++++++++++ 7 files changed, 1715 insertions(+) create mode 100644 verilog/Makefile create mode 100644 verilog/apr.v create mode 100644 verilog/coremem.v create mode 100644 verilog/fastmem.v create mode 100644 verilog/modules.v create mode 100644 verilog/test.gtkw create mode 100644 verilog/test.v diff --git a/verilog/Makefile b/verilog/Makefile new file mode 100644 index 0000000..650c709 --- /dev/null +++ b/verilog/Makefile @@ -0,0 +1,5 @@ +a.out: test.v apr.v coremem.v fastmem.v modules.v + iverilog test.v apr.v coremem.v fastmem.v modules.v + +run: a.out + vvp a.out diff --git a/verilog/apr.v b/verilog/apr.v new file mode 100644 index 0000000..e8dfb99 --- /dev/null +++ b/verilog/apr.v @@ -0,0 +1,565 @@ +//`default_nettype none + +module ar_reg( + input clk, + input arlt_clr, + input arrt_clr, + input arlt_fm_mb0, + input arrt_fm_mb0, + input arlt_fm_mb1, + input arrt_fm_mb1, + input arlt_fm_datasw1, + input arrt_fm_datasw1, + input [0:35] mb, + input [0:35] datasw, + output [0:35] ar +); + reg [0:17] arlt; + reg [18:35] arrt; + + always @(posedge clk) begin: arctl + integer i; + if(arlt_clr) + arlt <= 0; + if(arrt_clr) + arrt <= 0; + for(i = 0; i < 18; i = i+1) begin + if(arlt_fm_mb0 & ~mb[i]) + arlt[i] <= 0; + if(arlt_fm_mb1 & mb[i]) + arlt[i] <= 1; + if(arrt_fm_mb0 & ~mb[i+18]) + arrt[i+18] <= 0; + if(arrt_fm_mb1 & mb[i+18]) + arrt[i+18] <= 1; + end + if(arlt_fm_datasw1) + arlt <= arlt | datasw[0:17]; + if(arlt_fm_datasw1) + arrt <= arrt | datasw[18:35]; + end + + assign ar = {arlt, arrt}; +endmodule + +module mb_reg( + input clk, + input mblt_clr, + input mbrt_clr, + input mblt_fm_ar0, + input mbrt_fm_ar0, + input mblt_fm_ar1, + input mbrt_fm_ar1, + input mblt_fm_mbrtJ, + input mbrt_fm_mbltJ, + input [0:35] mbN_clr, + input [0:35] mbN_set, + input [0:35] ar, + output [0:35] mb +); + reg [0:17] mblt; + reg [18:35] mbrt; + + always @(posedge clk) begin: mbctl + integer i; + if(mblt_clr) + mblt <= 0; + if(mbrt_clr) + mbrt <= 0; + for(i = 0; i < 18; i = i+1) begin + if(mblt_fm_ar0 & ~ar[i]) + mblt[i] <= 0; + if(mblt_fm_ar1 & ar[i]) + mblt[i] <= 1; + if(mbrt_fm_ar0 & ~ar[i+18]) + mbrt[i+18] <= 0; + if(mbrt_fm_ar1 & ar[i+18]) + mbrt[i+18] <= 1; + end + for(i = 0; i < 18; i = i+1) begin + if(mbN_clr[i]) + mblt[i] <= 0; + if(mbN_clr[i+18]) + mbrt[i+18] <= 0; + if(mbN_set[i]) + mblt[i] <= 1; + if(mbN_set[i+18]) + mbrt[i+18] <= 1; + end + if(mblt_fm_mbrtJ) + mblt <= mbrt; + if(mbrt_fm_mbltJ) + mbrt <= mblt; + end + + assign mb = {mblt, mbrt}; +endmodule + +module pc_reg( + input clk, + input pc_clr, + input pc_inc, + input pc_fm_ma1, + input [18:35] ma, + output [18:35] pc +); + reg [18:35] pc; + + always @(posedge clk) begin + if(pc_clr) + pc <= 0; + if(pc_inc) + pc <= pc+1; + if(pc_fm_ma1) + pc <= pc | ma; + end +endmodule + +module ma_reg( + input clk, + input ma_clr, + input ma_inc, + input key_ma_fm_masw1, + input ma_fm_pc1, + input [18:35] mas, + input [18:35] pc, + output [18:35] ma +); + reg [18:35] ma; + reg en_cry; + reg ma32_cry_out; + + initial + en_cry = 0; + + always @(posedge clk) begin + if(ma_clr) + ma <= 0; + if(ma_inc) begin + {ma32_cry_out, ma[32:35]} = ma[32:35]+1; + ma[18:31] = ma[18:31] + (ma32_cry_out & en_cry); + end + if(key_ma_fm_masw1) + ma <= ma | mas; + end +endmodule + +module apr( + input clk, + input key_start, + input key_read_in, + input key_inst_cont, + input key_mem_cont, + input key_inst_stop, + input key_mem_stop, + input key_exec, + input key_ioreset, + input key_dep, + input key_dep_nxt, + input key_ex, + input key_ex_nxt, + input sw_addr_stop, + input sw_mem_disable, + input sw_repeat, + input sw_power, + input sw_rim_maint, + output [0:35] mi, + input [18:35] mas, + input [0:35] datasw, + + output membus_mc_wr_rs, + output membus_mc_rq_cyc, + output membus_mc_rd_rq, + output membus_mc_wr_rq, + output [21:35] membus_ma, + output [18:21] membus_sel, + output membus_fmc_select, + output [0:35] membus_mb_out, + + input membus_mai_cmc_addr_ack, + input membus_mai_cmc_rd_rs, + input [0:35] membus_mb_in +); + + reg run; + reg [0:35] mi; + wire [18:35] ma; + wire [18:35] pc; + wire [0:35] ar; + wire [0:35] mb; + wire [0:35] mbN_clr; + wire [0:35] mbN_set; + + // TMP + assign st7 = 0; + + /****** + * MA * + ******/ + + ma_reg ma_reg( + .clk(clk), + .ma_clr(ma_clr), + .ma_inc(ma_inc), + .key_ma_fm_masw1(key_ma_fm_masw1), + .mas(mas), + .pc(pc), + .ma(ma)); + assign ma_inc = key_ma_inc; + assign ma_clr = key_ma_clr; + + /****** + * PC * + ******/ + + pc_reg pc_reg( + .clk(clk), + .pc_clr(pc_clr), + .pc_inc(pc_inc), + .pc_fm_ma1(pc_fm_ma1), + .ma(ma), + .pc(pc)); + assign pc_clr = kt1 & key_start_OR_read_in; + assign pc_fm_ma1 = kt3 & key_start_OR_read_in; + + /****** + * AR * + ******/ + + ar_reg ar_reg( + .clk(clk), + .arlt_clr(arlt_clr), + .arrt_clr(arrt_clr), + .arlt_fm_mb0(arlt_fm_mb0), + .arrt_fm_mb0(arrt_fm_mb0), + .arlt_fm_mb1(arlt_fm_mb1), + .arrt_fm_mb1(arrt_fm_mb1), + .arlt_fm_datasw1(arlt_fm_datasw1), + .arrt_fm_datasw1(arrt_fm_datasw1), + .mb(mb), + .datasw(datasw), + .ar(ar)); + assign arlt_clr = key_ar_clr; + assign arrt_clr = key_ar_clr; + assign arlt_fm_mb0 = ar_fm_mbJ; + assign arrt_fm_mb0 = ar_fm_mbJ; + assign arlt_fm_mb1 = ar_fm_mbJ; + assign arrt_fm_mb1 = ar_fm_mbJ; + assign arlt_fm_datasw1 = key_ar_fm_datasw1; + assign arrt_fm_datasw1 = key_ar_fm_datasw1; + assign ar_fm_mbJ = mbJ_swap_arJ; + + /****** + * MB * + ******/ + + mb_reg mb_reg( + .clk(clk), + .mblt_clr(mblt_clr), + .mbrt_clr(mbrt_clr), + .mblt_fm_ar0(mblt_fm_ar0), + .mbrt_fm_ar0(mbrt_fm_ar0), + .mblt_fm_ar1(mblt_fm_ar1), + .mbrt_fm_ar1(mbrt_fm_ar1), + .mblt_fm_mbrtJ(mblt_fm_mbrtJ), + .mbrt_fm_mbltJ(mbrt_fm_mbltJ), + .mbN_clr(mbN_clr), + .mbN_set(mbN_set), + .ar(ar), + .mb(mb)); + dly100ns mbdly1(.clk(clk), .in(mc_mb_clr), .out(mc_mb_clr_dly)); + assign mb_clr = mc_mb_clr_dly; + assign mblt_clr = mb_clr; + assign mbrt_clr = mb_clr; + assign mblt_fm_ar0 = mb_fm_arJ; + assign mbrt_fm_ar0 = mb_fm_arJ; + assign mblt_fm_ar1 = mb_fm_arJ; + assign mbrt_fm_ar1 = mb_fm_arJ; + assign mbN_set = membus_mb_in & {36{mc_mb_membus_enable}}; + + assign mblt_fm_mbrtJ = 0; + assign mbrt_fm_mbltJ = 0; + assign mb_fm_arJ = key_wr; + assign mbJ_swap_arJ = 0; + + /****** + * MI * + ******/ + + assign mi_clr = (mai_rd_rs | mc_wr_rs) & ma == mas | + mc_rs_t1 & key_ex_OR_dep_nxt; + dly100ns midly0(.clk(clk), .in(mi_clr), .out(mi_fm_mb1)); + always @(posedge clk) begin + if(mi_clr) + mi <= 0; + if(mi_fm_mb1) + mi <= mi | mb; + end + + /******* + * KEY * + *******/ + + reg key_ex_st, key_dep_st, key_ex_sync, key_dep_sync; + reg key_rim_sbr; + + // KEY-1 + assign key_clr_rim = ~(key_read_in | key_mem_cont | key_inst_cont); + assign key_ma_fm_mas = key_ex_sync | key_dep_sync | + key_start_OR_read_in; + assign key_execute = key_exec & ~run; + assign key_start_OR_read_in = key_start | key_read_in; + assign key_start_OR_cont_OR_read_in = key_start_OR_read_in | + key_inst_cont; + assign key_ex_OR_dep_nxt = key_ex_nxt | key_dep_nxt; + assign key_dp_OR_dp_nxt = key_dep_sync | key_dep_nxt; + assign key_ex_OR_ex_nxt = key_ex_sync | key_ex_nxt; + assign key_ex_OR_dep_st = key_ex_st | key_dep_st; + assign key_run1_AND_NOT_ex_OR_dep = run & ~key_ex_OR_dep_st; + assign key_manual = key_ex | key_ex_nxt | key_dep | key_dep_nxt | + key_start | key_inst_cont | key_mem_cont | key_ioreset | + key_execute | key_read_in; + assign key_run_AND_ex_OR_dep = run & key_ex_OR_dep_st; + assign key_execute_OR_dp_OR_dp_nxt = key_execute | key_dp_OR_dp_nxt; + + syncpulse keysync1(clk, sw_power, mr_pwr_clr); + syncpulse keysync2(clk, key_inst_stop, run_clr); + + always @(posedge clk) begin + if(mr_pwr_clr | run_clr) + run <= 0; + if(kt0a | key_go) begin + key_ex_st <= 0; + key_dep_st <= 0; + end + if(kt0a) begin + key_ex_sync <= key_ex; + key_dep_sync <= key_dep; + end + if(key_go) begin + key_ex_sync <= 0; + key_dep_sync <= 0; + run <= 1; + end + end + + + // KEY-2 + assign mr_start = mr_pwr_clr | kt1 & key_ioreset; + assign mr_clr = kt1 & key_manual & ~key_mem_cont | + mr_pwr_clr; // TODO: more + assign key_ma_clr = kt1 & key_ma_fm_mas; + assign key_ma_fm_masw1 = kt2 & key_ma_fm_mas; + assign key_ma_inc = kt1 & key_ex_OR_dep_nxt; + assign key_ar_clr = kt1 & key_execute_OR_dp_OR_dp_nxt; + assign key_ar_fm_datasw1 = kt2 & key_execute_OR_dp_OR_dp_nxt | + 0; // TODO: more + assign key_rd = kt3 & key_ex_OR_ex_nxt; + assign key_wr = kt3 & key_dp_OR_dp_nxt; + + syncpulse keysync3(clk, key_manual, kt0); + + assign kt0a = kt0; + dly100ns keydly1(.clk(clk), .in(kt0a), .out(key_tmp1)); + assign kt1 = kt0a & key_mem_cont | + key_tmp1 & ~run & ~key_mem_cont; // no key_mem_cont in the real hardware, why? + dly200ns keydly2(.clk(clk), .in(kt1 & ~run), .out(kt2)); + dly200ns keydly3(.clk(clk), .in(kt2), .out(kt3)); + assign kt4 = kt3 & key_execute | + key_rdwr_ret | + mc_stop_set & key_mem_cont | + st7 & key_start_OR_cont_OR_read_in; + assign key_go = kt3 & key_start_OR_cont_OR_read_in | + kt4 & key_run1_AND_NOT_ex_OR_dep; + + always @(posedge clk) begin + if(kt1 & key_clr_rim) + key_rim_sbr <= 0; + if(kt1 & key_read_in | sw_rim_maint) + key_rim_sbr <= 1; + end + + sbr key_rdwr( + .clk(clk), + .clr(mr_clr), + .set(key_rd | key_wr), + .from(mc_rs_t1), + .ret(key_rdwr_ret)); + + + /****** + * MC * + ******/ + + reg mc_rd, mc_wr, mc_rq, mc_stop, mc_stop_sync, mc_split_cyc_sync; + + assign mc_mb_membus_enable = mc_rd; + assign membus_mc_rq_cyc = mc_rq & (mc_rd | mc_wr); + assign membus_mc_rd_rq = mc_rd; + assign membus_mc_wr_rq = mc_wr; + assign membus_ma = {rla[21:25], ma[26:35]}; + assign membus_sel = rla[18:21]; + assign membus_fmc_select = ~key_rim_sbr & ma[18:31] == 0; + assign membus_mc_wr_rs = mc_wr_rs; + assign membus_mb_out = mc_wr_rs_b ? mb : 0; + + // pulses + assign mc_mb_clr = mc_rd_rq_pulse | + mc_rdwr_rq_pulse; + assign mc_rd_rq_pulse = key_rd; // TODO + assign mc_wr_rq_pulse = key_wr | + mc_rdwr_rs_pulse & mc_split_cyc_sync; // TODO + assign mc_split_rd_rq = 0; + assign mc_rdwr_rq_pulse = 0;//key_rd; // TODO + assign mc_rdwr_rs_pulse = 0;//key_wr; + assign mc_split_wr_rq = 0; + assign mc_rq_pulse = mc_rd_rq_pulse | + mc_wr_rq_pulse | + mc_rdwr_rq_pulse; + + dly100us mcdly1(.clk(clk), .in(mc_rq_pulse), .out(mc_tmp3)); + assign mc_non_exist_mem = mc_tmp3 & mc_rq & ~mc_stop; + assign mc_non_exist_mem_rst = mc_non_exist_mem & ~sw_mem_disable; + assign mc_non_exist_rd = mc_non_exist_mem_rst & mc_rd; + syncpulse syncmc1(.clk(clk), .in(membus_mai_cmc_addr_ack), .out(mai_addr_ack)); + assign mc_addr_ack = mai_addr_ack | mc_non_exist_mem_rst; + syncpulse syncmc2(.clk(clk), .in(membus_mai_cmc_rd_rs), .out(mai_rd_rs)); + assign mc_rs_t0 = kt1 & key_mem_cont & mc_stop | + (mc_wr_rs | mc_non_exist_rd | mai_rd_rs) & ~mc_stop; + dly50ns mcdly2(.clk(clk), .in(mc_rs_t0), .out(mc_rs_t1)); + syncpulse syncmc3(.clk(clk), .in(| membus_mb_in), .out(mb_pulse)); + assign mc_wr_rs = + kt1 & key_manual & mc_stop & mc_stop_sync & ~key_mem_cont | + mc_addr_ack & mc_wr & ~mc_rd | + mc_tmp1 & ~mc_split_cyc_sync; + pa100ns mcpa0(.clk(clk), .in(mc_wr_rs), .out(mc_wr_rs_b)); + dly100ns mcdly3(.clk(clk), .in(mc_rdwr_rs_pulse), .out(mc_tmp1)); + dly200ns mcdly4(.clk(clk), .in(mc_rq_pulse), .out(mc_tmp2)); + assign mc_stop_set = mc_tmp2 & + (key_mem_stop | ma == mas & sw_addr_stop); + dly50ns mcdly5(.clk(clk), .in(mc_rq_pulse), .out(mc_tmp4)); + dly150ns mcdly6(.clk(clk), .in(mc_rq_pulse), .out(mc_tmp5)); + assign mc_rq_set = mc_tmp4 & ex_inh_rel | + mc_tmp5 & pr_rel_AND_ma_ok; + assign mc_illeg_address = mc_tmp5 & pr_rel_AND_NOT_ma_ok; + // TODO: 100ns -> ST7 + + always @(posedge clk) begin + if(mr_clr) begin + mc_rd <= 0; + mc_wr <= 0; + mc_rq <= 0; + mc_stop <= 0; + mc_stop_sync <= 0; + mc_split_cyc_sync <= 0; + end + if(mc_wr_rq_pulse | mc_rs_t1) + mc_rd <= 0; + if(mc_rd_rq_pulse | mc_rdwr_rq_pulse) + mc_rd <= 1; + if(mc_rd_rq_pulse) + mc_wr <= 0; + if(mc_wr_rq_pulse | mc_rdwr_rq_pulse) + mc_wr <= 1; + if(mc_addr_ack) + mc_rq <= 0; + if(mc_rq_set) + mc_rq <= 1; + if(mc_rq_pulse) + mc_stop <= 0; + if(mc_stop_set) + mc_stop <= 1; + if(mc_rdwr_rq_pulse) + mc_stop_sync <= 1; + // TODO: set mc_split_cyc_sync + end + + /* + * Memory relocation + */ + + reg [18:25] pr; + reg [18:25] rlr; + wire [18:25] rla; + + assign rla = ma[18:25] + (ex_inh_rel ? 0 : rlr); + assign pr18ok = ma[18:25] <= pr; + assign pr_rel_AND_ma_ok = pr18ok & ~ex_inh_rel; + assign pr_rel_AND_NOT_ma_ok = ~pr18ok & ~ex_inh_rel; + + /****** + * EX * + ******/ + + reg ex_user, ex_mode_sync, ex_uuo_sync, ex_pi_sync, ex_ill_op; + + assign ex_inh_rel = ~ex_user | ex_pi_sync | (ma[18:31] == 0) | ex_ill_op; + assign ex_clr = mr_start | + 0; // TODO + + always @(posedge clk) begin + if(mr_clr) begin + if(ex_mode_sync) + ex_user <= 1; + ex_mode_sync <= 0; + ex_uuo_sync <= 0; + if(~pi_cyc) + ex_pi_sync <= 0; + end + if(mr_start) begin + ex_user <= 0; + ex_ill_op <= 0; + end + if(ex_clr) begin + pr <= 0; + rlr <= 0; + end + end + + /****** + * PI * + ******/ + + reg pi_ov, pi_cyc, pi_active; + + assign pi_reset = mr_start | + 0; // TODO + + always @(posedge clk) begin + if(mr_start) begin + pi_ov <= 0; + pi_cyc <= 0; + end + if(pi_reset) + pi_active <= 0; + end + + /******* + * CPA * + *******/ + + reg cpa_iot_user, cpa_illeg_op, cpa_non_exist_mem; + reg cpa_clock_enable, cpa_clock_flag; + reg cpa_pc_chg_enable, cpa_pdl_ov; + reg cpa_arov_enable; + reg [33:35] cpa_pia; + + always @(posedge clk) begin + if(mr_start) begin + cpa_iot_user <= 0; + cpa_illeg_op <= 0; + cpa_non_exist_mem <= 0; + cpa_clock_enable <= 0; + cpa_clock_flag <= 0; + cpa_pc_chg_enable <= 0; + cpa_pdl_ov <= 0; + cpa_arov_enable <= 0; + cpa_pia <= 0; + end + if(mc_illeg_address) + cpa_illeg_op <= 1; + if(mc_non_exist_mem) + cpa_non_exist_mem <= 1; + end + +endmodule diff --git a/verilog/coremem.v b/verilog/coremem.v new file mode 100644 index 0000000..9cc4254 --- /dev/null +++ b/verilog/coremem.v @@ -0,0 +1,255 @@ +module coremem16k( + input clk, + + input mc_wr_rs_p0, + input mc_rq_cyc_p0, + input mc_rd_rq_p0, + input mc_wr_rq_p0, + input [21:35] ma_p0, + input [18:21] sel_p0, + input fmc_select_p0, + input [0:35] mb_in_p0, + output cmc_addr_ack_p0, + output cmc_rd_rs_p0, + output [0:35] mb_out_p0, + + input mc_wr_rs_p1, + input mc_rq_cyc_p1, + input mc_rd_rq_p1, + input mc_wr_rq_p1, + input [21:35] ma_p1, + input [18:21] sel_p1, + input fmc_select_p1, + input [0:35] mb_in_p1, + output cmc_addr_ack_p1, + output cmc_rd_rs_p1, + output [0:35] mb_out_p1, + + input mc_wr_rs_p2, + input mc_rq_cyc_p2, + input mc_rd_rq_p2, + input mc_wr_rq_p2, + input [21:35] ma_p2, + input [18:21] sel_p2, + input fmc_select_p2, + input [0:35] mb_in_p2, + output cmc_addr_ack_p2, + output cmc_rd_rs_p2, + output [0:35] mb_out_p2, + + input mc_wr_rs_p3, + input mc_rq_cyc_p3, + input mc_rd_rq_p3, + input mc_wr_rq_p3, + input [21:35] ma_p3, + input [18:21] sel_p3, + input fmc_select_p3, + input [0:35] mb_in_p3, + output cmc_addr_ack_p3, + output cmc_rd_rs_p3, + output [0:35] mb_out_p3 +); + + wire [21:35] ma; + wire [0:35] mb_out; + wire [0:35] mb_in; + wire cmc_power_start; + + reg power; + reg single_step_sw; + reg restart_sw; + reg [0:3] memsel_p0; + reg [0:3] memsel_p1; + reg [0:3] memsel_p2; + reg [0:3] memsel_p3; + + reg cmc_p0_act, cmc_p1_act, cmc_p2_act, cmc_p3_act; + reg cmc_last_proc; + reg cmc_aw_rq, cmc_proc_rs, cmc_pse_sync, cmc_stop; + reg cmc_rd, cmc_wr, cmc_inhibit; + reg [0:35] cmb; + reg [22:35] cma; + reg cma_rd_rq, cma_wr_rq; + reg [0:36] core[0:040000]; + + assign cyc_rq_p0 = memsel_p0 == sel_p0 & ~fmc_select_p0 & mc_rq_cyc_p0; + assign cyc_rq_p1 = memsel_p1 == sel_p1 & ~fmc_select_p1 & mc_rq_cyc_p1; + assign cyc_rq_p2 = memsel_p2 == sel_p2 & ~fmc_select_p2 & mc_rq_cyc_p2; + assign cyc_rq_p3 = memsel_p3 == sel_p3 & ~fmc_select_p3 & mc_rq_cyc_p3; + assign cmpc_p0_rq = cyc_rq_p0 & cmc_aw_rq; + assign cmpc_p1_rq = cyc_rq_p1 & cmc_aw_rq; + assign cmpc_p2_rq = cyc_rq_p2 & cmc_aw_rq; + assign cmpc_p3_rq = cyc_rq_p3 & cmc_aw_rq; + + // simulate power on + initial begin + power = 0; + cmc_aw_rq = 0; + cmc_rd = 0; + cmc_wr = 0; + single_step_sw = 0; + restart_sw = 0; + + cmc_proc_rs = 0; + cmc_pse_sync = 0; + cmc_last_proc = 0; + #500; + power = 1; + end + + // there has to be a better way.... + // from proc to mem + assign mc_wr_rs = cmc_p0_act ? mc_wr_rs_p0 : + cmc_p1_act ? mc_wr_rs_p1 : + cmc_p2_act ? mc_wr_rs_p2 : + cmc_p3_act ? mc_wr_rs_p3 : 0; + assign mc_rq_cyc = cmc_p0_act ? mc_rq_cyc_p0 : + cmc_p1_act ? mc_rq_cyc_p1 : + cmc_p2_act ? mc_rq_cyc_p2 : + cmc_p3_act ? mc_rq_cyc_p3 : 0; + assign mc_rd_rq = cmc_p0_act ? mc_rd_rq_p0 : + cmc_p1_act ? mc_rd_rq_p1 : + cmc_p2_act ? mc_rd_rq_p2 : + cmc_p3_act ? mc_rd_rq_p3 : 0; + assign mc_wr_rq = cmc_p0_act ? mc_wr_rq_p0 : + cmc_p1_act ? mc_wr_rq_p1 : + cmc_p2_act ? mc_wr_rq_p2 : + cmc_p3_act ? mc_wr_rq_p3 : 0; + assign ma = cmc_p0_act ? ma_p0 : + cmc_p1_act ? ma_p1 : + cmc_p2_act ? ma_p2 : + cmc_p3_act ? ma_p3 : 0; + assign mb_in = cmc_p0_act ? mb_in_p0 : + cmc_p1_act ? mb_in_p1 : + cmc_p2_act ? mb_in_p2 : + cmc_p3_act ? mb_in_p3 : 0; + + // from mem to proc + assign cmc_addr_ack_p0 = cmc_addr_ack & cmc_p0_act; + assign cmc_rd_rs_p0 = cmc_rd_rs & cmc_p0_act; + assign mb_out_p0 = cmc_p0_act ? mb_out : 0; + assign cmc_addr_ack_p1 = cmc_addr_ack & cmc_p1_act; + assign cmc_rd_rs_p1 = cmc_rd_rs & cmc_p1_act; + assign mb_out_p1 = cmc_p1_act ? mb_out : 0; + assign cmc_addr_ack_p2 = cmc_addr_ack & cmc_p2_act; + assign cmc_rd_rs_p2 = cmc_rd_rs & cmc_p2_act; + assign mb_out_p2 = cmc_p2_act ? mb_out : 0; + assign cmc_addr_ack_p3 = cmc_addr_ack & cmc_p3_act; + assign cmc_rd_rs_p3 = cmc_rd_rs & cmc_p3_act; + assign mb_out_p3 = cmc_p3_act ? mb_out : 0; + + syncpulse synccmc0(.clk(clk), .in(cmc_aw_rq & mc_rq_cyc), .out(cmc_t0)); + syncpulse synccmc2(.clk(clk), .in(mc_wr_rs), .out(mc_wr_rs_S)); + + dly200ns cmcdly1(.clk(clk), .in(cmc_t0), .out(cmc_t1)); + assign cmc_addr_ack = cmc_t1; + dly1000ns cmcdly2(.clk(clk), .in(cmc_t1), .out(cmc_t2)); + dly1000ns cmcdly3(.clk(clk), .in(cmc_t2), .out(cmc_t4)); + dly200ns cmcdly4(.clk(clk), .in(cmc_t4), .out(cmc_t5)); + assign cmc_t6 = cmc_t5 & ~cma_wr_rq | cmc_tmp4; + dly200ns cmcdly9(.clk(clk), .in(cmc_t6), .out(cmc_t7)); + dly200ns cmcdly10(.clk(clk), .in(cmc_t7), .out(cmc_t8)); + dly1000ns cmcdly11(.clk(clk), .in(cmc_t8), .out(cmc_t9)); + dly400ns cmcdly12(.clk(clk), .in(cmc_t9), .out(cmc_t9a)); + assign cmc_t10 = cmc_t9a & ~cmc_stop | cmc_pwr_start; + dly100ns cmcdly13(.clk(clk), .in(cmc_t10), .out(cmc_t11)); + dly200ns cmcdly14(.clk(clk), .in(cmc_t9a), .out(cmc_t12)); + dly800ns cmcdly5(.clk(clk), .in(cmc_t2), .out(cmc_tmp1)); + assign cmc_strb_sa = cmc_tmp1 & cma_rd_rq; + dly100ns cmcdly6(.clk(clk), .in(cmc_strb_sa), .out(cmc_rd_rs)); + dly250ns cmcdly7(.clk(clk), .in(cmc_strb_sa), .out(cmc_tmp2)); + dly200ns cmcdly8(.clk(clk), .in(cmc_strb_sa), .out(cmc_tmp3)); + assign cmc_cmb_clr = cmc_t0 | cmc_tmp2 & cma_wr_rq; + assign cmc_state_clr = cmc_tmp3 & ~cma_wr_rq | cmc_t10 | cmc_proc_rs1; + syncpulse synccmc1(.clk(clk), .in(| mb_in), .out(mb_pulse)); + syncpulse synccmc3(.clk(clk), .in(cmc_proc_rs & cmc_pse_sync), .out(cmc_tmp4)); + syncpulse synccmc4(.clk(clk), .in(cmc_proc_rs), .out(cmc_proc_rs1)); + syncpulse synccmc5(.clk(clk), .in(power), .out(cmc_pwr_start)); + + // generate a longer pulse so processor has time to read + pa100ns cmcpa0(.clk(clk), .in(cmc_strb_sa), .out(cmc_strb_sa_b)); + assign mb_out = cmc_strb_sa_b ? core[cma] : 0; + + wire [0:35] corescope; + assign corescope = core[cma]; + + always @(posedge clk) begin + if(cmc_power_start) + cmc_aw_rq <= 1; + if(cmc_aw_rq) begin + if(cmpc_p0_rq) + cmc_p0_act <= 1; + else if(cmpc_p1_rq) + cmc_p1_act <= 1; + else if(cmpc_p2_rq) begin + if(~cmpc_p3_rq | cmc_last_proc) + cmc_p2_act <= 1; + end else if(cmpc_p3_rq) begin + if(~cmpc_p2_rq | ~cmc_last_proc) + cmc_p3_act <= 1; + end + end + if(cmc_state_clr) begin + cmc_p0_act <= 0; + cmc_p1_act <= 0; + cmc_p2_act <= 0; + cmc_p3_act <= 0; + end + if(cmc_t0) begin + cmc_aw_rq <= 0; + cmc_proc_rs <= 0; + cmc_pse_sync <= 0; + cmc_stop <= 0; + cma <= 0; + cma_rd_rq <= 0; + cma_wr_rq <= 0; + end + if(cmc_t1) begin + cma <= cma | ma_p0[22:35]; + if(mc_rd_rq) + cma_rd_rq <= 1; + if(mc_wr_rq) + cma_wr_rq <= 1; + end + if(cmc_t2) begin + cmc_rd <= 1; + if(cmc_p2_act) + cmc_last_proc <= 0; + if(cmc_p3_act) + cmc_last_proc <= 1; + end + if(cmc_t5) begin + // this is hack, normally core should be cleared + // roughly at the time of cmc_strb_sa, which is + // however does not happen on a write + core[cma] <= 0; + cmc_rd <= 0; + cmc_pse_sync <= 1; + end + if(cmc_t7) + cmc_inhibit <= 1; // totally useless + if(cmc_t8) + cmc_wr <= 1; + if(cmc_t9 & cmc_wr) + // again a hack, core is written some time after T8 + // ...and we know cmc_wr is set then anway. + core[cma] <= core[cma] | cmb; + if(cmc_t11) + cmc_aw_rq <= 1; + if(cmc_t12) begin + cmc_rd <= 0; + cmc_wr <= 0; + cmc_inhibit <= 0; + end + if(mc_wr_rs_S) + cmc_proc_rs <= 1; + if(cmc_strb_sa) begin + cmb <= mb_out; + end + if(cmc_cmb_clr) + cmb <= 0; + if(mb_pulse) + cmb <= cmb | mb_in; + end + +endmodule diff --git a/verilog/fastmem.v b/verilog/fastmem.v new file mode 100644 index 0000000..278cd49 --- /dev/null +++ b/verilog/fastmem.v @@ -0,0 +1,195 @@ +module fastmem( + input clk, + + input mc_wr_rs_p0, + input mc_rq_cyc_p0, + input mc_rd_rq_p0, + input mc_wr_rq_p0, + input [21:35] ma_p0, + input [18:21] sel_p0, + input fmc_select_p0, + input [0:35] mb_in_p0, + output cmc_addr_ack_p0, + output cmc_rd_rs_p0, + output [0:35] mb_out_p0, + + input mc_wr_rs_p1, + input mc_rq_cyc_p1, + input mc_rd_rq_p1, + input mc_wr_rq_p1, + input [21:35] ma_p1, + input [18:21] sel_p1, + input fmc_select_p1, + input [0:35] mb_in_p1, + output cmc_addr_ack_p1, + output cmc_rd_rs_p1, + output [0:35] mb_out_p1, + + input mc_wr_rs_p2, + input mc_rq_cyc_p2, + input mc_rd_rq_p2, + input mc_wr_rq_p2, + input [21:35] ma_p2, + input [18:21] sel_p2, + input fmc_select_p2, + input [0:35] mb_in_p2, + output cmc_addr_ack_p2, + output cmc_rd_rs_p2, + output [0:35] mb_out_p2, + + input mc_wr_rs_p3, + input mc_rq_cyc_p3, + input mc_rd_rq_p3, + input mc_wr_rq_p3, + input [21:35] ma_p3, + input [18:21] sel_p3, + input fmc_select_p3, + input [0:35] mb_in_p3, + output cmc_addr_ack_p3, + output cmc_rd_rs_p3, + output [0:35] mb_out_p3 +); + wire [0:35] mb_out; + wire [0:35] mb_in; + + reg power; + reg single_step_sw; + reg restart_sw; + reg [0:3] memsel_p0; + reg [0:3] memsel_p1; + reg [0:3] memsel_p2; + reg [0:3] memsel_p3; + reg fmc_p0_sel; + reg fmc_p1_sel; + reg fmc_p2_sel; + reg fmc_p3_sel; + + reg fmc_act, fmc_rd0, fmc_rs, fmc_stop, fmc_wr; + reg [0:35] ff[0:16]; + wire [32:35] fma; + wire fma_rd_rq, fma_wr_rq; + wire [0:35] fm_out; + + // simulate power on + initial begin + power = 0; + single_step_sw = 0; + restart_sw = 0; + #500 power = 1; + end + + assign fma = fmc_p0_sel ? ma_p0[32:35] : + fmc_p1_sel ? ma_p1[32:35] : + fmc_p2_sel ? ma_p2[32:35] : + fmc_p3_sel ? ma_p3[32:35] : 0; + assign mb_in = fmc_p0_sel ? mb_in_p0 : + fmc_p1_sel ? mb_in_p1 : + fmc_p2_sel ? mb_in_p2 : + fmc_p3_sel ? mb_in_p3 : 0; + assign fmc_wr_rs = fmc_p0_sel ? mc_wr_rs_p0 : + fmc_p1_sel ? mc_wr_rs_p1 : + fmc_p2_sel ? mc_wr_rs_p2 : + fmc_p3_sel ? mc_wr_rs_p3 : 0; + assign fma_rd_rq = fmc_p0_sel ? mc_rd_rq_p0 : + fmc_p1_sel ? mc_rd_rq_p1 : + fmc_p2_sel ? mc_rd_rq_p2 : + fmc_p3_sel ? mc_rd_rq_p3 : 0; + assign fma_wr_rq = fmc_p0_sel ? mc_wr_rq_p0 : + fmc_p1_sel ? mc_wr_rq_p1 : + fmc_p2_sel ? mc_wr_rq_p2 : + fmc_p3_sel ? mc_wr_rq_p3 : 0; + assign cmc_addr_ack_p0 = fmc_addr_ack & fmc_p0_sel; + assign cmc_rd_rs_p0 = fmc_rd_rs & fmc_p0_sel; + assign mb_out_p0 = fmc_p0_sel ? mb_out : 0; + assign cmc_addr_ack_p1 = fmc_addr_ack & fmc_p1_sel; + assign cmc_rd_rs_p1 = fmc_rd_rs & fmc_p1_sel; + assign mb_out_p1 = fmc_p1_sel ? mb_out : 0; + assign cmc_addr_ack_p2 = fmc_addr_ack & fmc_p2_sel; + assign cmc_rd_rs_p2 = fmc_rd_rs & fmc_p2_sel; + assign mb_out_p2 = fmc_p2_sel ? mb_out : 0; + assign cmc_addr_ack_p3 = fmc_addr_ack & fmc_p3_sel; + assign cmc_rd_rs_p3 = fmc_rd_rs & fmc_p3_sel; + assign mb_out_p3 = fmc_p3_sel ? mb_out : 0; + + assign fmc_addr_ack = fmc_t0; + assign fmc_rd_rs = fmc_t1; + assign mb_out = fmc_rd_strb ? fm_out : 0; + assign fm_out = fma > 0 | fmc_rd0 ? ff[fma] : 0; + + assign fmc_p0_sel1 = fmc_p0_sel & ~fmc_stop; + assign fmc_p1_sel1 = fmc_p1_sel & ~fmc_stop; + assign fmc_p2_sel1 = fmc_p2_sel & ~fmc_stop; + assign fmc_p3_sel1 = fmc_p3_sel & ~fmc_stop; + assign fmc_p0_wr_sel = fmc_p0_sel & fmc_act & ~fma_rd_rq; + assign fmc_p1_wr_sel = fmc_p1_sel & fmc_act & ~fma_rd_rq; + assign fmc_p2_wr_sel = fmc_p2_sel & fmc_act & ~fma_rd_rq; + assign fmc_p3_wr_sel = fmc_p3_sel & fmc_act & ~fma_rd_rq; + assign fmpc_p0_rq = fmc_p0_sel1 & memsel_p0 == sel_p0 & + fmc_select_p0 & mc_rq_cyc_p0; + assign fmpc_p1_rq = fmc_p1_sel1 & memsel_p1 == sel_p1 & + fmc_select_p1 & mc_rq_cyc_p1; + assign fmpc_p2_rq = fmc_p2_sel1 & memsel_p2 == sel_p2 & + fmc_select_p2 & mc_rq_cyc_p2; + assign fmpc_p3_rq = fmc_p3_sel1 & memsel_p3 == sel_p3 & + fmc_select_p3 & mc_rq_cyc_p3; + + // Pulses + // the delays here aren't accurate, but gate delays accumulate + syncpulse syncfmc0(.clk(clk), .in(power), .out(fmc_pwr_start)); + syncpulse syncfmc1(.clk(clk), .in(fma_rd_rq), .out(fma_rd_rqD)); + dly50ns fmcdly0(.clk(clk), .in(fma_rd_rqD), .out(fmc_rd0_set)); + syncpulse syncfmc2(.clk(clk), .in(fmc_act), .out(fmc_t0)); + dly50ns fmcdly1(.clk(clk), .in(fmc_t0), .out(fmc_t0D)); + assign fmc_t1 = fmc_t0D & fma_rd_rq; + // generate a longer pulse so processor has time to read + pa100ns fmcpa0(.clk(clk), .in(fmc_t1), .out(fmc_rd_strb)); + dly100ns fmcdly2(.clk(clk), .in(fmc_t1), .out(fmc_t1D)); + assign fmc_t3 = fmc_t0D & ~fma_rd_rq & fma_wr_rq | + fmc_t1D & fma_wr_rq; + assign fmc_restart = fmc_pwr_start; + dly200ns fmcdly3(.clk(clk), .in(fmc_restart), .out(fmc_start), .level(fmc_clr)); + assign fmc_t4 = fmc_wr_rsD | fmc_t1D & ~fma_wr_rq; + dly50ns fmcdly4(.clk(clk), .in(fmc_t4), .out(fmc_t4D)); + assign fmc_t5 = fmc_start | fmc_t4D & ~fmc_stop; + + syncpulse syncfmc3(.clk(clk), .in(| mb_in), .out(fmb_in)); + syncpulse syncfmc4(.clk(clk), .in(fmc_wr_rs), .out(fmc_wr_rsS)); + dly50ns fmcdly5(.clk(clk), .in(fmc_wr_rsS), .out(fmc_wr_rsD)); + + wire [0:35] wordn; + assign wordn = ff[fma]; + + always @(posedge clk) begin + if(fmc_clr) begin + fmc_act <= 0; + fmc_stop <= 1; + end + if(fmpc_p0_rq | fmpc_p1_rq | fmpc_p2_rq | fmpc_p3_rq) + fmc_act <= 1; + if(fmc_rd0_set) + fmc_rd0 <= 1; + if(~fma_rd_rq) + fmc_rd0 <= 0; + if(fmc_t0) begin + fmc_rs <= 0; + fmc_stop <= single_step_sw; + end + if(fmc_t3) begin + fmc_wr <= 1; + ff[fma] <= 0; + end + if(fmc_t4) begin + fmc_rd0 <= 0; + fmc_act <= 0; + end + if(fmc_t5) begin + fmc_stop <= 0; + fmc_wr <= 0; + end + if(fmb_in & fmc_wr) + ff[fma] <= ff[fma] | mb_in; + if(fmc_wr_rsS) + fmc_rs <= 1; + end + +endmodule diff --git a/verilog/modules.v b/verilog/modules.v new file mode 100644 index 0000000..cecc5b0 --- /dev/null +++ b/verilog/modules.v @@ -0,0 +1,173 @@ +module syncpulse( + input clk, + input in, + output out +); + reg x0, x1; + initial begin + x0 <= 0; + x1 <= 0; + end + always @(posedge clk) begin + x0 <= in; + x1 <= x0; + end + assign out = x0 && !x1; +endmodule + +module sbr( + input clk, + input clr, + input set, + input from, + output ret +); + reg ff; + always @(posedge clk) begin + if(clr | from) + ff <= 0; + if(set) + ff <= 1; + end + assign ret = ff & from; +endmodule + +module pa100ns( + input clk, + input in, + output out +); + reg [1:0] r; + initial + r <= 0; + always @(posedge clk) begin + r = r << 1; + if(in) + r = 4'b11; + end + assign out = r[1]; +endmodule + +module dly50ns( + input clk, + input in, + output out +); + reg r; + initial + r <= 0; + always @(posedge clk) + r <= {r, in}; + assign out = r; +endmodule + +module dly100ns( + input clk, + input in, + output out +); + reg [1:0] r; + initial + r <= 0; + always @(posedge clk) + r <= {r, in}; + assign out = r[1]; +endmodule + +module dly150ns( + input clk, + input in, + output out +); + reg [2:0] r; + initial + r <= 0; + always @(posedge clk) + r <= {r, in}; + assign out = r[2]; +endmodule + +module dly200ns( + input clk, + input in, + output out, + output level +); + reg [3:0] r; + initial + r <= 0; + always @(posedge clk) + r <= {r, in}; + assign out = r[3]; + assign level = (|r[2:0]); +endmodule + +module dly250ns( + input clk, + input in, + output out +); + reg [4:0] r; + initial + r <= 0; + always @(posedge clk) + r <= {r, in}; + assign out = r[4]; +endmodule + +module dly400ns( + input clk, + input in, + output out +); + reg [7:0] r; + initial + r <= 0; + always @(posedge clk) + r <= {r, in}; + assign out = r[7]; +endmodule + +module dly800ns( + input clk, + input in, + output out +); + reg [15:0] r; + initial + r <= 0; + always @(posedge clk) + r <= {r, in}; + assign out = r[15]; +endmodule + + +module dly1000ns( + input clk, + input in, + output out +); + reg [19:0] r; + initial + r <= 0; + always @(posedge clk) + r <= {r, in}; + assign out = r[19]; +endmodule + +module dly100us( + input clk, + input in, + output out +); + reg [15:0] r; + initial + r <= 0; + always @(posedge clk) begin + if(r) + r = r + 1; + if(in) + r = 1; + end + assign out = r == 2000; +endmodule diff --git a/verilog/test.gtkw b/verilog/test.gtkw new file mode 100644 index 0000000..e7c77db --- /dev/null +++ b/verilog/test.gtkw @@ -0,0 +1,303 @@ +[*] +[*] GTKWave Analyzer v3.3.76 (w)1999-2016 BSI +[*] Tue Nov 8 22:00:50 2016 +[*] +[dumpfile] "/home/aap/src/verilog/dump.vcd" +[dumpfile_mtime] "Tue Nov 8 19:25:18 2016" +[dumpfile_size] 49349 +[savefile] "/home/aap/src/verilog/test.gtkw" +[timestart] 6847 +[size] 1916 1071 +[pos] -1 -1 +*-9.999172 8463 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] test. +[treeopen] test.fmem0. +[sst_width] 240 +[signals_width] 293 +[sst_expanded] 1 +[sst_vpaned_height] 286 +@28 +>-2 +test.apr.clk +@800200 +>0 +-regs +@30 +test.apr.ar[0:35] +test.apr.mb[0:35] +test.apr.pc[18:35] +test.apr.ma[18:35] +test.apr.mas[18:35] +test.apr.datasw[0:35] +test.apr.mi[0:35] +test.apr.rlr[18:25] +test.apr.rla[18:25] +@28 +test.apr.pr18ok +test.apr.pr_rel_AND_ma_ok +test.apr.pr_rel_AND_NOT_ma_ok +@1000200 +-regs +@800200 +-general +@28 +test.apr.run +test.apr.mr_clr +test.apr.mr_start +@1000200 +-general +@c00200 +-ma +@28 +test.apr.ma_reg.key_ma_fm_masw1 +test.apr.ma_reg.ma_clr +test.apr.ma_reg.ma_fm_pc1 +test.apr.ma_reg.ma_inc +@1401200 +-ma +@c00200 +-pc +@28 +test.apr.pc_clr +test.apr.pc_fm_ma1 +test.apr.pc_inc +@1401200 +-pc +@c00200 +-mb +@28 +test.apr.mblt_clr +test.apr.mbrt_clr +test.apr.mblt_fm_ar0 +test.apr.mbrt_fm_ar0 +test.apr.mblt_fm_ar1 +test.apr.mbrt_fm_ar1 +test.apr.mblt_fm_mbrtJ +test.apr.mbrt_fm_mbltJ +@1401200 +-mb +@c00200 +-ar +@28 +test.apr.arlt_clr +test.apr.arrt_clr +test.apr.arlt_fm_mb0 +test.apr.arrt_fm_mb0 +test.apr.arlt_fm_mb1 +test.apr.arrt_fm_mb1 +test.apr.arlt_fm_datasw1 +test.apr.arrt_fm_datasw1 +@1401200 +-ar +@c00200 +-keys +@28 +test.apr.key_start +test.apr.key_read_in +test.apr.key_mem_cont +test.apr.key_inst_cont +test.apr.key_mem_stop +test.apr.key_inst_stop +test.apr.key_exec +test.apr.key_ioreset +test.apr.key_dep +test.apr.key_dep_nxt +test.apr.key_ex +test.apr.key_ex_nxt +@1401200 +-keys +@c00200 +-keytime +@28 +test.apr.kt0 +test.apr.kt0a +test.apr.key_tmp1 +test.apr.kt1 +test.apr.kt2 +test.apr.kt3 +test.apr.kt4 +test.apr.key_wr +test.apr.key_rd +test.apr.key_rdwr_ret +test.apr.key_go +@1401200 +-keytime +@800200 +-EX +@28 +test.apr.ex_user +test.apr.ex_mode_sync +test.apr.ex_uuo_sync +test.apr.ex_pi_sync +test.apr.ex_ill_op +test.apr.ex_inh_rel +test.apr.ex_clr +@1000200 +-EX +@800200 +-MC +@28 +test.apr.mc_rd_rq_pulse +test.apr.mc_wr_rq_pulse +test.apr.mc_rdwr_rq_pulse +test.apr.mc_rdwr_rs_pulse +test.apr.mc_rq_pulse +test.apr.mc_tmp4 +test.apr.mc_tmp5 +test.apr.mc_illeg_address +test.apr.mc_non_exist_mem +test.apr.mc_non_exist_mem_rst +test.apr.mc_non_exist_rd +test.apr.mc_addr_ack +test.apr.mc_wr_rs +test.apr.mc_rs_t0 +test.apr.mc_rs_t1 +test.apr.mc_rd +test.apr.mc_mb_membus_enable +test.apr.mc_wr +test.apr.mc_rq +test.apr.mc_stop +test.apr.mc_stop_sync +test.apr.mc_split_cyc_sync +test.apr.mc_mb_clr +@1000200 +-MC +@800200 +-membus +@30 +test.apr.membus_ma[21:35] +test.apr.membus_sel[18:21] +@28 +test.apr.membus_fmc_select +test.apr.membus_mc_rq_cyc +test.apr.membus_mc_rd_rq +test.apr.membus_mc_wr_rq +test.apr.mc_mb_membus_enable +test.apr.membus_mai_cmc_addr_ack +test.apr.membus_mai_cmc_rd_rs +test.apr.membus_mc_wr_rs +@30 +test.apr.membus_mb_in[0:35] +test.apr.membus_mb_out[0:35] +@1000200 +-membus +@c00200 +-mem0 +@c00030 +test.mem0.ma[21:35] +@28 +(0)test.mem0.ma[21:35] +(1)test.mem0.ma[21:35] +(2)test.mem0.ma[21:35] +(3)test.mem0.ma[21:35] +(4)test.mem0.ma[21:35] +(5)test.mem0.ma[21:35] +(6)test.mem0.ma[21:35] +(7)test.mem0.ma[21:35] +(8)test.mem0.ma[21:35] +(9)test.mem0.ma[21:35] +(10)test.mem0.ma[21:35] +(11)test.mem0.ma[21:35] +(12)test.mem0.ma[21:35] +(13)test.mem0.ma[21:35] +(14)test.mem0.ma[21:35] +@1401200 +-group_end +@30 +test.mem0.mb_in[0:35] +test.mem0.mc_rq_cyc +test.mem0.mc_rd_rq +test.mem0.mc_wr_rq +test.mem0.mc_wr_rs +test.mem0.mb_out[0:35] +@28 +test.mem0.cmc_addr_ack +test.mem0.cmc_rd_rs +@30 +test.mem0.cma[22:35] +test.mem0.cma_rd_rq +test.mem0.cma_wr_rq +test.mem0.cmb[0:35] +@28 +test.mem0.cmc_p0_act +test.mem0.cmc_p1_act +test.mem0.cmc_p2_act +test.mem0.cmc_p3_act +test.mem0.cmc_last_proc +test.mem0.cmc_aw_rq +test.mem0.cmc_rd +test.mem0.cmc_wr +test.mem0.cmc_inhibit +test.mem0.cmc_pse_sync +test.mem0.cmc_proc_rs +test.mem0.cmc_pwr_start +test.mem0.mc_wr_rs +test.mem0.cmc_t0 +test.mem0.cmc_t1 +test.mem0.cmc_t2 +test.mem0.cmc_t4 +test.mem0.cmc_t5 +test.mem0.cmc_t6 +test.mem0.cmc_t7 +test.mem0.cmc_t8 +test.mem0.cmc_t9 +test.mem0.cmc_t9a +test.mem0.cmc_t10 +test.mem0.cmc_t11 +test.mem0.cmc_t12 +test.mem0.cmc_strb_sa +test.mem0.cmc_state_clr +test.mem0.cyc_rq_p0 +test.mem0.cyc_rq_p1 +test.mem0.cyc_rq_p2 +test.mem0.cyc_rq_p3 +test.mem0.cmpc_p0_rq +test.mem0.cmpc_p1_rq +test.mem0.cmpc_p2_rq +test.mem0.cmpc_p3_rq +@30 +test.mem0.corescope[0:35] +@1401200 +-mem0 +@800200 +-fmem0 +@28 +test.fmem0.fmc_wr_rsS +@22 +test.fmem0.fma[32:35] +@28 +test.fmem0.fma_rd_rq +test.fmem0.fma_wr_rq +test.fmem0.fmc_p0_wr_sel +test.fmem0.fmc_clr +test.fmem0.fmc_rd0 +test.fmem0.fmc_t0 +test.fmem0.fmc_t1 +test.fmem0.fmc_rd_strb +test.fmem0.fmc_t3 +test.fmem0.fmc_t4 +test.fmem0.fmc_t5 +test.fmem0.fmc_wr_rs +test.fmem0.fmc_pwr_start +test.fmem0.fmc_restart +test.fmem0.fmc_start +test.fmem0.fmc_act +test.fmem0.fmc_rd0 +test.fmem0.fmc_rs +test.fmem0.fmc_stop +test.fmem0.fmc_wr +test.fmem0.fmpc_p0_rq +test.fmem0.fmpc_p1_rq +test.fmem0.fmpc_p2_rq +test.fmem0.fmpc_p3_rq +@31 +test.fmem0.fm_out[0:35] +@28 +test.fmem0.fmb_in +@30 +test.fmem0.mb_in[0:35] +test.fmem0.wordn[0:35] +@1000200 +-fmem0 +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/verilog/test.v b/verilog/test.v new file mode 100644 index 0000000..39011ce --- /dev/null +++ b/verilog/test.v @@ -0,0 +1,219 @@ +`timescale 1ns/1ns + +module clock( + output clk +); + reg clk; + initial + clk = 0; + always + #25 clk = ~clk; + initial + #20000 $finish; +// #150000 $finish; + +endmodule + +//`define TESTKEY key_start +//`define TESTKEY key_read_in +//`define TESTKEY key_ex_nxt +`define TESTKEY key_ex +//`define TESTKEY key_dep +//`define TESTKEY key_mem_cont + +module test; + reg key_start, key_read_in; + reg key_inst_cont, key_mem_cont; + reg key_inst_stop, key_mem_stop; + reg key_exec, key_ioreset; + reg key_dep, key_dep_nxt; + reg key_ex, key_ex_nxt; + reg sw_addr_stop; + reg sw_mem_disable; + reg sw_repeat; + reg sw_power; + reg [18:35] mas; + reg [0:35] datasw; + reg sw_rim_maint; + + wire [0:35] mi; + wire [21:35] ma_p0; + wire [18:21] sel_p0; + wire [0:35] mb_in_p0; + wire [0:35] mb_out_p0_p; + wire [0:35] mb_out_p0_0; + wire [0:35] mb_out_p0_1; + + clock clock(.clk(clk)); + apr apr( + .clk(clk), + .key_start(key_start), + .key_read_in(key_read_in), + .key_inst_cont(key_inst_cont), + .key_mem_cont(key_mem_cont), + .key_inst_stop(key_inst_stop), + .key_mem_stop (key_mem_stop), + .key_exec(key_exec), + .key_ioreset(key_ioreset), + .key_dep(key_dep), + .key_dep_nxt(key_dep_nxt), + .key_ex(key_ex), + .key_ex_nxt(key_ex_nxt), + .sw_addr_stop(sw_addr_stop), + .sw_mem_disable(sw_mem_disable), + .sw_repeat(sw_repeat), + .sw_power(sw_power), + .sw_rim_maint(sw_rim_maint), + .mas(mas), + .datasw(datasw), + .mi(mi), + + .membus_mc_wr_rs(mc_wr_rs_p0), + .membus_mc_rq_cyc(mc_rq_cyc_p0), + .membus_mc_rd_rq(mc_rd_rq_p0), + .membus_mc_wr_rq(mc_wr_rq_p0), + .membus_ma(ma_p0), + .membus_sel(sel_p0), + .membus_fmc_select(fmc_select_p0), + .membus_mb_out(mb_out_p0_p), + + .membus_mai_cmc_addr_ack(cmc_addr_ack_p0), + .membus_mai_cmc_rd_rs(cmc_rd_rs_p0), + .membus_mb_in(mb_in_p0) + ); + + assign cmc_addr_ack_p0 = cmc_addr_ack_p0_0 | cmc_addr_ack_p0_1; + assign cmc_rd_rs_p0 = cmc_rd_rs_p0_0 | cmc_rd_rs_p0_1; + assign mb_in_p0 = mb_out_p0_p | mb_out_p0_0 | mb_out_p0_1; + + fastmem fmem0( + .clk(clk), + + .mc_wr_rs_p0(mc_wr_rs_p0), + .mc_rq_cyc_p0(mc_rq_cyc_p0), + .mc_rd_rq_p0(mc_rd_rq_p0), + .mc_wr_rq_p0(mc_wr_rq_p0), + .ma_p0(ma_p0), + .sel_p0(sel_p0), + .fmc_select_p0(fmc_select_p0), + .mb_in_p0(mb_in_p0), + + .cmc_addr_ack_p0(cmc_addr_ack_p0_0), + .cmc_rd_rs_p0(cmc_rd_rs_p0_0), + .mb_out_p0(mb_out_p0_0), + + .mc_rq_cyc_p1(1'b1), + .sel_p1(4'b0000), + .fmc_select_p1(1'b1), + + .mc_rq_cyc_p2(1'b1), + .sel_p2(4'b0000), + .fmc_select_p2(1'b1), + + .mc_rq_cyc_p3(1'b1), + .sel_p3(4'b0000), + .fmc_select_p3(1'b1) + ); + + coremem16k mem0( + .clk(clk), + + .mc_wr_rs_p0(mc_wr_rs_p0), + .mc_rq_cyc_p0(mc_rq_cyc_p0), + .mc_rd_rq_p0(mc_rd_rq_p0), + .mc_wr_rq_p0(mc_wr_rq_p0), + .ma_p0(ma_p0), + .sel_p0(sel_p0), + .fmc_select_p0(fmc_select_p0), + .mb_in_p0(mb_in_p0), + + .cmc_addr_ack_p0(cmc_addr_ack_p0_1), + .cmc_rd_rs_p0(cmc_rd_rs_p0_1), + .mb_out_p0(mb_out_p0_1), + + .mc_rq_cyc_p1(1'b0), + .sel_p1(4'b0000), + .fmc_select_p1(1'b0), + + .mc_rq_cyc_p2(1'b0), + .sel_p2(4'b0000), + .fmc_select_p2(1'b0), + + .mc_rq_cyc_p3(1'b0), + .sel_p3(4'b0000), + .fmc_select_p3(1'b0) + ); + + initial begin +// #1000 apr.rlr = 8'o201; +// apr.ex_user = 1; + end + + integer i; + initial begin + mem0.memsel_p0 = 0; + mem0.memsel_p1 = 0; + mem0.memsel_p2 = 0; + mem0.memsel_p3 = 0; + + fmem0.memsel_p0 = 0; + fmem0.memsel_p1 = 0; + fmem0.memsel_p2 = 0; + fmem0.memsel_p3 = 0; + fmem0.fmc_p0_sel = 1; + fmem0.fmc_p1_sel = 0; + fmem0.fmc_p2_sel = 0; + fmem0.fmc_p3_sel = 0; + + for(i = 0; i < 040000; i = i+1) + mem0.core[i] = 0; + mem0.core[4] = 36'o222333111666; + mem0.core['o20] = 36'o123234345456; + + for(i = 0; i < 16; i = i + 1) + fmem0.ff[i] = i+1 | 36'o50000; + + key_start <= 0; + key_read_in <= 0; + key_inst_cont <= 0; + key_mem_cont <= 0; + key_inst_stop <= 0; + key_mem_stop <= 0; + key_exec <= 0; + key_ioreset <= 0; + key_dep <= 0; + key_dep_nxt <= 0; + key_ex <= 0; + key_ex_nxt <= 0; + sw_addr_stop <= 0; + sw_mem_disable <= 0; + sw_repeat <= 0; + sw_power <= 0; + sw_rim_maint <= 0; +// mas <= 18'o777777; +// mas <= 18'o000000; + mas <= 18'o000004; +// mas <= 18'o000020; +// mas <= 18'o000104; +// mas <= 18'o300004; + datasw <= 36'o123456654321; + + $dumpfile("dump.vcd"); + $dumpvars(); + end + + initial begin + #10 sw_power = 1; + end + + initial begin + #400 `TESTKEY = 1; + #1000 `TESTKEY = 0; + end +// initial begin +// #7000; +// #400 key_dep = 1; +// #1000 key_dep = 0; +// end + +endmodule