module decode(clk,reset,irq,z,opcode,
asel,bsel,csel,wasel,werf,msel,msel_next,mwe,
addsub_op,cmp_lt,cmp_eq,
shift_op,shift_sxt,boole_and,boole_or,
wd_addsub,wd_cmp,wd_shift,wd_boole,wd_mult,
branch,trap,interrupt);
input clk,reset,irq,z;
input [5:0] opcode;
output asel,bsel,csel,wasel,werf,msel,msel_next,mwe;
output addsub_op,shift_op,shift_sxt,cmp_lt,cmp_eq,boole_and,boole_or;
output wd_addsub,wd_cmp,wd_shift,wd_boole,wd_mult;
output branch,trap,interrupt;
reg asel,bsel,csel,wasel,mem_next;
reg addsub_op,shift_op,shift_sxt,cmp_lt,cmp_eq,boole_and,boole_or;
reg wd_addsub,wd_cmp,wd_shift,wd_boole,wd_mult;
reg branch,trap,interrupt;
// a little bit of state...
reg annul,msel,mwrite;
always @ (opcode or z or annul or msel or irq or reset)
begin
// initial assignments for all control signals
asel = 1'hx;
bsel = 1'hx;
csel = 1'hx;
addsub_op = 1'hx;
shift_op = 1'hx;
shift_sxt = 1'hx;
cmp_lt = 1'hx;
cmp_eq = 1'hx;
boole_and = 1'hx;
boole_or = 1'hx;
wasel = 0;
mem_next = 0;
wd_addsub = 0;
wd_cmp = 0;
wd_shift = 0;
wd_boole = 0;
wd_mult = 0;
branch = 0;
trap = 0;
interrupt = 0;
if (irq && !reset && !annul && !msel) begin
interrupt = 1;
wasel = 1;
end else casez (opcode)
6'b011000: begin // LD
asel = 0; bsel = 1; csel = 0;
addsub_op = 0;
mem_next = 1;
end
6'b011001: begin // ST
asel = 0; bsel = 1; csel = 0;
addsub_op = 0;
mem_next = 1;
end
6'b011011: begin // JMP
asel = 0; bsel = 1; csel = 0;
addsub_op = 0;
branch = !annul && !msel;
end
6'b011101: begin // BEQ
asel = 1; bsel = 1; csel = 1;
addsub_op = 0;
branch = !annul && !msel && z;
end
6'b011110: begin // BNE
asel = 1; bsel = 1; csel = 1;
addsub_op = 0;
branch = !annul && !msel && ~z;
end
6'b011111: begin // LDR
asel = 1; bsel = 1; csel = 1;
addsub_op = 0;
mem_next = 1;
end
6'b1?0000: begin // ADD, ADDC
asel = 0; bsel = opcode[4]; csel = 0;
addsub_op = 0;
wd_addsub = 1;
end
6'b1?0001: begin // SUB, SUBC
asel = 0; bsel = opcode[4]; csel = 0;
addsub_op = 1;
wd_addsub = 1;
end
//6'b1?0010: begin // MUL, MULC
// asel = 0; bsel = opcode[4]; csel = 0;
// wd_mult = 1;
// end
6'b1?0100: begin // CMPEQ, CMPEQC
asel = 0; bsel = opcode[4]; csel = 0;
addsub_op = 1;
cmp_eq = 1; cmp_lt = 0;
wd_cmp = 1;
end
6'b1?0101: begin // CMPLT, CMPLTC
asel = 0; bsel = opcode[4]; csel = 0;
addsub_op = 1;
cmp_eq = 0; cmp_lt = 1;
wd_cmp = 1;
end
6'b1?0110: begin // CMPLE, CMPLEC
asel = 0; bsel = opcode[4]; csel = 0;
addsub_op = 1;
cmp_eq = 1; cmp_lt = 1;
wd_cmp = 1;
end
6'b1?1000: begin // AND, ANDC
asel = 0; bsel = opcode[4]; csel = 0;
boole_and = 1; boole_or = 0;
wd_boole = 1;
end
6'b1?1001: begin // OR, ORC
asel = 0; bsel = opcode[4]; csel = 0;
boole_and = 0; boole_or = 1;
wd_boole = 1;
end
6'b1?1010: begin // XOR, XORC
asel = 0; bsel = opcode[4]; csel = 0;
boole_and = 0; boole_or = 0;
wd_boole = 1;
end
6'b1?1100: begin // SHL, SHLC
asel = 0; bsel = opcode[4]; csel = 0;
shift_op = 0;
wd_shift = 1;
end
6'b1?1101: begin // SHR, SHRC
asel = 0; bsel = opcode[4]; csel = 0;
shift_op = 1; shift_sxt = 0;
wd_shift = 1;
end
6'b1?1110: begin // SRA, SRAC
asel = 0; bsel = opcode[4]; csel = 0;
shift_op = 1; shift_sxt = 1;
wd_shift = 1;
end
default: begin // illegal opcode
trap = !annul && !msel; wasel = 1;
end
endcase
end
// state
wire msel_next = !reset && !annul && mem_next && !msel;
wire mwrite_next = msel_next && opcode==6'b011001;
always @ (posedge clk)
begin
annul <= !reset && (trap || branch || interrupt);
msel <= msel_next;
mwrite <= mwrite_next;
end
assign mwe = mwrite_next; // assume synchronous memory
assign werf = msel ? !mwrite : (!annul & !mem_next);
endmodule
This page: |
Created: | Thu Dec 8 21:44:34 2005 |
|
From: |
./decode.v |