module beta2(clk,reset,irq,xadr,ma,mdin,mdout,mwe);
input clk,reset,irq;
input [30:0] xadr;
output [31:0] ma,mdout;
input [31:0] mdin;
output mwe;
// beta2 registers
reg [31:0] regfile[31:0];
reg [31:0] npc,pc_inc;
reg [31:0] inst;
reg [4:0] rc_save; // needed for second cycle on LD,LDR
// internal buses
wire [31:0] rd1,rd2,wd;
wire [31:0] a,b,xb,c,addsub,cmp,shift,boole,mult;
// control signals
wire wasel,werf,z,asel,bsel,csel;
wire addsub_op,cmp_lt,cmp_eq,shift_op,shift_sxt,boole_and,boole_or;
wire wd_addsub,wd_cmp,wd_shift,wd_boole,wd_mult;
wire msel,msel_next,branch,trap,interrupt;
// pc
wire [31:0] npc_inc,npc_next;
assign npc_inc = npc + 4;
assign npc_next = reset ? 32'h80000000 :
msel ? npc :
branch ? {npc[31] & addsub[31],addsub[30:2],2'b00} :
trap ? 32'h80000004 :
interrupt ? {1'b1,xadr} :
{npc[31],npc_inc[30:0]};
always @ (posedge clk) begin
npc <= npc_next; // logic for msel handled above
if (!msel) pc_inc <= {npc[31],npc_inc[30:0]};
end
// instruction reg
always @ (posedge clk) if (!msel) inst <= mdin;
// control logic
decode ctl(.clk(clk),.reset(reset),.irq(irq & !npc[31]),.z(z),
.opcode(inst[31:26]),
.asel(asel),.bsel(bsel),.csel(csel),.wasel(wasel),
.werf(werf),.msel(msel),.msel_next(msel_next),.mwe(mwe),
.addsub_op(addsub_op),.cmp_lt(cmp_lt),.cmp_eq(cmp_eq),
.shift_op(shift_op),.shift_sxt(shift_sxt),
.boole_and(boole_and),.boole_or(boole_or),
.wd_addsub(wd_addsub),.wd_cmp(wd_cmp),
.wd_shift(wd_shift),.wd_boole(wd_boole),.wd_mult(wd_mult),
.branch(branch),.trap(trap),.interrupt(interrupt));
// register file
wire [4:0] ra1,ra2,wa;
always @ (posedge clk) if (!msel) rc_save <= inst[25:21];
assign ra1 = inst[20:16];
assign ra2 = msel_next ? inst[25:21] : inst[15:11];
assign wa = msel ? rc_save : wasel ? 5'd30 : inst[25:21];
assign rd1 = (ra1 == 31) ? 0 : regfile[ra1]; // read port 1
assign rd2 = (ra2 == 31) ? 0 : regfile[ra2]; // read port 2
always @ (posedge clk) if (werf) regfile[wa] <= wd; // write port
assign z = ~| rd1; // used in BEQ/BNE instructions
// alu
assign a = asel ? pc_inc : rd1;
assign b = bsel ? c : rd2;
assign c = csel ? {{14{inst[15]}},inst[15:0],2'b00} :
{{16{inst[15]}},inst[15:0]};
wire addsub_n,addsub_v,addsub_z;
assign xb = {32{addsub_op}} ^ b;
assign addsub = a + xb + addsub_op;
assign addsub_n = addsub[31];
assign addsub_v = (addsub[31] & ~a[31] & ~xb[31]) |
(~addsub[31] & a[31] & xb[31]);
assign addsub_z = ~| addsub;
assign cmp[31:1] = 0;
assign cmp[0] = (cmp_lt & (addsub_n ^ addsub_v)) | (cmp_eq & addsub_z);
//mul32 mpy(a,b,mult);
wire [31:0] shift_right;
// Verilog >>> operator not synthesized correctly, so do it by hand
shift_right sr(shift_sxt,a,b[4:0],shift_right);
assign shift = shift_op ? shift_right : a << b[4:0];
assign boole = boole_and ? (a & b) : boole_or ? (a | b) : a ^ b;
// result mux, listed in order of speed (slowest first)
assign wd = msel ? mdin :
wd_cmp ? cmp :
wd_addsub ? addsub :
//wd_mult ? mult :
wd_shift ? shift :
wd_boole ? boole :
pc_inc;
// assume synchronous external memory
assign ma = msel_next ? {npc[31],addsub[30:0]} : npc_next;
assign mdout = rd2;
endmodule
This page: |
Created: | Thu Dec 8 21:44:34 2005 |
|
From: |
./beta2.v |