-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathbranchcontrol.v
More file actions
67 lines (58 loc) · 2.02 KB
/
Copy pathbranchcontrol.v
File metadata and controls
67 lines (58 loc) · 2.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
`include "bus.vh"
`include "flags.vh"
`include "opcode.vh"
module branchcontrol(opcode, readreg2, rd, flags, branch);
input wire [`OPCODESIZE-1:0] opcode;
input wire [`WORDSIZE-1:0] readreg2;
input wire [`REGADDRSIZE-1:0] rd;
input wire [`FLAGSIZE-1:0] flags;
output reg branch;
wire flagbranch[0:15];
wire unconditional;
wire conditional;
wire flagbased;
wire zero;
wire n;
wire z;
wire v;
wire c;
/* get whether readreg2 is zero */
assign zero = ~(|readreg2);
/* disassemble the flags */
assign n = flags[3];
assign z = flags[2];
assign v = flags[1];
assign c = flags[0];
/* branch based on flags */
assign flagbranch['h0] = z; /* B.EQ */
assign flagbranch['h1] = ~z; /* B.NE */
assign flagbranch['h2] = c; /* B.HS */
assign flagbranch['h3] = ~c; /* B.LO */
assign flagbranch['h4] = n; /* B.MI */
assign flagbranch['h5] = ~n; /* B.PL */
assign flagbranch['h6] = v; /* B.VS */
assign flagbranch['h7] = ~v; /* B.VC */
assign flagbranch['h8] = ~z & c; /* B.HI */
assign flagbranch['h9] = ~(~z & c); /* B.LS */
assign flagbranch['ha] = (n == v); /* B.GE */
assign flagbranch['hb] = (n != v); /* B.LT */
assign flagbranch['hc] = ~z & (n == v); /* B.GT */
assign flagbranch['hd] = ~(~z & (n == v)); /* B.LE */
assign flagbranch['he] = 1'b0;
assign flagbranch['hf] = 1'b0;
/* whether to unconditionally branch */
assign unconditional = (opcode & `B_MASK) == `B_BITSET;
/* whether conditionally branch based on the state of zero */
assign conditional = ((opcode & `CB_MASK) == `CB_BITSET)
&& ((~opcode[3] && zero) || (opcode[3] && ~zero));
/* whether to conditionally branch based on flags */
assign flagbased = ((opcode & `BFLAG_MASK) == `BFLAG_BITSET)
&& flagbranch[rd[3:0]];
/* set whether to branch */
always @(*) begin
if (unconditional | conditional | flagbased)
branch <= 1'b1;
else
branch <= 1'b0;
end
endmodule