📄 dw8051_cpu.v
字号:
.mem_psrd_n (mem_psrd_n), .mem_ale (mem_ale), .p0_mem_reg_n (p0_mem_reg_n), .p0_addr_data_n (p0_addr_data_n), .p2_mem_reg_n (p2_mem_reg_n), .int_rom_data_in (int_rom_data_in), .int_rom_rd_n (int_rom_rd_n), .int_rom_cs_n (int_rom_cs_n)); //--------------- // implement alu: //--------------- DW8051_alu i_alu (.clk (clk), .a (temp1), .b (temp2), .c (temp3), .ci (psw[7]), .aci (psw[6]), .ovi (psw[2]), .res (alu), .c_res (alu_l), .co (alu_co), .aco (alu_aco), .ovo (alu_ovo), .zero (alu_zero), .equal (alu_equal), .bit_sts (bit_status), .bit_pos (bit_nr[2:0]), .alu_op (alu_op)); // Internal RAM Interface signals: 'Just passing through! assign iram_addr = ram_addr; assign iram_data_in = ram_data_in; assign iram_rd_n = ram_rd_n; assign iram_we1_n = ram128_wr_addr_val_n & ram256_wr_addr_val_n; assign iram_we2_n = ram128_wr_n & ram256_wr_n; // generate lower-128-byte-RAM secific signals: assign ram128_cs_n = ram_addr[7]; // generate upper-128-byte-RAM secific signals: assign ram256_cs_n = ~ram_addr[7]; //---------------------------- // build pc (program counter): //---------------------------- DW8051_updn_ctr #(16) i_pc (.data (result), .up_dn (pc_cnt_dir), .load (set_pc_n), .cen (inc_pc), .clk (clk), .reset (rst_n), .count (pc), .tercnt (pc_tercnt)); // not used // mux for signed/unsigned addition: // upper 8 bits '0' if unsigned, else pc_inc(7): assign pc_inc_h[0] = pc_inc[7] & pc_add_signed; assign pc_inc_h[1] = pc_inc[7] & pc_add_signed; assign pc_inc_h[2] = pc_inc[7] & pc_add_signed; assign pc_inc_h[3] = pc_inc[7] & pc_add_signed; assign pc_inc_h[4] = pc_inc[7] & pc_add_signed; assign pc_inc_h[5] = pc_inc[7] & pc_add_signed; assign pc_inc_h[6] = pc_inc[7] & pc_add_signed; assign pc_inc_h[7] = pc_inc[7] & pc_add_signed; assign pc_add = {pc_inc_h, pc_inc[7:0]}; assign dp_add = {8'b00000000, dp_inc}; // mux for A and B: assign add16_a = (sel_pc_dptr_n == 0) ? dptr : pc; assign add16_b = (sel_pc_dptr_n == 0) ? dp_add : pc_add; //------------------------------------------------------ // 16 bit adder: used as pc incrementer (increment=rel), // dptr incrementer (increment=1) or // pc/dptr adder (increment=acc) //------------------------------------------------------ assign add16_sum = add16_a + add16_b ; //---------------------- // Indirect Data-In MUX: //---------------------- assign indir_data_in[0] = (ram_256 == 0) ? (iram_data_out[0] | ram_addr[7]) : (iram_data_out[0]); assign indir_data_in[1] = (ram_256 == 0) ? (iram_data_out[1] | ram_addr[7]) : (iram_data_out[1]); assign indir_data_in[2] = (ram_256 == 0) ? (iram_data_out[2] | ram_addr[7]) : (iram_data_out[2]); assign indir_data_in[3] = (ram_256 == 0) ? (iram_data_out[3] | ram_addr[7]) : (iram_data_out[3]); assign indir_data_in[4] = (ram_256 == 0) ? (iram_data_out[4] | ram_addr[7]) : (iram_data_out[4]); assign indir_data_in[5] = (ram_256 == 0) ? (iram_data_out[5] | ram_addr[7]) : (iram_data_out[5]); assign indir_data_in[6] = (ram_256 == 0) ? (iram_data_out[6] | ram_addr[7]) : (iram_data_out[6]); assign indir_data_in[7] = (ram_256 == 0) ? (iram_data_out[7] | ram_addr[7]) : (iram_data_out[7]); //----------------- // sfr_data_in mux: //----------------- assign cpu_sfr_cs = int_sfr_cs | sfr_reg_cs | ram256_cs_n; assign t_sfr_data_in = (cpu_sfr_cs == 0) ? ext_sfr_data_in : cpu_data_in; // (test_mode_n(1): deselect RAM for scan test assign cpu_data_in = ((ram128_cs_n == 0) && (test_mode_n == 1)) ? iram_data_out : (sfr_reg_cs == 1) ? sfr_reg_data_out : int_sfr_data_in; // (test_mode_n(1): deselect RAM for scan test //------------------------------------------------------- // build cycle counter: // The cycle counter counts from 0 to 11 (12 states) for // the compatibility mode of the timer modules. All other // modules use only the lower 2 bits (4 states). //------------------------------------------------------- DW8051_u_ctr_clr #(2) cyc1 (.q (t_cycle), .q_n (t_cycle_n), .clk (clk), .clr_n (t_stop_mode_n), // cleared in stop_mode .rst_n (sync_por_n)); // reset only by por_n ! //-------------------------------------- // build decoder for actual instruction: //-------------------------------------- DW8051_op_decoder i_opdec (.op (biu_instr), // from DW8051_biu .int (int_rec), //recognized at end of instr. .idle_mode_n (t_idle_mode_n), .itype (dec_itype), .last_cycle (dec_last_cycle), .src (dec_src), .src_cycle (dec_src_cycle), .dest (dec_dest), .alu_op (dec_alu_op), .chg_flags (dec_chg_flags), .rmw (dec_rmw)); //-------------------------- // build main SFR registers: //-------------------------- DW8051_main_regs i_mregs (.clk (clk), .rst_n (rst_n), .sfr_addr (t_sfr_addr), .sfr_reg_cs (sfr_reg_cs), .sfr_reg_data_out (sfr_reg_data_out), .sfr_data_out (t_sfr_data_out), .sfr_wr (t_sfr_wr), .biu_data_in (biu_data_in), .acc_data (acc_data), .cycle (t_cycle), .sp_cnt_dir (sp_cnt_dir), .cnt_sp (cnt_sp), .ld_acc (ld_acc), .ld_acc_direct (ld_acc_direct), .chg_flags (chg_flags), .alu_co (alu_co), .alu_aco (alu_aco), .alu_ovo (alu_ovo), .sp (sp), .dptr (dptr), .dps (dps), .pcon (pcon), .ckcon (ckcon), .psw (psw), .acc (acc), .b (b), .spc_fnc (spc_fnc), .mpage (mpage)); //--------------------- // main control module: //--------------------- DW8051_control i_control (.clk (clk), .rst_n (rst_n), .cycle (t_cycle), // inputs: .biu_instr (biu_instr), .biu_ram_access_rdy (biu_ram_access_rdy), .int_req (int_req), .int_src (int_src), .alu (alu), .alu_l (alu_l), .sp (sp), .dps (dps), .pcon (pcon), .psw (psw), .acc (acc), .b (b), .dptr (dptr), .indir_data_in (indir_data_in), .pc (pc), .add16_sum (add16_sum), .eie_eip_check (eie_eip_check), .mpage (mpage), .dec_itype (dec_itype), .dec_last_cycle (dec_last_cycle), .dec_src (dec_src), .dec_src_cycle (dec_src_cycle), .dec_dest (dec_dest), .dec_alu_op (dec_alu_op), .dec_chg_flags (dec_chg_flags), .dec_rmw (dec_rmw), .alu_zero (alu_zero), .alu_equal (alu_equal), .bit_status (bit_status), // outputs: .cpu_idle_mode_n (t_idle_mode_n), .cpu_stop_mode_n (t_stop_mode_n), .biu_ram_addr (biu_ram_addr), .biu_wr_ram_addr_h (biu_wr_ram_addr_h), .biu_wr_ram_addr_l (biu_wr_ram_addr_l), .biu_data_out (biu_data_out), .biu_wr_ram (biu_wr_ram), .biu_rd_ram (biu_rd_ram), .biu_rd_rom (biu_rd_rom), .ram_addr (ram_addr), .ram128_wr_addr_val_n (ram128_wr_addr_val_n), .ram256_wr_addr_val_n (ram256_wr_addr_val_n), .ram_data_in (ram_data_in), .ram128_wr_n (ram128_wr_n), .ram256_wr_n (ram256_wr_n), .ram_rd_n (ram_rd_n), .int_sfr_addr (t_sfr_addr), .int_sfr_data_out (t_sfr_data_out), .int_sfr_wr (t_sfr_wr), .ext_sfr_addr (ext_sfr_addr), .ext_sfr_data_out (ext_sfr_data_out), .ext_sfr_wr (ext_sfr_wr), .ext_sfr_rd (ext_sfr_rd), .sfr_data_in (t_sfr_data_in), .port_pin_reg_n (port_pin_reg_n), .int_ack (int_ack), .int_clr (int_clr), .int_rec (int_rec), .cpu_temp1 (temp1), .cpu_temp2 (temp2), .cpu_temp3 (temp3), .result (result), .pc_cnt_dir (pc_cnt_dir), .inc_pc (inc_pc), .set_pc_n (set_pc_n), .pc_inc (pc_inc), .dp_inc (dp_inc), .pc_add_signed (pc_add_signed), .sel_pc_dptr_n (sel_pc_dptr_n), .sp_cnt_dir (sp_cnt_dir), .cnt_sp (cnt_sp), .alu_op (alu_op), .chg_flags (chg_flags), .acc_data (acc_data), .ld_acc (ld_acc), .ld_acc_direct (ld_acc_direct), .cpu_bit_nr (bit_nr)); //--------------------------------------------------------- // 2 stage synchronizer for por_n: // The release of por_n is synchronized to the rising // edge of clk since the load on the reset net is // normally big enougth to meet recovery time requirements. //--------------------------------------------------------- always @(posedge clk) begin : por_del_proc por_n_del1 <= por_n; por_n_del2 <= por_n_del1; end //------------------------------------------------------- // normal rst_in_n sample process: // rst_in_n state is sampled at the end of c4. rst_in_n // must be asserted at least for 2 samples in order to be // recognized. //------------------------------------------------------- always @(posedge clk) begin : rst_proc if (sync_por_n == 0) begin rst_first <= 0; // in first cycle old_rst_in_n <= rst_in_n; // save current state sync_rst_n <= rst_in_n; // follow rst_in_n state end else begin // check rst_in state in c4: if (t_cycle == `c4) begin if (((old_rst_in_n == 1) && (rst_in_n == 0)) | ((old_rst_in_n == 0) && (rst_in_n == 1))) begin // rst_in goes low or high: rst_first <= 1; end // action only in second cycle: if (rst_first == 1) begin if (rst_in_n == 0) // still applied ? begin sync_rst_n <= 0; rst_first <= 0; end else if (rst_in_n == 1) begin sync_rst_n <= 1; rst_first <= 0; end end old_rst_in_n <= rst_in_n; // save current state end end end // rst_proc //----------------------------- // internal signal assignments: //----------------------------- assign sync_por_n = (por_n & (por_n_del2 | (~test_mode_n))); // controllable assign rst_n = (sync_por_n & (sync_rst_n | (~test_mode_n))); // por_n always assign biu_wrs = spc_fnc[0]; assign biu_rom_addr = pc; assign biu_md = ckcon[2:0]; //-------------------------- //output signal assignments: //-------------------------- assign rst_out_n = rst_n; assign cycle = t_cycle; assign stop_mode_n = t_stop_mode_n; assign idle_mode_n = t_idle_mode_n; assign int_sfr_addr = t_sfr_addr; assign int_sfr_data_out = t_sfr_data_out; assign int_sfr_wr = t_sfr_wr; assign tm = ckcon[5:3]; assign smod = pcon[7];endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -