summaryrefslogtreecommitdiffhomepage
path: root/source/cam.v
diff options
context:
space:
mode:
Diffstat (limited to 'source/cam.v')
-rw-r--r--source/cam.v85
1 files changed, 85 insertions, 0 deletions
diff --git a/source/cam.v b/source/cam.v
new file mode 100644
index 0000000..082194a
--- /dev/null
+++ b/source/cam.v
@@ -0,0 +1,85 @@
+/*
+ * cam.v
+ *
+ * Copyright (C) 2018, 2019 Mind Chasers Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * function: single cycle, parameterized CAM
+ *
+ */
+
+`timescale 1ns /10ps
+
+module cam #(parameter DEPTH = 4,
+ parameter DEPTHW = 2,
+ parameter WIDTH = 32)
+(
+ input rstn,
+ input clk,
+
+ // input for programming
+ input sel,
+ input we,
+ input [DEPTHW+1:0] addr, // add two bits for the byte selects
+ input [7:0] d_in,
+
+ input search,
+ input [(WIDTH-1):0]search_address,
+
+ // output
+ output reg match
+);
+
+ reg [(WIDTH-1):0] content[0:DEPTH-1];
+ reg [(DEPTH-1):0] valid;
+ integer i,j;
+
+ // Program the CAM
+ always @(posedge clk, negedge rstn)
+ if( !rstn ) begin
+ for (i=0; i < DEPTH; i=i+1) begin
+ content[i] <= 32'h0;
+ valid[i] <= 1'b0;
+ end
+ end
+ else if ( we && sel )
+ if (addr[1:0] == 2'b00) begin
+ content[addr[DEPTHW+1:2]][7:0] <= d_in;
+ valid[addr[DEPTHW+1:2]] <= 1'b1;
+ end
+ else if (addr[1:0] == 2'b01) begin
+ content[addr[DEPTHW+1:2]][15:8] <= d_in;
+ valid[addr[DEPTHW+1:2]] <= 1'b1;
+ end
+ else if (addr[1:0] == 2'b10) begin
+ content[addr[DEPTHW+1:2]][23:16] <= d_in;
+ valid[addr[DEPTHW+1:2]] <= 1'b1;
+ end
+ else if (addr[1:0] == 2'b11) begin
+ content[addr[DEPTHW+1:2]][31:24] <= d_in;
+ valid[addr[DEPTHW+1:2]] <= 1'b1;
+ end
+
+ // search the CAM
+ always @(posedge clk) begin
+ match <= 1'b0;
+ for (j=0; j < DEPTH; j=j+1) begin
+ if (search && valid[j] && search_address == content[j])
+ match <= 1'b1;
+
+ end
+ end
+
+
+endmodule