OpenCores
URL https://opencores.org/ocsvn/attiny_atmega_xmega_core/attiny_atmega_xmega_core/trunk

Subversion Repositories attiny_atmega_xmega_core

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /attiny_atmega_xmega_core
    from Rev 3 to Rev 4
    Reverse comparison

Rev 3 → Rev 4

/trunk/mega_core_opt.v
0,0 → 1,3352
/*----------------------------------------------------------------------------/
/ This IP is the Atmel ATTINY-ATMEGA-ATXMEGA CPU implementation. /
/-----------------------------------------------------------------------------/
/
/ Copyright (C) 2017 Iulian Gheorghiu (morgoth.creator@gmail.com), all right reserved.
/
/ This IP file is an open source software. Redistribution and use of this IP in
/ source and binary forms, with or without modification, are permitted provided
/ that the following condition is met:
 
/ 1. Redistributions of source code must retain the above copyright notice,
/ this condition and the following disclaimer.
/
/ This software is provided by the copyright holder and contributors "AS IS"
/ and any warranties related to this software are DISCLAIMED.
/ The copyright owner or contributors be NOT LIABLE for any damages caused
/ by use of this software.
/----------------------------------------------------------------------------*/
 
`timescale 1ns / 1ps
 
/*
* Define modes.
*/
 
`define USE_RAM_READ_DELAY 1// For now let it undefined because is not fully implemented( uncommenting this line will result in unnexpected behavior ).
 
//`define USE_EXTENDED_RAMP_REGS// For future usage.
//`define USE_CCP_REG// For future usage.
`define USE_LPM
 
/*
* Core configurations:
* "REDUCED" // (not working)
* "MINIMAL"
* "CLASSIC_8K"
* "CLASSIC_128K"
* "ENHANCED_8K"
* "ENHANCED_128K"
* "ENHANCED_4M" //Not implemented
* "XMEGA"
*/
 
/*
* Watchdog.
*/
module watchdog # (
parameter CNT_WIDTH = 0
)(
input rst,
input clk,
input wdt_clk,
input wdt_rst_in,
output reg wdt_rst_out);
reg [CNT_WIDTH:0]wdt_cnt;
reg reset;
reg reset_n;
reg wdt_reset;
reg wdt_reset_n;
 
always @ (posedge rst or posedge wdt_rst_in)
begin
if(rst)
reset <= 1'b0;
else
reset <= ~reset_n;
end
 
always @ (posedge rst or posedge wdt_clk)
begin
if(rst)
begin
reset_n <= 1'b0;
wdt_reset <=1'b0;
wdt_cnt <= 'h0000;
end
else if(reset != reset_n)
begin
reset_n <= reset;
wdt_cnt <= 'h0000;
end
else if(wdt_clk)
begin
if(wdt_cnt[CNT_WIDTH])
begin
wdt_reset <= ~wdt_reset_n;
wdt_cnt <= 'h0000;
end
else
begin
wdt_cnt <= wdt_cnt + 1;
end
end
end
 
always @ (posedge rst or posedge clk)
begin
wdt_rst_out <= 1'b0;
if(rst)
wdt_reset_n <= 1'b1;
else if(wdt_reset != wdt_reset_n)
begin
wdt_reset_n <= wdt_reset;
wdt_rst_out <= 1'b1;
end
end
 
endmodule
/*
* !Watchdog.
*/
/*
* !Define modes.
*/
 
/*
* Instruction set.
*/
 
`define INSTRUCTION_NOP 16'b0000000000000000
`define INSTRUCTION_MOVW 16'b00000001xxxxxxxx//00000001DDDDRRRR
`define INSTRUCTION_MULS 16'b00000010xxxxxxxx//00000010ddddrrrr
`define INSTRUCTION_MULSU 16'b000000110xxx0xxx//000000110ddd0rrr
`define INSTRUCTION_FMUL 16'b000000110xxx1xxx//000000110ddd1rrr
`define INSTRUCTION_FMULS 16'b000000111xxx0xxx//000000111dddurrr
`define INSTRUCTION_FMULSU 16'b000000111xxx1xxx//000000111dddurrr
`define INSTRUCTION_CPC 16'b000001xxxxxxxxxx//000001rdddddrrrr
`define INSTRUCTION_CP 16'b000101xxxxxxxxxx//000101rdddddrrrr
`define INSTRUCTION_SBC 16'b000010xxxxxxxxxx//000010rdddddrrrr
`define INSTRUCTION_SUB 16'b000110xxxxxxxxxx//000110rdddddrrrr
`define INSTRUCTION_ADD 16'b000011xxxxxxxxxx//000011rdddddrrrr
`define INSTRUCTION_ADC 16'b000111xxxxxxxxxx//000111rdddddrrrr
`define INSTRUCTION_CPSE 16'b000100xxxxxxxxxx//000100rdddddrrrr
`define INSTRUCTION_AND 16'b001000xxxxxxxxxx//001000rdddddrrrr
`define INSTRUCTION_EOR 16'b001001xxxxxxxxxx//001001rdddddrrrr
`define INSTRUCTION_OR 16'b001010xxxxxxxxxx//001010rdddddrrrr
`define INSTRUCTION_MOV 16'b001011xxxxxxxxxx//001011rdddddrrrr
`define INSTRUCTION_CPI 16'b0011xxxxxxxxxxxx//0011kkkkddddkkkk
`define INSTRUCTION_SUBI 16'b0101xxxxxxxxxxxx//0101kkkkddddkkkk
`define INSTRUCTION_SBCI 16'b0100xxxxxxxxxxxx//0100kkkkddddkkkk
`define INSTRUCTION_ORI_SBR 16'b0110xxxxxxxxxxxx//0110kkkkddddkkkk
`define INSTRUCTION_ANDI_CBR 16'b0111xxxxxxxxxxxx//0111kkkkddddkkkk
 
`define INSTRUCTION_LDD_STD 16'b10x0xxxxxxxxxxxx//10k0kksdddddykkk
`define INSTRUCTION_LDS_STS 16'b100100xxxxxx0000//100100sddddd0000
`define INSTRUCTION_LD_ST_YZP 16'b100100xxxxxxx001//100100sdddddy001
`define INSTRUCTION_LD_ST_YZN 16'b100100xxxxxxx010//100100sdddddy010
`define INSTRUCTION_LPM_R 16'b1001000xxxxx0100//1001000ddddd01q0
`define INSTRUCTION_LPM_R_P 16'b1001000xxxxx0101//1001000ddddd01q1
`define INSTRUCTION_XCH 16'b1001001xxxxx0100//1001001ddddd0100
`define INSTRUCTION_LAS 16'b1001001xxxxx0101//1001001ddddd0101
`define INSTRUCTION_LAC 16'b1001001xxxxx0110//1001001ddddd0110
`define INSTRUCTION_LAT 16'b1001001xxxxx0111//1001001ddddd0111
`define INSTRUCTION_LD_ST_X 16'b100100xxxxxx1100//100100sddddd1100
`define INSTRUCTION_LD_ST_XP 16'b100100xxxxxx1101//100100sddddd1101
`define INSTRUCTION_LD_ST_XN 16'b100100xxxxxx1110//100100sddddd1110
`define INSTRUCTION_POP_PUSH 16'b100100xxxxxx1111//100100sddddd1111
`define INSTRUCTION_COM 16'b1001010xxxxx0000//1001010ddddd0000
`define INSTRUCTION_NEG 16'b1001010xxxxx0001//1001010ddddd0001
`define INSTRUCTION_SWAP 16'b1001010xxxxx0010//1001010ddddd0010
`define INSTRUCTION_INC 16'b1001010xxxxx0011//1001010ddddd0011
`define INSTRUCTION_ASR 16'b1001010xxxxx0101//1001010ddddd0101
`define INSTRUCTION_LSR 16'b1001010xxxxx0110//1001010ddddd0110
`define INSTRUCTION_ROR 16'b1001010xxxxx0111//1001010ddddd0111
`define INSTRUCTION_SEx_CLx 16'b10010100xxxx1000//10010100Bbbb1000
`define INSTRUCTION_RET_RETI 16'b10010101000x1000//10010101000x1000
`define INSTRUCTION_RET 16'b1001010100001000//1001010100001000
`define INSTRUCTION_RETI 16'b1001010100011000//1001010100001000
`define INSTRUCTION_SLEEP 16'b1001010110000000//1001010100001000
`define INSTRUCTION_BREAK 16'b1001010110011000//1001010100011000
`define INSTRUCTION_WDR 16'b1001010110101000//1001010100101000
`define INSTRUCTION_LPM_ELPM 16'b10010101110x1000//10010101110q1000
`define INSTRUCTION_SPM 16'b1001010111101000//1001010111101000
`define INSTRUCTION_SPM_Z_P 16'b1001010111111000//1001010111111000
`define INSTRUCTION_IJMP 16'b1001010000001001//1001010c000e1001
`define INSTRUCTION_ICALL 16'b1001010100001001//1001010c000e1001
`define INSTRUCTION_DEC 16'b1001010xxxxx1010//1001010ddddd1010
`define INSTRUCTION_DES 16'b10010100xxxx1011//10010100kkkk1011
`define INSTRUCTION_JMP 16'b1001010xxxxx110x//1001010kkkkk110k
`define INSTRUCTION_CALL 16'b1001010xxxxx111x//1001010kkkkk111k
`define INSTRUCTION_ADIW 16'b10010110xxxxxxxx//10010110kkppkkkk
`define INSTRUCTION_SBIW 16'b10010111xxxxxxxx//10010111kkppkkkk
`define INSTRUCTION_CBI_SBI 16'b100110x0xxxxxxxx//100110B0aaaaabbb
`define INSTRUCTION_SBIC_SBIS 16'b100110x1xxxxxxxx//100110B1aaaaabbb
`define INSTRUCTION_MUL 16'b100111xxxxxxxxxx//100111rdddddrrrr
`define INSTRUCTION_IN_OUT 16'b1011xxxxxxxxxxxx//1011saadddddaaaa
`define INSTRUCTION_RJMP 16'b1100xxxxxxxxxxxx//1100xxxxxxxxxxxx
`define INSTRUCTION_RCALL 16'b1101xxxxxxxxxxxx//1101xxxxxxxxxxxx
`define INSTRUCTION_LDI 16'b1110xxxxxxxxxxxx//1110KKKKddddKKKK
`define INSTRUCTION_COND_BRANCH 16'b11110xxxxxxxxxxx//11110Bxxxxxxxbbb
`define INSTRUCTION_BLD_BST 16'b111110xxxxxx0xxx//111110sddddd0bbb
`define INSTRUCTION_SBRC_SBRS 16'b111111xxxxxx0xxx//111111Bddddd0bbb
/*
* !Instruction set.
*/
 
/*
* Instruction decoder.
*/
module inst_dec(
input [15:0]inst,
input INTERRUPT_IN_EXECUTION,
output reg SEL_INSTRUCTION_MOVW,
output reg SEL_INSTRUCTION_MULS,
output reg SEL_INSTRUCTION_MULSU,
output reg SEL_INSTRUCTION_FMUL,
output reg SEL_INSTRUCTION_FMULS,
output reg SEL_INSTRUCTION_FMULSU,
output reg SEL_INSTRUCTION_CPC,
output reg SEL_INSTRUCTION_CP,
output reg SEL_INSTRUCTION_SBC,
output reg SEL_INSTRUCTION_SUB,
output reg SEL_INSTRUCTION_ADD,
output reg SEL_INSTRUCTION_ADC,
output reg SEL_INSTRUCTION_CPSE,
output reg SEL_INSTRUCTION_AND,
output reg SEL_INSTRUCTION_EOR,
output reg SEL_INSTRUCTION_OR,
output reg SEL_INSTRUCTION_MOV,
output reg SEL_INSTRUCTION_CPI,
output reg SEL_INSTRUCTION_SUBI,
output reg SEL_INSTRUCTION_SBCI,
output reg SEL_INSTRUCTION_ORI_SBR,
output reg SEL_INSTRUCTION_ANDI_CBR,
output reg SEL_INSTRUCTION_LDD_STD,
output reg SEL_INSTRUCTION_LDS_STS,
output reg SEL_INSTRUCTION_LD_ST_YZP,
output reg SEL_INSTRUCTION_LD_ST_YZN,
output reg SEL_INSTRUCTION_LPM_R,
output reg SEL_INSTRUCTION_LPM_R_P,
output reg SEL_INSTRUCTION_XCH,
output reg SEL_INSTRUCTION_LAS,
output reg SEL_INSTRUCTION_LAC,
output reg SEL_INSTRUCTION_LAT,
output reg SEL_INSTRUCTION_LD_ST_X,
output reg SEL_INSTRUCTION_LD_ST_XP,
output reg SEL_INSTRUCTION_LD_ST_XN,
output reg SEL_INSTRUCTION_POP_PUSH,
output reg SEL_INSTRUCTION_COM,
output reg SEL_INSTRUCTION_NEG,
output reg SEL_INSTRUCTION_SWAP,
output reg SEL_INSTRUCTION_INC,
output reg SEL_INSTRUCTION_ASR,
output reg SEL_INSTRUCTION_LSR,
output reg SEL_INSTRUCTION_ROR,
output reg SEL_INSTRUCTION_SEx_CLx,
output reg SEL_INSTRUCTION_RET,
output reg SEL_INSTRUCTION_RETI,
output reg SEL_INSTRUCTION_SLEEP,
output reg SEL_INSTRUCTION_BREAK,
output reg SEL_INSTRUCTION_WDR,
output reg SEL_INSTRUCTION_LPM_ELPM,
output reg SEL_INSTRUCTION_SPM,
output reg SEL_INSTRUCTION_SPM_Z_P,
output reg SEL_INSTRUCTION_IJMP,
output reg SEL_INSTRUCTION_ICALL,
output reg SEL_INSTRUCTION_DEC,
output reg SEL_INSTRUCTION_DES,
output reg SEL_INSTRUCTION_JMP,
output reg SEL_INSTRUCTION_CALL,
output reg SEL_INSTRUCTION_ADIW,
output reg SEL_INSTRUCTION_SBIW,
output reg SEL_INSTRUCTION_CBI_SBI,
output reg SEL_INSTRUCTION_SBIC_SBIS,
output reg SEL_INSTRUCTION_MUL,
output reg SEL_INSTRUCTION_IN_OUT,
output reg SEL_INSTRUCTION_RJMP,
output reg SEL_INSTRUCTION_RCALL,
output reg SEL_INSTRUCTION_LDI,
output reg SEL_INSTRUCTION_COND_BRANCH,
output reg SEL_INSTRUCTION_BLD_BST,
output reg SEL_INSTRUCTION_SBRC_SBRS
);
 
always @ (*)
begin
SEL_INSTRUCTION_MOVW <= 1'b0;
SEL_INSTRUCTION_MULS <= 1'b0;
SEL_INSTRUCTION_MULSU <= 1'b0;
SEL_INSTRUCTION_FMUL <= 1'b0;
SEL_INSTRUCTION_FMULS <= 1'b0;
SEL_INSTRUCTION_FMULSU <= 1'b0;
SEL_INSTRUCTION_CPC <= 1'b0;
SEL_INSTRUCTION_CP <= 1'b0;
SEL_INSTRUCTION_SBC <= 1'b0;
SEL_INSTRUCTION_SUB <= 1'b0;
SEL_INSTRUCTION_ADD <= 1'b0;
SEL_INSTRUCTION_ADC <= 1'b0;
SEL_INSTRUCTION_CPSE <= 1'b0;
SEL_INSTRUCTION_AND <= 1'b0;
SEL_INSTRUCTION_EOR <= 1'b0;
SEL_INSTRUCTION_OR <= 1'b0;
SEL_INSTRUCTION_MOV <= 1'b0;
SEL_INSTRUCTION_CPI <= 1'b0;
SEL_INSTRUCTION_SUBI <= 1'b0;
SEL_INSTRUCTION_SBCI <= 1'b0;
SEL_INSTRUCTION_ORI_SBR <= 1'b0;
SEL_INSTRUCTION_ANDI_CBR <= 1'b0;
SEL_INSTRUCTION_LDD_STD <= 1'b0;
SEL_INSTRUCTION_LDS_STS <= 1'b0;
SEL_INSTRUCTION_LD_ST_YZP <= 1'b0;
SEL_INSTRUCTION_LD_ST_YZN <= 1'b0;
SEL_INSTRUCTION_LPM_R <= 1'b0;
SEL_INSTRUCTION_LPM_R_P <= 1'b0;
SEL_INSTRUCTION_XCH <= 1'b0;
SEL_INSTRUCTION_LAS <= 1'b0;
SEL_INSTRUCTION_LAC <= 1'b0;
SEL_INSTRUCTION_LAT <= 1'b0;
SEL_INSTRUCTION_LD_ST_X <= 1'b0;
SEL_INSTRUCTION_LD_ST_XP <= 1'b0;
SEL_INSTRUCTION_LD_ST_XN <= 1'b0;
SEL_INSTRUCTION_POP_PUSH <= 1'b0;
SEL_INSTRUCTION_COM <= 1'b0;
SEL_INSTRUCTION_NEG <= 1'b0;
SEL_INSTRUCTION_SWAP <= 1'b0;
SEL_INSTRUCTION_INC <= 1'b0;
SEL_INSTRUCTION_ASR <= 1'b0;
SEL_INSTRUCTION_LSR <= 1'b0;
SEL_INSTRUCTION_ROR <= 1'b0;
SEL_INSTRUCTION_SEx_CLx <= 1'b0;
SEL_INSTRUCTION_RET <= 1'b0;
SEL_INSTRUCTION_RETI <= 1'b0;
SEL_INSTRUCTION_SLEEP <= 1'b0;
SEL_INSTRUCTION_BREAK <= 1'b0;
SEL_INSTRUCTION_WDR <= 1'b0;
SEL_INSTRUCTION_LPM_ELPM <= 1'b0;
SEL_INSTRUCTION_SPM <= 1'b0;
SEL_INSTRUCTION_SPM_Z_P <= 1'b0;
SEL_INSTRUCTION_IJMP <= 1'b0;
SEL_INSTRUCTION_ICALL <= 1'b0;
SEL_INSTRUCTION_DEC <= 1'b0;
SEL_INSTRUCTION_DES <= 1'b0;
SEL_INSTRUCTION_JMP <= 1'b0;
SEL_INSTRUCTION_CALL <= 1'b0;
SEL_INSTRUCTION_ADIW <= 1'b0;
SEL_INSTRUCTION_SBIW <= 1'b0;
SEL_INSTRUCTION_CBI_SBI <= 1'b0;
SEL_INSTRUCTION_SBIC_SBIS <= 1'b0;
SEL_INSTRUCTION_MUL <= 1'b0;
SEL_INSTRUCTION_IN_OUT <= 1'b0;
SEL_INSTRUCTION_RJMP <= 1'b0;
SEL_INSTRUCTION_RCALL <= 1'b0;
SEL_INSTRUCTION_LDI <= 1'b0;
SEL_INSTRUCTION_COND_BRANCH <= 1'b0;
SEL_INSTRUCTION_BLD_BST <= 1'b0;
SEL_INSTRUCTION_SBRC_SBRS <= 1'b0;
casex({INTERRUPT_IN_EXECUTION, inst})
{1'b0, `INSTRUCTION_MOVW}: SEL_INSTRUCTION_MOVW <= 1'b1;
{1'b0, `INSTRUCTION_MULS}: SEL_INSTRUCTION_MULS <= 1'b1;
{1'b0, `INSTRUCTION_MULSU}: SEL_INSTRUCTION_MULSU <= 1'b1;
{1'b0, `INSTRUCTION_FMUL}: SEL_INSTRUCTION_FMUL <= 1'b1;
{1'b0, `INSTRUCTION_FMULS}: SEL_INSTRUCTION_FMULS <= 1'b1;
{1'b0, `INSTRUCTION_FMULSU}: SEL_INSTRUCTION_FMULSU <= 1'b1;
{1'b0, `INSTRUCTION_CPC}: SEL_INSTRUCTION_CPC <= 1'b1;
{1'b0, `INSTRUCTION_CP}: SEL_INSTRUCTION_CP <= 1'b1;
{1'b0, `INSTRUCTION_SBC}: SEL_INSTRUCTION_SBC <= 1'b1;
{1'b0, `INSTRUCTION_SUB}: SEL_INSTRUCTION_SUB <= 1'b1;
{1'b0, `INSTRUCTION_ADD}: SEL_INSTRUCTION_ADD <= 1'b1;
{1'b0, `INSTRUCTION_ADC}: SEL_INSTRUCTION_ADC <= 1'b1;
{1'b0, `INSTRUCTION_CPSE}: SEL_INSTRUCTION_CPSE <= 1'b1;
{1'b0, `INSTRUCTION_AND}: SEL_INSTRUCTION_AND <= 1'b1;
{1'b0, `INSTRUCTION_EOR}: SEL_INSTRUCTION_EOR <= 1'b1;
{1'b0, `INSTRUCTION_OR}: SEL_INSTRUCTION_OR <= 1'b1;
{1'b0, `INSTRUCTION_MOV}: SEL_INSTRUCTION_MOV <= 1'b1;
{1'b0, `INSTRUCTION_CPI}: SEL_INSTRUCTION_CPI <= 1'b1;
{1'b0, `INSTRUCTION_SUBI}: SEL_INSTRUCTION_SUBI <= 1'b1;
{1'b0, `INSTRUCTION_SBCI}: SEL_INSTRUCTION_SBCI <= 1'b1;
{1'b0, `INSTRUCTION_ORI_SBR}: SEL_INSTRUCTION_ORI_SBR <= 1'b1;
{1'b0, `INSTRUCTION_ANDI_CBR}: SEL_INSTRUCTION_ANDI_CBR <= 1'b1;
{1'b0, `INSTRUCTION_LDD_STD}: SEL_INSTRUCTION_LDD_STD <= 1'b1;
{1'b0, `INSTRUCTION_LDS_STS}: SEL_INSTRUCTION_LDS_STS <= 1'b1;
{1'b0, `INSTRUCTION_LD_ST_YZP}: SEL_INSTRUCTION_LD_ST_YZP <= 1'b1;
{1'b0, `INSTRUCTION_LD_ST_YZN}: SEL_INSTRUCTION_LD_ST_YZN <= 1'b1;
{1'b0, `INSTRUCTION_LPM_R}: SEL_INSTRUCTION_LPM_R <= 1'b1;
{1'b0, `INSTRUCTION_LPM_R_P}: SEL_INSTRUCTION_LPM_R_P <= 1'b1;
{1'b0, `INSTRUCTION_XCH}: SEL_INSTRUCTION_XCH <= 1'b1;
{1'b0, `INSTRUCTION_LAS}: SEL_INSTRUCTION_LAS <= 1'b1;
{1'b0, `INSTRUCTION_LAC}: SEL_INSTRUCTION_LAC <= 1'b1;
{1'b0, `INSTRUCTION_LAT}: SEL_INSTRUCTION_LAT <= 1'b1;
{1'b0, `INSTRUCTION_LD_ST_X}: SEL_INSTRUCTION_LD_ST_X <= 1'b1;
{1'b0, `INSTRUCTION_LD_ST_XP}: SEL_INSTRUCTION_LD_ST_XP <= 1'b1;
{1'b0, `INSTRUCTION_LD_ST_XN}: SEL_INSTRUCTION_LD_ST_XN <= 1'b1;
{1'b0, `INSTRUCTION_POP_PUSH}: SEL_INSTRUCTION_POP_PUSH <= 1'b1;
{1'b0, `INSTRUCTION_COM}: SEL_INSTRUCTION_COM <= 1'b1;
{1'b0, `INSTRUCTION_NEG}: SEL_INSTRUCTION_NEG <= 1'b1;
{1'b0, `INSTRUCTION_SWAP}: SEL_INSTRUCTION_SWAP <= 1'b1;
{1'b0, `INSTRUCTION_INC}: SEL_INSTRUCTION_INC <= 1'b1;
{1'b0, `INSTRUCTION_ASR}: SEL_INSTRUCTION_ASR <= 1'b1;
{1'b0, `INSTRUCTION_LSR}: SEL_INSTRUCTION_LSR <= 1'b1;
{1'b0, `INSTRUCTION_ROR}: SEL_INSTRUCTION_ROR <= 1'b1;
{1'b0, `INSTRUCTION_SEx_CLx}: SEL_INSTRUCTION_SEx_CLx <= 1'b1;
{1'b0, `INSTRUCTION_RET}: SEL_INSTRUCTION_RET <= 1'b1;
{1'b0, `INSTRUCTION_RETI}: SEL_INSTRUCTION_RETI <= 1'b1;
{1'b0, `INSTRUCTION_SLEEP}: SEL_INSTRUCTION_SLEEP <= 1'b1;
{1'b0, `INSTRUCTION_BREAK}: SEL_INSTRUCTION_BREAK <= 1'b1;
{1'b0, `INSTRUCTION_WDR}: SEL_INSTRUCTION_WDR <= 1'b1;
{1'b0, `INSTRUCTION_LPM_ELPM}: SEL_INSTRUCTION_LPM_ELPM <= 1'b1;
{1'b0, `INSTRUCTION_SPM}: SEL_INSTRUCTION_SPM <= 1'b1;
{1'b0, `INSTRUCTION_SPM_Z_P}: SEL_INSTRUCTION_SPM_Z_P <= 1'b1;
{1'b0, `INSTRUCTION_IJMP}: SEL_INSTRUCTION_IJMP <= 1'b1;
{1'b0, `INSTRUCTION_ICALL}: SEL_INSTRUCTION_ICALL <= 1'b1;
{1'b0, `INSTRUCTION_DEC}: SEL_INSTRUCTION_DEC <= 1'b1;
{1'b0, `INSTRUCTION_DES}: SEL_INSTRUCTION_DES <= 1'b1;
{1'b0, `INSTRUCTION_JMP}: SEL_INSTRUCTION_JMP <= 1'b1;
{1'b0, `INSTRUCTION_CALL}: SEL_INSTRUCTION_CALL <= 1'b1;
{1'b0, `INSTRUCTION_ADIW}: SEL_INSTRUCTION_ADIW <= 1'b1;
{1'b0, `INSTRUCTION_SBIW}: SEL_INSTRUCTION_SBIW <= 1'b1;
{1'b0, `INSTRUCTION_CBI_SBI}: SEL_INSTRUCTION_CBI_SBI <= 1'b1;
{1'b0, `INSTRUCTION_SBIC_SBIS}: SEL_INSTRUCTION_SBIC_SBIS <= 1'b1;
{1'b0, `INSTRUCTION_MUL}: SEL_INSTRUCTION_MUL <= 1'b1;
{1'b0, `INSTRUCTION_IN_OUT}: SEL_INSTRUCTION_IN_OUT <= 1'b1;
{1'b0, `INSTRUCTION_RJMP}: SEL_INSTRUCTION_RJMP <= 1'b1;
{1'b0, `INSTRUCTION_RCALL}: SEL_INSTRUCTION_RCALL <= 1'b1;
{1'b0, `INSTRUCTION_LDI}: SEL_INSTRUCTION_LDI <= 1'b1;
{1'b0, `INSTRUCTION_COND_BRANCH}: SEL_INSTRUCTION_COND_BRANCH <= 1'b1;
{1'b0, `INSTRUCTION_BLD_BST}: SEL_INSTRUCTION_BLD_BST <= 1'b1;
{1'b0, `INSTRUCTION_SBRC_SBRS}: SEL_INSTRUCTION_SBRC_SBRS <= 1'b1;
endcase
end
endmodule
/*
* !Instruction decoder.
*/
 
/*
* Registers memory.
*/
`define ALU_FLAG_C 0
`define ALU_FLAG_Z 1
`define ALU_FLAG_N 2
`define ALU_FLAG_V 3
`define ALU_FLAG_S 4
`define ALU_FLAG_H 5
`define ALU_FLAG_T 6
`define ALU_FLAG_I 7
 
module mega_regs #
(
parameter PLATFORM = "XILINX"
)(
input rst,
input clk,
input [4:0]rw_addr,
input [15:0]rw_data,
input rw_16bit,
input write,
input [4:0]rd_addr_d,
output [15:0]rd_data_d,
input rd_16bit_d,
input read_d,
input [4:0]rd_addr_r,
output [15:0]rd_data_r,
input rd_16bit_r,
input read_r
);
 
generate
if(PLATFORM == "XILINX")
begin
reg [7:0]REGL[0:15];
reg [7:0]REGH[0:15];
 
/*integer k;
 
initial
begin
for (k = 0; k < 16; k = k + 1)
begin
REGL[k] = 0;
REGH[k] = 0;
end
end*/
always @ (posedge clk)
begin
if(write)
begin
if(!rw_16bit & !rw_addr[0])
REGL[rw_addr[4:1]] <= rw_data[7:0];
else if(!rw_16bit & rw_addr[0])
REGH[rw_addr[4:1]] <= rw_data[7:0];
else
begin
REGL[rw_addr[4:1]] <= rw_data[7:0];
REGH[rw_addr[4:1]] <= rw_data[15:8];
end
end
end
 
assign rd_data_d = (read_d) ? (rd_16bit_d) ? {REGH[rd_addr_d[4:1]], REGL[rd_addr_d[4:1]]} : (rd_addr_d[0]) ? {8'h00, REGH[rd_addr_d[4:1]]} : {8'h00, REGL[rd_addr_d[4:1]]} : 16'bx;
assign rd_data_r = (read_r) ? (rd_16bit_r) ? {REGH[rd_addr_r[4:1]], REGL[rd_addr_r[4:1]]} : (rd_addr_r[0]) ? {8'h00, REGH[rd_addr_r[4:1]]} : {8'h00, REGL[rd_addr_r[4:1]]} : 16'bx;
end /* PLATFORM != "XILINX" */
else
if(PLATFORM == "LATTICE_ECP5" || PLATFORM == "LATTICE_ECP3" || PLATFORM == "LATTICE_LIFMD" || PLATFORM == "LATTICE_MARCHXO2" || PLATFORM == "LATTICE_MARCHXO3L")
begin/* Lattice Diamond does not know how to implement distributed RAM with true three ports, so I implement him from individual distributed RAM cells. */
wire [7:0]REGLD_out;
wire [7:0]REGHD_out;
wire [7:0]REGLR_out;
wire [7:0]REGHR_out;
wire write_to_L = write & ((!rw_16bit & !rw_addr[0]) || rw_16bit);
wire write_to_H = write &((!rw_16bit & rw_addr[0]) || rw_16bit);
wire write_to_HL = write &rw_16bit;
 
DPR16X4C REG_L_D_4_7(
.DI3(rw_data[7]),
.DI2(rw_data[6]),
.DI1(rw_data[5]),
.DI0(rw_data[4]),
.WAD3(rw_addr[4]),
.WAD2(rw_addr[3]),
.WAD1(rw_addr[2]),
.WAD0(rw_addr[1]),
.WCK(clk),
.WRE(write_to_L | write_to_HL),
.RAD3(rd_addr_d[4]),
.RAD2(rd_addr_d[3]),
.RAD1(rd_addr_d[2]),
.RAD0(rd_addr_d[1]),
.DO3(REGLD_out[7]),
.DO2(REGLD_out[6]),
.DO1(REGLD_out[5]),
.DO0(REGLD_out[4])
);
DPR16X4C REG_L_D_0_3(
.DI3(rw_data[3]),
.DI2(rw_data[2]),
.DI1(rw_data[1]),
.DI0(rw_data[0]),
.WAD3(rw_addr[4]),
.WAD2(rw_addr[3]),
.WAD1(rw_addr[2]),
.WAD0(rw_addr[1]),
.WCK(clk),
.WRE(write_to_L | write_to_HL),
.RAD3(rd_addr_d[4]),
.RAD2(rd_addr_d[3]),
.RAD1(rd_addr_d[2]),
.RAD0(rd_addr_d[1]),
.DO3(REGLD_out[3]),
.DO2(REGLD_out[2]),
.DO1(REGLD_out[1]),
.DO0(REGLD_out[0])
);
DPR16X4C REG_H_D_4_7(
.DI3(write_to_HL ? rw_data[15] : rw_data[7]),
.DI2(write_to_HL ? rw_data[14] : rw_data[6]),
.DI1(write_to_HL ? rw_data[13] : rw_data[5]),
.DI0(write_to_HL ? rw_data[12] : rw_data[4]),
.WAD3(rw_addr[4]),
.WAD2(rw_addr[3]),
.WAD1(rw_addr[2]),
.WAD0(rw_addr[1]),
.WCK(clk),
.WRE(write_to_H | write_to_HL),
.RAD3(rd_addr_d[4]),
.RAD2(rd_addr_d[3]),
.RAD1(rd_addr_d[2]),
.RAD0(rd_addr_d[1]),
.DO3(REGHD_out[7]),
.DO2(REGHD_out[6]),
.DO1(REGHD_out[5]),
.DO0(REGHD_out[4])
);
DPR16X4C REG_H_D_0_3(
.DI3(write_to_HL ? rw_data[11] : rw_data[3]),
.DI2(write_to_HL ? rw_data[10] : rw_data[2]),
.DI1(write_to_HL ? rw_data[9] : rw_data[1]),
.DI0(write_to_HL ? rw_data[8] : rw_data[0]),
.WAD3(rw_addr[4]),
.WAD2(rw_addr[3]),
.WAD1(rw_addr[2]),
.WAD0(rw_addr[1]),
.WCK(clk),
.WRE(write_to_H | write_to_HL),
.RAD3(rd_addr_d[4]),
.RAD2(rd_addr_d[3]),
.RAD1(rd_addr_d[2]),
.RAD0(rd_addr_d[1]),
.DO3(REGHD_out[3]),
.DO2(REGHD_out[2]),
.DO1(REGHD_out[1]),
.DO0(REGHD_out[0])
);
DPR16X4C REG_L_R_4_7(
.DI3(rw_data[7]),
.DI2(rw_data[6]),
.DI1(rw_data[5]),
.DI0(rw_data[4]),
.WAD3(rw_addr[4]),
.WAD2(rw_addr[3]),
.WAD1(rw_addr[2]),
.WAD0(rw_addr[1]),
.WCK(clk),
.WRE(write_to_L | write_to_HL),
.RAD3(rd_addr_r[4]),
.RAD2(rd_addr_r[3]),
.RAD1(rd_addr_r[2]),
.RAD0(rd_addr_r[1]),
.DO3(REGLR_out[7]),
.DO2(REGLR_out[6]),
.DO1(REGLR_out[5]),
.DO0(REGLR_out[4])
);
DPR16X4C REG_L_R_0_3(
.DI3(rw_data[3]),
.DI2(rw_data[2]),
.DI1(rw_data[1]),
.DI0(rw_data[0]),
.WAD3(rw_addr[4]),
.WAD2(rw_addr[3]),
.WAD1(rw_addr[2]),
.WAD0(rw_addr[1]),
.WCK(clk),
.WRE(write_to_L | write_to_HL),
.RAD3(rd_addr_r[4]),
.RAD2(rd_addr_r[3]),
.RAD1(rd_addr_r[2]),
.RAD0(rd_addr_r[1]),
.DO3(REGLR_out[3]),
.DO2(REGLR_out[2]),
.DO1(REGLR_out[1]),
.DO0(REGLR_out[0])
);
DPR16X4C REG_H_R_4_7(
.DI3(write_to_HL ? rw_data[15] : rw_data[7]),
.DI2(write_to_HL ? rw_data[14] : rw_data[6]),
.DI1(write_to_HL ? rw_data[13] : rw_data[5]),
.DI0(write_to_HL ? rw_data[12] : rw_data[4]),
.WAD3(rw_addr[4]),
.WAD2(rw_addr[3]),
.WAD1(rw_addr[2]),
.WAD0(rw_addr[1]),
.WCK(clk),
.WRE(write_to_H | write_to_HL),
.RAD3(rd_addr_r[4]),
.RAD2(rd_addr_r[3]),
.RAD1(rd_addr_r[2]),
.RAD0(rd_addr_r[1]),
.DO3(REGHR_out[7]),
.DO2(REGHR_out[6]),
.DO1(REGHR_out[5]),
.DO0(REGHR_out[4])
);
DPR16X4C REG_H_R_0_3(
.DI3(write_to_HL ? rw_data[11] : rw_data[3]),
.DI2(write_to_HL ? rw_data[10] : rw_data[2]),
.DI1(write_to_HL ? rw_data[9] : rw_data[1]),
.DI0(write_to_HL ? rw_data[8] : rw_data[0]),
.WAD3(rw_addr[4]),
.WAD2(rw_addr[3]),
.WAD1(rw_addr[2]),
.WAD0(rw_addr[1]),
.WCK(clk),
.WRE(write_to_H | write_to_HL),
.RAD3(rd_addr_r[4]),
.RAD2(rd_addr_r[3]),
.RAD1(rd_addr_r[2]),
.RAD0(rd_addr_r[1]),
.DO3(REGHR_out[3]),
.DO2(REGHR_out[2]),
.DO1(REGHR_out[1]),
.DO0(REGHR_out[0])
);
assign rd_data_d = (read_d) ? (rd_16bit_d) ? {REGHD_out, REGLD_out} : (rd_addr_d[0]) ? {8'h00, REGHD_out} : {8'h00, REGLD_out} : 16'bx;
assign rd_data_r = (read_r) ? (rd_16bit_r) ? {REGHR_out, REGLR_out} : (rd_addr_r[0]) ? {8'h00, REGHR_out} : {8'h00, REGLR_out} : 16'bx;
 
end/* PLATFORM != "LATTICE_ECP5" || PLATFORM != "LATTICE_ECP3" || PLATFORM != "LATTICE_LIFMD" || PLATFORM != "LATTICE_MARCHXO2" || PLATFORM != "LATTICE_MARCHXO3L" */
endgenerate
endmodule
/*
* !Registers memory.
*/
 
/*
* Asynchronous ALU.
*/
module mega_alu # (
parameter CORE_CONFIG = "XMEGA"
)(
input [3:0]inst,
input [4:0]in_addr_1,
input [4:0]in_addr_2,
input [15:0]in_1,
input [15:0]in_2,
output reg [15:0]out,
//output c_out,
input ALU_FLAG_C_IN, //Zero Flag
input ALU_FLAG_Z_IN, //Zero Flag
input ALU_FLAG_N_IN, //Negative Flag
input ALU_FLAG_V_IN, //Two's complement overflow indicator
input ALU_FLAG_S_IN, //N?V for signed tests
input ALU_FLAG_H_IN, //Half Carry Flag
input ALU_FLAG_T_IN, //Transfer bit used by BLD and BST instructions
input ALU_FLAG_I_IN, //Global Interrupt Enable/Disable Flag
output reg ALU_FLAG_C_OUT, //Carry Flag
output reg ALU_FLAG_Z_OUT, //Zero Flag
output reg ALU_FLAG_N_OUT, //Negative Flag
output reg ALU_FLAG_V_OUT, //Two's complement overflow indicator
output reg ALU_FLAG_S_OUT, //N?V for signed tests
output reg ALU_FLAG_H_OUT, //Half Carry Flag
output reg ALU_FLAG_T_OUT, //Transfer bit used by BLD and BST instructions
output reg ALU_FLAG_I_OUT, //Global Interrupt Enable/Disable Flag
input SEL_INSTRUCTION_MOVW,
input SEL_INSTRUCTION_MULS,
input SEL_INSTRUCTION_MULSU,
input SEL_INSTRUCTION_FMUL,
input SEL_INSTRUCTION_FMULS,
input SEL_INSTRUCTION_FMULSU,
input SEL_INSTRUCTION_CPC,
input SEL_INSTRUCTION_CP,
input SEL_INSTRUCTION_SBC,
input SEL_INSTRUCTION_SUB,
input SEL_INSTRUCTION_ADD,
input SEL_INSTRUCTION_ADC,
input SEL_INSTRUCTION_AND,
input SEL_INSTRUCTION_ANDI_CBR,
input SEL_INSTRUCTION_EOR,
input SEL_INSTRUCTION_OR,
input SEL_INSTRUCTION_ORI_SBR,
input SEL_INSTRUCTION_MOV,
input SEL_INSTRUCTION_CPI,
input SEL_INSTRUCTION_SUBI,
input SEL_INSTRUCTION_SBCI,
input SEL_INSTRUCTION_LPM_R_P,
input SEL_INSTRUCTION_COM,
input SEL_INSTRUCTION_NEG,
input SEL_INSTRUCTION_SWAP,
input SEL_INSTRUCTION_INC,
input SEL_INSTRUCTION_ASR,
input SEL_INSTRUCTION_LSR,
input SEL_INSTRUCTION_ROR,
input SEL_INSTRUCTION_SEx_CLx,
input SEL_INSTRUCTION_DEC,
input SEL_INSTRUCTION_ADIW,
input SEL_INSTRUCTION_SBIW,
input SEL_INSTRUCTION_MUL
);
 
reg in_addr_1_and_2_equal;
 
always @ (in_addr_1 or in_addr_2)
begin
in_addr_1_and_2_equal = in_addr_1 == in_addr_2;
end
 
reg [15:0]in_2_int;
reg cin_int;
 
always @ (*)
begin
in_2_int <= in_1;
cin_int <= ALU_FLAG_C_IN;
 
if(SEL_INSTRUCTION_ADD |
SEL_INSTRUCTION_ADC)
begin
if(!in_addr_1_and_2_equal)
in_2_int <= in_2;
end
if(
(SEL_INSTRUCTION_ADIW && CORE_CONFIG != "REDUCED") |
(SEL_INSTRUCTION_SBIW && CORE_CONFIG != "REDUCED") |
SEL_INSTRUCTION_SUB |
SEL_INSTRUCTION_SBC |
SEL_INSTRUCTION_SUBI |
SEL_INSTRUCTION_SBCI |
SEL_INSTRUCTION_INC |
SEL_INSTRUCTION_DEC |
SEL_INSTRUCTION_LPM_R_P |
SEL_INSTRUCTION_CP |
SEL_INSTRUCTION_CPI |
SEL_INSTRUCTION_CPC) in_2_int <= in_2;
 
if(SEL_INSTRUCTION_ADD |
(SEL_INSTRUCTION_ADIW && CORE_CONFIG != "REDUCED") |
(SEL_INSTRUCTION_SBIW && CORE_CONFIG != "REDUCED") |
SEL_INSTRUCTION_LSR |
SEL_INSTRUCTION_NEG |
SEL_INSTRUCTION_SUB |
SEL_INSTRUCTION_SUBI |
SEL_INSTRUCTION_INC |
SEL_INSTRUCTION_DEC |
SEL_INSTRUCTION_LPM_R_P |
SEL_INSTRUCTION_CP |
SEL_INSTRUCTION_CPI) cin_int <= 1'b0;
end
 
wire [17:0] add_result_int_w_c_tmp = {in_1, 1'b1} + {in_2_int, cin_int};
wire [16:0] add_result_int_w_c = add_result_int_w_c_tmp[17:1];
wire [17:0] sub_result_int_w_c_tmp = {in_1, 1'b0} - {in_2_int, cin_int};
wire [16:0] sub_result_int_w_c = sub_result_int_w_c_tmp[17:1];
 
/*
* Multiply Unit.
*/
 
reg [7:0]in_1_mul;
reg [7:0]in_2_mul;
wire [15:0]mul_result_int = in_1_mul * in_2_mul;
wire mul_sign_int = in_1[7] ^ in_2[7];
always @ (*)
begin
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
begin
in_1_mul <= 0;
in_2_mul <= 0;
if(SEL_INSTRUCTION_MUL | SEL_INSTRUCTION_FMUL)
begin
in_1_mul <= in_1[7:0];
in_2_mul <= in_2[7:0];
end
if(SEL_INSTRUCTION_MULS | SEL_INSTRUCTION_FMULS)
begin
in_1_mul <= {1'b0, in_1[6:0]};
in_2_mul <= {1'b0, in_2[6:0]};
end
if(SEL_INSTRUCTION_MULSU | SEL_INSTRUCTION_FMULSU)
begin
in_1_mul <= {1'b0, in_1[6:0]};
in_2_mul <= in_2[7:0];
end
end
end
 
always @ (*)
begin
{ALU_FLAG_C_OUT, out} <= {ALU_FLAG_C_IN, in_1};
if(SEL_INSTRUCTION_ADD)
begin
if(in_addr_1_and_2_equal)
{ALU_FLAG_C_OUT, out} <= {in_1[7], 8'h00, in_1[6:0], cin_int};//LSL
else
{ALU_FLAG_C_OUT, out} <= {add_result_int_w_c[8], 8'h00, add_result_int_w_c[7:0]};
end
if(SEL_INSTRUCTION_ADC)
begin
if(in_addr_1_and_2_equal)
{ALU_FLAG_C_OUT, out} <= {in_1[7], 8'h00, in_1[6:0], cin_int};//ROL
else
{ALU_FLAG_C_OUT, out} <= {add_result_int_w_c[8], 8'h00, add_result_int_w_c[7:0]};
end
if(SEL_INSTRUCTION_INC |
SEL_INSTRUCTION_DEC) {ALU_FLAG_C_OUT, out} <= {add_result_int_w_c[8], 8'h00, add_result_int_w_c[7:0]};
if(SEL_INSTRUCTION_SUB |
SEL_INSTRUCTION_SBC |
SEL_INSTRUCTION_SUBI |
SEL_INSTRUCTION_SBCI) {ALU_FLAG_C_OUT, out} <= {sub_result_int_w_c[8], 8'h00, sub_result_int_w_c[7:0]};
if(SEL_INSTRUCTION_LSR |
SEL_INSTRUCTION_ROR) {ALU_FLAG_C_OUT, out} <= {in_1[0], 8'h00, cin_int, in_1[7:1]};
if(SEL_INSTRUCTION_AND |
SEL_INSTRUCTION_ANDI_CBR) {ALU_FLAG_C_OUT, out} <= {ALU_FLAG_C_IN, 8'h00, (in_1[7:0] & in_2[7:0])};
if(SEL_INSTRUCTION_OR |
SEL_INSTRUCTION_ORI_SBR) {ALU_FLAG_C_OUT, out} <= {ALU_FLAG_C_IN, 8'h00, (in_1[7:0] | in_2[7:0])};
if(SEL_INSTRUCTION_EOR) {ALU_FLAG_C_OUT, out} <= {ALU_FLAG_C_IN, 8'h00, (in_1[7:0] ^ in_2[7:0])};
if(SEL_INSTRUCTION_MOV) {ALU_FLAG_C_OUT, out} <= {ALU_FLAG_C_IN, 8'h00, in_2[7:0]};
if(SEL_INSTRUCTION_MOVW) {ALU_FLAG_C_OUT, out} <= {ALU_FLAG_C_IN, in_2};
if(SEL_INSTRUCTION_COM) {ALU_FLAG_C_OUT, out} <= {1'b1, 8'h00, (8'hFF - in_1[7:0])};
if(SEL_INSTRUCTION_NEG) {ALU_FLAG_C_OUT, out} <= {|in_1[7:0], 8'h00, (8'h00 - in_1[7:0])};
if(SEL_INSTRUCTION_ADIW && CORE_CONFIG != "REDUCED")
{ALU_FLAG_C_OUT, out} <= add_result_int_w_c;
if(SEL_INSTRUCTION_SBIW && CORE_CONFIG != "REDUCED")
{ALU_FLAG_C_OUT, out} <= sub_result_int_w_c;
if((SEL_INSTRUCTION_MUL) && CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
{ALU_FLAG_C_OUT, out} <= {mul_result_int[15], mul_result_int};
if((SEL_INSTRUCTION_MULS) && CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
{ALU_FLAG_C_OUT, out} <= {mul_sign_int, mul_sign_int, mul_result_int[14:0]};
if((SEL_INSTRUCTION_MULSU) && CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
{ALU_FLAG_C_OUT, out} <= {in_1[7], in_1[7], mul_result_int};
if((SEL_INSTRUCTION_FMUL) && CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
{ALU_FLAG_C_OUT, out} <= {mul_result_int[15], mul_result_int[14:0], 1'b0};
if((SEL_INSTRUCTION_FMULS) && CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
{ALU_FLAG_C_OUT, out} <= {mul_sign_int, mul_result_int[14:0], 1'b0};
if((SEL_INSTRUCTION_FMULSU) && CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
{ALU_FLAG_C_OUT, out} <= {in_1[7], mul_result_int[14:0], 1'b0};
if(SEL_INSTRUCTION_ASR) {ALU_FLAG_C_OUT, out} <= {in_1[0], 8'h00, in_1[7], in_1[7:1]};
if(SEL_INSTRUCTION_CP |
SEL_INSTRUCTION_CPI |
SEL_INSTRUCTION_CPC) {ALU_FLAG_C_OUT, out} <= {sub_result_int_w_c[8], 8'h00, sub_result_int_w_c[7:0]};
if(SEL_INSTRUCTION_SWAP) {ALU_FLAG_C_OUT, out} <= {ALU_FLAG_C_IN, 8'b0, in_1[3:0], in_1[7:4]};
if(SEL_INSTRUCTION_SEx_CLx) {ALU_FLAG_C_OUT, out} <= inst[2:0] ? {ALU_FLAG_C_IN, {16{1'b0}}} : {~inst[3], {16{1'b0}}};
if(SEL_INSTRUCTION_LPM_R_P && CORE_CONFIG != "REDUCED")
{ALU_FLAG_C_OUT, out} <= add_result_int_w_c;
end
 
wire flag_h_adc_sub_cp = (~in_1[3] & in_2[3])|(in_2[3] & out[3])|(out[3] & ~in_1[3]);
wire flag_v_add_adc = (in_1[7] & in_2[7] & ~out[7])|(~in_1[7] & ~in_2[7] & out[7]);
wire flag_v_sub_sbc = (in_1[7] & ~in_2[7] & ~out[7])|(~in_1[7] & in_2[7] & out[7]);
/*
* ALU FLAG effect for each instruction.
*/
always @ (inst or out or in_1 or in_2 or
ALU_FLAG_Z_IN or ALU_FLAG_N_IN or ALU_FLAG_V_IN or
ALU_FLAG_S_IN or ALU_FLAG_H_IN or ALU_FLAG_T_IN or
ALU_FLAG_I_IN or ALU_FLAG_C_OUT or in_addr_1_and_2_equal or
flag_v_add_adc or flag_h_adc_sub_cp or
flag_v_sub_sbc or SEL_INSTRUCTION_ADD or
SEL_INSTRUCTION_ADC or SEL_INSTRUCTION_SUB or
SEL_INSTRUCTION_SUBI or SEL_INSTRUCTION_CP or
SEL_INSTRUCTION_CPI or SEL_INSTRUCTION_INC or
SEL_INSTRUCTION_DEC or SEL_INSTRUCTION_SBC or
SEL_INSTRUCTION_SBCI or SEL_INSTRUCTION_CPC or
SEL_INSTRUCTION_ADIW or SEL_INSTRUCTION_SBIW or
SEL_INSTRUCTION_AND or SEL_INSTRUCTION_OR or
SEL_INSTRUCTION_COM or SEL_INSTRUCTION_EOR or
SEL_INSTRUCTION_NEG or SEL_INSTRUCTION_ASR or
SEL_INSTRUCTION_LSR or SEL_INSTRUCTION_ROR or
SEL_INSTRUCTION_SEx_CLx or SEL_INSTRUCTION_MUL or
SEL_INSTRUCTION_FMUL or SEL_INSTRUCTION_MULS or
SEL_INSTRUCTION_MULSU or SEL_INSTRUCTION_FMULS or
SEL_INSTRUCTION_FMULSU)
begin
ALU_FLAG_Z_OUT <= ALU_FLAG_Z_IN;
ALU_FLAG_N_OUT <= ALU_FLAG_N_IN;
ALU_FLAG_V_OUT <= ALU_FLAG_V_IN;
ALU_FLAG_S_OUT <= ALU_FLAG_S_IN;
ALU_FLAG_H_OUT <= ALU_FLAG_H_IN;
ALU_FLAG_T_OUT <= ALU_FLAG_T_IN;
ALU_FLAG_I_OUT <= ALU_FLAG_I_IN;
if(SEL_INSTRUCTION_ADD)
begin
ALU_FLAG_N_OUT <= out[7];
if(in_addr_1_and_2_equal)
begin//LSL
ALU_FLAG_H_OUT <= in_1[3];
ALU_FLAG_V_OUT <= ALU_FLAG_N_OUT ^ ALU_FLAG_C_OUT;
ALU_FLAG_S_OUT <= out[7] != ALU_FLAG_V_OUT;
end
else
begin
ALU_FLAG_H_OUT <= (in_1[3] & in_2[3])|(in_2[3] & ~out[3])|(~out[3] & in_1[3]);
ALU_FLAG_V_OUT <= flag_v_add_adc;
ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
end
ALU_FLAG_Z_OUT <= &(~out[7:0]);
end
if(SEL_INSTRUCTION_ADC)
begin//ROL
ALU_FLAG_N_OUT <= out[7];
if(in_addr_1_and_2_equal)
begin
ALU_FLAG_H_OUT <= in_1[3];
ALU_FLAG_V_OUT <= ALU_FLAG_N_OUT ^ ALU_FLAG_C_OUT;
ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_N_OUT ^ ALU_FLAG_C_OUT;
end
else
begin
ALU_FLAG_H_OUT <= (in_1[3] & in_2[3])|(in_2[3] & out[3])|(~out[3] & ~in_1[3]);
ALU_FLAG_V_OUT <= flag_v_add_adc;
ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
end
ALU_FLAG_Z_OUT <= &(~out[7:0]);
end
if(SEL_INSTRUCTION_SUB |
SEL_INSTRUCTION_SUBI |
SEL_INSTRUCTION_CP |
SEL_INSTRUCTION_CPI)
begin
ALU_FLAG_H_OUT <= flag_h_adc_sub_cp;
ALU_FLAG_V_OUT <= flag_v_sub_sbc;
ALU_FLAG_N_OUT <= out[7];
ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
ALU_FLAG_Z_OUT <= &(~out[7:0]);
end
if(SEL_INSTRUCTION_INC |
SEL_INSTRUCTION_DEC)
begin
ALU_FLAG_V_OUT <= &{~out[7], out[6:0]};
ALU_FLAG_N_OUT <= out[7];
ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
ALU_FLAG_Z_OUT <= &(~out[7:0]);
end
if(SEL_INSTRUCTION_SBC |
SEL_INSTRUCTION_SBCI |
SEL_INSTRUCTION_CPC)
begin
ALU_FLAG_H_OUT <= flag_h_adc_sub_cp;
ALU_FLAG_V_OUT <= flag_v_sub_sbc;
ALU_FLAG_N_OUT <= out[7];
ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
ALU_FLAG_Z_OUT <= &{~out[7:0], ALU_FLAG_Z_IN};
end
if(CORE_CONFIG != "REDUCED")
begin
if(SEL_INSTRUCTION_ADIW |
SEL_INSTRUCTION_SBIW)
begin
ALU_FLAG_V_OUT <= ALU_FLAG_C_OUT;
ALU_FLAG_N_OUT <= out[15];
ALU_FLAG_S_OUT <= out[15] ^ ALU_FLAG_C_OUT;
ALU_FLAG_Z_OUT <= &(~out[15:0]);
end
end
if(SEL_INSTRUCTION_ANDI_CBR |
SEL_INSTRUCTION_ORI_SBR |
SEL_INSTRUCTION_AND |
SEL_INSTRUCTION_OR |
SEL_INSTRUCTION_COM |
SEL_INSTRUCTION_EOR)
begin
ALU_FLAG_V_OUT <= 1'b0;
ALU_FLAG_N_OUT <= out[7];
ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
ALU_FLAG_Z_OUT <= &(~out[7:0]);
end
if(SEL_INSTRUCTION_NEG)
begin
ALU_FLAG_H_OUT <= out[3] + ~in_1[3];
ALU_FLAG_V_OUT <= &{out[7], ~out[6:0]};
ALU_FLAG_N_OUT <= out[7];
ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
ALU_FLAG_Z_OUT <= &(~out[7:0]);
end
if(SEL_INSTRUCTION_ASR)
begin
ALU_FLAG_V_OUT <= 1'b0;
ALU_FLAG_N_OUT <= out[7];
ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
ALU_FLAG_Z_OUT <= &(~out[7:0]);
end
if(SEL_INSTRUCTION_LSR |
SEL_INSTRUCTION_ROR)
begin
ALU_FLAG_H_OUT <= in_1[3];
ALU_FLAG_N_OUT <= 0;
ALU_FLAG_V_OUT <= 0 ^ ALU_FLAG_C_OUT;
ALU_FLAG_S_OUT <= 0 ^ ALU_FLAG_V_OUT;
ALU_FLAG_Z_OUT <= &(~out[7:0]);
end
if(SEL_INSTRUCTION_SEx_CLx)
begin
case(inst[2:0])
3'd1: ALU_FLAG_Z_OUT <= ~inst[3];
3'd2: ALU_FLAG_N_OUT <= ~inst[3];
3'd3: ALU_FLAG_V_OUT <= ~inst[3];
3'd4: ALU_FLAG_S_OUT <= ~inst[3];
3'd5: ALU_FLAG_H_OUT <= ~inst[3];
3'd6: ALU_FLAG_T_OUT <= ~inst[3];
3'd7: ALU_FLAG_I_OUT <= ~inst[3];
endcase
end
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
begin
if(SEL_INSTRUCTION_MUL |
SEL_INSTRUCTION_FMUL)
ALU_FLAG_Z_OUT <= &(~out[15:0]);
if(SEL_INSTRUCTION_MULS |
SEL_INSTRUCTION_MULSU |
SEL_INSTRUCTION_FMULS |
SEL_INSTRUCTION_FMULSU)
ALU_FLAG_Z_OUT <= &(~out[15:0]);
end
end
 
endmodule
/*
* !Asynchronous ALU.
*/
/*
* Interrupt and priority encoder.
*/
module int_encoder # (
parameter VECTOR_INT_TABLE_SIZE = 0,
parameter STORE_INTERUPTS = "FALSE"
)(
input rst,
input [((VECTOR_INT_TABLE_SIZE == 0) ? 0 : VECTOR_INT_TABLE_SIZE-1):0]int_sig_in,
output int_request,
output reg[((VECTOR_INT_TABLE_SIZE > 127) ? 7 :
(VECTOR_INT_TABLE_SIZE > 63) ? 6 :
(VECTOR_INT_TABLE_SIZE > 31) ? 5 :
(VECTOR_INT_TABLE_SIZE > 15) ? 4 :
(VECTOR_INT_TABLE_SIZE > 7) ? 3 :
(VECTOR_INT_TABLE_SIZE > 3) ? 2 :
(VECTOR_INT_TABLE_SIZE > 1) ? 1 : 0) : 0]int_vect,
input executed
);
 
reg [VECTOR_INT_TABLE_SIZE : 0]int_sig_in_int;
reg [VECTOR_INT_TABLE_SIZE : 0]int_sig_in_int_n;
wire [VECTOR_INT_TABLE_SIZE : 0]int_sig_in_int_active = int_sig_in_int ^ int_sig_in_int_n;
 
genvar i;
generate
for (i = 0; i < VECTOR_INT_TABLE_SIZE;i = i + 1)
begin :int_sig_store
always @(posedge rst or posedge int_sig_in[i])
begin
if(STORE_INTERUPTS == "TRUE" && VECTOR_INT_TABLE_SIZE != 0)
begin
if(rst)
int_sig_in_int[i] <= 1'b0;
else
begin
if(int_sig_in_int_n[i] == int_sig_in_int[i])
int_sig_in_int[i] <= ~int_sig_in_int_n[i];
end
end
end
always @ (posedge rst or posedge executed)
begin
if(STORE_INTERUPTS == "TRUE" && VECTOR_INT_TABLE_SIZE != 0)
begin
if(rst)
int_sig_in_int_n[i] <= 1'b0;
else if(executed && int_vect == i)
int_sig_in_int_n[int_vect] <= int_sig_in_int[int_vect];
end
end
end
endgenerate
 
integer j;
always @*
begin
if(VECTOR_INT_TABLE_SIZE != 0)
begin
int_vect <= 0;
for (j=VECTOR_INT_TABLE_SIZE-1; j>=0; j=j-1)
if ((STORE_INTERUPTS == "TRUE") ? int_sig_in_int_active[j] : int_sig_in[j])
int_vect <= j+1;
end
end
 
assign int_request = (int_vect != 0 && VECTOR_INT_TABLE_SIZE != 'h0);
 
endmodule
/*
* !Interrupt and priority encoder.
*/
 
/*
* XMega core.
*/
 
`define STEP0 0
`define STEP1 1
`define STEP2 2
 
module mega_core # (
parameter PLATFORM = "XILINX",
parameter CORE_CONFIG = "XMEGA",// Supported: "REDUCED", "MINIMAL", "CLASSIC_8K", "CLASSIC_128K", "ENHANCED_8K", "ENHANCED_128K", "ENHANCED_4M", "XMEGA"
parameter BUS_ADDR_PGM_WIDTH = 14,
parameter BUS_ADDR_DATA_WIDTH = 13,
parameter USE_BRAM_ROM = "FALSE",
parameter WATCHDOG_CNT_WIDTH = 0,
parameter VECTOR_INT_TABLE_SIZE = 0,
parameter STORE_INTERUPTS = "FALSE",
parameter MAP_REGS_IN_TO_SRAM_SECTION = "FALSE"
 
)(
input rst,
output sys_rst,
input clk,
input clk_wdt,
output reg [BUS_ADDR_PGM_WIDTH-1:0]pgm_addr,
input [15:0]pgm_data,
output reg [BUS_ADDR_DATA_WIDTH-1:0]data_addr,
input [7:0]data_in,
output [7:0]data_out,
output data_we,
output data_re,
output [5:0]io_addr,
input [7:0]io_in,
output [7:0]io_out,
output io_we,
output io_re,
input [(VECTOR_INT_TABLE_SIZE == 0 ? 0 : VECTOR_INT_TABLE_SIZE - 1):0]int_sig,
output reg [(VECTOR_INT_TABLE_SIZE == 0 ? 0 : VECTOR_INT_TABLE_SIZE - 1):0]int_rst,
output reg wdt_rst_out
);
 
reg [7:0]ALU_FLAGS; //Carry Flag
wire ALU_FLAG_C_OUT; //Carry Flag
wire ALU_FLAG_Z_OUT; //Zero Flag
wire ALU_FLAG_N_OUT; //Negative Flag
wire ALU_FLAG_V_OUT; //Two's complement overflow indicator
wire ALU_FLAG_S_OUT; //N?V for signed tests
wire ALU_FLAG_H_OUT; //Half Carry Flag
wire ALU_FLAG_T_OUT; //Transfer bit used by BLD and BST instructions
wire ALU_FLAG_I_OUT; //Global Interrupt Enable/Disable Flag
reg [BUS_ADDR_PGM_WIDTH-1:0]PC;
reg [BUS_ADDR_PGM_WIDTH-1:0]pgm_indirect_addr;
wire [BUS_ADDR_PGM_WIDTH-1:0]PC_PLUS_ONE = PC + 1;
wire [BUS_ADDR_PGM_WIDTH-1:0]PC_PLUS_TWO = PC + 2;
wire [BUS_ADDR_PGM_WIDTH-1:0]PC_PLUS_THREE = PC + 3;
reg [BUS_ADDR_DATA_WIDTH-1:0]SP;
wire [BUS_ADDR_DATA_WIDTH-1:0]SP_PLUS_ONE = SP + 1;
wire [BUS_ADDR_DATA_WIDTH-1:0]SP_MINUS_ONE = SP - 1;
reg [1:0]step_cnt;
reg [15:0]tmp_pgm_data;
 
`ifdef USE_CCP_REG
reg [7:0]CCP; /* Configuration Change Protection */
`endif
`ifdef USE_EXTENDED_RAMP_REGS
reg [7:0]RAMPD; /* Ramp D */
reg [7:0]RAMPX; /* Ramp X */
reg [7:0]RAMPY; /* Ramp Y */
reg [7:0]RAMPZ; /* Ramp Z */
reg [7:0]EIND; /* Extended Indirect Jump */
`endif
 
wire core_rst;
assign sys_rst = (WATCHDOG_CNT_WIDTH != 'd0) ? core_rst : rst;
 
wire alu_rdy;
 
wire [7:0]data_in_int;
reg [7:0]data_out_int;
wire [7:0]io_in_int;
reg [7:0]io_out_int;
 
reg data_we_int;
reg data_re_int;
 
reg [BUS_ADDR_DATA_WIDTH - 1:0]data_addr_int;
reg [BUS_ADDR_DATA_WIDTH - 1:0]data_addr_int_tmp;
 
reg [5:0]io_addr_int;
 
reg io_we_int;
reg io_re_int;
 
assign io_we = io_we_int;
assign io_re = io_re_int;
assign io_addr = io_addr_int;
assign io_in_int = io_in;
assign io_out = io_out_int;
assign data_we = data_we_int;
assign data_re = data_re_int;
always @ (*) data_addr <= data_addr_int;
assign data_out = data_out_int;
assign data_in_int = data_in;
 
/*
* ! pgm_addr bus switcher
*/
 
// REG aditional
reg write_to_reg;
// REG wires
reg [4:0]rw_addr;
reg [15:0]rw_data;
reg rw_16bit;
//wire write;
reg [4:0]rd_addr_d;
wire [15:0]rd_data_d;
reg rd_16bit_d;
wire read_d;
reg [4:0]rd_addr_r;
wire [15:0]rd_data_r;
 
wire [BUS_ADDR_DATA_WIDTH-1:0]rd_data_r_PLUS_ONE = rd_data_r + 1;
wire [BUS_ADDR_DATA_WIDTH-1:0]rd_data_r_MINUS_ONE = rd_data_r - 1;
reg rd_16bit_r;
wire read_r;
 
// ALU wires
reg [15:0]alu_in_1;
reg [15:0]alu_in_2;
wire [15:0]alu_out;
//wire alu_c_out;
reg [BUS_ADDR_DATA_WIDTH-1:0]indirect_addr_offset;
wire [BUS_ADDR_DATA_WIDTH-1:0]indirect_addr_offset_res = rd_data_r + indirect_addr_offset;
 
reg [4:0]reg_clr_cnt;
assign alu_rdy = reg_clr_cnt == 16;
//`ifdef USE_RAM_READ_DELAY
reg rom_read_delay;
reg [1:0]ram_read_delay;
//`endif
 
reg [15:0]pgm_data_int;
 
 
always @ (*)
begin
pgm_data_int <= pgm_data;
end
 
localparam int_bus_size = (VECTOR_INT_TABLE_SIZE > 127) ? 8 :
(VECTOR_INT_TABLE_SIZE > 63) ? 7 :
(VECTOR_INT_TABLE_SIZE > 31) ? 6 :
(VECTOR_INT_TABLE_SIZE > 15) ? 5 :
(VECTOR_INT_TABLE_SIZE > 7) ? 4 :
(VECTOR_INT_TABLE_SIZE > 3) ? 3 :
(VECTOR_INT_TABLE_SIZE > 1) ? 2 : 1;
reg interrupt_registered;
reg current_int_executed;
wire [int_bus_size - 1 : 0]current_int_vect;
reg [int_bus_size - 1 : 0]current_int_vect_int;
wire int_request;
 
/*always @ (posedge interrupt_registered)
begin
current_int_vect_int <= current_int_vect;
end*/
 
int_encoder # (
.VECTOR_INT_TABLE_SIZE(VECTOR_INT_TABLE_SIZE),
.STORE_INTERUPTS(STORE_INTERUPTS)
)int_encoder_inst(
.rst(rst),
.int_sig_in(int_sig),
.int_vect(current_int_vect),
.int_request(int_request),
.executed(current_int_executed)
);
 
/*
* pgm_addr bus switcher
*/
always @ (*)
begin
if(CORE_CONFIG != "REDUCED")
begin
`ifdef USE_LPM
case(step_cnt)
`STEP2:
begin
casex(tmp_pgm_data)
`INSTRUCTION_LPM_R,
`INSTRUCTION_LPM_R_P: pgm_addr <= pgm_indirect_addr[{1'b0, BUS_ADDR_PGM_WIDTH-1}:1];
default: pgm_addr <= PC;
endcase
end
default: pgm_addr <= PC;
endcase
`endif
end
else
begin
pgm_addr <= PC;
end
end
 
 
wire SEL_S1_INSTRUCTION_MOVW;
wire SEL_S1_INSTRUCTION_MULS;
wire SEL_S1_INSTRUCTION_MULSU;
wire SEL_S1_INSTRUCTION_FMUL;
wire SEL_S1_INSTRUCTION_FMULS;
wire SEL_S1_INSTRUCTION_FMULSU;
wire SEL_S1_INSTRUCTION_CPC;
wire SEL_S1_INSTRUCTION_CP;
wire SEL_S1_INSTRUCTION_SBC;
wire SEL_S1_INSTRUCTION_SUB;
wire SEL_S1_INSTRUCTION_ADD;
wire SEL_S1_INSTRUCTION_ADC;
wire SEL_S1_INSTRUCTION_CPSE;
wire SEL_S1_INSTRUCTION_AND;
wire SEL_S1_INSTRUCTION_EOR;
wire SEL_S1_INSTRUCTION_OR;
wire SEL_S1_INSTRUCTION_MOV;
wire SEL_S1_INSTRUCTION_CPI;
wire SEL_S1_INSTRUCTION_SUBI;
wire SEL_S1_INSTRUCTION_SBCI;
wire SEL_S1_INSTRUCTION_ORI_SBR;
wire SEL_S1_INSTRUCTION_ANDI_CBR;
wire SEL_S1_INSTRUCTION_LDD_STD;
wire SEL_S1_INSTRUCTION_LDS_STS;
wire SEL_S1_INSTRUCTION_LD_ST_YZP;
wire SEL_S1_INSTRUCTION_LD_ST_YZN;
wire SEL_S1_INSTRUCTION_LPM_R;
wire SEL_S1_INSTRUCTION_LPM_R_P;
wire SEL_S1_INSTRUCTION_XCH;
wire SEL_S1_INSTRUCTION_LAS;
wire SEL_S1_INSTRUCTION_LAC;
wire SEL_S1_INSTRUCTION_LAT;
wire SEL_S1_INSTRUCTION_LD_ST_X;
wire SEL_S1_INSTRUCTION_LD_ST_XP;
wire SEL_S1_INSTRUCTION_LD_ST_XN;
wire SEL_S1_INSTRUCTION_POP_PUSH;
wire SEL_S1_INSTRUCTION_COM;
wire SEL_S1_INSTRUCTION_NEG;
wire SEL_S1_INSTRUCTION_SWAP;
wire SEL_S1_INSTRUCTION_INC;
wire SEL_S1_INSTRUCTION_ASR;
wire SEL_S1_INSTRUCTION_LSR;
wire SEL_S1_INSTRUCTION_ROR;
wire SEL_S1_INSTRUCTION_SEx_CLx;
wire SEL_S1_INSTRUCTION_RET;
wire SEL_S1_INSTRUCTION_RETI;
wire SEL_S1_INSTRUCTION_SLEEP;
wire SEL_S1_INSTRUCTION_BREAK;
wire SEL_S1_INSTRUCTION_WDR;
wire SEL_S1_INSTRUCTION_LPM_ELPM;
wire SEL_S1_INSTRUCTION_SPM;
wire SEL_S1_INSTRUCTION_SPM_Z_P;
wire SEL_S1_INSTRUCTION_IJMP;
wire SEL_S1_INSTRUCTION_ICALL;
wire SEL_S1_INSTRUCTION_DEC;
wire SEL_S1_INSTRUCTION_DES;
wire SEL_S1_INSTRUCTION_JMP;
wire SEL_S1_INSTRUCTION_CALL;
wire SEL_S1_INSTRUCTION_ADIW;
wire SEL_S1_INSTRUCTION_SBIW;
wire SEL_S1_INSTRUCTION_CBI_SBI;
wire SEL_S1_INSTRUCTION_SBIC_SBIS;
wire SEL_S1_INSTRUCTION_MUL;
wire SEL_S1_INSTRUCTION_IN_OUT;
wire SEL_S1_INSTRUCTION_RJMP;
wire SEL_S1_INSTRUCTION_RCALL;
wire SEL_S1_INSTRUCTION_LDI;
wire SEL_S1_INSTRUCTION_COND_BRANCH;
wire SEL_S1_INSTRUCTION_BLD_BST;
wire SEL_S1_INSTRUCTION_SBRC_SBRS;
 
inst_dec inst_dec_s1_inst(
.inst(
`ifdef USE_RAM_READ_DELAY
ram_read_delay != `USE_RAM_READ_DELAY || step_cnt != `STEP1 ? tmp_pgm_data :
`endif
pgm_data_int),
.INTERRUPT_IN_EXECUTION(interrupt_registered),
.SEL_INSTRUCTION_MOVW(SEL_S1_INSTRUCTION_MOVW),
.SEL_INSTRUCTION_MULS(SEL_S1_INSTRUCTION_MULS),
.SEL_INSTRUCTION_MULSU(SEL_S1_INSTRUCTION_MULSU),
.SEL_INSTRUCTION_FMUL(SEL_S1_INSTRUCTION_FMUL),
.SEL_INSTRUCTION_FMULS(SEL_S1_INSTRUCTION_FMULS),
.SEL_INSTRUCTION_FMULSU(SEL_S1_INSTRUCTION_FMULSU),
.SEL_INSTRUCTION_CPC(SEL_S1_INSTRUCTION_CPC),
.SEL_INSTRUCTION_CP(SEL_S1_INSTRUCTION_CP),
.SEL_INSTRUCTION_SBC(SEL_S1_INSTRUCTION_SBC),
.SEL_INSTRUCTION_SUB(SEL_S1_INSTRUCTION_SUB),
.SEL_INSTRUCTION_ADD(SEL_S1_INSTRUCTION_ADD),
.SEL_INSTRUCTION_ADC(SEL_S1_INSTRUCTION_ADC),
.SEL_INSTRUCTION_CPSE(SEL_S1_INSTRUCTION_CPSE),
.SEL_INSTRUCTION_AND(SEL_S1_INSTRUCTION_AND),
.SEL_INSTRUCTION_EOR(SEL_S1_INSTRUCTION_EOR),
.SEL_INSTRUCTION_OR(SEL_S1_INSTRUCTION_OR),
.SEL_INSTRUCTION_MOV(SEL_S1_INSTRUCTION_MOV),
.SEL_INSTRUCTION_CPI(SEL_S1_INSTRUCTION_CPI),
.SEL_INSTRUCTION_SUBI(SEL_S1_INSTRUCTION_SUBI),
.SEL_INSTRUCTION_SBCI(SEL_S1_INSTRUCTION_SBCI),
.SEL_INSTRUCTION_ORI_SBR(SEL_S1_INSTRUCTION_ORI_SBR),
.SEL_INSTRUCTION_ANDI_CBR(SEL_S1_INSTRUCTION_ANDI_CBR),
.SEL_INSTRUCTION_LDD_STD(SEL_S1_INSTRUCTION_LDD_STD),
.SEL_INSTRUCTION_LDS_STS(SEL_S1_INSTRUCTION_LDS_STS),
.SEL_INSTRUCTION_LD_ST_YZP(SEL_S1_INSTRUCTION_LD_ST_YZP),
.SEL_INSTRUCTION_LD_ST_YZN(SEL_S1_INSTRUCTION_LD_ST_YZN),
.SEL_INSTRUCTION_LPM_R(SEL_S1_INSTRUCTION_LPM_R),
.SEL_INSTRUCTION_LPM_R_P(SEL_S1_INSTRUCTION_LPM_R_P),
.SEL_INSTRUCTION_XCH(SEL_S1_INSTRUCTION_XCH),
.SEL_INSTRUCTION_LAS(SEL_S1_INSTRUCTION_LAS),
.SEL_INSTRUCTION_LAC(SEL_S1_INSTRUCTION_LAC),
.SEL_INSTRUCTION_LAT(SEL_S1_INSTRUCTION_LAT),
.SEL_INSTRUCTION_LD_ST_X(SEL_S1_INSTRUCTION_LD_ST_X),
.SEL_INSTRUCTION_LD_ST_XP(SEL_S1_INSTRUCTION_LD_ST_XP),
.SEL_INSTRUCTION_LD_ST_XN(SEL_S1_INSTRUCTION_LD_ST_XN),
.SEL_INSTRUCTION_POP_PUSH(SEL_S1_INSTRUCTION_POP_PUSH),
.SEL_INSTRUCTION_COM(SEL_S1_INSTRUCTION_COM),
.SEL_INSTRUCTION_NEG(SEL_S1_INSTRUCTION_NEG),
.SEL_INSTRUCTION_SWAP(SEL_S1_INSTRUCTION_SWAP),
.SEL_INSTRUCTION_INC(SEL_S1_INSTRUCTION_INC),
.SEL_INSTRUCTION_ASR(SEL_S1_INSTRUCTION_ASR),
.SEL_INSTRUCTION_LSR(SEL_S1_INSTRUCTION_LSR),
.SEL_INSTRUCTION_ROR(SEL_S1_INSTRUCTION_ROR),
.SEL_INSTRUCTION_SEx_CLx(SEL_S1_INSTRUCTION_SEx_CLx),
.SEL_INSTRUCTION_RET(SEL_S1_INSTRUCTION_RET),
.SEL_INSTRUCTION_RETI(SEL_S1_INSTRUCTION_RETI),
.SEL_INSTRUCTION_SLEEP(SEL_S1_INSTRUCTION_SLEEP),
.SEL_INSTRUCTION_BREAK(SEL_S1_INSTRUCTION_BREAK),
.SEL_INSTRUCTION_WDR(SEL_S1_INSTRUCTION_WDR),
.SEL_INSTRUCTION_LPM_ELPM(SEL_S1_INSTRUCTION_LPM_ELPM),
.SEL_INSTRUCTION_SPM(SEL_S1_INSTRUCTION_SPM),
.SEL_INSTRUCTION_SPM_Z_P(SEL_S1_INSTRUCTION_SPM_Z_P),
.SEL_INSTRUCTION_IJMP(SEL_S1_INSTRUCTION_IJMP),
.SEL_INSTRUCTION_ICALL(SEL_S1_INSTRUCTION_ICALL),
.SEL_INSTRUCTION_DEC(SEL_S1_INSTRUCTION_DEC),
.SEL_INSTRUCTION_DES(SEL_S1_INSTRUCTION_DES),
.SEL_INSTRUCTION_JMP(SEL_S1_INSTRUCTION_JMP),
.SEL_INSTRUCTION_CALL(SEL_S1_INSTRUCTION_CALL),
.SEL_INSTRUCTION_ADIW(SEL_S1_INSTRUCTION_ADIW),
.SEL_INSTRUCTION_SBIW(SEL_S1_INSTRUCTION_SBIW),
.SEL_INSTRUCTION_CBI_SBI(SEL_S1_INSTRUCTION_CBI_SBI),
.SEL_INSTRUCTION_SBIC_SBIS(SEL_S1_INSTRUCTION_SBIC_SBIS),
.SEL_INSTRUCTION_MUL(SEL_S1_INSTRUCTION_MUL),
.SEL_INSTRUCTION_IN_OUT(SEL_S1_INSTRUCTION_IN_OUT),
.SEL_INSTRUCTION_RJMP(SEL_S1_INSTRUCTION_RJMP),
.SEL_INSTRUCTION_RCALL(SEL_S1_INSTRUCTION_RCALL),
.SEL_INSTRUCTION_LDI(SEL_S1_INSTRUCTION_LDI),
.SEL_INSTRUCTION_COND_BRANCH(SEL_S1_INSTRUCTION_COND_BRANCH),
.SEL_INSTRUCTION_BLD_BST(SEL_S1_INSTRUCTION_BLD_BST),
.SEL_INSTRUCTION_SBRC_SBRS(SEL_S1_INSTRUCTION_SBRC_SBRS)
);
 
reg SEL_S2_INSTRUCTION_CPSE;
reg SEL_S2_INSTRUCTION_LDS_STS;
reg SEL_S2_INSTRUCTION_LD_ST_YZP;
reg SEL_S2_INSTRUCTION_LD_ST_YZN;
reg SEL_S2_INSTRUCTION_LPM_ELPM;
reg SEL_S2_INSTRUCTION_LPM_R;
reg SEL_S2_INSTRUCTION_LPM_R_P;
reg SEL_S2_INSTRUCTION_LD_ST_X;
reg SEL_S2_INSTRUCTION_LD_ST_XP;
reg SEL_S2_INSTRUCTION_LD_ST_XN;
reg SEL_S2_INSTRUCTION_RET;
reg SEL_S2_INSTRUCTION_RETI;
reg SEL_S2_INSTRUCTION_ICALL;
reg SEL_S2_INSTRUCTION_JMP;
reg SEL_S2_INSTRUCTION_CALL;
reg SEL_S2_INSTRUCTION_SBIC_SBIS;
reg SEL_S2_INSTRUCTION_MUL;
reg SEL_S2_INSTRUCTION_MULS;
reg SEL_S2_INSTRUCTION_MULSU;
reg SEL_S2_INSTRUCTION_FMUL;
reg SEL_S2_INSTRUCTION_FMULS;
reg SEL_S2_INSTRUCTION_FMULSU;
reg SEL_S2_INSTRUCTION_RCALL;
reg SEL_S2_INSTRUCTION_SBRC_SBRS;
 
reg select_io_in_stam;
integer io_ports_displacement;
 
/*
* IO maping switch
*/
always @*
begin
if(CORE_CONFIG == "XMEGA")
begin
if(ram_read_delay == 0)
select_io_in_stam = data_addr_int_tmp < 'h40;
else
select_io_in_stam = pgm_data_int < 'h40;
io_ports_displacement = 'h0000;
end
else
begin
if(ram_read_delay == 0)
select_io_in_stam = data_addr_int_tmp < 'h60;
else
select_io_in_stam = pgm_data_int < 'h60;
io_ports_displacement = 'h0020;
end
end
/*
* !IO maping switch
*/
 
`ifdef USE_RAM_READ_DELAY
wire [15:0]tmp_pgm_data_switched = ram_read_delay == `USE_RAM_READ_DELAY ? pgm_data_int : tmp_pgm_data;
`else
wire [15:0]tmp_pgm_data_switched = pgm_data_int;
`endif
 
/*
* Busses switch.
*/
reg skip_execution;
always @ (*)
begin
rw_addr <= 5'h0;
rw_16bit <= 1'b0;
rd_addr_d <= 5'h0;
rd_16bit_d <= 1'b0;
rd_addr_r <= 5'h0;
rd_16bit_r <= 1'b0;
// Connect busses
rw_data <= 16'h0;
alu_in_1 <= 16'h0;
alu_in_2 <= 16'h0;
write_to_reg <= 1'b0;
io_we_int <= 1'b0;
io_re_int <= 1'b0;
io_addr_int <= 16'h0;
io_out_int <= 'h0;
data_addr_int <= 'hz;
data_out_int <= 'hz;
data_re_int <= 1'b0;
indirect_addr_offset <= 16'h0;
data_we_int <= 1'b0;
 
if(~alu_rdy)
begin
rw_addr <= reg_clr_cnt;
rw_16bit <= 1'b1;
rw_data <= 16'h0;
write_to_reg <= 1'b1;
end
else
begin
/*
* Data address switch.
*/
if(!skip_execution | USE_BRAM_ROM != "TRUE")
begin
case(step_cnt)
`STEP1:
begin
if(CORE_CONFIG != "REDUCED")
begin
if(SEL_S1_INSTRUCTION_LDD_STD)
data_addr_int <= indirect_addr_offset_res;
if(SEL_S1_INSTRUCTION_POP_PUSH)
begin
if(pgm_data_int[9])
data_addr_int <= SP;
else
data_addr_int <= SP_PLUS_ONE;
end
end
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")
begin
if(SEL_S1_INSTRUCTION_LD_ST_X |
SEL_S1_INSTRUCTION_LD_ST_XP |
SEL_S1_INSTRUCTION_LD_ST_YZP)
data_addr_int <= rd_data_r;
if(SEL_S1_INSTRUCTION_LD_ST_XN |
SEL_S1_INSTRUCTION_LD_ST_YZN)
data_addr_int <= rd_data_r_MINUS_ONE;
end
if((SEL_S1_INSTRUCTION_ICALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")) |
(SEL_S1_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) |
SEL_S1_INSTRUCTION_RCALL |
(interrupt_registered && VECTOR_INT_TABLE_SIZE != 0))
data_addr_int <= SP;
if(SEL_S1_INSTRUCTION_RET |
SEL_S1_INSTRUCTION_RETI)
data_addr_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, SP_PLUS_ONE};
if (SEL_S1_INSTRUCTION_XCH |
SEL_S1_INSTRUCTION_LAS |
SEL_S1_INSTRUCTION_LAC |
SEL_S1_INSTRUCTION_LAT)
data_addr_int <= rd_data_r;
end
`STEP2:
begin
if(interrupt_registered && VECTOR_INT_TABLE_SIZE != 0)
data_addr_int <= SP;
else
begin
casex(tmp_pgm_data)
`INSTRUCTION_ICALL:
begin
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")
begin
data_addr_int <= SP;
end
end
`INSTRUCTION_CALL:
begin
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")
begin
data_addr_int <= SP;
end
end
`INSTRUCTION_RCALL: data_addr_int <= SP;
`INSTRUCTION_RET_RETI: data_addr_int <= SP_PLUS_ONE;
`INSTRUCTION_LDS_STS:
begin
`ifdef USE_RAM_READ_DELAY
if(ram_read_delay == `USE_RAM_READ_DELAY)
`endif
data_addr_int <= pgm_data_int[BUS_ADDR_DATA_WIDTH-1:0];
`ifdef USE_RAM_READ_DELAY
else
data_addr_int <= data_addr_int_tmp;
`endif
end
endcase
end
end
endcase
/*
* Instruction decode.
*/
rd_addr_d <= 'h0;
rd_addr_r <= 'h0;
case(step_cnt)
`STEP1:
begin
if(SEL_S1_INSTRUCTION_MOVW)
begin
rw_addr <= {pgm_data_int[7:4], 1'b0};
rw_16bit <= 1'b1;
rd_addr_d <= {pgm_data_int[7:4], 1'b0};
rd_16bit_d <= 1'b1;
rd_addr_r <= {pgm_data_int[3:0], 1'b0};
rd_16bit_r <= 1'b1;
// Connect busses
alu_in_1 <= rd_data_d;
alu_in_2 <= rd_data_r;
rw_data <= alu_out;
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
/*if(SEL_S1_INSTRUCTION_CPSE)
begin
end*/
if(SEL_S1_INSTRUCTION_CPI)
begin
rd_addr_d <= {1'b1, pgm_data_int[7:4]};
// Connect busses
alu_in_1 <= rd_data_d;
alu_in_2 <= {pgm_data_int[11:8], pgm_data_int[3:0]};
end
if(SEL_S1_INSTRUCTION_CPC |
SEL_S1_INSTRUCTION_CP)
begin
rd_addr_d <= pgm_data_int[8:4];
rd_addr_r <= {pgm_data_int[9], pgm_data_int[3:0]};
// Connect busses
alu_in_1 <= rd_data_d;
alu_in_2 <= rd_data_r;
end
if(SEL_S1_INSTRUCTION_SBC |
SEL_S1_INSTRUCTION_SUB |
SEL_S1_INSTRUCTION_ADD |
SEL_S1_INSTRUCTION_ADC |
SEL_S1_INSTRUCTION_AND |
SEL_S1_INSTRUCTION_EOR |
SEL_S1_INSTRUCTION_OR |
SEL_S1_INSTRUCTION_MOV)
begin
rw_addr <= pgm_data_int[8:4];
rd_addr_d <= pgm_data_int[8:4];
rd_addr_r <= {pgm_data_int[9], pgm_data_int[3:0]};
// Connect busses
alu_in_1 <= rd_data_d;
alu_in_2 <= rd_data_r;
rw_data <= alu_out;
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
if(SEL_S1_INSTRUCTION_SUBI |
SEL_S1_INSTRUCTION_SBCI |
SEL_S1_INSTRUCTION_ORI_SBR |
SEL_S1_INSTRUCTION_ANDI_CBR)
begin
rw_addr <= {1'b1, pgm_data_int[7:4]};
rd_addr_d <= {1'b1, pgm_data_int[7:4]};
// Connect busses
alu_in_1 <= rd_data_d;
alu_in_2 <= {8'h00, pgm_data_int[11:8], pgm_data_int[3:0]};
rw_data <= alu_out;
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
if(SEL_S1_INSTRUCTION_COM |
SEL_S1_INSTRUCTION_NEG |
SEL_S1_INSTRUCTION_SWAP |
SEL_S1_INSTRUCTION_INC |
SEL_S1_INSTRUCTION_DEC |
SEL_S1_INSTRUCTION_ASR |
SEL_S1_INSTRUCTION_LSR |
SEL_S1_INSTRUCTION_ROR)
begin
rw_addr <= pgm_data_int[8:4];
rd_addr_d <= pgm_data_int[8:4];
// Connect busses
alu_in_1 <= rd_data_d;
if(SEL_S1_INSTRUCTION_INC) alu_in_2 <= 16'h0001;
if(SEL_S1_INSTRUCTION_DEC) alu_in_2 <= 16'hFFFF;
rw_data <= alu_out;
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
if(CORE_CONFIG != "REDUCED")
begin
if(SEL_S1_INSTRUCTION_LDD_STD)
begin
rd_addr_r <= {{3{1'b1}}, ~tmp_pgm_data_switched[3], 1'b0};
rd_16bit_r <= 1'b1;
indirect_addr_offset <= {{10{1'b0}}, tmp_pgm_data_switched[13], tmp_pgm_data_switched[11:10], tmp_pgm_data_switched[2:0]};
if(tmp_pgm_data_switched[9])
begin
rd_addr_d <= tmp_pgm_data_switched[8:4];
data_out_int <= rd_data_d;
data_we_int <= 1'b1;
end
else
begin
rw_addr <= tmp_pgm_data_switched[8:4];
// Connect busses
rw_data <= data_in_int;
// Signalize write_to_reg;
if(ram_read_delay == 0)
write_to_reg <= 1'b1;
data_re_int <= 1'b1;
end
end
`ifdef USE_LPM
if(SEL_S1_INSTRUCTION_LPM_R |
SEL_S1_INSTRUCTION_LPM_R_P |
SEL_S1_INSTRUCTION_LPM_ELPM)
begin
rd_addr_d <= 'h1E;//pgm_data_int[8:4];
rd_16bit_d <= 1'b1;
if(pgm_data_int[0])
begin
// Connect busses
alu_in_1 <= rd_data_d;
alu_in_2 <= 1;
rw_addr <= 'h1E;//pgm_data_int[8:4];
rw_data <= alu_out;
rw_16bit <= 1'b1;
write_to_reg <= 1'b1;
end
end
`endif
end/*!CORE_CONFIG != "REDUCED"*/
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")
begin
/*if(SEL_S1_INSTRUCTION_LD_ST_X)
begin
rd_addr_r <= 5'd26;
rd_16bit_r <= 1'b1;
if(pgm_data_int[9])
begin
rd_addr_d <= tmp_pgm_data_switched[8:4];
data_out_int <= rd_data_d;
data_we_int <= 1'b1;
end
else
begin
rw_addr <= tmp_pgm_data_switched[8:4];
// Connect busses
rw_data <= data_in_int;
// Signalize write_to_reg;
write_to_reg <= 1'b1;
data_re_int <= 1'b1;
end
end*/
if(SEL_S1_INSTRUCTION_LD_ST_YZP |
SEL_S1_INSTRUCTION_LD_ST_YZN)
begin
rd_addr_r <= {{3{1'b1}}, ~tmp_pgm_data_switched[3], 1'b0};
rd_16bit_r <= 1'b1;
rw_addr <= {{3{1'b1}}, ~tmp_pgm_data_switched[3], 1'b0};
//rw_16bit <= 1'b1;
//rw_16bit <= 1'b1;
if(tmp_pgm_data_switched[9])
begin
rd_addr_d <= tmp_pgm_data_switched[8:4];
data_out_int <= rd_data_d;
data_we_int <= 1'b1;
end
else
begin
rw_addr <= tmp_pgm_data_switched[8:4];
// Connect busses
rw_data <= data_in_int;
// Signalize write_to_reg;
if(ram_read_delay == 0)
write_to_reg <= 1'b1;
data_re_int <= 1'b1;
end
end
if(SEL_S1_INSTRUCTION_LD_ST_X |
SEL_S1_INSTRUCTION_LD_ST_XP |
SEL_S1_INSTRUCTION_LD_ST_XN)
begin
rd_addr_r <= 5'd26;
rd_16bit_r <= 1'b1;
rw_addr <= 5'd26;
//rw_16bit <= 1'b1;
//rw_16bit <= 1'b1;
if(tmp_pgm_data_switched[9])
begin
rd_addr_d <= tmp_pgm_data_switched[8:4];
data_out_int <= rd_data_d;
data_we_int <= 1'b1;
end
else
begin
rw_addr <= tmp_pgm_data_switched[8:4];
// Connect busses
rw_data <= data_in_int;
// Signalize write_to_reg;
if(ram_read_delay == 0)
write_to_reg <= 1'b1;
data_re_int <= 1'b1;
end
end
if(SEL_S1_INSTRUCTION_ADIW |
SEL_S1_INSTRUCTION_SBIW)
begin
rw_addr <= {2'b11, pgm_data_int[5:4], 1'b0};
rw_16bit <= 1'b1;
rd_addr_d <= {2'b11, pgm_data_int[5:4], 1'b0};
rd_16bit_d <= 1'b1;
//rd_addr_r <= {5{1'b00}};
rd_16bit_r <= 1'b1;
// Connect busses
rw_data <= alu_out;
alu_in_1 <= rd_data_d;
alu_in_2 <= {10'h000, pgm_data_int[7:6], pgm_data_int[3:0]};
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
if(SEL_S1_INSTRUCTION_POP_PUSH)
begin
if(tmp_pgm_data_switched[9])
begin
rd_addr_d <= tmp_pgm_data_switched[8:4];
data_out_int <= rd_data_d;
data_we_int <= 1'b1; // Put "data_we" to high to store the selected register.
end
else
begin
rd_addr_d <= tmp_pgm_data_switched[8:4];
rw_addr <= tmp_pgm_data_switched[8:4];
// Connect busses
rw_data <= data_in_int;
// Signalize write_to_reg;
if(ram_read_delay == 0)
write_to_reg <= 1'b1;
data_re_int <= 1'b1;
end
end
if(SEL_S1_INSTRUCTION_IJMP)
begin
rd_addr_d <= 5'h1e;
rd_16bit_d <= 1'b1;
end
end/*!CORE_CONFIG != "REDUCED" || CORE_CONFIG != "MINIMAL"*/
if(SEL_S1_INSTRUCTION_IN_OUT)
begin
rw_addr <= pgm_data_int[8:4];
rd_addr_d <= pgm_data_int[8:4];
if(!pgm_data_int[11])
begin
case({pgm_data_int[10:9], pgm_data_int[3:0]})
`ifdef USE_CCP_REG
6'h34:
begin
if(CORE_CONFIG == "XMEGA")
begin
rw_data <= CCP;
end
end
`endif
`ifdef USE_EXTENDED_RAMP_REGS
6'h38:
begin
if(CORE_CONFIG == "XMEGA")
begin
rw_data <= RAMPD;
end
end
6'h39:
begin
if(CORE_CONFIG == "XMEGA")
begin
rw_data <= RAMPX;
end
end
6'h3A:
begin
if(CORE_CONFIG == "XMEGA")
begin
rw_data <= RAMPY;
end
end
6'h3B:
begin
if(CORE_CONFIG == "XMEGA")
begin
rw_data <= RAMPZ;
end
end
6'h3C:
begin
if(CORE_CONFIG == "XMEGA")
begin
rw_data <= EIND;
end
end
`endif
6'h3D: //SPL
begin
if(CORE_CONFIG != "REDUCED")
begin
rw_data <= SP[7:0];
end
end
6'h3E: //SPH
begin
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && BUS_ADDR_DATA_WIDTH > 8)
begin
rw_data <= {{BUS_ADDR_DATA_WIDTH-1-8{1'b0}}, SP[BUS_ADDR_DATA_WIDTH-1:8]};
end
end
6'h3F: rw_data <= ALU_FLAGS;
default:
begin
io_addr_int <= {pgm_data_int[10:9], pgm_data_int[3:0]};
io_re_int <= 1'b1;
rw_data <= io_in_int;
end
endcase
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
else
begin
case({pgm_data_int[10:9], pgm_data_int[3:0]})
`ifdef USE_CCP_REG
6'h34,
`endif
`ifdef USE_EXTENDED_RAMP_REGS
6'h38,
6'h39,
6'h3A,
6'h3B,
6'h3C,
`endif
6'h3D,// SPL
6'h3E,// SPH
6'h3F:;//SREG
default:
begin
io_addr_int <= {pgm_data_int[10:9], pgm_data_int[3:0]};
io_out_int <= rd_data_d;
io_we_int <= 1'b1; // Put "data_we" to high to store the selected register.
end
endcase
end
end
if(CORE_CONFIG == "XMEGA")
begin
if(SEL_S1_INSTRUCTION_XCH |
SEL_S1_INSTRUCTION_LAS |
SEL_S1_INSTRUCTION_LAC |
SEL_S1_INSTRUCTION_LAT)
begin
rd_addr_d <= pgm_data_int[8:4];
rd_addr_r <= 5'h1e;
rw_addr <= pgm_data_int[8:4];
data_re_int <= 1'b1;
if(SEL_S1_INSTRUCTION_XCH) data_out_int <= rd_data_d;
else if(SEL_S1_INSTRUCTION_LAS) data_out_int <= data_in_int | rd_data_d;
else if(SEL_S1_INSTRUCTION_LAC) data_out_int <= data_in_int & ~rd_data_d;
else if(SEL_S1_INSTRUCTION_LAT) data_out_int <= data_in_int ^ rd_data_d;
// Connect busses
rw_data <= data_in_int;
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
end
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
begin
if((SEL_S1_INSTRUCTION_MUL |
SEL_S1_INSTRUCTION_MULS |
SEL_S1_INSTRUCTION_MULSU |
SEL_S1_INSTRUCTION_FMUL |
SEL_S1_INSTRUCTION_FMULS |
SEL_S1_INSTRUCTION_FMULSU))
begin
rw_16bit <= 1'b1;
rd_addr_d <= pgm_data_int[8:4];
rd_addr_r <= {pgm_data_int[9], pgm_data_int[3:0]};
// Connect busses
alu_in_1 <= rd_data_d;
alu_in_2 <= rd_data_r;
rw_data <= alu_out;
// Signalize write_to_reg;
//write_to_reg <= 1'b1;
// Because the multiply unit has more latency, we will add an extra clock.
end
end
if(SEL_S1_INSTRUCTION_LDI)
begin
rw_addr <= {1'b1, pgm_data_int[7:4]};
// Connect busses
rw_data <= {8'h00, pgm_data_int[11:8], pgm_data_int[3:0]};
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
if(SEL_S1_INSTRUCTION_CBI_SBI)
begin
io_addr_int <= {{11{1'b0}}, pgm_data_int[7:3]};
case(pgm_data_int[2:0])
3'h0: io_out_int <= {io_in_int[7:1], pgm_data_int[9]};
3'h1: io_out_int <= {io_in_int[7:2], pgm_data_int[9], io_in_int[0]};
3'h2: io_out_int <= {io_in_int[7:3], pgm_data_int[9], io_in_int[1:0]};
3'h3: io_out_int <= {io_in_int[7:4], pgm_data_int[9], io_in_int[2:0]};
3'h4: io_out_int <= {io_in_int[7:5], pgm_data_int[9], io_in_int[3:0]};
3'h5: io_out_int <= {io_in_int[7:6], pgm_data_int[9], io_in_int[4:0]};
3'h6: io_out_int <= {io_in_int[7], pgm_data_int[9], io_in_int[5:0]};
3'h7: io_out_int <= {pgm_data_int[9], io_in_int[6:0]};
endcase
io_re_int <= 1'b1;
io_we_int <= 1'b1;
end
if(SEL_S1_INSTRUCTION_BLD_BST)
begin
rd_addr_d <= pgm_data_int[8:4];
if(~pgm_data_int[9])
begin
rw_addr <= pgm_data_int[8:4];
// Signalize write_to_reg;
write_to_reg <= 1'b1;
case(pgm_data_int[2:0])
3'h0: rw_data <= {rd_data_d[7:1], ALU_FLAGS[`ALU_FLAG_T]};
3'h1: rw_data <= {rd_data_d[7:2], ALU_FLAGS[`ALU_FLAG_T], rd_data_d[0]};
3'h2: rw_data <= {rd_data_d[7:3], ALU_FLAGS[`ALU_FLAG_T], rd_data_d[1:0]};
3'h3: rw_data <= {rd_data_d[7:4], ALU_FLAGS[`ALU_FLAG_T], rd_data_d[2:0]};
3'h4: rw_data <= {rd_data_d[7:5], ALU_FLAGS[`ALU_FLAG_T], rd_data_d[3:0]};
3'h5: rw_data <= {rd_data_d[7:6], ALU_FLAGS[`ALU_FLAG_T], rd_data_d[4:0]};
3'h6: rw_data <= {rd_data_d[7], ALU_FLAGS[`ALU_FLAG_T], rd_data_d[5:0]};
3'h7: rw_data <= {ALU_FLAGS[`ALU_FLAG_T], rd_data_d[6:0]};
endcase
end
end
if(SEL_S1_INSTRUCTION_RCALL)
begin
case(USE_BRAM_ROM)
"TRUE" : data_out_int <= PC[7:0];// Put low byte of the PC.
default : data_out_int <= PC_PLUS_ONE[7:0];// Put low byte of the PC.
endcase
data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
end
if(SEL_S1_INSTRUCTION_ICALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL"))
begin
case(USE_BRAM_ROM)
"TRUE" : data_out_int <= PC[7:0];// Put low byte of the PC.
default : data_out_int <= PC_PLUS_ONE[7:0];// Put low byte of the PC.
endcase
data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
end
if(interrupt_registered && VECTOR_INT_TABLE_SIZE != 0)
begin
case(USE_BRAM_ROM)
"TRUE" : data_out_int <= PC_PLUS_ONE[7:0];
default : data_out_int <= PC[7:0];
endcase
data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
end
if((SEL_S1_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")))
begin
case(USE_BRAM_ROM)
"TRUE" : data_out_int <= PC_PLUS_ONE[7:0];
default : data_out_int <= PC_PLUS_TWO[7:0];
endcase
data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
end
if(SEL_S1_INSTRUCTION_RET |
SEL_S1_INSTRUCTION_RETI)
begin
data_re_int <= 1'b1;
end
if(SEL_S1_INSTRUCTION_CPSE)
begin
rd_addr_d <= pgm_data_int[8:4];
rd_addr_r <= {pgm_data_int[9], pgm_data_int[3:0]};
end
if(SEL_S1_INSTRUCTION_SBRC_SBRS)
begin
rd_addr_d <= pgm_data_int[8:4];
end
if(SEL_S1_INSTRUCTION_SBIC_SBIS)
begin
io_addr_int <= {{11{1'b0}}, pgm_data_int[7:3]};
io_re_int <= 1'b1;
end
end
`STEP2:
begin
`ifdef USE_LPM
if(CORE_CONFIG != "REDUCED")
begin
if(SEL_S2_INSTRUCTION_LPM_R |
SEL_S2_INSTRUCTION_LPM_R_P |
SEL_S2_INSTRUCTION_LPM_ELPM)
begin
if(~rom_read_delay || USE_BRAM_ROM == "FALSE")
begin
if(SEL_S2_INSTRUCTION_LPM_ELPM)
rw_addr <= 0;
else
rw_addr <= tmp_pgm_data[8:4];
rw_data <= pgm_indirect_addr[0] ? pgm_data_int[15:8] : pgm_data_int[7:0];
rw_16bit <= 1'b0;
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
end
end
`endif
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")
begin
if(SEL_S2_INSTRUCTION_ICALL)
begin
case(USE_BRAM_ROM)
"TRUE" : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC[BUS_ADDR_PGM_WIDTH-1:8]};// Put high byte of the PC.
default : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC_PLUS_ONE[BUS_ADDR_PGM_WIDTH-1:8]};// Put high byte of the PC.
endcase
rd_addr_d <= 5'h1e;
data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
rd_16bit_d <= 1'b1;
end
if(SEL_S2_INSTRUCTION_LDS_STS)
begin
if(tmp_pgm_data[9])
begin
rd_addr_d <= tmp_pgm_data[8:4];
if(select_io_in_stam)
begin
case(pgm_data_int[(CORE_CONFIG == "XMEGA" ? 5 : 6):0])
`ifdef USE_CCP_REG
'h34 + io_ports_displacement,
`endif
`ifdef USE_EXTENDED_RAMP_REGS
'h38 + io_ports_displacement,
'h39 + io_ports_displacement,
'h3A + io_ports_displacement,
'h3B + io_ports_displacement,
'h3C + io_ports_displacement,
`endif
'h00, 'h01, 'h02, 'h03, 'h04, 'h05, 'h06, 'h07, 'h08, 'h09, 'h0A, 'h0B, 'h0C, 'h0D, 'h0E, 'h0F,
'h10, 'h11, 'h12, 'h13, 'h14, 'h15, 'h16, 'h17, 'h18, 'h19, 'h1A, 'h1B, 'h1C, 'h1D, 'h1E, 'h1F:
begin
if(CORE_CONFIG != "XMEGA")
begin
if(MAP_REGS_IN_TO_SRAM_SECTION == "TRUE")
begin
rw_addr <= tmp_pgm_data[4:0];
rw_data <= rd_data_d;
end
end
end
'h3D + io_ports_displacement,// SPL
'h3E + io_ports_displacement,// SPH
'h3F + io_ports_displacement:;//SREG
default:
begin
data_out_int <= rd_data_d;
data_we_int <= 1'b1;
end
endcase
end
else
begin
data_out_int <= rd_data_d;
data_we_int <= 1'b1;
end
end
else
begin
rw_addr <= tmp_pgm_data[8:4];
// Signalize write_to_reg;
//write_to_reg <= 1'b1;
if(select_io_in_stam)
begin
`ifdef USE_RAM_READ_DELAY
if(ram_read_delay == `USE_RAM_READ_DELAY)
`endif
write_to_reg <= 1'b1;
case(pgm_data_int[(CORE_CONFIG == "XMEGA" ? 5 : 6):0])
`ifdef USE_CCP_REG
'h34 + io_ports_displacement: rw_data <= CCP;
`endif
`ifdef USE_EXTENDED_RAMP_REGS
'h38 + io_ports_displacement: rw_data <= RAMPD;
'h39 + io_ports_displacement: rw_data <= RAMPX;
'h3A + io_ports_displacement: rw_data <= RAMPY;
'h3B + io_ports_displacement: rw_data <= RAMPZ;
'h3C + io_ports_displacement: rw_data <= EIND;
`endif
'h00, 'h01, 'h02, 'h03, 'h04, 'h05, 'h06, 'h07, 'h08, 'h09, 'h0A, 'h0B, 'h0C, 'h0D, 'h0E, 'h0F,
'h10, 'h11, 'h12, 'h13, 'h14, 'h15, 'h16, 'h17, 'h18, 'h19, 'h1A, 'h1B, 'h1C, 'h1D, 'h1E, 'h1F:
begin
if(CORE_CONFIG != "XMEGA")
begin
if(MAP_REGS_IN_TO_SRAM_SECTION == "TRUE")
begin
rd_addr_d <= tmp_pgm_data[4:0];
rw_data <= rd_data_d;
end
end
end
'h3D + io_ports_displacement: //SPL
begin
if(CORE_CONFIG != "REDUCED")
begin
rw_data <= SP[7:0];
end
end
'h3E + io_ports_displacement: //SPH
begin
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && BUS_ADDR_DATA_WIDTH > 8)
begin
rw_data <= {{BUS_ADDR_DATA_WIDTH-1-8{1'b0}}, SP[BUS_ADDR_DATA_WIDTH-1:8]};
end
end
'h3F + io_ports_displacement: rw_data <= ALU_FLAGS;//SREG
default:
begin
// Connect busses
rw_data <= data_in_int;
data_re_int <= 1'b1;
end
endcase
end
else
begin
//rd_addr_d <= tmp_pgm_data[4:0];
//rw_data <= rd_data_d;
`ifdef USE_RAM_READ_DELAY
if(ram_read_delay == 0)
`endif
write_to_reg <= 1'b1;
rw_data <= data_in_int;
data_re_int <= 1'b1;
end
end
end
if(SEL_S2_INSTRUCTION_LD_ST_X |
SEL_S2_INSTRUCTION_LD_ST_XP |
SEL_S2_INSTRUCTION_LD_ST_XN)
begin
rd_addr_r <= 5'd26;
rd_16bit_r <= 1'b1;
rw_addr <= 5'd26;
rw_16bit <= 1'b1;
case(tmp_pgm_data[1:0])
2'b00: rw_data <= rd_data_r;
2'b01: rw_data <= rd_data_r_PLUS_ONE;
2'b10: rw_data <= rd_data_r_MINUS_ONE;
endcase
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
if(SEL_S2_INSTRUCTION_LD_ST_YZP |
SEL_S2_INSTRUCTION_LD_ST_YZN)
begin
rd_addr_r <= {{3{1'b1}}, ~tmp_pgm_data[3], 1'b0};
rd_16bit_r <= 1'b1;
rw_addr <= {{3{1'b1}}, ~tmp_pgm_data[3], 1'b0};
rw_16bit <= 1'b1;
case(tmp_pgm_data[1:0])
2'b01: rw_data <= rd_data_r_PLUS_ONE;
2'b10: rw_data <= rd_data_r_MINUS_ONE;
endcase
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
end/*!CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL"*/
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
begin
if((SEL_S2_INSTRUCTION_MUL |
SEL_S2_INSTRUCTION_MULS |
SEL_S2_INSTRUCTION_MULSU |
SEL_S2_INSTRUCTION_FMUL |
SEL_S2_INSTRUCTION_FMULS |
SEL_S2_INSTRUCTION_FMULSU))
begin
rw_16bit <= 1'b1;
rd_addr_d <= pgm_data_int[8:4];
rd_addr_r <= {pgm_data_int[9], pgm_data_int[3:0]};
// Connect busses
alu_in_1 <= rd_data_d;
alu_in_2 <= rd_data_r;
rw_data <= alu_out;
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
end
if(SEL_S2_INSTRUCTION_RET |
SEL_S2_INSTRUCTION_RETI)
begin
data_re_int <= 1'b1;
end
if(interrupt_registered && VECTOR_INT_TABLE_SIZE != 0)
begin
case(USE_BRAM_ROM)
"TRUE" : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC_PLUS_ONE[BUS_ADDR_PGM_WIDTH-1:8]};// Put high byte of the PC.
default : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC[BUS_ADDR_PGM_WIDTH-1:8]};
endcase
data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
end
if(SEL_S2_INSTRUCTION_RCALL)
begin
case(USE_BRAM_ROM)
"TRUE" : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC[BUS_ADDR_PGM_WIDTH-1:8]};// Put high byte of the PC.
default : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC_PLUS_ONE[BUS_ADDR_PGM_WIDTH-1:8]};// Put high byte of the PC.
endcase
data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
end
if((SEL_S2_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")))
begin
case(USE_BRAM_ROM)
"TRUE" : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC[BUS_ADDR_PGM_WIDTH-1:8]};// Put high byte of the PC.
default : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC_PLUS_ONE[BUS_ADDR_PGM_WIDTH-1:8]};// Put high byte of the PC.
endcase
data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
end
if(SEL_S2_INSTRUCTION_CPSE)
begin
rd_addr_d <= tmp_pgm_data[8:4];
rd_addr_r <= {tmp_pgm_data[9], tmp_pgm_data[3:0]};
end
if(SEL_S2_INSTRUCTION_SBRC_SBRS)
begin
rd_addr_d <= tmp_pgm_data[8:4];
end
if(SEL_S2_INSTRUCTION_SBIC_SBIS)
begin
io_addr_int <= {{11{1'b0}}, tmp_pgm_data[7:3]};
io_re_int <= 1'b1;
end
end
endcase
end
end
end
/*
* !Busses switch.
*/
 
wire [15:0]relative_offset = (USE_BRAM_ROM == "TRUE") ? PC + {{5{tmp_pgm_data[11]}}, tmp_pgm_data[10:0]} : PC_PLUS_ONE + {{5{pgm_data_int[11]}}, pgm_data_int[10:0]};
wire [15:0]relative_offset_rjmp = PC + {{5{pgm_data_int[11]}}, pgm_data_int[10:0]};
 
reg [BUS_ADDR_PGM_WIDTH-1-8:0]PGM_HI_TMP;
 
 
/*
* Instruction execution sequencer.
*/
always @ (posedge clk)
begin
if((WATCHDOG_CNT_WIDTH != 'd0) ? core_rst : rst)
begin
reg_clr_cnt <= 0;
end
else
if(~alu_rdy)
begin
ALU_FLAGS[0] <= 1'b0; //Carry Flag
ALU_FLAGS[1] <= 1'b0; //Zero Flag
ALU_FLAGS[2] <= 1'b0; //Negative Flag
ALU_FLAGS[3] <= 1'b0; //Two's complement overflow indicator
ALU_FLAGS[4] <= 1'b0; //N?V for signed tests
ALU_FLAGS[5] <= 1'b0; //Half Carry Flag
ALU_FLAGS[6] <= 1'b0; //Transfer bit used by BLD and BST instructions
ALU_FLAGS[7] <= 1'b0; //Global Interrupt Enable/Disable Flag
SEL_S2_INSTRUCTION_CPSE <= 'h0;
SEL_S2_INSTRUCTION_LDS_STS <= 'h0;
SEL_S2_INSTRUCTION_LD_ST_YZP <= 'h0;
SEL_S2_INSTRUCTION_LD_ST_YZN <= 'h0;
SEL_S2_INSTRUCTION_LPM_ELPM <= 'h0;
SEL_S2_INSTRUCTION_LPM_R <= 'h0;
SEL_S2_INSTRUCTION_LPM_R_P <= 'h0;
SEL_S2_INSTRUCTION_LD_ST_X <= 'h0;
SEL_S2_INSTRUCTION_LD_ST_XP <= 'h0;
SEL_S2_INSTRUCTION_LD_ST_XN <='h0 ;
SEL_S2_INSTRUCTION_RET <= 'h0;
SEL_S2_INSTRUCTION_RETI <= 'h0;
SEL_S2_INSTRUCTION_ICALL <= 'h0;
SEL_S2_INSTRUCTION_JMP <= 'h0;
SEL_S2_INSTRUCTION_CALL <= 'h0;
SEL_S2_INSTRUCTION_SBIC_SBIS <= 'h0;
SEL_S2_INSTRUCTION_MUL <= 'h0;
SEL_S2_INSTRUCTION_MULS <= 'h0;
SEL_S2_INSTRUCTION_MULSU <= 'h0;
SEL_S2_INSTRUCTION_FMUL <= 'h0;
SEL_S2_INSTRUCTION_FMULS <= 'h0;
SEL_S2_INSTRUCTION_FMULSU <= 'h0;
SEL_S2_INSTRUCTION_RCALL <= 'h0;
SEL_S2_INSTRUCTION_SBRC_SBRS <= 'h0;
PC <= 'h0000;
SP <= 'h0000;
current_int_executed <= 1'b0;
if (USE_BRAM_ROM == "TRUE")
skip_execution <= 1'b0;
if(CORE_CONFIG == "XMEGA")
begin
`ifdef USE_CCP_REG
CCP <= 8'h0;
`endif //!USE_CCP_REG
`ifdef USE_EXTENDED_RAMP_REGS
RAMPD <= 8'h0;
RAMPX <= 8'h0;
RAMPY <= 8'h0;
RAMPZ <= 8'h0;
EIND <= 8'h0;
`endif //!USE_EXTENDED_RAMP_REGS
end/*!CORE_CONFIG == "XMEGA"*/
step_cnt <= `STEP1;
`ifdef USE_RAM_READ_DELAY
ram_read_delay <= `USE_RAM_READ_DELAY;
`endif
rom_read_delay <= 1'b1;
reg_clr_cnt <= reg_clr_cnt + 1;
wdt_rst_out <= 1'b0;
interrupt_registered <= 1'b0;
end
else
begin
/*
* Preserve flags until otervice specified.
*/
ALU_FLAGS[0] <= ALU_FLAG_C_OUT; //Carry Flag
ALU_FLAGS[1] <= ALU_FLAG_Z_OUT; //Zero Flag
ALU_FLAGS[2] <= ALU_FLAG_N_OUT; //Negative Flag
ALU_FLAGS[3] <= ALU_FLAG_V_OUT; //Two's complement overflow indicator
ALU_FLAGS[4] <= ALU_FLAG_S_OUT; //N?V for signed tests
ALU_FLAGS[5] <= ALU_FLAG_H_OUT; //Half Carry Flag
ALU_FLAGS[6] <= ALU_FLAG_T_OUT; //Transfer bit used by BLD and BST instructions
ALU_FLAGS[7] <= ALU_FLAG_I_OUT; //Global Interrupt Enable/Disable Flag
step_cnt <= `STEP1;
PC <= PC_PLUS_ONE;// Increment PC by 1 if not specified otherwise.
wdt_rst_out <= 1'b0;
current_int_executed <= 1'b0;
int_rst <= 'h00;
`ifdef USE_RAM_READ_DELAY
if(ram_read_delay == `USE_RAM_READ_DELAY)
begin
`endif
SEL_S2_INSTRUCTION_CPSE <= SEL_S1_INSTRUCTION_CPSE;
SEL_S2_INSTRUCTION_LDS_STS <= SEL_S1_INSTRUCTION_LDS_STS;
SEL_S2_INSTRUCTION_LD_ST_YZP <= SEL_S1_INSTRUCTION_LD_ST_YZP;
SEL_S2_INSTRUCTION_LD_ST_YZN <= SEL_S1_INSTRUCTION_LD_ST_YZN;
SEL_S2_INSTRUCTION_LPM_R <= SEL_S1_INSTRUCTION_LPM_R;
SEL_S2_INSTRUCTION_LPM_R_P <= SEL_S1_INSTRUCTION_LPM_R_P;
SEL_S2_INSTRUCTION_LPM_ELPM <= SEL_S1_INSTRUCTION_LPM_ELPM;
SEL_S2_INSTRUCTION_LD_ST_X <= SEL_S1_INSTRUCTION_LD_ST_X;
SEL_S2_INSTRUCTION_LD_ST_XP <= SEL_S1_INSTRUCTION_LD_ST_XP;
SEL_S2_INSTRUCTION_LD_ST_XN <=SEL_S1_INSTRUCTION_LD_ST_XN ;
SEL_S2_INSTRUCTION_RET <= SEL_S1_INSTRUCTION_RET;
SEL_S2_INSTRUCTION_RETI <= SEL_S1_INSTRUCTION_RETI;
SEL_S2_INSTRUCTION_ICALL <= SEL_S1_INSTRUCTION_ICALL;
SEL_S2_INSTRUCTION_JMP <= SEL_S1_INSTRUCTION_JMP;
SEL_S2_INSTRUCTION_CALL <= SEL_S1_INSTRUCTION_CALL;
SEL_S2_INSTRUCTION_SBIC_SBIS <= SEL_S1_INSTRUCTION_SBIC_SBIS;
SEL_S2_INSTRUCTION_MUL <= SEL_S1_INSTRUCTION_MUL;
SEL_S2_INSTRUCTION_MULS <= SEL_S1_INSTRUCTION_MULS;
SEL_S2_INSTRUCTION_MULSU <= SEL_S1_INSTRUCTION_MULSU;
SEL_S2_INSTRUCTION_FMUL <= SEL_S1_INSTRUCTION_FMUL;
SEL_S2_INSTRUCTION_FMULS <= SEL_S1_INSTRUCTION_FMULS;
SEL_S2_INSTRUCTION_FMULSU <= SEL_S1_INSTRUCTION_FMULSU;
SEL_S2_INSTRUCTION_RCALL <= SEL_S1_INSTRUCTION_RCALL;
SEL_S2_INSTRUCTION_SBRC_SBRS <= SEL_S1_INSTRUCTION_SBRC_SBRS;
`ifdef USE_RAM_READ_DELAY
end
`endif
`ifdef USE_RAM_READ_DELAY
//if(int_request && step_cnt == `STEP1 && ram_read_delay == `USE_RAM_READ_DELAY && ALU_FLAGS[7] && VECTOR_INT_TABLE_SIZE != 0)
if(int_request && ALU_FLAGS[7] && VECTOR_INT_TABLE_SIZE != 0)
begin
case(step_cnt)
/*`STEP1:
begin
if(ram_read_delay == 0 &&
//(SEL_S1_INSTRUCTION_LDD_STD && ~tmp_pgm_data_switched[9]) ||
(SEL_S1_INSTRUCTION_POP_PUSH && ~tmp_pgm_data_switched[9]))
begin
if(current_int_vect)
begin
interrupt_registered <= 1'b1;
current_int_vect_int <= current_int_vect;
PC <= PC_PLUS_ONE;
int_rst <= 1'b1 << (current_int_vect - 1);
end
end
end */
`STEP2:
begin
if(ram_read_delay == 0 &&
(SEL_S2_INSTRUCTION_LPM_R ||
SEL_S2_INSTRUCTION_LPM_R_P ||
SEL_S2_INSTRUCTION_LPM_ELPM ||
(SEL_S2_INSTRUCTION_LDS_STS && ~pgm_data_int[9]) ||
((SEL_S2_INSTRUCTION_MUL |
SEL_S2_INSTRUCTION_MULS |
SEL_S2_INSTRUCTION_MULSU |
SEL_S2_INSTRUCTION_FMUL |
SEL_S2_INSTRUCTION_FMULS |
SEL_S2_INSTRUCTION_FMULSU) && (CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")) ||
((SEL_S2_INSTRUCTION_LD_ST_YZP ||
SEL_S2_INSTRUCTION_LD_ST_YZN ||
SEL_S2_INSTRUCTION_LD_ST_X ||
SEL_S2_INSTRUCTION_LD_ST_XP ||
SEL_S2_INSTRUCTION_LD_ST_XN) && ~pgm_data_int[9]) ||
(SEL_S2_INSTRUCTION_JMP && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) ||
(SEL_S2_INSTRUCTION_ICALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")) ||
(SEL_S2_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) ||
SEL_S2_INSTRUCTION_RCALL ||
SEL_S2_INSTRUCTION_RET ||
SEL_S2_INSTRUCTION_RETI ||
SEL_S2_INSTRUCTION_CPSE ||
SEL_S2_INSTRUCTION_SBRC_SBRS ||
SEL_S2_INSTRUCTION_SBIC_SBIS))
begin
if(current_int_vect)
begin
interrupt_registered <= 1'b1;
current_int_vect_int <= current_int_vect;
PC <= PC_PLUS_ONE;
int_rst <= 1'b1 << (current_int_vect - 1);
end
end
end
endcase
end
`else
if(int_request && step_cnt == `STEP1 && ALU_FLAGS[7] && VECTOR_INT_TABLE_SIZE != 0)
begin
interrupt_registered <= 1'b1;
current_int_vect_int <= current_int_vect;
PC <= PC - 1;
int_rst <= 1'b1 << (current_int_vect - 1);
end
`endif
if(skip_execution == 1'b0 || USE_BRAM_ROM != "TRUE")
begin
case(step_cnt)
`STEP1:
begin
if(SEL_S1_INSTRUCTION_WDR)
begin
case(WATCHDOG_CNT_WIDTH)
0:;
default: wdt_rst_out <= 1'b1;
endcase
end
if(SEL_S1_INSTRUCTION_IN_OUT)
begin
if(pgm_data_int[11])
begin
case({pgm_data_int[10:9], pgm_data_int[3:0]})
`ifdef USE_CCP_REG
6'h34:
begin
if(CORE_CONFIG == "XMEGA")
begin
CCP <= rd_data_d;
end
end
`endif
`ifdef USE_EXTENDED_RAMP_REGS
6'h38:
begin
if(CORE_CONFIG == "XMEGA")
begin
RAMPD <= rd_data_d;
end
end
6'h39:
begin
if(CORE_CONFIG == "XMEGA")
begin
RAMPX <= rd_data_d;
end
end
6'h3A:
begin
if(CORE_CONFIG == "XMEGA")
begin
RAMPY <= rd_data_d;
end
end
6'h3B:
begin
if(CORE_CONFIG == "XMEGA")
begin
RAMPZ <= rd_data_d;
end
end
6'h3C:
begin
if(CORE_CONFIG == "XMEGA")
begin
EIND <= rd_data_d;
end
end
`endif
6'h3D: //SPL
begin
if(CORE_CONFIG != "REDUCED")
begin
SP[7:0] <= rd_data_d;
end
end
6'h3E: //SPH
begin
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && BUS_ADDR_DATA_WIDTH > 8)
begin
SP[BUS_ADDR_DATA_WIDTH-1:8] <= rd_data_d[BUS_ADDR_DATA_WIDTH-1-8:0];
end
end
6'h3F: ALU_FLAGS <= rd_data_d;//SREG
endcase
end
end
if(CORE_CONFIG != "REDUCED")
begin
`ifdef USE_RAM_READ_DELAY
if(SEL_S1_INSTRUCTION_LDD_STD)
begin
if(~tmp_pgm_data_switched[9])
begin
if(ram_read_delay == `USE_RAM_READ_DELAY)
tmp_pgm_data <= pgm_data_int;
if(ram_read_delay)
begin
ram_read_delay <= ram_read_delay - 1;
PC <= PC;
step_cnt <= step_cnt;
end
else
begin
ram_read_delay <= `USE_RAM_READ_DELAY;
end
end
end
`endif
`ifdef USE_LPM
if(SEL_S1_INSTRUCTION_LPM_R |
SEL_S1_INSTRUCTION_LPM_R_P |
SEL_S1_INSTRUCTION_LPM_ELPM)
begin
tmp_pgm_data <= pgm_data_int;
pgm_indirect_addr <= rd_data_d[BUS_ADDR_PGM_WIDTH-1:0];
case(USE_BRAM_ROM)
"TRUE" : PC <= PC;
endcase
step_cnt <= `STEP2;
end
`endif
if(SEL_S1_INSTRUCTION_POP_PUSH)
begin
if(tmp_pgm_data_switched[9])
SP <= SP_MINUS_ONE;
else
begin
`ifdef USE_RAM_READ_DELAY
if(ram_read_delay == `USE_RAM_READ_DELAY)
tmp_pgm_data <= pgm_data_int;
if(ram_read_delay)
begin
ram_read_delay <= ram_read_delay - 1;
PC <= PC;
step_cnt <= step_cnt;
end
else
begin
ram_read_delay <= `USE_RAM_READ_DELAY;
SP <= SP_PLUS_ONE;
end
`else
SP <= SP_PLUS_ONE;
`endif
end
end
end/*!CORE_CONFIG == "REDUCED"*/
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")
begin
if(SEL_S1_INSTRUCTION_IJMP)
begin
PC <= rd_data_d;
case(USE_BRAM_ROM)
"TRUE" : skip_execution <= 1'b1;
endcase
end
if(SEL_S1_INSTRUCTION_LDS_STS)
begin
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
end
if((SEL_S1_INSTRUCTION_MUL |
SEL_S1_INSTRUCTION_MULS |
SEL_S1_INSTRUCTION_MULSU |
SEL_S1_INSTRUCTION_FMUL |
SEL_S1_INSTRUCTION_FMULS |
SEL_S1_INSTRUCTION_FMULSU) && (CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K"))
begin
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
PC <= PC;
end
if(SEL_S1_INSTRUCTION_LD_ST_YZP |
SEL_S1_INSTRUCTION_LD_ST_YZN |
SEL_S1_INSTRUCTION_LD_ST_X |
SEL_S1_INSTRUCTION_LD_ST_XP |
SEL_S1_INSTRUCTION_LD_ST_XN)
begin
`ifdef USE_RAM_READ_DELAY
if((~pgm_data_int[9] && ram_read_delay == `USE_RAM_READ_DELAY) || (~tmp_pgm_data[9] && ram_read_delay != `USE_RAM_READ_DELAY))
begin
if(ram_read_delay)
begin
if(ram_read_delay == `USE_RAM_READ_DELAY)
tmp_pgm_data <= pgm_data_int;
ram_read_delay <= ram_read_delay - 1;
PC <= PC;
step_cnt <= step_cnt;
end
else
begin
ram_read_delay <= `USE_RAM_READ_DELAY;
case(USE_BRAM_ROM)
"TRUE" :;
default: tmp_pgm_data <= pgm_data_int;
endcase
step_cnt <= `STEP2;
PC <= PC;
end
end
else
begin
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
PC <= PC;
end
`else
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
PC <= PC;
`endif
end
end/*!CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL"*/
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")
begin
if(SEL_S1_INSTRUCTION_JMP)
begin
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
end
end
if(SEL_S1_INSTRUCTION_RJMP)
begin
case(USE_BRAM_ROM)
"TRUE" :
begin
skip_execution <= 1'b1;
if(PC)
PC <= relative_offset_rjmp;
else
PC <= relative_offset_rjmp + 1;
end
default : PC <= relative_offset;
endcase
end
if((SEL_S1_INSTRUCTION_ICALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")) |
(SEL_S1_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) |
SEL_S1_INSTRUCTION_RCALL |
interrupt_registered)
begin
step_cnt <= `STEP2;
tmp_pgm_data <= pgm_data_int;
SP <= SP_MINUS_ONE;
if((SEL_S1_INSTRUCTION_ICALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")) |
SEL_S1_INSTRUCTION_RCALL) PC <= PC;
else if(interrupt_registered && VECTOR_INT_TABLE_SIZE != 0)
begin
ALU_FLAGS[7] <= 1'b0;
PC <= PC;
end
end
if(SEL_S1_INSTRUCTION_RET |
SEL_S1_INSTRUCTION_RETI)
begin
`ifdef USE_RAM_READ_DELAY
if(ram_read_delay == `USE_RAM_READ_DELAY)
tmp_pgm_data <= pgm_data_int;
if(ram_read_delay)
begin
ram_read_delay <= ram_read_delay - 1;
PC <= PC;
step_cnt <= step_cnt;
end
else
begin
step_cnt <= `STEP2;
SP <= SP_PLUS_ONE;
PGM_HI_TMP <= data_in_int;
ram_read_delay <= `USE_RAM_READ_DELAY;
end
`else
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
SP <= SP_PLUS_ONE;
PGM_HI_TMP <= data_in_int;
PC <= PC;
`endif
end
if(SEL_S1_INSTRUCTION_COND_BRANCH)
begin
if(~pgm_data_int[10] == ALU_FLAGS[pgm_data_int[2:0]])
begin
case(USE_BRAM_ROM)
"TRUE" :
begin
skip_execution <= 1'b1;
PC <= PC + {{10{pgm_data_int[9]}}, pgm_data_int[8:3]};
end
default : PC <= PC + {{10{pgm_data_int[9]}}, pgm_data_int[8:3]} + 16'h0001;
endcase
end
end
if(SEL_S1_INSTRUCTION_CPSE)
begin
case(USE_BRAM_ROM)
"TRUE" :
begin
if(rd_data_d != rd_data_r)
begin
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
end
end
default:
begin
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
end
endcase
end
if(SEL_S1_INSTRUCTION_SBRC_SBRS)
begin
case(USE_BRAM_ROM)
"TRUE" :
begin
if(rd_data_d[tmp_pgm_data[2:0]] != tmp_pgm_data[9])
begin
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
end
end
default:
begin
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
end
endcase
end
if(SEL_S1_INSTRUCTION_SBIC_SBIS)
begin
case(USE_BRAM_ROM)
"TRUE" :
begin
if(io_in_int[tmp_pgm_data[2:0]] != tmp_pgm_data[9])
begin
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
end
end
default:
begin
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
end
endcase
end
if(SEL_S1_INSTRUCTION_BLD_BST)
begin
if(pgm_data_int[9])
ALU_FLAGS[`ALU_FLAG_T] <= rd_data_d[pgm_data_int[2:0]];
end
end
`STEP2:
begin
if(CORE_CONFIG != "REDUCED")
begin
`ifdef USE_LPM
if(SEL_S2_INSTRUCTION_LPM_R |
SEL_S2_INSTRUCTION_LPM_R_P)
begin
case(USE_BRAM_ROM)
"TRUE":
begin
if(rom_read_delay)
begin
rom_read_delay <= 1'b0;
step_cnt <= `STEP2;
end
else
begin
rom_read_delay <= 1'b1;
skip_execution <= 1'b1;
end
end
endcase
PC <= PC;
end
`endif
end
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")
begin
if(SEL_S2_INSTRUCTION_LDS_STS)
begin
if(tmp_pgm_data[9])
begin
if(select_io_in_stam)
begin
case(pgm_data_int[(CORE_CONFIG == "XMEGA" ? 5 : 6):0])
`ifdef USE_CCP_REG
'h34 + io_ports_displacement:
begin
if(CORE_CONFIG == "XMEGA")
begin
CCP <= rd_data_d;
end
end
`endif
`ifdef USE_EXTENDED_RAMP_REGS
'h38 + io_ports_displacement:
begin
if(CORE_CONFIG == "XMEGA")
begin
RAMPD <= rd_data_d;
end
end
'h39 + io_ports_displacement:
begin
if(CORE_CONFIG == "XMEGA")
begin
RAMPX <= rd_data_d;
end
end
'h3A + io_ports_displacement:
begin
if(CORE_CONFIG == "XMEGA")
begin
RAMPY <= rd_data_d;
end
end
'h3B + io_ports_displacement:
begin
if(CORE_CONFIG == "XMEGA")
begin
RAMPZ <= rd_data_d;
end
end
'h3C + io_ports_displacement:
begin
if(CORE_CONFIG == "XMEGA")
begin
EIND <= rd_data_d;
end
end
`endif
'h3D + io_ports_displacement: //SPL
begin
if(CORE_CONFIG != "REDUCED")
begin
SP[7:0] <= rd_data_d;
end
end
'h3E + io_ports_displacement: //SPH
begin
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && BUS_ADDR_DATA_WIDTH > 8)
begin
SP[BUS_ADDR_DATA_WIDTH-1:8] <= rd_data_d[BUS_ADDR_DATA_WIDTH-1-8:0];
end
end
'h3F + io_ports_displacement: ALU_FLAGS <= rd_data_d;//SREG
endcase
end
end
else
begin
`ifdef USE_RAM_READ_DELAY
if(ram_read_delay)
begin
ram_read_delay <= ram_read_delay - 1;
PC <= PC;
step_cnt <= step_cnt;
data_addr_int_tmp <= pgm_data_int;
end
else
begin
ram_read_delay <= `USE_RAM_READ_DELAY;
end
`endif
end
end
if(SEL_S2_INSTRUCTION_ICALL)
begin
SP <= SP_MINUS_ONE;
PC <= rd_data_d;// Backup the reg Z value to a 16bit temporary register because the reading section of REG's is asynchronous.
case(USE_BRAM_ROM)
"TRUE" : skip_execution <= 1'b1;
endcase
end
end/*!CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL"*/
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")
begin
if(SEL_S2_INSTRUCTION_JMP)
begin
PC <= pgm_data_int;
case(USE_BRAM_ROM)
"TRUE" : skip_execution <= 1'b1;
endcase
end
end
if((SEL_S2_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) |
interrupt_registered)
begin
SP <= SP_MINUS_ONE;
if(interrupt_registered && VECTOR_INT_TABLE_SIZE != 0)
begin
interrupt_registered <= 1'b0;
current_int_executed <= 1'b1;
if(CORE_CONFIG == "XMEGA")
begin
PC <= {current_int_vect_int, 1'b0};
end
else
begin
if(BUS_ADDR_PGM_WIDTH > 12)
PC <= {current_int_vect_int, 1'b0};
else
PC <= current_int_vect_int;
end
end
else
begin
PC <= pgm_data_int;
end
case(USE_BRAM_ROM)
"TRUE" : skip_execution <= 1'b1;
endcase
end
if(SEL_S2_INSTRUCTION_RCALL)
begin
SP <= SP_MINUS_ONE;
PC <= relative_offset;// If is a relative CALL load the offset to "TEMP16".
case(USE_BRAM_ROM)
"TRUE" : skip_execution <= 1'b1;
endcase
end
if(SEL_S2_INSTRUCTION_RET |
SEL_S2_INSTRUCTION_RETI)
begin
`ifdef USE_RAM_READ_DELAY
if(ram_read_delay == `USE_RAM_READ_DELAY)
tmp_pgm_data <= tmp_pgm_data;
if(ram_read_delay)
begin
ram_read_delay <= ram_read_delay - 1;
PC <= PC;
step_cnt <= step_cnt;
end
else
begin
`endif
SP <= SP_PLUS_ONE;
if(tmp_pgm_data[4])
ALU_FLAGS[7] <= 1'b1;
PC <= {PGM_HI_TMP, data_in_int};
case(USE_BRAM_ROM)
"TRUE" : skip_execution <= 1'b1;
endcase
`ifdef USE_RAM_READ_DELAY
ram_read_delay <= `USE_RAM_READ_DELAY;
end
`endif
end
if(SEL_S2_INSTRUCTION_CPSE)
begin
if(rd_data_d == rd_data_r)
begin
if((SEL_S1_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) |
SEL_S1_INSTRUCTION_LDS_STS |
SEL_S1_INSTRUCTION_JMP)
begin
PC <= PC_PLUS_TWO;
case(USE_BRAM_ROM)
"TRUE" : skip_execution <= 1'b1;
endcase
end
end
else
begin
case(USE_BRAM_ROM)
"TRUE" :;
default: PC <= PC;
endcase
end
end
if(SEL_S2_INSTRUCTION_SBRC_SBRS)
begin
if(rd_data_d[tmp_pgm_data[2:0]] == tmp_pgm_data[9])
begin
if((SEL_S1_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) |
SEL_S1_INSTRUCTION_LDS_STS |
SEL_S1_INSTRUCTION_JMP)
begin
PC <= PC_PLUS_TWO;
case(USE_BRAM_ROM)
"TRUE" : skip_execution <= 1'b1;
endcase
end
end
else
begin
case(USE_BRAM_ROM)
"TRUE" :;
default: PC <= PC;
endcase
end
end
if(SEL_S2_INSTRUCTION_SBIC_SBIS)
begin
if(io_in_int[tmp_pgm_data[2:0]] == tmp_pgm_data[9])
begin
if((SEL_S1_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) |
SEL_S1_INSTRUCTION_LDS_STS |
SEL_S1_INSTRUCTION_JMP)
begin
PC <= PC_PLUS_TWO;
case(USE_BRAM_ROM)
"TRUE" : skip_execution <= 1'b1;
endcase
end
end
else
begin
case(USE_BRAM_ROM)
"TRUE" :;
default: PC <= PC;
endcase
end
end
end
endcase
end
else
begin
case(USE_BRAM_ROM)
"TRUE" : skip_execution <= 1'b0;
endcase
end
end
end
 
mega_regs #(
.PLATFORM(PLATFORM)
)regs(
.rst(rst),
.clk(clk),
.rw_addr(rw_addr),
.rw_data(rw_data),
.rw_16bit(rw_16bit),
.write(write_to_reg),
.rd_addr_d(rd_addr_d),
.rd_data_d(rd_data_d),
.rd_16bit_d(rd_16bit_d),
.read_d(1'b1),
.rd_addr_r(rd_addr_r),
.rd_data_r(rd_data_r),
.rd_16bit_r(rd_16bit_r),
.read_r(1'b1)
);
 
mega_alu #(
.CORE_CONFIG(CORE_CONFIG)
)alu(
.inst(pgm_data_int[7:4]),
.in_addr_1(rd_addr_d),
.in_addr_2(rd_addr_r),
.in_1(alu_in_1),
.in_2(alu_in_2),
.out(alu_out),
.ALU_FLAG_C_IN(ALU_FLAGS[0]), //Carry Flag
.ALU_FLAG_Z_IN(ALU_FLAGS[1]), //Zero Flag
.ALU_FLAG_N_IN(ALU_FLAGS[2]), //Negative Flag
.ALU_FLAG_V_IN(ALU_FLAGS[3]), //Two's complement overflow indicator
.ALU_FLAG_S_IN(ALU_FLAGS[4]), //N?V for signed tests
.ALU_FLAG_H_IN(ALU_FLAGS[5]), //Half Carry Flag
.ALU_FLAG_T_IN(ALU_FLAGS[6]), //Transfer bit used by BLD and BST instructions
.ALU_FLAG_I_IN(ALU_FLAGS[7]), //Global Interrupt Enable/Disable Flag
 
.ALU_FLAG_C_OUT(ALU_FLAG_C_OUT), //Carry Flag
.ALU_FLAG_Z_OUT(ALU_FLAG_Z_OUT), //Zero Flag
.ALU_FLAG_N_OUT(ALU_FLAG_N_OUT), //Negative Flag
.ALU_FLAG_V_OUT(ALU_FLAG_V_OUT), //Two's complement overflow indicator
.ALU_FLAG_S_OUT(ALU_FLAG_S_OUT), //N?V for signed tests
.ALU_FLAG_H_OUT(ALU_FLAG_H_OUT), //Half Carry Flag
.ALU_FLAG_T_OUT(ALU_FLAG_T_OUT), //Transfer bit used by BLD and BST instructions
.ALU_FLAG_I_OUT(ALU_FLAG_I_OUT), //Global Interrupt Enable/Disable Flag
.SEL_INSTRUCTION_MOVW(SEL_S1_INSTRUCTION_MOVW),
.SEL_INSTRUCTION_MULS(SEL_S1_INSTRUCTION_MULS),
.SEL_INSTRUCTION_MULSU(SEL_S1_INSTRUCTION_MULSU),
.SEL_INSTRUCTION_FMUL(SEL_S1_INSTRUCTION_FMUL),
.SEL_INSTRUCTION_FMULS(SEL_S1_INSTRUCTION_FMULS),
.SEL_INSTRUCTION_FMULSU(SEL_S1_INSTRUCTION_FMULSU),
.SEL_INSTRUCTION_CPC(SEL_S1_INSTRUCTION_CPC),
.SEL_INSTRUCTION_CP(SEL_S1_INSTRUCTION_CP),
.SEL_INSTRUCTION_SBC(SEL_S1_INSTRUCTION_SBC),
.SEL_INSTRUCTION_SUB(SEL_S1_INSTRUCTION_SUB),
.SEL_INSTRUCTION_ADD(SEL_S1_INSTRUCTION_ADD),
.SEL_INSTRUCTION_ADC(SEL_S1_INSTRUCTION_ADC),
.SEL_INSTRUCTION_AND(SEL_S1_INSTRUCTION_AND),
.SEL_INSTRUCTION_ANDI_CBR(SEL_S1_INSTRUCTION_ANDI_CBR),
.SEL_INSTRUCTION_EOR(SEL_S1_INSTRUCTION_EOR),
.SEL_INSTRUCTION_OR(SEL_S1_INSTRUCTION_OR),
.SEL_INSTRUCTION_ORI_SBR(SEL_S1_INSTRUCTION_ORI_SBR),
.SEL_INSTRUCTION_MOV(SEL_S1_INSTRUCTION_MOV),
.SEL_INSTRUCTION_CPI(SEL_S1_INSTRUCTION_CPI),
.SEL_INSTRUCTION_SUBI(SEL_S1_INSTRUCTION_SUBI),
.SEL_INSTRUCTION_SBCI(SEL_S1_INSTRUCTION_SBCI),
.SEL_INSTRUCTION_LPM_R_P(SEL_S1_INSTRUCTION_LPM_R_P),
.SEL_INSTRUCTION_COM(SEL_S1_INSTRUCTION_COM),
.SEL_INSTRUCTION_NEG(SEL_S1_INSTRUCTION_NEG),
.SEL_INSTRUCTION_SWAP(SEL_S1_INSTRUCTION_SWAP),
.SEL_INSTRUCTION_INC(SEL_S1_INSTRUCTION_INC),
.SEL_INSTRUCTION_ASR(SEL_S1_INSTRUCTION_ASR),
.SEL_INSTRUCTION_LSR(SEL_S1_INSTRUCTION_LSR),
.SEL_INSTRUCTION_ROR(SEL_S1_INSTRUCTION_ROR),
.SEL_INSTRUCTION_SEx_CLx(SEL_S1_INSTRUCTION_SEx_CLx),
.SEL_INSTRUCTION_DEC(SEL_S1_INSTRUCTION_DEC),
.SEL_INSTRUCTION_ADIW(SEL_S1_INSTRUCTION_ADIW),
.SEL_INSTRUCTION_SBIW(SEL_S1_INSTRUCTION_SBIW),
.SEL_INSTRUCTION_MUL(SEL_S1_INSTRUCTION_MUL)
);
 
watchdog # (
.CNT_WIDTH(WATCHDOG_CNT_WIDTH)
)wdt_inst(
.rst(rst),
.clk(clk),
.wdt_clk(clk_wdt),
.wdt_rst_in(wdt_rst_out),
.wdt_rst_out(core_rst)
);
 
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.