/* Copyright (C) 2008 Martin Furter This file is part of wbavr. wbavr is free software/hardware; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. wbavr is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with wbavr; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ==============================================================================*/ /* wbavr_avr: AVR CPU. This is just the glue between all AVR related modules. */ `include "wbavr_consts.v" module wbavr_avr( // avr common avr_clk_i, avr_reset_i, // avr code bus avr_c_adr_o, avr_c_dat_rd_i, avr_c_dat_wr_o, avr_c_rd_o, avr_c_wr_o, // avr data bus avr_d_adr_o, avr_d_dat_rd_i, avr_d_dat_wr_o, avr_d_rd_o, avr_d_wr_o, // interrupts irq_vect_i, irq_ack_o, // misc wdr_o ); parameter irq_vect_width; // avr clock and reset input avr_clk_i; input avr_reset_i; // avr code bus output [15:1] avr_c_adr_o; input [15:0] avr_c_dat_rd_i; output [15:0] avr_c_dat_wr_o; output avr_c_rd_o; output avr_c_wr_o; // avr data bus output [15:0] avr_d_adr_o; input [7:0] avr_d_dat_rd_i; output [7:0] avr_d_dat_wr_o; output avr_d_rd_o; output avr_d_wr_o; // interrupts input [irq_vect_width-1:0] irq_vect_i; output irq_ack_o; // misc output wdr_o; reg [15:0] instruction; reg [15:0] program_counter; reg [15:0] stack_pointer; reg [7:0] flags; wire fetch_instr; wire fetch_addr; wire interrupt_request; assign interrupt_request = &{ flags[FLAG_I_IDX], |{ irq_vect_i } }; always @( posedge avr_clk_i ) begin if( avr_reset_i ) begin program_counter = 0; // +++++ block everything end else begin if( fetch_instr ) begin instruction = avr_c_dat_rd_i; program_counter = program_counter + 1; end if( fetch_addr ) begin // lds/sts ??? addr_reg = avr_c_dat_rd_i; end if( exec_irq ) begin program_counter = { 0, irq_vect_i, 1'b0 }; end end end endmodule /* two word: lds (2), sts (2) => avr_d_adr_o = avr_c_dat_rd_i; reg[X] = avr_d_dat_rd_i; jmp (3) => PC = avr_c_dat_rd_i; nop; fetch_instr... call (4/5) => push PC; PC = avr_c_dat_rd_i; fetch_instr... avr_d_adr_o: = avr_c_dat_rd_i: lds, sts = addr_reg: ld R,-?[XYZ]+?, st R,-?[XYZ]+? */