diff --git a/Readme.rst b/Readme.rst
new file mode 100644
index 0000000..1cd7dda
--- /dev/null
+++ b/Readme.rst
@@ -0,0 +1,28 @@
+OpenOFDM
+========
+
+This project contains a Verilog implementation of 802.11 OFDM PHY decoder.
+Features are:
+
+ - Fully synthesizable (tested on Ettus Research USRP N210 platform)
+ - Full support for legacy 802.11a/g
+ - Support 802.11n for MCS 0 - 7 @ 20 MHz bandwidth
+ - Cross validation with included Python decoder
+
+
+Environment Setup
+-----------------
+
+This project has the following dependencies:
+
+ - `Icarus Verilog `_: for compiling Verilog files and simulation.
+ - `GtkWave `_: for wave form visualization.
+
+
+Input and Output
+----------------
+
+In a nutshell, the top level ``dot11`` Verilog module takes 32-bit I/Q samples
+(16-bit each) as input, and output decoded bytes in 802.11 packet. The sampling
+rate is 20 MSPS and the clock rate is 100 MHz. This means this module expects
+one pair of I/Q sample every 5 clock ticks.
diff --git a/scripts/policy.py b/scripts/policy.py
deleted file mode 100755
index 094bcd5..0000000
--- a/scripts/policy.py
+++ /dev/null
@@ -1,267 +0,0 @@
-#!/usr/bin/env python
-
-
-import os
-import argparse
-import jsonschema
-import json
-import itertools
-
-MCS_MAX = 7
-LENGTH_MAX = 4095
-
-MAX_ACTION_LEN = 256
-
-HEADER_LEN = 16
-
-SR_RATE_FILTER = 7
-SR_LEN_FILTER = 8
-SR_HEADER_FILTER = 9
-SR_HEADER_LEN =10
-SR_JAM_POLICY = 11
-
-POLICY_JSON_SCHEMA = """
-{
- "title": "Jamming Policy Format Specification",
- "type": "array",
- "items": {
- "$ref": "#/definitions/policy"
- },
- "minItems": 1,
- "additionalProperties": false,
- "definitions": {
- "policy": {
- "type": "object",
- "properties": {
- "length": {
- "type": "integer",
- "minimum": 0,
- "maximum": 4095
- },
- "length_min": {
- "type": "integer",
- "minimum": 0,
- "maximum": 4095
- },
- "length_max": {
- "type": "integer",
- "minimum": 0,
- "maximum": 4095
- },
-
- "mcs": {
- "type": "integer",
- "minimum": 0,
- "maximum": 7
- },
- "mcs_min": {
- "type": "integer",
- "minimum": 0,
- "maximum": 7
- },
- "mcs_max": {
- "type": "integer",
- "minimum": 0,
- "maximum": 7
- },
-
- "header": {
- "type": "string",
- "maxLength": 47
- },
- "actions": {
- "type": "array",
- "minItems": 1,
- "maxItems": 256,
- "items": {
- "type": "string",
- "enum": ["Jam", "Pass", "JamAck"]
- }
- }
- },
- "additionalProperties": false
- }
- },
- "$schema": "http://json-schema.org/draft-04/schema#"
-}
-"""
-
-
-def arg_parser():
- parser = argparse.ArgumentParser()
- parser.add_argument('file', help="JSON file that contains the policy")
- parser.add_argument('--out', help="Output file")
- return parser
-
-
-def check_policy(args):
- for policy in args.policies:
- if 'length' in policy and ('length_min' in policy or
- 'length_max' in policy):
- print "[ERROR] Policy can not contain both exact and range "\
- "quantifiers for length"
- return False
-
- if 'mcs' in policy and ('mcs_min' in policy or 'mcs_max' in policy):
- print "[ERROR] Policy can not contain both exact and range "\
- "quantifiers for mcs"
- return False
-
- return True
-
-
-def make_canonical(args):
- for policy in args.policies:
- has_mcs = any([k.startswith('mcs') for k in policy])
- has_length = any([k.startswith('length') for k in policy])
- has_header = 'header' in policy
-
- if has_mcs:
- if 'mcs' in policy:
- policy['mcs_min'] = policy['mcs']
- policy['mcs_max'] = policy['mcs']
- del policy['mcs']
-
- if 'mcs_min' not in policy:
- policy['mcs_min'] = 0
-
- if 'mcs_max' not in policy:
- policy['mcs_max'] = MCS_MAX
-
- policy['mcs_weight'] = 3
- if has_length:
- policy['mcs_weight'] -= 1
- if has_header:
- policy['mcs_weight'] -= 1
- else:
- policy['mcs_min'] = MCS_MAX
- policy['mcs_max'] = 0
- policy['mcs_weight'] = 0
-
- if has_length:
- if 'length' in policy:
- policy['length_min'] = policy['length']
- policy['length_max'] = policy['length']
- del policy['length']
-
- if 'length_min' not in policy:
- policy['length_min'] = 0
-
- if 'length_max' not in policy:
- policy['length_max'] = LENGTH_MAX
-
- policy['length_weight'] = 3 - policy['mcs_weight']
- if has_header:
- policy['mcs_weight'] -= 1
- else:
- policy['length_min'] = LENGTH_MAX
- policy['length_max'] = 0
- policy['length_weight'] = 0
-
- if has_header:
- bytes = []
- for s in policy['header'].split():
- if s == 'xx':
- bytes.append(0x1ff)
- else:
- bytes.append(int(s, 16))
- policy['header'] = bytes
- else:
- policy['header'] = []
-
- iter = itertools.cycle(policy['actions'])
- for _ in range(MAX_ACTION_LEN-len(policy['actions'])):
- policy['actions'].append(iter.next())
-
- args.max_header_len = max([len(p['header']) for p in args.policies])
- for policy in args.policies:
- for _ in range(args.max_header_len - len(policy['header'])):
- policy['header'].append(0x1ff)
-
- cano_file = '_canonical'.join(os.path.splitext(args.file))
- with open(cano_file, 'w') as f:
- f.write(json.dumps(args.policies, indent=2))
-
-
-def translate(args):
- rate_data = []
- len_data = []
- header_data = []
- action_data = []
-
- for id, policy in enumerate(args.policies):
- val = (id<<28) + (policy['mcs_min']<<6) + (policy['mcs_max']<<2) +\
- (policy['mcs_weight']&0x3)
- rate_data.append(val)
-
- val = (id<<28) + (policy['length_min']<<14) +\
- (policy['length_max']<<2) + (policy['length_weight']&0x3)
- len_data.append(val)
-
- for addr, b in enumerate(policy['header']):
- val = (id<<28) + (addr<<23) + (b&0x1ff)
- header_data.append(val)
-
- for addr, a in enumerate(policy['actions']):
- val = (id<<28) + (addr<<20)
- if a == 'Jam':
- val += 1
- elif a == 'Pass':
- val += 0
- elif a == 'JamAck':
- val += 2
- action_data.append(val)
-
- with open(args.out, 'w') as f:
- f.write('0x%x\n' % (SR_RATE_FILTER))
- f.write('0x%x\n' % (len(rate_data)))
- for d in rate_data:
- f.write('0x%08x\n' % (d))
-
- f.write('0x%x\n' % (SR_LEN_FILTER))
- f.write('0x%x\n' % (len(len_data)))
- for d in len_data:
- f.write('0x%08x\n' % (d))
-
- f.write('0x%x\n' % (SR_HEADER_FILTER))
- f.write('0x%x\n' % (len(header_data)))
- for d in header_data:
- f.write('0x%08x\n' % (d))
-
- f.write('0x%x\n' % (SR_HEADER_LEN))
- f.write('0x1\n')
- f.write('0x%x\n' % (args.max_header_len))
-
- f.write('0x%x\n' % (SR_JAM_POLICY))
- f.write('0x%x\n' % (len(action_data)))
- for d in action_data:
- f.write('0x%08x\n' % (d))
-
- print "Jam file written to %s" % (args.out)
-
-
-def main():
- args = arg_parser().parse_args()
-
- if args.out is None:
- args.out = "%s.jam" % (os.path.splitext(args.file)[0])
- print "No output file specified, using %s" % (args.out)
-
- schema = json.loads(POLICY_JSON_SCHEMA)
-
- with open(args.file, 'r') as f:
- args.policies = json.loads(f.read())
-
- print "Validating policy ..."
- jsonschema.validate(args.policies, schema)
-
- if not check_policy(args):
- return
-
- print "Making canonical policy..."
- make_canonical(args)
-
- translate(args)
-
-if __name__ == '__main__':
- main()
diff --git a/scripts/policy_schema.json b/scripts/policy_schema.json
deleted file mode 100644
index 0995e50..0000000
--- a/scripts/policy_schema.json
+++ /dev/null
@@ -1,63 +0,0 @@
-{
- "title": "Jamming Policy Format Specification",
- "type": "array",
- "items": {
- "$ref": "#/definitions/policy"
- },
- "minItems": 1,
- "additionalProperties": false,
- "definitions": {
- "policy": {
- "type": "object",
- "properties": {
- "length": {
- "type": "integer",
- "minimum": 0,
- "maximum": 4095
- },
- "length_min": {
- "type": "integer",
- "minimum": 0,
- "maximum": 4095
- },
- "length_max": {
- "type": "integer",
- "minimum": 0,
- "maximum": 4095
- },
-
- "mcs": {
- "type": "integer",
- "minimum": 0,
- "maximum": 7
- },
- "mcs_min": {
- "type": "integer",
- "minimum": 0,
- "maximum": 7
- },
- "mcs_max": {
- "type": "integer",
- "minimum": 0,
- "maximum": 7
- },
-
- "header": {
- "type": "string",
- "maxLength": 47
- },
- "actions": {
- "type": "array",
- "minItems": 1,
- "maxItems": 256,
- "items": {
- "type": "string",
- "enum": ["Jam", "Pass", "JamAck"]
- }
- }
- },
- "additionalProperties": false
- }
- },
- "$schema": "http://json-schema.org/draft-04/schema#"
-}
diff --git a/verilog/common_params.v b/verilog/common_params.v
index 1392a70..6f7e82a 100644
--- a/verilog/common_params.v
+++ b/verilog/common_params.v
@@ -1,14 +1,3 @@
-//////////////////////////////////////////////////////////////////////////
-// JAM FILTER STATUS
-//////////////////////////////////////////////////////////////////////////
-localparam FILTER_NO_MATCH = 0;
-localparam FILTER_MATCH_PASS = 1;
-localparam FILTER_MATCH_JAM = 2;
-localparam FILTER_MATCH_JAM_ACK = 3;
-localparam FILTER_RATIO_PASS = 4;
-localparam FILTER_RATIO_JAM = 5;
-
-
//////////////////////////////////////////////////////////////////////////
// PI DEFINITION
//////////////////////////////////////////////////////////////////////////
@@ -24,9 +13,6 @@ localparam PI_3_4 = PI_2 + PI_4;
//////////////////////////////////////////////////////////////////////////
// USER REG DEFINITION
//////////////////////////////////////////////////////////////////////////
-localparam SR_JAMMER_ENABLE = 1;
-localparam SR_JAMMER_RESET = 2;
-
// power trigger
localparam SR_POWER_THRES = 3;
localparam SR_POWER_WINDOW = 4;
@@ -35,15 +21,6 @@ localparam SR_SKIP_SAMPLE = 5;
// sync short
localparam SR_MIN_PLATEAU = 6;
-// filter
-localparam SR_RATE_FILTER = 7;
-localparam SR_LEN_FILTER = 8;
-localparam SR_HEADER_FILTER = 9;
-localparam SR_HEADER_LEN = 10;
-localparam SR_JAM_POLICY = 11;
-
-localparam SR_JAM_SIGNAL = 12;
-
//////////////////////////////////////////////////////////////////////////
// DOT11 STATE MACHINE
//////////////////////////////////////////////////////////////////////////
diff --git a/verilog/dot11.v b/verilog/dot11.v
index 4ff1599..79b4c15 100644
--- a/verilog/dot11.v
+++ b/verilog/dot11.v
@@ -5,6 +5,7 @@ module dot11 (
input enable,
input reset,
+ // setting registers
input set_stb,
input [7:0] set_addr,
input [31:0] set_data,
diff --git a/verilog/xilinx_viterbi_tb.v b/verilog/xilinx_viterbi_tb.v
deleted file mode 100644
index deb4a4b..0000000
--- a/verilog/xilinx_viterbi_tb.v
+++ /dev/null
@@ -1,125 +0,0 @@
-module viterbi_tb;
-
-reg clock;
-reg reset;
-reg enable;
-
-localparam RAM_SIZE = 1<<25;
-reg encoded_data [0:RAM_SIZE-1];
-reg [31:0] encoded_data_addr;
-
-reg decoded_data [0:RAM_SIZE-1];
-reg [31:0] decoded_data_addr;
-
-wire expected = decoded_data[decoded_data_addr];
-
-reg [31:0] input_count;
-
-
-localparam ENCODED_DATA_FILE = "./test_in/conv_encoded_data.txt";
-localparam DECODED_DATA_FILE = "./test_in/conv_decoded_data.txt";
-
-reg clr;
-reg sym0;
-reg sym1;
-
-reg [31:0] error_count;
-
-wire [15:0] ber;
-wire ber_done;
-wire data_out;
-wire rdy;
-
-viterbi_v7_0 viterbi_inst (
- .clk(clock),
- .ce(1),
- .sclr(clr),
- .data_in0(sym0),
- .data_in1(sym1),
- .rdy(rdy),
- .data_out(data_out)
-);
-
-initial begin
- $dumpfile("xilinx_viterbi_tb.vcd");
- $dumpvars;
-
- $display("Reading memory from %s ...", ENCODED_DATA_FILE);
- $readmemb(ENCODED_DATA_FILE, encoded_data);
- $readmemb(DECODED_DATA_FILE, decoded_data);
- $display("Done.");
-
- clock = 0;
- reset = 1;
- enable = 0;
- clr = 1;
-
- # 100 reset = 0;
- # 100 enable = 1;
-
- # 20000 $finish;
-end
-
-
-always begin
- #1 clock = !clock;
-end
-
-localparam S_INPUT = 0;
-localparam S_FLUSH = 1;
-
-reg [3:0] state;
-
-localparam BITS_TO_DECODE = 48*6+48;
-
-
-always @(posedge clock) begin
- if (reset) begin
- sym0 <= 0;
- sym1 <= 0;
- input_count <= 0;
-
- error_count <= 0;
-
- encoded_data_addr <= 0;
- decoded_data_addr <= 0;
- state <= S_INPUT;
- end else if (enable) begin
- clr <= 0;
- case(state)
- S_INPUT: begin
- if (input_count < BITS_TO_DECODE) begin
- sym0 <= encoded_data[encoded_data_addr];
- sym1 <= encoded_data[encoded_data_addr+1];
- encoded_data_addr <= encoded_data_addr + 2;
- input_count <= input_count + 2;
- end else begin
- sym0 <= 0;
- sym1 <= 0;
- state <= S_FLUSH;
- end
- end
-
- S_FLUSH: begin
- end
- endcase
-
- if (rdy) begin
- $display("%d\t%d\t%d\t%d", decoded_data_addr, expected, data_out, error_count);
- if (data_out != expected) begin
- error_count <= error_count + 1;
- if (error_count > 500) begin
- $display("too many errors.");
- $finish;
- end
- end
- if (decoded_data_addr >= BITS_TO_DECODE/2) begin
- $finish;
- end else begin
- decoded_data_addr <= decoded_data_addr + 1;
- end
- end
- end
-end
-
-endmodule