Download rtl/bit_accelerator.sv from Snapkitty/bit-string-accelerator: direct link, hf CLI and curl.
- Browser
- Download file 3.9 kB
-
https://huggingface.co/Snapkitty/bit-string-accelerator/resolve/main/rtl/bit_accelerator.sv
- Command line
-
hf download hf://Snapkitty/bit-string-accelerator/rtl/bit_accelerator.sv
-
curl -L -o bit_accelerator.sv https://huggingface.co/Snapkitty/bit-string-accelerator/resolve/main/rtl/bit_accelerator.sv
3.9 kB
| // Bit-string accelerator: one GET/TEST/SET/CLEAR/TOGGLE per operation on a | |
| // 64-bit-word memory. See docs/verification.md for the interface contract. | |
| // | |
| // effective_bit = (base_address << 3) + bit_offset (mod 2^64) | |
| // mem_addr = (effective_bit >> 6) << 3 (8-byte aligned) | |
| // bit index = effective_bit[5:0] (LSB-first) | |
| // | |
| // result_valid is a one-cycle pulse; error and result_bit are valid in that | |
| // same cycle. On error, result_bit holds its previous value. | |
| module bit_accelerator #( | |
| parameter int ADDR_W=64, | |
| parameter int WORD_W=64 | |
| )( | |
| input logic clk,input logic reset, | |
| input logic op_valid, output logic op_ready, | |
| input logic [ADDR_W-1:0] base_address, | |
| input logic [63:0] bit_offset, | |
| input logic [2:0] operation, | |
| output logic result_valid, output logic result_bit, output logic error, | |
| output logic mem_valid, output logic mem_write, | |
| output logic [ADDR_W-1:0] mem_addr, | |
| output logic [WORD_W-1:0] mem_wdata, | |
| output logic [WORD_W/8-1:0] mem_wstrb, | |
| input logic mem_ready, input logic mem_rvalid, | |
| input logic [WORD_W-1:0] mem_rdata, input logic mem_fault | |
| ); | |
| localparam logic [2:0] OP_GET=3'b000, OP_TEST=3'b001, OP_SET=3'b010, | |
| OP_CLEAR=3'b011, OP_TOGGLE=3'b100; | |
| typedef enum logic [2:0] {IDLE,READ_REQ,READ_WAIT,WRITE_REQ,WRITE_WAIT,RESP} state_t; | |
| state_t state; | |
| logic [ADDR_W-1:0] req_addr; | |
| logic [63:0] eff_bit; | |
| logic [5:0] bit_idx_q; | |
| logic err_q; // error latched during the operation, reported with result_valid | |
| logic [2:0] op_q; | |
| logic old_bit_q; | |
| logic [WORD_W-1:0] new_word_q; | |
| logic [WORD_W-1:0] shifted_one; | |
| assign op_ready = (state == IDLE) && !reset; | |
| assign mem_valid = (state == READ_REQ || state == WRITE_REQ); | |
| assign mem_write = (state == WRITE_REQ); | |
| assign mem_addr = req_addr; | |
| assign mem_wdata = new_word_q; | |
| assign mem_wstrb = {WORD_W/8{1'b1}}; | |
| assign shifted_one = ({{(WORD_W-1){1'b0}},1'b1} << bit_idx_q); | |
| assign eff_bit = (64'(base_address) << 3) + bit_offset; | |
| always_ff @(posedge clk) begin | |
| if (reset) begin | |
| state <= IDLE; result_valid <= 1'b0; result_bit <= 1'b0; error <= 1'b0; | |
| req_addr <= '0; bit_idx_q <= '0; err_q <= 1'b0; | |
| op_q <= OP_GET; old_bit_q <= 1'b0; new_word_q <= '0; | |
| end else begin | |
| result_valid <= 1'b0; error <= 1'b0; | |
| case (state) | |
| IDLE: if (op_valid) begin | |
| op_q <= operation; | |
| err_q <= 1'b0; | |
| bit_idx_q <= eff_bit[5:0]; | |
| req_addr <= ADDR_W'((eff_bit >> 6) << 3); | |
| state <= READ_REQ; | |
| end | |
| READ_REQ: if (mem_ready) state <= READ_WAIT; | |
| READ_WAIT: if (mem_fault) begin err_q <= 1'b1; state <= RESP; end | |
| else if (mem_rvalid) begin | |
| old_bit_q <= mem_rdata[bit_idx_q]; | |
| case (op_q) | |
| OP_GET, OP_TEST: state <= RESP; | |
| OP_SET: begin new_word_q <= mem_rdata | shifted_one; state <= WRITE_REQ; end | |
| OP_CLEAR: begin new_word_q <= mem_rdata & ~shifted_one; state <= WRITE_REQ; end | |
| OP_TOGGLE: begin new_word_q <= mem_rdata ^ shifted_one; state <= WRITE_REQ; end | |
| default: begin err_q <= 1'b1; state <= RESP; end | |
| endcase | |
| end | |
| WRITE_REQ: if (mem_ready) state <= WRITE_WAIT; | |
| WRITE_WAIT: begin | |
| if (mem_fault) err_q <= 1'b1; | |
| state <= RESP; | |
| end | |
| RESP: begin | |
| result_valid <= 1'b1; | |
| error <= err_q; | |
| if (!err_q) begin | |
| case (op_q) | |
| OP_GET, OP_TEST: result_bit <= old_bit_q; | |
| OP_SET: result_bit <= 1'b1; | |
| OP_CLEAR: result_bit <= 1'b0; | |
| OP_TOGGLE: result_bit <= ~old_bit_q; | |
| default: result_bit <= 1'b0; | |
| endcase | |
| end | |
| state <= IDLE; | |
| end | |
| default: state <= IDLE; | |
| endcase | |
| end | |
| end | |
| endmodule | |