Ревизия обновлена: 14 янв 2024.
Ниже представлен готовый код ядра процессора.
module avr
(
input clock,
input reset_n,
output reg [15:0] pc,
input [15:0] ir,
output reg [15:0] address,
input [ 7:0] data_i,
output reg [ 7:0] data_o,
output reg we,
output reg read,
input intr,
input [ 2:0] vect
);
initial begin
address = 1'b0;
pc = 1'b0;
we = 1'b0;
data_o = 1'b0;
read = 1'b0;
r[0] = 8'h00; r[4] = 8'h00; r[8] = 8'h00; r[12] = 8'h01;
r[1] = 8'h00; r[5] = 8'h00; r[9] = 8'h00; r[13] = 8'h00;
r[2] = 8'h00; r[6] = 8'h00; r[10] = 8'h00; r[14] = 8'h00;
r[3] = 8'h00; r[7] = 8'h00; r[11] = 8'h00; r[15] = 8'h00;
r[16] = 8'h00; r[20] = 8'h00; r[24] = 8'h00; r[28] = 8'h00;
r[17] = 8'h00; r[21] = 8'h00; r[25] = 8'h00; r[29] = 8'h00;
r[18] = 8'h00; r[22] = 8'h00; r[26] = 8'h00; r[30] = 8'h05;
r[19] = 8'h00; r[23] = 8'h00; r[27] = 8'h00; r[31] = 8'hFA;
end
localparam
SPDEC = 1,
SPINC = 2;
reg [7:0] din;
always @* begin
casex (address)
16'b0000_0000_000x_xxxx: din = r[ address[4:0] ];
16'h005B: din = rampz;
16'h005D: din = sp[ 7:0];
16'h005E: din = sp[15:8];
16'h005F: din = sreg;
default: din = data_i;
endcase
end
reg [ 7:0] r[32];
reg [ 1:0] tstate = 0;
reg [15:0] latch = 0;
reg [15:0] pclatch = 0;
reg [15:0] sp = 16'h1FFF;
reg [ 7:0] sreg = 8'b0000_0000;
reg [ 4:0] alu = 0;
reg reg_w = 0;
reg sreg_w = 0;
reg [ 4:0] reg_id = 0;
reg [ 1:0] sp_mth = 0;
reg reg_ww = 1'b0;
reg reg_ws = 1'b0;
reg reg_wm = 1'b0;
reg [ 1:0] reg_idw = 1'b0;
reg [15:0] wb2 = 1'b0;
reg [ 7:0] rampz = 1'b0;
wire [15:0] opcode = tstate ? latch : ir;
wire [15:0] X = {r[27], r[26]};
wire [15:0] Y = {r[29], r[28]};
wire [15:0] Z = {r[31], r[30]};
wire [15:0] Xm = X - 1'b1;
wire [15:0] Xp = X + 1'b1;
wire [15:0] Ym = Y - 1'b1;
wire [15:0] Yp = Y + 1'b1;
wire [15:0] Zm = Z - 1'b1;
wire [15:0] Zp = Z + 1'b1;
wire [ 5:0] q = {opcode[13], opcode[11:10], opcode[2:0]};
wire [ 4:0] rd = opcode[8:4];
wire [ 4:0] rr = {opcode[9], opcode[3:0]};
wire [ 4:0] rdi = {1'b1, opcode[7:4]};
wire [ 4:0] rri = {1'b1, opcode[3:0]};
wire [ 7:0] K = {opcode[11:8], opcode[3:0]};
reg skip_instr = 1'b0;
wire [15:0] pcnext = pc + 1'h1;
wire [15:0] pcnext2 = pc + 2'h2;
wire is_call = {opcode[14], opcode[3:1]} == 4'b0111;
reg [ 7:0] op1, op2, alu_res, alu_sreg;
reg [15:0] op1w, resw;
reg intr_trigger = 1'b0;
reg intr_prev = 1'b0;
reg [2:0] intr_vect = 1'b0;
always @(posedge clock)
if (reset_n == 1'b0) begin
pc <= 1'b0;
tstate <= 1'b0;
end
else begin
we <= 1'b0;
read <= 1'b0;
reg_w <= 1'b0;
sreg_w <= 1'b0;
sp_mth <= 1'b0;
reg_ww <= 1'b0;
reg_ws <= 1'b0;
reg_wm <= 1'b0;
if (tstate == 0) latch <= ir;
if (skip_instr) begin
casex (opcode)
16'b1001_010x_xxxx_11xx,
16'b1001_00xx_xxxx_0000:
pc <= pcnext + 1;
default:
pc <= pcnext;
endcase
skip_instr <= 0;
end
else if (intr_trigger) begin
case (tstate)
0: begin
tstate <= 1;
address <= sp;
data_o <= pc[7:0];
we <= 1'b1;
sp_mth <= SPDEC;
end
1: begin
tstate <= 0;
address <= sp;
data_o <= pc[15:8];
we <= 1'b1;
sp_mth <= SPDEC;
pc <= {intr_vect, 1'b0};
intr_trigger <= 0;
alu <= 11;
op2 <= {1'b0, sreg[6:0]};
sreg_w <= 1'b1;
end
endcase
end
else if (sreg[7] && tstate == 0 && intr ^ intr_prev) begin
intr_vect <= vect + 1;
intr_prev <= intr;
intr_trigger <= 1'b1;
end
else casex (opcode)
16'b0000_0000_0000_0000: pc <= pcnext;
16'b1001_0101_1001_1000: pc <= pcnext;
16'b1110_xxxx_xxxx_xxxx: begin
pc <= pcnext;
alu <= 0;
op2 <= K;
reg_w <= 1'b1;
reg_id <= rdi;
end
16'b1100_xxxx_xxxx_xxxx: pc <= pcnext + {{4{opcode[11]}}, opcode[11:0]};
16'b1001_0100_000x_1001: pc <= Z;
16'b1001_010x_xxxx_110x:
case (tstate)
0: begin tstate <= 1; pc <= pcnext; end
1: begin tstate <= 0; pc <= ir; end
endcase
16'b000x_01xx_xxxx_xxxx,
16'b000x_1xxx_xxxx_xxxx,
16'b0010_0xxx_xxxx_xxxx,
16'b0010_10xx_xxxx_xxxx:
begin
pc <= pcnext;
alu <= opcode[13:10];
op1 <= r[rd];
op2 <= r[rr];
reg_id <= rd;
reg_w <= (opcode[13:10] != 4'b0001 && opcode[13:10] != 4'b0101);
sreg_w <= 1'b1;
end
16'b1111_0xxx_xxxx_xxxx:
begin
if (sreg[ opcode[2:0] ] ^ opcode[10])
pc <= pcnext + {{9{opcode[9]}}, opcode[9:3]};
else
pc <= pcnext;
end
16'b0011_xxxx_xxxx_xxxx,
16'b0100_xxxx_xxxx_xxxx,
16'b0101_xxxx_xxxx_xxxx,
16'b0110_xxxx_xxxx_xxxx,
16'b0111_xxxx_xxxx_xxxx:
begin
pc <= pcnext;
op1 <= r[rdi];
op2 <= K;
reg_id <= rdi;
reg_w <= (opcode[15:12] != 4'b0011);
sreg_w <= 1'b1;
case (opcode[15:12])
4'b0011: alu <= 5;
4'b0100: alu <= 2;
4'b0101: alu <= 6;
4'b0110: alu <= 10;
4'b0111: alu <= 8;
endcase
end
16'b0010_11xx_xxxx_xxxx:
begin
pc <= pcnext;
alu <= 0;
op2 <= r[rr];
reg_id <= rd;
reg_w <= 1'b1;
end
16'b1101_xxxx_xxxx_xxxx,
16'b1001_0101_000x_1001,
16'b1001_010x_xxxx_111x:
case (tstate)
0: begin
tstate <= 1;
address <= sp;
data_o <= is_call ? pcnext2[7:0] : pcnext[7:0];
we <= 1'b1;
sp_mth <= SPDEC;
pc <= pcnext;
end
1: begin
tstate <= 0;
address <= sp;
data_o <= is_call ? pcnext[15:8] : pc[15:8];
we <= 1'b1;
sp_mth <= SPDEC;
if (is_call) pc <= ir;
else if (opcode[14]) pc <= (pc + {{4{opcode[11]}}, opcode[11:0]});
else pc <= Z;
end
endcase
16'b1001_0101_000x_1000:
case (tstate)
0: begin
tstate <= 1;
read <= 1;
address <= sp + 1;
sp_mth <= SPINC;
end
1: begin
tstate <= 2;
read <= 1;
pc[15:8] <= din;
address <= sp + 1;
sp_mth <= SPINC;
end
2: begin
tstate <= 0;
pc[ 7:0] <= din;
alu <= 11;
op2 <= {sreg[7] | opcode[4], sreg[6:0]};
sreg_w <= 1;
end
endcase
16'b1001_00xx_xxxx_1100,
16'b1001_00xx_xxxx_1101,
16'b1001_00xx_xxxx_1110,
16'b1001_00xx_xxxx_1001,
16'b1001_00xx_xxxx_1010,
16'b1001_00xx_xxxx_0001,
16'b1001_00xx_xxxx_0010:
case (tstate)
0: begin
tstate <= opcode[9] ? 0 : 1;
pc <= pcnext;
data_o <= r[rd];
we <= opcode[9];
read <= !opcode[9];
case (opcode[3:0])
4'b11_00: begin address <= X; end
4'b11_01: begin address <= X; wb2 <= Xp; reg_idw <= 2'b01; reg_ww <= 1; end
4'b11_10: begin address <= Xm; wb2 <= Xm; reg_idw <= 2'b01; reg_ww <= 1; end
4'b10_01: begin address <= Y; wb2 <= Yp; reg_idw <= 2'b10; reg_ww <= 1; end
4'b10_10: begin address <= Ym; wb2 <= Ym; reg_idw <= 2'b10; reg_ww <= 1; end
4'b00_01: begin address <= Z; wb2 <= Zp; reg_idw <= 2'b11; reg_ww <= 1; end
4'b00_10: begin address <= Zm; wb2 <= Zm; reg_idw <= 2'b11; reg_ww <= 1; end
endcase
end
1: begin
tstate <= 0;
alu <= 0;
op2 <= din;
reg_w <= 1;
reg_id <= rd;
end
endcase
16'b10x0_xxxx_xxxx_xxxx:
case (tstate)
0: begin
tstate <= opcode[9] ? 0 : 1;
pc <= pcnext;
address <= (opcode[3] ? Y : Z) + q;
data_o <= r[rd];
we <= opcode[9];
read <= !opcode[9];
end
1: begin
tstate <= 0;
alu <= 0;
op2 <= din;
reg_w <= 1;
reg_id <= rd;
end
endcase
16'b1001_010x_xxxx_00xx,
16'b1001_010x_xxxx_011x,
16'b1001_010x_xxxx_0101,
16'b1001_010x_xxxx_1010: begin
pc <= pcnext;
op1 <= r[rd];
reg_w <= 1;
sreg_w <= 1;
reg_id <= rd;
case (opcode[3:0])
4'b0000: alu <= 5'h0C;
4'b0001: alu <= 5'h0D;
4'b0010: alu <= 5'h0E;
4'b0011: alu <= 5'h0F;
4'b0101: alu <= 5'h10;
4'b0110: alu <= 5'h11;
4'b0111: alu <= 5'h12;
4'b1010: alu <= 5'h13;
endcase
end
16'b0000_0001_xxxx_xxxx:
case (tstate)
0: begin
tstate <= 1;
pc <= pcnext;
alu <= 0;
op2 <= r[ {opcode[3:0], 1'b0} ];
reg_id <= {opcode[7:4], 1'b0};
reg_w <= 1;
end
1: begin
tstate <= 0;
alu <= 0;
op2 <= r[ {opcode[3:0], 1'b1} ];
reg_id <= {opcode[7:4], 1'b1};
reg_w <= 1;
end
endcase
16'b1001_0110_xxxx_xxxx,
16'b1001_0111_xxxx_xxxx:
begin
pc <= pcnext;
alu <= opcode[8] ? 5'h15 : 5'h14;
case (opcode[5:4])
0: op1w <= {r[25], r[24]};
1: op1w <= {r[27], r[26]};
2: op1w <= {r[29], r[28]};
3: op1w <= {r[31], r[30]};
endcase
op2 <= {opcode[7:6], opcode[3:0]};
reg_idw <= opcode[5:4];
reg_ww <= 1;
reg_ws <= 1;
sreg_w <= 1;
end
16'b1001_0101_110x_1000,
16'b1001_000x_xxxx_01x0,
16'b1001_000x_xxxx_01x1:
case (tstate)
0: begin
tstate <= 1;
pclatch <= pcnext;
if (opcode[1] || (opcode[10] && opcode[4]))
pc <= {rampz[0], Z[15:1]};
else pc <= Z[15:1];
end
1: begin
tstate <= 0;
pc <= pclatch;
alu <= 0;
reg_idw <= 2'b11;
reg_ww <= (!opcode[10] & opcode[0]);
wb2 <= Zp;
reg_w <= 1;
reg_id <= opcode[10] ? 0 : rd;
op2 <= Z[0] ? ir[15:8] : ir[7:0];
end
endcase
16'b1011_xxxx_xxxx_xxxx:
case (tstate)
0: begin
tstate <= opcode[11] ? 0 : 1;
pc <= pcnext;
data_o <= r[rd];
we <= opcode[11];
read <= !opcode[11];
address <= {opcode[10:9], opcode[3:0]} + 16'h20;
end
1: begin
tstate <= 0;
alu <= 0;
op2 <= din;
reg_id <= rd;
reg_w <= 1;
end
endcase
16'b1111_11xx_xxxx_0xxx: begin
pc <= pcnext;
if (r[rd][ opcode[2:0] ] == opcode[9])
skip_instr <= 1;
end
16'b1001_10x1_xxxx_xxxx:
casex (tstate)
0: begin
tstate <= 1;
read <= 1;
address <= opcode[7:3] + 16'h20;
end
1: begin
tstate <= 0;
pc <= pcnext;
if (din[ opcode[2:0] ] == opcode[9])
skip_instr <= 1;
end
endcase
16'b0001_00xx_xxxx_xxxx: begin
if (r[rd] == r[rr]) skip_instr <= 1;
pc <= pcnext;
end
16'b1001_00xx_xxxx_0000:
case (tstate)
0: begin
tstate <= 1;
pc <= pcnext;
end
1: begin
tstate <= opcode[9] ? 0 : 2;
pc <= pcnext;
reg_id <= rd;
address <= ir;
data_o <= r[rd];
we <= opcode[9];
read <= !opcode[9];
end
2: begin
tstate <= 0;
alu <= 0;
reg_w <= 1;
op2 <= din;
end
endcase
16'b1001_0100_xxxx_1000: begin
case (opcode[6:4])
0: op2 <= {sreg[7:1], !opcode[7]};
1: op2 <= {sreg[7:2], !opcode[7], sreg[0]};
2: op2 <= {sreg[7:3], !opcode[7], sreg[1:0]};
3: op2 <= {sreg[7:4], !opcode[7], sreg[2:0]};
4: op2 <= {sreg[7:5], !opcode[7], sreg[3:0]};
5: op2 <= {sreg[7:6], !opcode[7], sreg[4:0]};
6: op2 <= {sreg[7], !opcode[7], sreg[5:0]};
7: op2 <= {!opcode[7], sreg[6:0]};
endcase
alu <= 11;
sreg_w <= 1;
pc <= pcnext;
end
16'b1001_001x_xxxx_1111: begin
pc <= pcnext;
data_o <= r[rd];
we <= 1'b1;
address <= sp;
sp_mth <= SPDEC;
end
16'b1001_000x_xxxx_1111:
case (tstate)
0: begin
tstate <= 1;
pc <= pcnext;
address <= sp + 1;
sp_mth <= SPINC;
read <= 1;
end
1: begin
tstate <= 0;
alu <= 0;
op2 <= din;
reg_id <= rd;
reg_w <= 1;
end
endcase
16'b1111_101x_xxxx_0xxx: begin
pc <= pcnext;
alu <= 11;
op2 <= {sreg[7], r[rd][ opcode[2:0] ], sreg[5:0]};
sreg_w <= 1;
end
16'b1111_100x_xxxx_0xxx: begin
pc <= pcnext;
alu <= 22;
op1 <= r[rd];
op2 <= opcode[2:0];
reg_id <= rd;
reg_w <= 1;
end
16'b1001_10x0_xxxx_xxxx:
case (tstate)
0: begin
tstate <= 1;
read <= 1;
pc <= pcnext;
address <= opcode[7:3] + 16'h20;
end
1: begin
tstate <= 1'b0;
we <= 1'b1;
case (opcode[2:0])
0: data_o <= {din[7:1], opcode[9]};
1: data_o <= {din[7:2], opcode[9], din[0]};
2: data_o <= {din[7:3], opcode[9], din[1:0]};
3: data_o <= {din[7:4], opcode[9], din[2:0]};
4: data_o <= {din[7:5], opcode[9], din[3:0]};
5: data_o <= {din[7:6], opcode[9], din[4:0]};
6: data_o <= {din[ 7], opcode[9], din[5:0]};
7: data_o <= { opcode[9], din[6:0]};
endcase
end
endcase
16'b1001_11xx_xxxx_xxxx: begin
pc <= pcnext;
alu <= 23;
op1 <= r[rd];
op2 <= r[rr];
reg_wm <= 1;
end
16'b0000_0010_xxxx_xxxx: begin
pc <= pcnext;
alu <= 24;
op1 <= r[ {1'b1, opcode[7:4]} ];
op2 <= r[ {1'b1, opcode[3:0]} ];
reg_wm <= 1;
end
16'b0000_0011_0xxx_0xxx: begin
pc <= pcnext;
alu <= 25;
op1 <= r[ {2'b10, opcode[6:4]} ];
op2 <= r[ {2'b10, opcode[2:0]} ];
reg_wm <= 1;
end
endcase
end
always @(negedge clock)
begin
if (reg_w) r[ reg_id ] <= alu_res;
if (sreg_w) sreg <= alu_sreg;
case (sp_mth)
SPDEC: sp <= sp - 1'b1;
SPINC: sp <= sp + 1'b1;
endcase
if (reg_ww) begin
case (reg_idw)
0: {r[25], r[24]} <= reg_ws ? resw : wb2;
1: {r[27], r[26]} <= reg_ws ? resw : wb2;
2: {r[29], r[28]} <= reg_ws ? resw : wb2;
3: {r[31], r[30]} <= reg_ws ? resw : wb2;
endcase
end
if (reg_wm) {r[1], r[0]} <= resw;
if (we) begin
case (address)
16'h005B: rampz <= data_o;
16'h005D: sp[ 7:0] <= data_o;
16'h005E: sp[15:8] <= data_o;
16'h005F: sreg <= data_o;
default: if (address < 16'h20) r[ address[4:0] ] <= data_o;
endcase
end
end
wire [7:0] sub = op1 - op2;
wire [7:0] add = op1 + op2;
wire [8:0] sbc = op1 - op2 - sreg[0];
wire [7:0] adc = op1 + op2 + sreg[0];
wire [7:0] lsr = {1'b0, op1[7:1]};
wire [7:0] ror = {sreg[0], op1[7:1]};
wire [7:0] asr = {op1[7], op1[7:1]};
wire [7:0] neg = -op1;
wire [7:0] inc = op1 + 1;
wire [7:0] dec = op1 - 1;
wire [7:0] com = ~op1;
wire [7:0] swap = {op1[3:0], op1[7:4]};
wire [15:0] adiw = op1w + op2;
wire [15:0] sbiw = op1w - op2;
wire [15:0] mul = op1[7:0] * op2[7:0];
wire [15:0] mulsu = {{8{op1[7]}}, op1[7:0]} * op2[7:0];
wire [15:0] muls = {{8{op1[7]}}, op1[7:0]} * {{8{op2[7]}}, op2[7:0]};
wire add_flag_v = (op1[7] & op2[7] & !alu_res[7]) | (!op1[7] & !op2[7] & alu_res[7]);
wire sub_flag_v = (op1[7] & !op2[7] & !alu_res[7]) | (!op1[7] & op2[7] & alu_res[7]);
wire neg_flag_v = alu_res == 8'h80;
wire add_flag_h = ( op1[3] & op2[3]) | (op2[3] & !alu_res[3]) | (!alu_res[3] & op1[3]);
wire sub_flag_h = (!op1[3] & op2[3]) | (op2[3] & alu_res[3]) | ( alu_res[3] & !op1[3]);
wire neg_flag_h = op1[3] | (op1[3] & alu_res[3]) | alu_res[3];
wire adiw_c = op1w[15] & !resw[15];
wire adiw_v = !op1w[15] & resw[15];
wire [7:0] set_logic_flag = {
sreg[7],
sreg[6],
sreg[5],
alu_res[7],
1'b0,
alu_res[7],
alu_res[7:0] == 0,
sreg[0]
};
wire [7:0] set_subcarry_flag = {
sreg[7],
sreg[6],
sub_flag_h,
sub_flag_v ^ alu_res[7],
sub_flag_v,
alu_res[7],
(alu_res[7:0] == 0) & sreg[1],
sbc[8]
};
wire [7:0] set_subtract_flag = {
sreg[7],
sreg[6],
sub_flag_h,
sub_flag_v ^ alu_res[7],
sub_flag_v,
alu_res[7],
(alu_res[7:0] == 0),
op1 < op2
};
wire [7:0] set_com_flag = {
sreg[7],
sreg[6],
sreg[5],
alu_res[7],
1'b0,
alu_res[7],
(alu_res[7:0] == 0),
1'b1
};
wire [7:0] set_neg_flag = {
sreg[7],
sreg[6],
neg_flag_h,
neg_flag_v ^ alu_res[7],
neg_flag_v,
alu_res[7],
(alu_res[7:0] == 0),
op1 != 0
};
wire [7:0] set_add_flag = {
sreg[7],
sreg[6],
add_flag_h,
add_flag_v ^ alu_res[7],
add_flag_v,
alu_res[7],
(alu_res[7:0] == 0),
op1 + op2 >= 9'h100
};
wire [7:0] set_adc_flag = {
sreg[7],
sreg[6],
add_flag_h,
add_flag_v ^ alu_res[7],
add_flag_v,
alu_res[7],
(alu_res[7:0] == 0),
op1 + op2 + sreg[0] >= 9'h100
};
wire [7:0] set_lsr_flag = {
sreg[7],
sreg[6],
sreg[5],
op1[0],
alu_res[7] ^ op1[0],
alu_res[7],
(alu_res[7:0] == 0),
op1[0]
};
wire [7:0] set_inc_flag = {
sreg[7],
sreg[6],
sreg[5],
(alu_res == 8'h80) ^ alu_res[7],
(alu_res == 8'h80),
alu_res[7],
(alu_res[7:0] == 0),
sreg[0]
};
wire [7:0] set_dec_flag = {
sreg[7],
sreg[6],
sreg[5],
(alu_res == 8'h7F) ^ alu_res[7],
(alu_res == 8'h7F),
alu_res[7],
(alu_res[7:0] == 0),
sreg[0]
};
wire [7:0] set_adiw_flag = {
sreg[7],
sreg[6],
sreg[5],
adiw_v ^ resw[15],
adiw_v,
resw[15],
(resw[15:0] == 0),
adiw_c
};
wire [7:0] set_sbiw_flag = {
sreg[7],
sreg[6],
sreg[5],
adiw_c ^ resw[15],
adiw_c,
resw[15],
(resw[15:0] == 0),
adiw_v
};
wire [7:0] set_mul_flag = {sreg[7:2], (mul [15:0] == 0), mul [15]};
wire [7:0] set_muls_flag = {sreg[7:2], (muls [15:0] == 0), muls [15]};
wire [7:0] set_mulsu_flag = {sreg[7:2], (mulsu[15:0] == 0), mulsu[15]};
always @(*)
begin
alu_sreg = sreg;
case (alu)
0: begin alu_res = op2; end
1: begin alu_res = sbc[7:0]; alu_sreg = set_subcarry_flag; end
2: begin alu_res = sbc[7:0]; alu_sreg = set_subcarry_flag; end
3: begin alu_res = add; alu_sreg = set_add_flag; end
5: begin alu_res = sub; alu_sreg = set_subtract_flag; end
6: begin alu_res = sub; alu_sreg = set_subtract_flag; end
7: begin alu_res = adc; alu_sreg = set_adc_flag; end
8: begin alu_res = op1 & op2; alu_sreg = set_logic_flag; end
9: begin alu_res = op1 ^ op2; alu_sreg = set_logic_flag; end
10: begin alu_res = op1 | op2; alu_sreg = set_logic_flag; end
11: begin alu_sreg = op2; end
12: begin alu_res = com; alu_sreg = set_com_flag; end
13: begin alu_res = neg; alu_sreg = set_neg_flag; end
14: begin alu_res = swap; end
15: begin alu_res = inc; alu_sreg = set_inc_flag; end
16: begin alu_res = asr; alu_sreg = set_lsr_flag; end
17: begin alu_res = lsr; alu_sreg = set_lsr_flag; end
18: begin alu_res = ror; alu_sreg = set_lsr_flag; end
19: begin alu_res = dec; alu_sreg = set_dec_flag; end
20: begin resw = adiw; alu_sreg = set_adiw_flag; end
21: begin resw = sbiw; alu_sreg = set_sbiw_flag; end
22: begin
case (op2[2:0])
0: alu_res = {op1[7:1], sreg[6]};
1: alu_res = {op1[7:2], sreg[6], op1[0]};
2: alu_res = {op1[7:3], sreg[6], op1[1:0]};
3: alu_res = {op1[7:4], sreg[6], op1[2:0]};
4: alu_res = {op1[7:5], sreg[6], op1[3:0]};
5: alu_res = {op1[7:6], sreg[6], op1[4:0]};
6: alu_res = {op1[ 7], sreg[6], op1[5:0]};
7: alu_res = { sreg[6], op1[6:0]};
endcase
end
23: begin resw = mul; alu_sreg = set_mul_flag; end
24: begin resw = muls; alu_sreg = set_muls_flag; end
25: begin resw = mulsu; alu_sreg = set_mulsu_flag; end
default: alu_res = 8'hFF;
endcase
end
endmodule