📄 dw8051_control.v
字号:
// write to dph (dps(0)=0) or dph1 (dps(0)=1): case (cycle) `c3 : begin sfr_addr = {5'b10000, (1'b0 ^ dps[0]), (1'b1 ^ dps[0]), 1'b1}; end `c4 : begin if (dest == 13) sfr_data_out = biu_instr; else begin // INC DPTR sfr_data_out = add16_sum[15:8]; end sfr_wr = 1; end default: begin end endcase end 2 : begin // write to dpl (dps(0)=0) or dpl1 (dps(0)=1): case (cycle) `c3 : begin sfr_addr = {5'b10000, (1'b0 ^ dps[0]), (1'b1 ^ dps[0]), 1'b0}; end `c4 : begin if (dest == 13) sfr_data_out = biu_instr; else begin // INC DPTR sfr_data_out = add16_sum[7:0]; end sfr_wr = 1; end default: begin end endcase end default: begin end endcase end // 15: dest ext.RAM, @DPTR 15 : begin case (instr_cycle) 0 : begin case (cycle) `c3 : begin biu_wr_ram_addr_h <= 1; biu_wr_ram_addr_l <= 1; biu_wr_ram <= 1; end `c4 : begin biu_wr_ram_addr_h <= 0; biu_wr_ram_addr_l <= 0; biu_ram_addr <= dptr; biu_data_out <= acc; end default: begin end endcase end default: begin end endcase end default: begin end endcase //------------------------------------------ // Miscellaneous actions depending on cycle: //------------------------------------------ if (cycle == `c1) begin sfr_wr = 0; // finish write cycle (all dest) ram128_wr_n <= 1; ram256_wr_n <= 1; ram128_wr_addr_val_n <= 1; ram256_wr_addr_val_n <= 1; ld_acc <= 0; ld_acc_direct <= 0; dest <= 0; sel_pc_dptr_n <= 1; // default: pc pc_add_signed <= 1; // default: unsigned chg_flags <= 0; end if (cycle == `c4) begin inc_pc <= 0; // done always in c4 pc_cnt_dir <= 1; // back to default (up) any way end //---------------------- // for most instructions // pc is incremented // automatically in c4: //---------------------- if (auto_inc_pc == 1) begin case (cycle) `c3 : begin // late check for interrupts: if ((instr_cycle == last_cycle) && (int_req == 1) && (int_delay == 0)) inc_pc <= 0; else if (idle_mode_n == 0) inc_pc <= 0; else inc_pc <= 1; end default: begin end endcase end //----------------------- // increment instr_cycle: //----------------------- if ((cycle == `c4 ) & (wait_for_ram == 0)) begin instr_cycle <= (instr_cycle + 1); end //----------------------------------- // Finish execution in c3 if // instr_cycle = last_cycle. // Interrupts are recognized here !!! //----------------------------------- if (instr_cycle == last_cycle) begin if ((wait_for_ram == 0) | (biu_ram_access_rdy == 1)) begin // if <no MOVX @DPTR> or <MOVX @DPTR and ready) case (cycle) `c2 : begin auto_inc_pc <= 1; // may by overridden in next cyle //------------------------------------- // check if interrupt has to be delayed // (write access to IE,IP,EIE,EIP): //------------------------------------- if (t_dest == 3) begin case (biu_instr) `ie_addr, `ip_addr : int_delay <= 1; `eie_addr, `eip_addr : begin if (eie_eip_check == 1) int_delay <= 1; end default : begin end endcase end if (t_dest == 7) begin case (sfr_bit_addr) `ie_addr, `ip_addr : int_delay <= 1; `eie_addr, `eip_addr : begin if (eie_eip_check == 1) int_delay <= 1; end default : begin end endcase end if (t_dest == 8) begin case (t_sfr_addr) `ie_addr, `ip_addr : int_delay <= 1; `eie_addr, `eip_addr : begin if (eie_eip_check == 1) int_delay <= 1; end default : begin end endcase end if (t_dest == 9) begin case (xch_addr) `ie_addr, `ip_addr : int_delay <= 1; `eie_addr, `eip_addr : begin if (eie_eip_check == 1) int_delay <= 1; end default : begin end endcase end // check for RETI: if (act_instr == 8'b00110010) begin int_delay <= 1; end end `c3 : begin // step to next instruction, also check for interrupts: itype <= 0; if ((int_req == 1) && (int_delay == 0)) begin // accept interrupt request auto_inc_pc <= 0; // stay at last pc addr int_rec <= 1; t_int_ack <= 1; // if last instruction was MOVX, // decrement PC (discard read instruction) ! if (biu_ram_access_rdy == 1) begin pc_cnt_dir <= 0; // down inc_pc <= 1; end // interrupt in idle mode ? if (idle_mode_n == 0) begin idle_mode_n <= 1; // clear pcon(0): sfr_addr = `pcon_addr; temp1 <= {pcon[7:1], 1'b0}; dest <= 3; // execute next // decrement pc: pc_cnt_dir <= 0; // down inc_pc <= 1; end end else if (idle_mode_n == 0) auto_inc_pc <= 0; // stay here until int else begin auto_inc_pc <= 1; int_rec <= 0; end int_delay <= 0; // clear delay flag end default: begin end endcase end end //----------------------- // instruction sequencer: // new instructions are // decoded always in c1 //----------------------- case (itype) 0 : begin // wait for next instr. case (cycle) `c4 : begin int_src_rec <= int_src; // save int_src t_int_ack <= 0; end `c1 : begin itype <= dec_itype; last_cycle <= dec_last_cycle; act_instr <= biu_instr; src <= dec_src; src_cycle <= dec_src_cycle; t_dest <= dec_dest; alu_op <= dec_alu_op; chg_flags <= dec_chg_flags; port_pin_reg_n <= (~dec_rmw); auto_inc_pc <= 1; instr_cycle <= 0; biu_wr_ram <= 0; biu_rd_ram <= 0; biu_rd_rom <= 0; // Unconditional read of Ri, used for // instructions with @Ri (source/destination): sfr_addr = {3'b000, rs, 2'b00, biu_instr[0]}; ram_rd_n <= 0; end default: begin end endcase end // one cycle instructions: 1 : begin // Most 1 Byte's case (cycle) `c2 : dest <= t_dest; default: begin end endcase end 2 : begin // IDLE MODE end 3 : begin // ANL,ORL,XRL (1 Byte) case (cycle) // ADD,ADDC,SUBB `c2 : begin temp2 <= acc; dest <= t_dest; end default: begin end endcase end // two cycle instructions: 4 : begin // ANL,ORL,XRL (2 Bytes) case (instr_cycle) // ADD,ADDC,SUBB 1 : begin case (cycle) `c2 : begin temp2 <= acc; dest <= t_dest; if (act_instr[6] == 0) begin // ADD,ADDC,SUBB chg_flags <= 1; end end default: begin end endcase end default: begin end endcase end 5 : begin // Most 2 Byte's case (instr_cycle) 1 : begin case (cycle) `c2 : dest <= t_dest; default: begin end endcase end default: begin end endcase end 6 : begin // ORL C,bit, .. case (instr_cycle) 1 : begin case (cycle) `c2 : begin dest <= t_dest; chg_flags <= 1; // update C end default: begin end endcase end default: begin end endcase end 7 : begin // PUSH,POP case (instr_cycle) 0 : begin case (cycle) `c2 : begin if (act_instr[4] == 0) begin // PUSH, (SP) <- (SP) + 1 sp_cnt_dir <= 1; // up cnt_sp <= 1; end end `c3 : cnt_sp <= 0; default: begin end endcase end 1 : begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -