summaryrefslogtreecommitdiff
path: root/sim/decode.sv
blob: 5c9a9c981e7dc33d80a0f4c1ab9f4a655c98d63d (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
77
78
79
80
81
82
module decode
    #(  parameter   UROM        = "<no file specified>"
    ,   parameter   UIP_BITS    = 15
    ,   parameter   UROM_BITS   = 8
    ,   parameter   BUS_BITS    = 16
    ,   parameter   OPCODE_BITS = 8
    )
    (   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 [OPCODE_BITS-1:0] opcode;
bit [BUS_BITS-1:0] a;
bit [BUS_BITS-1:0] b;
bit needmore;

bit [UIP_BITS-1:0] new_uip;
assign new_uip = {opcode, {(UIP_BITS-OPCODE_BITS){1'b0}}};

typedef enum
    { CLEAR
    , DECODE
    , OUTADDR
    , OUTADDR_SEL0
    , OUTADDR_SEL1
    , OUTDATA
    , OUTDATA_SEL0
    , OUTDATA_SEL1
    } CtrlBit;

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

bit [1:0] asel;
assign asel = {ctrl[OUTADDR_SEL1], ctrl[OUTADDR_SEL0]};

bit [1:0] dsel;
assign dsel = {ctrl[OUTDATA_SEL1], ctrl[OUTDATA_SEL0]};

bit [BUS_BITS-1:0] aout;
assign aout =
    (asel == 0) ? a :
    (asel == 1) ? b :
    (asel == 2) ? {{(BUS_BITS-UIP_BITS){1'b0}}, new_uip} :
    {(BUS_BITS){1'bX}};

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

bit [BUS_BITS-1:0] dout;
assign dout =
    (dsel == 0) ? a :
    (dsel == 1) ? b :
    (dsel == 2) ? {{(BUS_BITS-1){1'b0}}, needmore} :
    {(BUS_BITS){1'bX}};

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

always @(posedge clk) begin
    if (reset || ctrl[CLEAR]) begin
        opcode <= 0;
        a <= 0;
        b <= 0;
        needmore <= 1;
    end else if (ctrl[DECODE]) begin
        automatic bit m = dbus[7];
        automatic bit i = dbus[6];
        automatic bit [1:0] field = dbus[5:4];
        automatic bit [3:0] shift = dbus[3:0];
        needmore <= m;
        if (field == 0) begin
            opcode <= {i ? ~opcode[OPCODE_BITS-1-4:0] : opcode[OPCODE_BITS-1-4:0], shift};
        end else if (field == 2) begin
            a <= {i ? ~a[BUS_BITS-1-4:0] : a[BUS_BITS-1-4:0], shift};
        end else if (field == 3) begin
            b <= {i ? ~b[BUS_BITS-1-4:0] : b[BUS_BITS-1-4:0], shift};
        end
    end
end
endmodule