Line 1... |
Line 1... |
|
|
/*
|
/*
|
* Signals which registers have to be read/written for the current opcode
|
* Decodes an opcode
|
*
|
|
*
|
*
|
|
* All decoders in one module
|
*
|
*
|
*/
|
*/
|
`include "defs.v"
|
`include "defs.v"
|
|
|
module decoders(
|
module decoders(
|
Line 12... |
Line 11... |
input wire [7:0] opcode,
|
input wire [7:0] opcode,
|
input wire [7:0] postbyte0,
|
input wire [7:0] postbyte0,
|
input wire page2_valid, // is 1 when the postbyte0 is a valid opcode (after it was loaded)
|
input wire page2_valid, // is 1 when the postbyte0 is a valid opcode (after it was loaded)
|
input wire page3_valid, // is 1 when the postbyte0 is a valid opcode (after it was loaded)
|
input wire page3_valid, // is 1 when the postbyte0 is a valid opcode (after it was loaded)
|
|
|
output wire [3:0] path_left_addr_o,
|
|
output wire [3:0] path_right_addr_o,
|
|
output wire [3:0] dest_reg_o,
|
|
output reg [3:0] path_left_addr_lo,
|
output reg [3:0] path_left_addr_lo,
|
output reg [3:0] path_right_addr_lo,
|
output reg [3:0] path_right_addr_lo,
|
output reg [3:0] dest_reg_lo,
|
output reg [3:0] dest_reg_lo,
|
output wire write_dest,
|
output wire write_dest,
|
output wire source_size,
|
output wire source_size,
|
Line 51... |
Line 47... |
output wire [4:0] alu_opcode,
|
output wire [4:0] alu_opcode,
|
output wire dest_flags_o
|
output wire dest_flags_o
|
|
|
|
|
);
|
);
|
reg [3:0] lr, rr, dr;
|
reg [3:0] lr, rr, dr; // left, right and destination register addresses
|
reg [1:0] lm, rm, dm;
|
reg [1:0] lm, rm, dm; // left, right and destination memory sizes
|
reg ss, sz, p2, p3;
|
reg ss, sz, p2, p3; // S or *U, 16 or *8, page 2, page 3
|
reg [2:0] mo;
|
reg [2:0] mo; // Addressing Mode
|
reg [4:0] aop;
|
reg [4:0] aop; // ALU opcode
|
assign write_dest = (dr != `RN_INV);
|
assign write_dest = (dr != `RN_INV);
|
assign source_size = (lr < `RN_ACCA) | sz | (rm == `MT_WORD);
|
assign source_size = (lr < `RN_ACCA) | sz | (rm == `MT_WORD);
|
// result size is used to determine the size of the argument
|
// result size is used to determine the size of the argument
|
// to load, compare has no result, thus the source is used instead,
|
// to load, compare has no result, thus the source is used instead,
|
// why do we need the result size ?... because of tfr&exg
|
// why do we need the result size ?... because of tfr&exg
|
assign result_size = (dr == `RN_INV) ? (lr < `RN_ACCA):
|
assign result_size = (dr == `RN_INV) ? (lr < `RN_ACCA):
|
(dr < `RN_ACCA) ? 1:0;
|
(dr < `RN_ACCA) ? 1:0;
|
|
|
assign path_right_addr_o = rr;
|
|
assign path_left_addr_o = lr;
|
|
assign dest_reg_o = dr;
|
|
|
|
// for registers, memory writes are handled differently
|
// for registers, memory writes are handled differently
|
|
|
assign operand_read_o = (lm != `MT_NONE) | (rm != `MT_NONE);
|
assign operand_read_o = (lm != `MT_NONE) | (rm != `MT_NONE);
|
assign operand_write_o = dm != `MT_NONE;
|
assign operand_write_o = dm != `MT_NONE;
|
assign path_left_memtype_o = lm;
|
assign path_left_memtype_o = lm;
|
Line 817... |
Line 809... |
wire [7:0] op = page2_valid ? postbyte0:opcode;
|
wire [7:0] op = page2_valid ? postbyte0:opcode;
|
|
|
always @(*)
|
always @(*)
|
begin
|
begin
|
cond_taken = 1'b0;
|
cond_taken = 1'b0;
|
if ((op == 8'h16) || (op == 8'h17) || (op == 8'h8D) ||
|
if ((opcode == 8'h16) || (opcode == 8'h17) || (opcode == 8'h8D) ||
|
(op == 8'h0e) || (op == 8'h6e) || (op == 8'h7e)) // jmp
|
(opcode == 8'h0e) || (opcode == 8'h6e) || (opcode == 8'h7e)) // jmp
|
cond_taken = 1'b1; // LBRA/LBSR, BSR
|
cond_taken = 1'b1; // LBRA/LBSR, BSR
|
if (op[7:4] == 4'h2)
|
if (op[7:4] == 4'h2)
|
case (op[3:0])
|
case (op[3:0])
|
4'h0: cond_taken = 1'b1; // BRA
|
4'h0: cond_taken = 1'b1; // BRA
|
4'h1: cond_taken = 0; // BRN
|
4'h1: cond_taken = 0; // BRN
|