mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-02-12 10:57:09 +00:00
139 lines
3.6 KiB
Systemverilog
139 lines
3.6 KiB
Systemverilog
// Decodes IRD into ALU row (1-15)
|
|
// Slow, but no need to optimize for speed since IRD is latched at least two CPU cycles before it is used
|
|
// We also register the result after combining with column from nanocode
|
|
//
|
|
// Many opcodes are not decoded because they either don't do any ALU op,
|
|
// or use only columns 1 and 5 that are the same for all rows.
|
|
|
|
module rowDecoder( input [15:0] ird,
|
|
output logic [15:0] row, output noCcrEn, output logic isArX);
|
|
|
|
|
|
// Addr or data register direct
|
|
wire eaRdir = (ird[ 5:4] == 2'b00);
|
|
// Addr register direct
|
|
wire eaAdir = (ird[ 5:3] == 3'b001);
|
|
wire size11 = ird[7] & ird[6];
|
|
|
|
always_comb begin
|
|
case( ird[15:12])
|
|
'h4,
|
|
'h9,
|
|
'hd:
|
|
isArX = row[10] | row[12];
|
|
default:
|
|
isArX = 1'b0;
|
|
endcase
|
|
end
|
|
|
|
always_comb begin
|
|
unique case( ird[15:12])
|
|
|
|
'h4: begin
|
|
if( ird[8])
|
|
row = `ALU_ROW_06; // chk (or lea)
|
|
else case( ird[11:9])
|
|
'b000: row = `ALU_ROW_10; // negx
|
|
'b001: row = `ALU_ROW_04; // clr
|
|
'b010: row = `ALU_ROW_05; // neg
|
|
'b011: row = `ALU_ROW_11; // not
|
|
'b100: row = (ird[7]) ? `ALU_ROW_08 : `ALU_ROW_09; // nbcd/swap/ext(or pea)
|
|
'b101: row = `ALU_ROW_15; // tst & tas
|
|
default: row = 0;
|
|
endcase
|
|
end
|
|
|
|
'h0: begin
|
|
if( ird[8]) // dynamic bit
|
|
row = ird[7] ? `ALU_ROW_14 : `ALU_ROW_13;
|
|
else case( ird[ 11:9])
|
|
'b000: row = `ALU_ROW_14; // ori
|
|
'b001: row = `ALU_ROW_04; // andi
|
|
'b010: row = `ALU_ROW_05; // subi
|
|
'b011: row = `ALU_ROW_02; // addi
|
|
'b100: row = ird[7] ? `ALU_ROW_14 : `ALU_ROW_13; // static bit
|
|
'b101: row = `ALU_ROW_13; // eori
|
|
'b110: row = `ALU_ROW_06; // cmpi
|
|
default: row = 0;
|
|
endcase
|
|
end
|
|
|
|
// MOVE
|
|
// move.b originally also rows 5 & 15. Only because IRD bit 14 is not decoded.
|
|
// It's the same for move the operations performed by MOVE.B
|
|
|
|
'h1,'h2,'h3: row = `ALU_ROW_02;
|
|
|
|
'h5:
|
|
if( size11)
|
|
row = `ALU_ROW_15; // As originally and easier to decode
|
|
else
|
|
row = ird[8] ? `ALU_ROW_05 : `ALU_ROW_02; // addq/subq
|
|
'h6: row = 0; //bcc/bra/bsr
|
|
'h7: row = `ALU_ROW_02; // moveq
|
|
'h8:
|
|
if( size11) // div
|
|
row = `ALU_ROW_01;
|
|
else if( ird[8] & eaRdir) // sbcd
|
|
row = `ALU_ROW_09;
|
|
else
|
|
row = `ALU_ROW_14; // or
|
|
'h9:
|
|
if( ird[8] & ~size11 & eaRdir)
|
|
row = `ALU_ROW_10; // subx
|
|
else
|
|
row = `ALU_ROW_05; // sub/suba
|
|
'hb:
|
|
if( ird[8] & ~size11 & ~eaAdir)
|
|
row = `ALU_ROW_13; // eor
|
|
else
|
|
row = `ALU_ROW_06; // cmp/cmpa/cmpm
|
|
'hc:
|
|
if( size11)
|
|
row = `ALU_ROW_07; // mul
|
|
else if( ird[8] & eaRdir) // abcd
|
|
row = `ALU_ROW_03;
|
|
else
|
|
row = `ALU_ROW_04; // and
|
|
'hd:
|
|
if( ird[8] & ~size11 & eaRdir)
|
|
row = `ALU_ROW_12; // addx
|
|
else
|
|
row = `ALU_ROW_02; // add/adda
|
|
'he:
|
|
begin
|
|
reg [1:0] stype;
|
|
|
|
if( size11) // memory shift/rotate
|
|
stype = ird[ 10:9];
|
|
else // register shift/rotate
|
|
stype = ird[ 4:3];
|
|
|
|
case( {stype, ird[8]})
|
|
0: row = `ALU_ROW_02; // ASR
|
|
1: row = `ALU_ROW_03; // ASL
|
|
2: row = `ALU_ROW_05; // LSR
|
|
3: row = `ALU_ROW_04; // LSL
|
|
4: row = `ALU_ROW_08; // ROXR
|
|
5: row = `ALU_ROW_11; // ROXL
|
|
6: row = `ALU_ROW_10; // ROR
|
|
7: row = `ALU_ROW_09; // ROL
|
|
endcase
|
|
end
|
|
|
|
default: row = 0;
|
|
endcase
|
|
end
|
|
|
|
// Decode opcodes that don't affect flags
|
|
// ADDA/SUBA ADDQ/SUBQ MOVEA
|
|
|
|
assign noCcrEn =
|
|
// ADDA/SUBA
|
|
( ird[15] & ~ird[13] & ird[12] & size11) |
|
|
// ADDQ/SUBQ to An
|
|
( (ird[15:12] == 4'h5) & eaAdir) |
|
|
// MOVEA
|
|
( (~ird[15] & ~ird[14] & ird[13]) & ird[8:6] == 3'b001);
|
|
|
|
endmodule
|