// module : rtavr_ior // sub module : rtavr_ior_port // sub module : rtavr_ior_timer0 `define SELF_DECODE_PORT `define SELF_DECODE_TIMER `define TIM0_FUNC_MINIMUM module rtavr_ior_port( input CLK, `ifdef SELF_DECODE_PORT input WR,RD, input [5:0] ADDR, `else input WE_ddr, WE_port, input OE_pin, OE_ddr, OE_port, `endif input [7:0] DI, inout [7:0] DO // external I/O , inout [7:0] PORT ); parameter BASE_ADDR = 0; // PORTA 0x00 // parameter BASE_ADDR = 4; // PORTB 0x04 // parameter BASE_ADDR = 27; // PORTC 0x1b reg [7:0] i_pin; reg [7:0] i_ddr; reg [7:0] i_port; `ifdef SELF_DECODE_PORT wire OE_pin = RD & (ADDR == BASE_ADDR); //wire WE_pin = WR & (ADDR == BASE_ADDR); wire OE_ddr = RD & (ADDR == (BASE_ADDR + 1)); wire WE_ddr = WR & (ADDR == (BASE_ADDR + 1)); wire OE_port = RD & (ADDR == (BASE_ADDR + 2)); wire WE_port = WR & (ADDR == (BASE_ADDR + 2)); `endif bufif1(DO,i_pin,OE_pin); bufif1(DO,i_ddr,OE_ddr); bufif1(DO,i_port,OE_port); always @(posedge CLK) begin //if(WE_pin) i_pin <= DI; if(WE_ddr) i_ddr <= DI; if(WE_port) i_port <= DI; i_pin <= PORT; end generate genvar i; for (i=0; i<8; i=i+1) begin : port_out bufif1(PORT[i],i_port[i],i_ddr[i]); end endgenerate endmodule module rtavr_ior_timer0( input CLK, input [7:0] DI, inout [7:0] DO `ifdef SELF_DECODE_TIMER , input WR,RD , input [5:0] ADDR `else , input WE_ocr0b, OE_ocr0b, WE_ocr0a, OE_ocr0a , input WE_tcnt0, OE_tcnt0 , input WE_tccr0b, OE_tccr0b, WE_tccr0a, OE_tccr0a `endif // external I/O , output TIM0_OVF , output TIM0_COMPA , output TIM0_COMPB ); parameter BASE_ADDR = 21; // OCR0B 0x15 reg [9:0] i_prescaler; reg [7:0] i_tcnt0; reg [7:0] i_ocr0b; reg [7:0] i_ocr0a; reg i_tim0_compa; reg i_tim0_compb; reg i_tim0_ovf; assign TIM0_OVF = i_tim0_ovf; assign TIM0_COMPA = i_tim0_compa; assign TIM0_COMPB = i_tim0_compb; `ifdef SELF_DECODE_TIMER wire OE_ocr0b = RD & (ADDR == BASE_ADDR); wire WE_ocr0b = WR & (ADDR == BASE_ADDR); wire OE_ocr0a = RD & (ADDR == (BASE_ADDR + 1)); wire WE_ocr0a = WR & (ADDR == (BASE_ADDR + 1)); wire OE_tcnt0 = RD & (ADDR == (BASE_ADDR + 2)); wire WE_tcnt0 = WR & (ADDR == (BASE_ADDR + 2)); wire OE_tccr0b = RD & (ADDR == (BASE_ADDR + 3)); wire WE_tccr0b = WR & (ADDR == (BASE_ADDR + 3)); wire OE_tccr0a = RD & (ADDR == (BASE_ADDR + 4)); wire WE_tccr0a = WR & (ADDR == (BASE_ADDR + 4)); `endif reg [2:0] cs0; reg [2:0] wgm0; reg [1:0] com0a; reg [1:0] com0b; reg tsm; `ifdef TIM0_FUNC_MINIMUM `else reg psr; reg foc0b; reg foc0a; `endif wire [7:0] i_tccr0b = {com0a, com0b, wgm0[2], cs0}; wire [7:0] i_tccr0a = {2'b0, tsm, 3'b0 , wgm0[1:0]}; reg t0_prev; wire t0_nops = (cs0 == 1); wire t0_clk = (cs0 == 2) ? i_prescaler[2] // 1/8 : (cs0 == 3) ? i_prescaler[5] // 1/64 : (cs0 == 4) ? i_prescaler[7] // 1/256 : (cs0 == 5) ? i_prescaler[9] // 1/1024 : 0; wire t0_top_ocr0a = ((wgm0 == 2) | (wgm0 == 5) | (wgm0 == 7)); `ifdef TIM0_FUNC_MINIMUM `else wire ocr0_chg_top = ((wgm0 == 1) | (wgm0 == 5)); wire ocr0_chg_btm = ((wgm0 == 3) | (wgm0 == 7)); wire ocr0_chg_imm = (wgm0[0] == 0); `endif bufif1(DO,i_ocr0b,OE_ocr0b); bufif1(DO,i_ocr0a,OE_ocr0a); bufif1(DO,i_tcnt0,OE_tcnt0); bufif1(DO,i_tccr0a,OE_tccr0a); bufif1(DO,i_tccr0b,OE_tccr0b); always @(posedge CLK) begin if(WE_ocr0b) i_ocr0b <= DI; if(WE_ocr0a) i_ocr0a <= DI; if(WE_tccr0b) begin cs0 <= DI[2:0]; wgm0[2] <= DI[3]; com0b <= DI[5:4]; com0a <= DI[7:6]; end if(WE_tccr0a) begin wgm0[1:0] <= DI[1:0]; tsm <= DI[5]; `ifdef TIM0_FUNC_MINIMUM `else psr <= DI[4]; foc0b <= DI[6]; foc0a <= DI[7]; `endif end `ifdef TIM0_FUNC_MINIMUM i_prescaler <= i_prescaler + 1; if(WE_tcnt0) i_tcnt0 <= DI; else begin if (t0_nops | (t0_clk ^ t0_prev)) begin if (t0_top_ocr0a & (i_tcnt0 == i_ocr0a)) i_tcnt0 <= 0; else i_tcnt0 <= i_tcnt0 + 1; i_tim0_ovf <= (i_tcnt0 == 255); i_tim0_compa <= (i_tcnt0 == i_ocr0a); i_tim0_compb <= (i_tcnt0 == i_ocr0b); end end `else NOT IMPLEMENTED YET `endif t0_prev <= t0_clk; end endmodule module rtavr_ior( input CLK, input WR,RD, input [7:0] DI, input [5:0] ADDR, inout [7:0] DO // external I/O , inout [7:0] PORTA , inout [7:0] PORTB , inout [7:0] PORTC `ifdef TEST1 , output TIM0_OVF , output TIM0_COMPA , output TIM0_COMPB `endif ); parameter PORTA_ADDR = 0; // PINA 0x00 , DDRA, PORTA parameter PORTB_ADDR = 4; // PINB 0x04 , DDRB, PORTB parameter PORTC_ADDR = 27; // PINC 0x1b , DDRC, PORTC parameter TIM0_ADDR = 21; // OCR0B 0x15 - TCCR0A 0x19 parameter SREG_ADDR = 63; // SREG 0x3f , SPH,SPL,CCP,RSRFR,MCUCR 0x3a parameter GIFR_ADDR = 11; // GIFR 0x0e , GIMSK 0x0c parameter TIFR_ADDR = 37; // TIFR 0x25 , TIMSK 0x26 reg [7:0] i_sreg; reg [7:0] i_sph; reg [7:0] i_spl; wire OE_sreg = RD & (ADDR == SREG_ADDR); wire WE_sreg = WR & (ADDR == SREG_ADDR); wire OE_sph = RD & (ADDR == (SREG_ADDR -1)); wire WE_sph = WR & (ADDR == (SREG_ADDR -1)); wire OE_spl = RD & (ADDR == (SREG_ADDR -2)); wire WE_spl = WR & (ADDR == (SREG_ADDR -2)); wire TIM0_OVF; // int 10 wire TIM0_COMPA; // int 11 wire TIM0_COMPB; // int 12 wire OE_tifr = RD & (ADDR == TIFR_ADDR); wire WE_tifr = WR & (ADDR == TIFR_ADDR); wire OE_timsk = RD & (ADDR == (TIFR_ADDR +1)); wire WE_timsk = WR & (ADDR == (TIFR_ADDR +1)); reg t0_ovf_prev; reg t0_compa_prev; reg t0_compb_prev; reg t0_ovf, t0_ovf_ie; // bit0 reg t0_compa, t0_compa_ie; // bit1 reg t0_compb, t0_compb_ie; // bit2 //reg intf0, int0; // bit0 `ifdef SELF_DECODE_PORT `else wire OE_pin_a = RD & (ADDR == PORTA_ADDR); // wire WE_pin_a = WR & (ADDR == PORTA_ADDR); wire OE_ddr_a = RD & (ADDR == (PORTA_ADDR + 1)); wire WE_ddr_a = WR & (ADDR == (PORTA_ADDR + 1)); wire OE_port_a = RD & (ADDR == (PORTA_ADDR + 2)); wire WE_port_a = WR & (ADDR == (PORTA_ADDR + 2)); wire OE_pin_b = RD & (ADDR == PORTB_ADDR); // wire WE_pin_b = WR & (ADDR == PORTB_ADDR); wire OE_ddr_b = RD & (ADDR == (PORTB_ADDR + 1)); wire WE_ddr_b = WR & (ADDR == (PORTB_ADDR + 1)); wire OE_port_b = RD & (ADDR == (PORTB_ADDR + 2)); wire WE_port_b = WR & (ADDR == (PORTB_ADDR + 2)); wire OE_pin_c = RD & (ADDR == PORTC_ADDR); // wire WE_pin_c = WR & (ADDR == PORTC_ADDR); wire OE_ddr_c = RD & (ADDR == (PORTC_ADDR + 1)); wire WE_ddr_c = WR & (ADDR == (PORTC_ADDR + 1)); wire OE_port_c = RD & (ADDR == (PORTC_ADDR + 2)); wire WE_port_c = WR & (ADDR == (PORTC_ADDR + 2)); `endif `ifdef SELF_DECODE_TIMER `else wire OE_ocr0b = RD & (ADDR == TIM0_ADDR); wire WE_ocr0b = WR & (ADDR == TIM0_ADDR); wire OE_ocr0a = RD & (ADDR == (TIM0_ADDR + 1)); wire WE_ocr0a = WR & (ADDR == (TIM0_ADDR + 1)); wire OE_tcnt0 = RD & (ADDR == (TIM0_ADDR + 2)); wire WE_tcnt0 = WR & (ADDR == (TIM0_ADDR + 2)); wire OE_tccr0b = RD & (ADDR == (TIM0_ADDR + 3)); wire WE_tccr0b = WR & (ADDR == (TIM0_ADDR + 3)); wire OE_tccr0a = RD & (ADDR == (TIM0_ADDR + 4)); wire WE_tccr0a = WR & (ADDR == (TIM0_ADDR + 4)); `endif bufif1(DO,i_sreg,OE_sreg); bufif1(DO,i_sph,OE_sph); bufif1(DO,i_spl,OE_spl); bufif1(DO,{5'b0 , t0_compb, t0_compa ,t0_ovf}, OE_tifr); bufif1(DO,{5'b0 , t0_compb_ie, t0_compa_ie ,t0_ovf_ie}, OE_timsk); always @(posedge CLK) begin if(WE_sreg) i_sreg <= DI; if(WE_sph) i_sph <= DI; if(WE_spl) i_spl <= DI; if(WE_timsk) {t0_compb_ie, t0_compa_ie ,t0_ovf_ie} <= DI[2:0]; if((WE_tifr & DI[0]) | (~t0_ovf_prev & TIM0_OVF)) t0_ovf <= 1; if((WE_tifr & DI[1]) | (~t0_compa_prev & TIM0_COMPA)) t0_compa <= 1; if((WE_tifr & DI[2]) | (~t0_compb_prev & TIM0_COMPB)) t0_compb <= 1; t0_ovf_prev <= TIM0_OVF; t0_compa_prev <= TIM0_COMPA; t0_compb_prev <= TIM0_COMPB; end `ifdef SELF_DECODE_PORT rtavr_ior_port #(.BASE_ADDR(PORTA_ADDR)) i_port_a( .CLK(CLK), .DI(DI), .DO(DO) , .PORT(PORTA) , .WR(WR), .RD(RD), .ADDR(ADDR) ); rtavr_ior_port #(.BASE_ADDR(PORTB_ADDR)) i_port_b( .CLK(CLK), .DI(DI), .DO(DO) , .PORT(PORTB) , .WR(WR), .RD(RD), .ADDR(ADDR) ); rtavr_ior_port #(.BASE_ADDR(PORTC_ADDR)) i_port_c( .CLK(CLK), .DI(DI), .DO(DO) , .PORT(PORTC) , .WR(WR), .RD(RD), .ADDR(ADDR) ); `else rtavr_ior_port i_port_a(.CLK(CLK), .DI(DI), .DO(DO) , .PORT(PORTA) , .OE_port(OE_port_a), .WE_port(WE_port_a) , .OE_ddr(OE_ddr_a), .WE_ddr(WE_ddr_a), .OE_pin(OE_pin_a) ); rtavr_ior_port i_port_b(.CLK(CLK), .DI(DI), .DO(DO) , .PORT(PORTB) , .OE_port(OE_port_b), .WE_port(WE_port_b) , .OE_ddr(OE_ddr_b), .WE_ddr(WE_ddr_b), .OE_pin(OE_pin_b) ); rtavr_ior_port i_port_c(.CLK(CLK), .DI(DI), .DO(DO) , .PORT(PORTC) , .OE_port(OE_port_c), .WE_port(WE_port_c) , .OE_ddr(OE_ddr_c), .WE_ddr(WE_ddr_c), .OE_pin(OE_pin_c) ); `endif `ifdef SELF_DECODE_TIMER rtavr_ior_timer0 #(.BASE_ADDR(TIM0_ADDR)) i_timer0( .CLK(CLK), .DI(DI), .DO(DO) , .WR(WR), .RD(RD), .ADDR(ADDR) , .TIM0_OVF(TIM0_OVF) , .TIM0_COMPB(TIM0_COMPB) , .TIM0_COMPA(TIM0_COMPA) ); `else rtavr_ior_timer0 i_timer0(.CLK(CLK), .DI(DI), .DO(DO) , .WE_ocr0b(WE_ocr0b), .OE_ocr0b(OE_ocr0b) , .WE_ocr0a(WE_ocr0a), .OE_ocr0a(OE_ocr0a) , .WE_tcnt0(WE_tcnt0), .OE_tcnt0(OE_tcnt0) , .WE_tccr0b(WE_tccr0b), .OE_tccr0b(OE_tccr0b) , .WE_tccr0a(WE_tccr0a), .OE_tccr0a(OE_tccr0a) , .TIM0_OVF(TIM0_OVF) , .TIM0_COMPB(TIM0_COMPB) , .TIM0_COMPA(TIM0_COMPA) ); `endif endmodule