File size: 6,145 Bytes
a8baeed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
// Top-Level Bit-String Hardware Accelerator
// Implements: BIT_BASE + BIT_OFFSET addressing with atomic read-modify-write

module bit_accelerator #(
  parameter int ADDR_WIDTH = 64,
  parameter int WORD_WIDTH = 64,
  parameter int WORD_BYTES = WORD_WIDTH / 8
) (
  input  logic                         clk,
  input  logic                         reset,

  // Operation Interface
  input  logic                         op_valid,
  output logic                         op_ready,
  input  logic [63:0]                  base_address,
  input  logic [63:0]                  bit_offset,
  input  logic [2:0]                   operation,  // 3'b000=GET, 3'b001=TEST, 3'b010=SET, 3'b011=CLEAR, 3'b100=TOGGLE

  // Response Interface
  output logic                         result_valid,
  output logic                         result_bit,
  output logic                         error,

  // Memory Interface (AXI-like, word-addressed)
  output logic                         mem_req_valid,
  input  logic                         mem_req_ready,
  output logic [ADDR_WIDTH-1:0]        mem_addr,
  output logic                         mem_read,
  output logic                         mem_write,
  output logic [WORD_BYTES-1:0]        mem_wstrb,
  output logic [WORD_WIDTH-1:0]        mem_wdata,

  input  logic                         mem_rvalid,
  input  logic [WORD_WIDTH-1:0]        mem_rdata,
  input  logic                         mem_fault
);

  // ===== State Machine =====
  typedef enum logic [2:0] {
    ST_IDLE,
    ST_READ_REQUEST,
    ST_READ_WAIT,
    ST_MODIFY,
    ST_WRITE_REQUEST,
    ST_WRITE_WAIT,
    ST_DONE
  } state_t;

  state_t current_state, next_state;

  // ===== Internal Registers =====
  logic [63:0] base_addr_reg, bit_offset_reg;
  logic [2:0]  operation_reg;
  logic [63:0] absolute_bit_address;
  logic [57:0] word_address;        // byte address / 8
  logic [5:0]  bit_index_in_word;   // bit position within 64-bit word
  logic [63:0] read_word;
  logic [63:0] modified_word;
  logic        is_modify_op;        // SET, CLEAR, TOGGLE

  // ===== Combinational: Address Calculation =====

  // absolute_bit_address = (base_address × 8) + bit_offset
  logic [127:0] temp_addr;
  assign temp_addr = {1'b0, base_addr_reg} * 8 + {1'b0, bit_offset_reg};

  // Truncate to 64-bit (overflow handling)
  assign absolute_bit_address = temp_addr[63:0];

  // word_address = absolute_bit_address / 64 (right-shift by 6)
  assign word_address = absolute_bit_address[63:6];

  // bit_index_in_word = absolute_bit_address % 64
  assign bit_index_in_word = absolute_bit_address[5:0];

  // Convert word address to byte address for memory interface
  // word_address is already in 64-bit word units, multiply by 8 for byte address
  assign mem_addr = {word_address, 3'b000};  // Shift left by 3 (multiply by 8)

  // Check if operation is a modify operation
  assign is_modify_op = (operation_reg == 3'b010) ||  // SET
                        (operation_reg == 3'b011) ||  // CLEAR
                        (operation_reg == 3'b100);    // TOGGLE

  // ===== Submodules =====

  bit_extractor bit_extractor_inst (
    .word_data    (read_word),
    .bit_index    (bit_index_in_word),
    .field_width  (6'h1),
    .is_multibit  (1'b0),
    .result       ()  // Not used directly, result_bit comes from shift+AND
  );

  bit_modifier bit_modifier_inst (
    .word_data    (read_word),
    .bit_index    (bit_index_in_word),
    .operation    (operation_reg),
    .result       (modified_word)
  );

  // ===== Result Extraction (Combinational) =====
  logic [63:0] shifted_for_result;
  assign shifted_for_result = read_word >> bit_index_in_word;

  // ===== State Machine: Sequential =====

  always_ff @(posedge clk or negedge reset) begin
    if (!reset) begin
      current_state <= ST_IDLE;
      base_addr_reg <= 64'h0;
      bit_offset_reg <= 64'h0;
      operation_reg <= 3'h0;
      read_word <= 64'h0;
      result_valid <= 1'b0;
      result_bit <= 1'b0;
      error <= 1'b0;
    end else begin
      current_state <= next_state;
      result_valid <= 1'b0;
      error <= 1'b0;

      if (op_valid && op_ready) begin
        base_addr_reg <= base_address;
        bit_offset_reg <= bit_offset;
        operation_reg <= operation;
      end

      if (mem_rvalid && current_state == ST_READ_WAIT) begin
        read_word <= mem_rdata;
      end

      if (mem_fault) begin
        error <= 1'b1;
        result_valid <= 1'b1;
      end
    end
  end

  // ===== State Machine: Combinational Next-State Logic =====

  always_comb begin
    next_state = current_state;
    op_ready = 1'b0;
    mem_req_valid = 1'b0;
    mem_read = 1'b0;
    mem_write = 1'b0;
    mem_wstrb = 8'h00;
    mem_wdata = 64'h0;

    case (current_state)
      ST_IDLE: begin
        op_ready = 1'b1;
        if (op_valid) begin
          next_state = ST_READ_REQUEST;
        end
      end

      ST_READ_REQUEST: begin
        mem_req_valid = 1'b1;
        mem_read = 1'b1;
        if (mem_req_ready) begin
          next_state = ST_READ_WAIT;
        end
      end

      ST_READ_WAIT: begin
        if (mem_rvalid) begin
          if (is_modify_op) begin
            next_state = ST_MODIFY;
          end else begin
            next_state = ST_DONE;
          end
        end
        if (mem_fault) begin
          next_state = ST_DONE;
        end
      end

      ST_MODIFY: begin
        next_state = ST_WRITE_REQUEST;
      end

      ST_WRITE_REQUEST: begin
        mem_req_valid = 1'b1;
        mem_write = 1'b1;
        mem_wstrb = 8'hFF;  // All 8 bytes of the 64-bit word
        mem_wdata = modified_word;
        if (mem_req_ready) begin
          next_state = ST_WRITE_WAIT;
        end
      end

      ST_WRITE_WAIT: begin
        // For write operations, we don't wait for a write response in this simple model
        // Assume write completes immediately after acceptance
        next_state = ST_DONE;
      end

      ST_DONE: begin
        result_valid = 1'b1;
        result_bit = shifted_for_result[0];
        next_state = ST_IDLE;
      end

      default: next_state = ST_IDLE;
    endcase
  end

endmodule : bit_accelerator