summaryrefslogtreecommitdiff
path: root/sim/alu.sv
blob: 407b083e784feb5c7ebb0b4aa754487a03bdbbba (plain) (blame)
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
68
69
70
71
72
73
74
75
76
module alu
    #(  parameter   UROM        = "<no file specified>"
    ,   parameter   UIP_BITS    = 15
    ,   parameter   UROM_BITS   = 8
    ,   parameter   BUS_BITS    = 16
    )
    (   input   bit                 clk
    ,   input   bit                 reset
    ,   input   bit [UIP_BITS-1:0]  uip
    ,   inout   bit [BUS_BITS-1:0]  abus
    ,   inout   bit [BUS_BITS-1:0]  dbus
    );

bit [BUS_BITS-1:0] x;

typedef enum
    { OP
    , OP_SEL0
    , OP_SEL1
    , OP_SEL2
    , OUTADDR
    , OUTDATA
    } CtrlBit;

bit [UROM_BITS-1:0] ctrl;
urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl);

bit [2:0] sel;
assign sel = {ctrl[OP_SEL2], ctrl[OP_SEL1], ctrl[OP_SEL0]};

bit [BUS_BITS-1:0] and_result;
bit [BUS_BITS-1:0] or_result;
bit [BUS_BITS-1:0] xor_result;
bit [BUS_BITS-1:0] add_result;
bit [BUS_BITS-1:0] sub_result;
bit [BUS_BITS-1:0] cmp_result;
bit [BUS_BITS-1:0] lshift_result;
bit [BUS_BITS-1:0] rshift_result;

assign and_result = abus & dbus;
assign or_result = abus | dbus;
assign xor_result = abus ^ dbus;
assign add_result = abus + dbus;
assign sub_result = abus - dbus;
assign cmp_result = {{(BUS_BITS-6){1'b0}},
    (abus != 0) & (dbus != 0),
    (abus != 0) | (dbus != 0),
    (abus != 0) ^ (dbus != 0),
    abus > dbus,
    abus == dbus,
    abus < dbus};
assign lshift_result = (dbus >= BUS_BITS) ? 0 : (abus << dbus);
assign rshift_result = (dbus >= BUS_BITS) ? 0 : (abus >> dbus);

bit [BUS_BITS-1:0] newx;
assign newx =
    (sel == 0) ? and_result :
    (sel == 1) ? or_result :
    (sel == 2) ? xor_result :
    (sel == 3) ? add_result :
    (sel == 4) ? sub_result :
    (sel == 5) ? cmp_result :
    (sel == 6) ? lshift_result :
    (sel == 7) ? rshift_result :
    {(BUS_BITS){1'bX}};

assign abus = ctrl[OUTADDR] ? x : {(BUS_BITS){1'bZ}};
assign dbus = ctrl[OUTDATA] ? x : {(BUS_BITS){1'bZ}};

always @(posedge clk) begin
    if (ctrl[OP]) begin
        x <= newx;
    end
end

endmodule