ThatAIguyA world of ideas

THE CONSCIOUSNESS ATLAS
Read. Experiment. Follow the evidence.

ConsciousnessLearn · Explore · Joseph Anady

Janady13/AI_Brain / the_tired_agi/core/src/fpga_memory_bus.v

Source identity, revision, and recovered contents.

GitHub sourceSource text recovered

Source identity

FieldRecorded value
Source typeGitHub source
Original recordJanady13/AI_Brain / the_tired_agi/core/src/fpga_memory_bus.v
DateNot specified in source
RepositoryJanady13/AI_Brain
Revisiond6c309d3fa439714ca46b9d3bb94caf478ea5376
Branchmain
Path or archive memberthe_tired_agi/core/src/fpga_memory_bus.v
Original SHA-2562eca66be66339aba7be98a31d1b5ae0949c4bfc44feafe0df97d1d074070ca9f
Git blob SHA51d531d6d114b96742291ead5d9c53a5d9d488d9
Reading-copy SHA-2562eca66be66339aba7be98a31d1b5ae0949c4bfc44feafe0df97d1d074070ca9f

Original source ↗

Every recorded occurrence

These 2 records contain identical original source bytes. Their paths and revisions remain part of the archive.

Original recordBranch or archiveRevision / identifierOriginal location
Janady13/AI_Brain / the_tired_agi/core/src/fpga_memory_bus.vmaind6c309d3fa439714ca46b9d3bb94caf478ea5376Open original
Janady13/AI_Brain / the_tired_agi/core/src/fpga_memory_bus.vclaude/binary-helix-fibonacci-hive-011CUj7dx1WWJLVYcWCjBbYv527d4882c71eb041393f9d8945996177c5ac9e86Open original

Recovered source transcript

//============================================================================= // FPGA Memory Bus - Production Implementation // 256-bit wide memory interface with DMA support // Target: PCIe Gen3 x4 (4 GB/s), DDR3/DDR4 controller integration // Synthesizable for Lattice ECP5 / Xilinx Artix-7 //============================================================================= `timescale 1ns / 1ps module fpga_memory_bus #( parameter ADDR_WIDTH = 32, parameter DATA_WIDTH = 256, parameter ID_WIDTH = 4, parameter NUM_CHANNELS = 4, parameter FIFO_DEPTH = 512 )( input wire clk, input wire rst_n, //========================================================================= // AXI4-Style Memory Interface (to DDR controller) //========================================================================= // Write Address Channel output reg [ID_WIDTH-1:0] m_axi_awid, output reg [ADDR_WIDTH-1:0] m_axi_awaddr, output reg [7:0] m_axi_awlen, // Burst length - 1 output reg [2:0] m_axi_awsize, // Burst size output reg [1:0] m_axi_awburst, // Burst type output reg m_axi_awvalid, input wire m_axi_awready, // Write Data Channel output reg [DATA_WIDTH-1:0] m_axi_wdata, output reg [DATA_WIDTH/8-1:0] m_axi_wstrb, output reg m_axi_wlast, output reg m_axi_wvalid, input wire m_axi_wready, // Write Response Channel input wire [ID_WIDTH-1:0] m_axi_bid, input wire [1:0] m_axi_bresp, input wire m_axi_bvalid, output reg m_axi_bready, // Read Address Channel output reg [ID_WIDTH-1:0] m_axi_arid, output reg [ADDR_WIDTH-1:0] m_axi_araddr, output reg [7:0] m_axi_arlen, output reg [2:0] m_axi_arsize, output reg [1:0] m_axi_arburst, output reg m_axi_arvalid, input wire m_axi_arready, // Read Data Channel input wire [ID_WIDTH-1:0] m_axi_rid, input wire [DATA_WIDTH-1:0] m_axi_rdata, input wire [1:0] m_axi_rresp, input wire m_axi_rlast, input wire m_axi_rvalid, output reg m_axi_rready, //========================================================================= // DMA Descriptor Interface (from PCIe) //========================================================================= input wire [63:0] dma_desc_addr, // Source/dest address input wire [31:0] dma_desc_len, // Transfer length (bytes) input wire [3:0] dma_desc_channel, // Channel ID input wire dma_desc_dir, // 0=read, 1=write input wire dma_desc_valid, output reg dma_desc_ready, //========================================================================= // Channel Stream Interfaces (to ingest lanes) //========================================================================= // Channel Write (from lanes to memory) input wire [NUM_CHANNELS-1:0][DATA_WIDTH-1:0] ch_wr_data, input wire [NUM_CHANNELS-1:0][DATA_WIDTH/8-1:0] ch_wr_strb, input wire [NUM_CHANNELS-1:0] ch_wr_valid, output wire [NUM_CHANNELS-1:0] ch_wr_ready, // Channel Read (from memory to CPU) output wire [NUM_CHANNELS-1:0][DATA_WIDTH-1:0] ch_rd_data, output wire [NUM_CHANNELS-1:0] ch_rd_valid, input wire [NUM_CHANNELS-1:0] ch_rd_ready, //========================================================================= // Status and Control //========================================================================= output reg [31:0] status_bytes_written [0:NUM_CHANNELS-1], output reg [31:0] status_bytes_read [0:NUM_CHANNELS-1], output reg [NUM_CHANNELS-1:0] status_ch_busy, output reg [15:0] status_errors, input wire [NUM_CHANNELS-1:0] ctrl_ch_enable, input wire ctrl_reset_counters ); //========================================================================= // Internal State //========================================================================= localparam ST_IDLE = 3'd0; localparam ST_DESC_PARSE = 3'd1; localparam ST_ADDR_WRITE = 3'd2; localparam ST_DATA_WRITE = 3'd3; localparam ST_ADDR_READ = 3'd4; localparam ST_DATA_READ = 3'd5; localparam ST_WAIT_RESP = 3'd6; reg [2:0] state [0:NUM_CHANNELS-1]; reg [2:0] next_state [0:NUM_CHANNELS-1]; // DMA Descriptor Queue (per channel) reg [63:0] desc_addr [0:NUM_CHANNELS-1]; reg [31:0] desc_len [0:NUM_CHANNELS-1]; reg desc_dir [0:NUM_CHANNELS-1]; reg desc_valid_internal [0:NUM_CHANNELS-1]; // Transfer State reg [ADDR_WIDTH-1:0] current_addr [0:NUM_CHANNELS-1]; reg [31:0] bytes_remaining [0:NUM_CHANNELS-1]; reg [7:0] burst_count [0:NUM_CHANNELS-1]; // FIFOs for buffering wire [NUM_CHANNELS-1:0] wr_fifo_full; wire [NUM_CHANNELS-1:0] wr_fifo_empty; wire [NUM_CHANNELS-1:0] rd_fifo_full; wire [NUM_CHANNELS-1:0] rd_fifo_empty; reg [NUM_CHANNELS-1:0] wr_fifo_wr_en; reg [NUM_CHANNELS-1:0] wr_fifo_rd_en; reg [NUM_CHANNELS-1:0] rd_fifo_wr_en; reg [NUM_CHANNELS-1:0] rd_fifo_rd_en; wire [DATA_WIDTH-1:0] wr_fifo_dout [0:NUM_CHANNELS-1]; wire [DATA_WIDTH-1:0] rd_fifo_dout [0:NUM_CHANNELS-1]; // Arbitration reg [ID_WIDTH-1:0] arb_grant; reg arb_valid; //========================================================================= // DMA Descriptor Parsing //========================================================================= always @(posedge clk or negedge rst_n) begin if (!rst_n) begin dma_desc_ready <= 1'b1; end else begin if (dma_desc_valid && dma_desc_ready) begin if (dma_desc_channel < NUM_CHANNELS && ctrl_ch_enable[dma_desc_channel]) begin desc_addr[dma_desc_channel] <= dma_desc_addr; desc_len[dma_desc_channel] <= dma_desc_len; desc_dir[dma_desc_channel] <= dma_desc_dir; desc_valid_internal[dma_desc_channel] <= 1'b1; end end end end //========================================================================= // Per-Channel State Machines //========================================================================= genvar ch; generate for (ch = 0; ch < NUM_CHANNELS; ch = ch + 1) begin : channel_sm always @(posedge clk or negedge rst_n) begin if (!rst_n) begin state[ch] <= ST_IDLE; current_addr[ch] <= {ADDR_WIDTH{1'b0}}; bytes_remaining[ch] <= 32'd0; burst_count[ch] <= 8'd0; status_bytes_written[ch] <= 32'd0; status_bytes_read[ch] <= 32'd0; status_ch_busy[ch] <= 1'b0; end else begin state[ch] <= next_state[ch]; case (state[ch]) ST_IDLE: begin status_ch_busy[ch] <= 1'b0; if (desc_valid_internal[ch] && ctrl_ch_enable[ch]) begin current_addr[ch] <= desc_addr[ch][ADDR_WIDTH-1:0]; bytes_remaining[ch] <= desc_len[ch]; status_ch_busy[ch] <= 1'b1; end end ST_DESC_PARSE: begin // Calculate burst parameters // Max burst: 256 beats (AXI4) if (bytes_remaining[ch] >= (DATA_WIDTH/8 * 256)) begin burst_count[ch] <= 8'd255; // 256 beats - 1 end else begin burst_count[ch] <= (bytes_remaining[ch] / (DATA_WIDTH/8)) - 1; end end ST_ADDR_WRITE: begin if (m_axi_awready && arb_grant == ch && arb_valid) begin bytes_remaining[ch] <= bytes_remaining[ch] - ((burst_count[ch] + 1) * (DATA_WIDTH/8)); current_addr[ch] <= current_addr[ch] + ((burst_count[ch] + 1) * (DATA_WIDTH/8)); end end ST_DATA_WRITE: begin if (m_axi_wready && m_axi_wlast) begin status_bytes_written[ch] <= status_bytes_written[ch] + ((burst_count[ch] + 1) * (DATA_WIDTH/8)); end end ST_ADDR_READ: begin if (m_axi_arready && arb_grant == ch && arb_valid) begin bytes_remaining[ch] <= bytes_remaining[ch] - ((burst_count[ch] + 1) * (DATA_WIDTH/8)); current_addr[ch] <= current_addr[ch] + ((burst_count[ch] + 1) * (DATA_WIDTH/8)); end end ST_DATA_READ: begin if (m_axi_rvalid && m_axi_rlast) begin status_bytes_read[ch] <= status_bytes_read[ch] + ((burst_count[ch] + 1) * (DATA_WIDTH/8)); end end endcase // Reset counters if (ctrl_reset_counters) begin status_bytes_written[ch] <= 32'd0; status_bytes_read[ch] <= 32'd0; end end end // Next state logic always @(*) begin next_state[ch] = state[ch]; case (state[ch]) ST_IDLE: begin if (desc_valid_internal[ch] && ctrl_ch_enable[ch]) begin next_state[ch] = ST_DESC_PARSE; end end ST_DESC_PARSE: begin if (desc_dir[ch]) begin next_state[ch] = ST_ADDR_WRITE; end else begin next_state[ch] = ST_ADDR_READ; end end ST_ADDR_WRITE: begin if (m_axi_awready && arb_grant == ch) begin next_state[ch] = ST_DATA_WRITE; end end ST_DATA_WRITE: begin if (m_axi_wlast && m_axi_wready) begin next_state[ch] = ST_WAIT_RESP; end end ST_ADDR_READ: begin if (m_axi_arready && arb_grant == ch) begin next_state[ch] = ST_DATA_READ; end end ST_DATA_READ: begin if (m_axi_rlast && m_axi_rvalid) begin if (bytes_remaining[ch] > 0) begin next_state[ch] = ST_DESC_PARSE; end else begin next_state[ch] = ST_IDLE; end end end ST_WAIT_RESP: begin if (m_axi_bvalid) begin if (bytes_remaining[ch] > 0) begin next_state[ch] = ST_DESC_PARSE; end else begin next_state[ch] = ST_IDLE; end end end endcase end end endgenerate //========================================================================= // Round-Robin Arbiter for Memory Access //========================================================================= reg [ID_WIDTH-1:0] arb_last_grant; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin arb_grant <= {ID_WIDTH{1'b0}}; arb_valid <= 1'b0; arb_last_grant <= {ID_WIDTH{1'b0}}; end else begin arb_valid <= 1'b0; // Find next requester (round-robin) for (integer i = 0; i < NUM_CHANNELS; i = i + 1) begin integer idx = (arb_last_grant + i + 1) % NUM_CHANNELS; if (status_ch_busy[idx] && (state[idx] == ST_ADDR_WRITE || state[idx] == ST_ADDR_READ)) begin arb_grant <= idx[ID_WIDTH-1:0]; arb_valid <= 1'b1; arb_last_grant <= idx[ID_WIDTH-1:0]; break; end end end end //========================================================================= // AXI Master Write Address //========================================================================= always @(posedge clk or negedge rst_n) begin if (!rst_n) begin m_axi_awvalid <= 1'b0; end else begin if (arb_valid && state[arb_grant] == ST_ADDR_WRITE) begin m_axi_awid <= arb_grant; m_axi_awaddr <= current_addr[arb_grant]; m_axi_awlen <= burst_count[arb_grant]; m_axi_awsize <= $clog2(DATA_WIDTH/8); // Size = log2(bytes per beat) m_axi_awburst <= 2'b01; // INCR burst m_axi_awvalid <= 1'b1; end else if (m_axi_awready) begin m_axi_awvalid <= 1'b0; end end end //========================================================================= // AXI Master Write Data //========================================================================= reg [7:0] wr_beat_count; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin m_axi_wvalid <= 1'b0; m_axi_wlast <= 1'b0; wr_beat_count <= 8'd0; end else begin if (state[arb_grant] == ST_DATA_WRITE && !wr_fifo_empty[arb_grant]) begin m_axi_wdata <= wr_fifo_dout[arb_grant]; m_axi_wstrb <= {(DATA_WIDTH/8){1'b1}}; m_axi_wvalid <= 1'b1; m_axi_wlast <= (wr_beat_count == burst_count[arb_grant]); if (m_axi_wready) begin wr_beat_count <= wr_beat_count + 1'b1; if (m_axi_wlast) begin wr_beat_count <= 8'd0; end end end else begin m_axi_wvalid <= 1'b0; m_axi_wlast <= 1'b0; end end end //========================================================================= // AXI Master Read Address //========================================================================= always @(posedge clk or negedge rst_n) begin if (!rst_n) begin m_axi_arvalid <= 1'b0; end else begin if (arb_valid && state[arb_grant] == ST_ADDR_READ) begin m_axi_arid <= arb_grant; m_axi_araddr <= current_addr[arb_grant]; m_axi_arlen <= burst_count[arb_grant]; m_axi_arsize <= $clog2(DATA_WIDTH/8); m_axi_arburst <= 2'b01; // INCR burst m_axi_arvalid <= 1'b1; end else if (m_axi_arready) begin m_axi_arvalid <= 1'b0; end end end //========================================================================= // AXI Master Read Data //========================================================================= always @(posedge clk or negedge rst_n) begin if (!rst_n) begin m_axi_rready <= 1'b1; end else begin // Always ready to receive (buffered in FIFOs) m_axi_rready <= !rd_fifo_full[m_axi_rid]; end end //========================================================================= // Write Response Handling //========================================================================= always @(posedge clk or negedge rst_n) begin if (!rst_n) begin m_axi_bready <= 1'b1; status_errors <= 16'd0; end else begin if (m_axi_bvalid) begin if (m_axi_bresp != 2'b00) begin // OKAY response = 2'b00 status_errors <= status_errors + 1'b1; end end end end //========================================================================= // Channel FIFOs (for data buffering) //========================================================================= generate for (ch = 0; ch < NUM_CHANNELS; ch = ch + 1) begin : channel_fifos // Write FIFO (from ingest lanes to memory) sync_fifo #( .DATA_WIDTH(DATA_WIDTH), .DEPTH(FIFO_DEPTH) ) wr_fifo_inst ( .clk(clk), .rst_n(rst_n), .wr_en(ch_wr_valid[ch] && ch_wr_ready[ch]), .din(ch_wr_data[ch]), .full(wr_fifo_full[ch]), .rd_en(wr_fifo_rd_en[ch]), .dout(wr_fifo_dout[ch]), .empty(wr_fifo_empty[ch]) ); assign ch_wr_ready[ch] = !wr_fifo_full[ch]; assign wr_fifo_rd_en[ch] = (state[ch] == ST_DATA_WRITE) && m_axi_wready && !wr_fifo_empty[ch]; // Read FIFO (from memory to CPU) sync_fifo #( .DATA_WIDTH(DATA_WIDTH), .DEPTH(FIFO_DEPTH) ) rd_fifo_inst ( .clk(clk), .rst_n(rst_n), .wr_en(m_axi_rvalid && m_axi_rid == ch && !rd_fifo_full[ch]), .din(m_axi_rdata), .full(rd_fifo_full[ch]), .rd_en(ch_rd_ready[ch] && !rd_fifo_empty[ch]), .dout(rd_fifo_dout[ch]), .empty(rd_fifo_empty[ch]) ); assign ch_rd_data[ch] = rd_fifo_dout[ch]; assign ch_rd_valid[ch] = !rd_fifo_empty[ch]; end endgenerate endmodule //============================================================================= // Synchronous FIFO (parameterized) //============================================================================= module sync_fifo #( parameter DATA_WIDTH = 256, parameter DEPTH = 512, parameter ADDR_WIDTH = $clog2(DEPTH) )( input wire clk, input wire rst_n, input wire wr_en, input wire [DATA_WIDTH-1:0] din, output reg full, input wire rd_en, output reg [DATA_WIDTH-1:0] dout, output reg empty ); reg [DATA_WIDTH-1:0] mem [0:DEPTH-1]; reg [ADDR_WIDTH:0] wr_ptr; // Extra bit for full/empty detection reg [ADDR_WIDTH:0] rd_ptr; wire [ADDR_WIDTH:0] next_wr_ptr = wr_ptr + 1'b1; wire [ADDR_WIDTH:0] next_rd_ptr = rd_ptr + 1'b1; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin wr_ptr <= {(ADDR_WIDTH+1){1'b0}}; rd_ptr <= {(ADDR_WIDTH+1){1'b0}}; full <= 1'b0; empty <= 1'b1; end else begin // Write if (wr_en && !full) begin mem[wr_ptr[ADDR_WIDTH-1:0]] <= din; wr_ptr <= next_wr_ptr; end // Read if (rd_en && !empty) begin dout <= mem[rd_ptr[ADDR_WIDTH-1:0]]; rd_ptr <= next_rd_ptr; end // Update flags full <= (next_wr_ptr[ADDR_WIDTH] != rd_ptr[ADDR_WIDTH]) && (next_wr_ptr[ADDR_WIDTH-1:0] == rd_ptr[ADDR_WIDTH-1:0]); empty <= (wr_ptr == rd_ptr); end end endmodule

Search equations, builds, manuscript text, and recovered sources.