/* 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_iomap: I/O mapping of GP-Regs, SP and SREG. Overrides selection signals depending on the data address. */ `include "wbavr_consts.v" module wbavr_iomap( avr_d_adr_i, avr_d_rd_i, avr_d_wr_i, alu_i0_sel_i, flag_sel_i, sp_sel_i, gp_rd_adr_0_i, gp_wr_adr_0_i, gp_wr_en_0_i, avr_d_rd_o, avr_d_wr_o, alu_i0_sel_o, flag_sel_o, sp_sel_o, gp_rd_adr_0_o, gp_wr_adr_0_o, gp_wr_en_0_o, ); input [15:0] avr_d_adr_i; input avr_d_rd_i; input avr_d_wr_i; always begin casex( { avr_d_rd_i, avr_d_wr_i, avr_d_adr_i } ) // GP registers at address 0x0000 - 0x001F 18'b10_0000_0000_000?_????: begin // read avr_d_rd_o <= 1'b0; avr_d_wr_o <= 1'b0; alu_i0_sel_o <= `ALU_I0_SEL_REG0; flag_sel_o <= flag_sel_i; sp_sel_o <= sp_sel_i; gp_rd_adr_0_o <= avr_d_adr_i[4:0]; gp_wr_adr_0_o <= gp_wr_adr_0_i; gp_wr_en_0_o <= gp_wr_en_0_i; end 18'b01_0000_0000_000?_????: begin // write avr_d_rd_o <= 1'b0; avr_d_wr_o <= 1'b0; alu_i0_sel_o <= alu_i0_sel_i; flag_sel_o <= flag_sel_i; sp_sel_o <= sp_sel_i; gp_rd_adr_0_o <= gp_rd_adr_0_i; gp_wr_adr_0_o <= avr_d_adr_i[4:0]; gp_wr_en_0_o <= 1'b1; end // control register (SPMCSR) at address 0x005D 18'b10_0000_0000_0101_1100: begin // read avr_d_rd_o <= 1'b0; avr_d_wr_o <= 1'b0; alu_i0_sel_o <= `ALU_I0_SEL_CTRL; flag_sel_o <= flag_sel_i; sp_sel_o <= sp_sel_i; gp_rd_adr_0_o <= gp_rd_adr_0_i; gp_wr_adr_0_o <= gp_wr_adr_0_i; gp_wr_en_0_o <= gp_wr_en_0_i; end 18'b01_0000_0000_0101_1100: begin // write avr_d_rd_o <= 1'b0; avr_d_wr_o <= 1'b0; alu_i0_sel_o <= alu_i0_sel_i; flag_sel_o <= flag_sel_i; sp_sel_o <= sp_sel_i; gp_rd_adr_0_o <= gp_rd_adr_0_i; gp_wr_adr_0_o <= gp_wr_adr_0_i; gp_wr_en_0_o <= gp_wr_en_0_i; end // stack pointer low at address 0x005D 18'b10_0000_0000_0101_1101: begin // read avr_d_rd_o <= 1'b0; avr_d_wr_o <= 1'b0; alu_i0_sel_o <= `ALU_I0_SEL_SP_LO; flag_sel_o <= flag_sel_i; sp_sel_o <= sp_sel_i; gp_rd_adr_0_o <= gp_rd_adr_0_i; gp_wr_adr_0_o <= gp_wr_adr_0_i; gp_wr_en_0_o <= gp_wr_en_0_i; end 18'b01_0000_0000_0101_1101: begin // write avr_d_rd_o <= 1'b0; avr_d_wr_o <= 1'b0; alu_i0_sel_o <= alu_i0_sel_i; flag_sel_o <= flag_sel_i; sp_sel_o <= `SP_SEL_WR_LO; gp_rd_adr_0_o <= gp_rd_adr_0_i; gp_wr_adr_0_o <= gp_wr_adr_0_i; gp_wr_en_0_o <= gp_wr_en_0_i; end // stack pointer high at address 0x005E 18'b10_0000_0000_0101_1110: begin // read avr_d_rd_o <= 1'b0; avr_d_wr_o <= 1'b0; alu_i0_sel_o <= `ALU_I0_SEL_SP_HI; flag_sel_o <= flag_sel_i; sp_sel_o <= sp_sel_i; gp_rd_adr_0_o <= gp_rd_adr_0_i; gp_wr_adr_0_o <= gp_wr_adr_0_i; gp_wr_en_0_o <= gp_wr_en_0_i; end 18'b01_0000_0000_0101_1110: begin // write avr_d_rd_o <= 1'b0; avr_d_wr_o <= 1'b0; alu_i0_sel_o <= alu_i0_sel_i; flag_sel_o <= flag_sel_i; sp_sel_o <= `SP_SEL_WR_HI; gp_rd_adr_0_o <= gp_rd_adr_0_i; gp_wr_adr_0_o <= gp_wr_adr_0_i; gp_wr_en_0_o <= gp_wr_en_0_i; end // flags (SREG) at address 0x005F 18'b10_0000_0000_0101_1111: begin // read avr_d_rd_o <= 1'b0; avr_d_wr_o <= 1'b0; alu_i0_sel_o <= `ALU_I0_SEL_FLAGS; flag_sel_o <= flag_sel_i; sp_sel_o <= sp_sel_i; gp_rd_adr_0_o <= gp_rd_adr_0_i; gp_wr_adr_0_o <= gp_wr_adr_0_i; gp_wr_en_0_o <= gp_wr_en_0_i; end 18'b01_0000_0000_0101_1111: begin // write avr_d_rd_o <= 1'b0; avr_d_wr_o <= 1'b0; alu_i0_sel_o <= alu_i0_sel_i; flag_sel_o <= `FLAG_SEL_ALU; sp_sel_o <= sp_sel_i; gp_rd_adr_0_o <= gp_rd_adr_0_i; gp_wr_adr_0_o <= gp_wr_adr_0_i; gp_wr_en_0_o <= gp_wr_en_0_i; end default: begin avr_d_rd_o <= avr_d_rd_i; avr_d_wr_o <= avr_d_wr_i; alu_i0_sel_o <= alu_i0_sel_i; flag_sel_o <= flag_sel_i; sp_sel_o <= sp_sel_i; gp_rd_adr_0_o <= gp_rd_adr_0_i; gp_wr_adr_0_o <= gp_wr_adr_0_i; gp_wr_en_0_o <= gp_wr_en_0_i; end end endmodule