URL
https://opencores.org/ocsvn/wiegand_ctl/wiegand_ctl/trunk
Subversion Repositories wiegand_ctl
Compare Revisions
- This comparison shows the changes necessary to convert path
/wiegand_ctl/trunk
- from Rev 3 to Rev 4
- ↔ Reverse comparison
Rev 3 → Rev 4
/rtl/verilog/wiegand_defines.v
0,0 → 1,104
////////////////////////////////////////////////////////////////////// |
//// //// |
//// wiegand_defines.v //// |
//// //// |
//// //// |
//// This file is part of the Wiegand Controller //// |
//// http://www.opencores.org/projects/wiegand/ //// |
//// //// |
//// //// |
//// Author(s): //// |
//// Jeff Anderson //// |
//// jeaander@opencores.org //// |
//// //// |
//// //// |
//// All additional information is available in the README.txt //// |
//// file. //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2013 Authors //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// Revisions at end of file |
// |
|
/********************** WISHBONE DEFINES ***************************/ |
// define the WB bus width; uncomment ONE correct width |
//`define WB_WIDTH64 |
`define WB_WIDTH32 |
//`define WB_WIDTH16 |
//`define WB_WIDTH08 |
|
|
`ifdef WB_WIDTH64 |
`define WB_WIDTH 64 |
`define WIEGAND_WIDTH64 |
`elsif WB_WIDTH32 |
`define WB_WIDTH 32 |
`define WIEGAND_WIDTH32 |
`elsif WB_WIDTH16 |
`define WB_WIDTH 16 |
`define WIEGAND_WIDTH16 |
`else |
`define WB_WIDTH 8 |
`define WIEGAND_WIDTH8 |
`endif |
|
//define the width of WB address |
`define WB_ADDR_WIDTH 6 |
|
/*********************** WIEGAND DEFINES *****************************/ |
//WIEGAND_WIDTH defined above |
|
//define depth of FIFO for 64-bit message format; largest message I've seen in open literature; 64/`WB_WIDTH |
`define WIEGAND_FIFODEPTH 2 |
|
//uncomment a single implementation of FIFO; |
`define WIEGAND_CUSTOMFIFO |
|
//set to base address of controller; base address is data FIFO, and the config registers are relative to it |
`define WIEGAND_ADDR 6'h01 |
|
`define WB_CNFG_PW `WIEGAND_ADDR+1 |
`define WB_CNFG_P2P `WIEGAND_ADDR+2 |
`define WB_CNFG_MSGSIZE `WIEGAND_ADDR+3 |
|
//states in teh state machine |
`define ZERO 3'b111 |
`define ONE 3'b100 |
`define IDLE 3'b000 |
`define DATA 3'b001 |
`define TX 3'b101 |
`define DONE 3'b110 |
|
|
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: $ |
// |
/rtl/verilog/wiegand_tx_top.v
0,0 → 1,221
////////////////////////////////////////////////////////////////////// |
//// //// |
//// wiegand_tx_top.v //// |
//// //// |
//// //// |
//// This file is part of the Wiegand Protocol Controller //// |
//// Wiegand Transmitter IP core //// |
//// http://www.opencores.org/projects/wiegand/ //// |
//// //// |
//// //// |
//// Author(s): //// |
//// Jeff Anderson //// |
//// jeaander@opencores.org //// |
//// //// |
//// //// |
//// All additional information is available in the README.txt //// |
//// file. //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2014 Authors //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// Revisions at end of file |
// |
|
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
`include "wiegand_defines.v" |
|
module wiegand_tx_top( |
|
one_o, |
zero_o, |
|
wb_clk_i, |
wb_rst_i, |
wb_dat_i, |
wb_dat_o, |
wb_cyc_i, |
wb_stb_i, |
wb_we_i, |
wb_adr_i, |
wb_ack_o, |
wb_err_o, |
wb_rty_o |
); |
//to PHY layer |
output reg one_o; |
output reg zero_o; |
|
//wishbone interface |
input wb_clk_i; |
input wb_rst_i; |
input [`WB_WIDTH-1:0] wb_dat_i; |
output [`WB_WIDTH-1:0] wb_dat_o; |
input wb_cyc_i; |
input wb_stb_i; |
input wb_we_i; |
input [`WB_ADDR_WIDTH-1:0] wb_adr_i; |
output wb_ack_o; |
output wb_err_o; |
output wb_rty_o; |
|
//intermediate signals |
wire rst; |
|
wire [`WB_ADDR_WIDTH-1:0] pulsewidth; |
wire [(`WB_ADDR_WIDTH/2)-1:0] sampleCnt; |
wire [`WB_ADDR_WIDTH-1:0] p2p; |
reg [1000:0] p2pCnt; |
wire [6:0] msgLength; |
reg [31:0] word_out; |
reg [2:0] state, next_state; |
reg [1:0] zero_edge, one_edge; |
wire zero_det, one_det; |
wire clk; |
reg lock_cfg; |
reg zero,one, tx, data, done; |
reg [`WB_ADDR_WIDTH-1:0] pulseCnt; |
reg [6:0] bitCount; |
wire start_tx; |
wire [`WB_WIDTH-1:0] data_o; |
|
/***************************** TX logic *********************************************************/ |
//output registers clocked directly from the state machine |
always @(negedge clk or posedge rst) begin |
if (rst) begin |
one_o <= 1'b1; |
zero_o <= 1'b1; |
end |
else begin |
one_o <= one; |
zero_o <= zero; |
end |
end |
|
//counters enabled by state machine for programmable wiegand timing |
|
//pulse to pulse timing |
always @(negedge clk or posedge rst) begin |
if (rst) p2pCnt <= 5'h0; |
else if (tx) p2pCnt <= p2pCnt+1; |
else p2pCnt <= 5'h0; |
end |
|
//pulse width timer |
always @(negedge clk or posedge rst) begin |
if (rst) pulseCnt <= 5'h0; |
else if (zero | one) pulseCnt <= pulseCnt+1; |
else pulseCnt <= 5'h0; |
end |
|
//message bit counter |
always @(negedge clk or posedge rst) begin |
if (rst) bitCount <= 5'h0; |
else if (done) bitCount <= bitCount+1; |
else bitCount <= 5'h0; |
end |
|
//main state machine for transmitter |
always @(posedge clk or posedge rst) begin |
if (rst) state <= `IDLE; |
else state <= next_state; |
end |
|
always @ (*) begin |
next_state = `IDLE; |
zero = 1'b1; |
one = 1'b1; |
tx = 1'b0; |
data = 1'b0; |
done = 1'b0; |
case (state) |
`IDLE: begin |
if (start_tx) next_state = `DATA; |
else next_state = `IDLE; |
end |
`DATA: begin |
data = 1'b1; |
next_state = `TX; |
end |
`TX: begin |
tx = 1'b1; |
if (bitCount > msgLength) next_state = `IDLE; |
else if (bitCount == 6'd31) next_state = `DATA; |
else if (word_out[31] && (p2pCnt == p2p)) next_state = `ONE; |
else if (~word_out[31] && (p2pCnt == p2p)) next_state = `ZERO; |
else next_state = `TX; |
end |
`ONE: begin |
one = 1'b0; |
if (pulseCnt == pulsewidth) next_state = `DONE; |
else next_state = `ONE; |
end |
`ZERO: begin |
zero = 1'b0; |
if (pulseCnt == pulsewidth) next_state = `DONE; |
else next_state = `ZERO; |
end |
`DONE: begin |
done = 1'b1; |
next_state = `TX; |
end |
endcase |
end |
|
//dont want config being changed during a write cycle |
always @(negedge clk or posedge rst) begin |
if (rst) lock_cfg <= 1'b0; |
else lock_cfg <= tx | done | one | zero | data; |
end |
|
/***************************** output FIFO *******************************************************/ |
always @(posedge clk or posedge rst) begin |
if (rst) word_out <= 32'h0; |
else if (data) word_out <= data_o; |
else if (done) word_out <= {word_out[30:0],1'b0}; |
end |
|
fifo_wieg datafifowrite(wb_clk_i,wb_clk_i,wb_data_i,data_o,rst,wb_wr_en,wei_rd_en,full,empty); |
|
|
/***************************** WB interface *******************************************************/ |
wb_interface_wieg wb_interface(wb_rst_i,wb_clk_i,wb_stb_i,wb_ack_o,wb_addr_i,wb_we_i,data_o,wb_sel_i, |
wb_dat_o,wb_cyc_i,wb_cti_i,wb_err_o,wb_rty_o,rst,wb_dat_o,start_tx,size, |
p2p,msg_done,clk,latchData,emptyWrite,lock_cfg); |
|
|
endmodule |
|
//////////////////////////////////////////////////////////////////// |
// CVS Revision History |
// |
// $Log: $ |
// |
/rtl/verilog/fifos.v.bak
0,0 → 1,227
////////////////////////////////////////////////////////////////////// |
//// //// |
//// fifos.v //// |
//// //// |
//// //// |
//// This file is part of the Time Triggered Protocol Controller //// |
//// http://www.opencores.org/projects/wiegand/ //// |
//// //// |
//// //// |
//// Author(s): //// |
//// Jeff Anderson //// |
//// jeaander@opencores.org //// |
//// //// |
//// //// |
//// All additional information is available in the README.txt //// |
//// file. //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2013 Authors //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from hWIEGAND://www.opencores.org/lgpl.shtml //// |
//// //// |
//// The WIEGAND/C protocol is developed by SAE International. //// |
//// The SAE standard AS6003 can be downloaded from www.sae.org //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// Revisions at end of file |
// |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
`include "wiegand_defines.v" |
|
//pulling in data bus width from WIEGAND_defines file |
`ifdef WIEGAND_WIDTH64 |
`define WIEGAND_FIFODATAWIDTH 64 |
`elsif WIEGAND_WIDTH32 |
`define WIEGAND_FIFODATAWIDTH 32 |
`elsif WIEGAND_WIDTH16 |
`define WIEGAND_FIFODATAWIDTH 16 |
`else |
`define WIEGAND_FIFODATAWIDTH 8 |
`endif |
|
//define depth of FIFO; pulling in depth from WIEGAND_defines |
//`define WIEGAND_FIFODEPTH 16 |
|
//uncomment a single implementation of FIFO; pulling in implementation from WIEGAND_defines |
//`define WIEGAND_CUSTOMFIFO |
|
module fifo_wieg |
( |
clk_rd, |
clk_wr, |
d_i, |
d_o, |
rst, |
wr_en, |
rd_en, |
full, |
empty |
); |
input clk_rd; |
input clk_wr; |
input [`WIEGAND_FIFODATAWIDTH-1:0] d_i; |
output [`WIEGAND_FIFODATAWIDTH-1:0] d_o; |
input rst; |
input wr_en; |
input rd_en; |
output full; |
output empty; |
|
`ifdef WIEGAND_CUSTOMFIFO |
`ifdef WIEGAND_WIDTH64 |
custom_fifo_dp custom_fifo_dp1(clk_rd,clk_wr,d_i[63:56],d_o[63:56],rst,wr_en,rd_en,full,empty); |
custom_fifo_dp custom_fifo_dp2(clk_rd,clk_wr,d_i[55:48],d_o[55:48],rst,wr_en,rd_en,full,empty); |
custom_fifo_dp custom_fifo_dp3(clk_rd,clk_wr,d_i[47:40],d_o[47:40],rst,wr_en,rd_en,full,empty); |
custom_fifo_dp custom_fifo_dp4(clk_rd,clk_wr,d_i[39:32],d_o[39:32],rst,wr_en,rd_en,full,empty); |
custom_fifo_dp custom_fifo_dp5(clk_rd,clk_wr,d_i[31:24],d_o[31:24],rst,wr_en,rd_en,full,empty); |
custom_fifo_dp custom_fifo_dp6(clk_rd,clk_wr,d_i[23:16],d_o[23:16],rst,wr_en,rd_en,full,empty); |
custom_fifo_dp custom_fifo_dp7(clk_rd,clk_wr,d_i[15:8],d_o[15:8],rst,wr_en,rd_en,full,empty); |
custom_fifo_dp custom_fifo_dp8(clk_rd,clk_wr,d_i[7:0],d_o[7:0],rst,wr_en,rd_en,full,empty); |
`elsif WIEGAND_WIDTH32 |
custom_fifo_dp custom_fifo_dp5(clk_rd,clk_wr,d_i[31:24],d_o[31:24],rst,wr_en,rd_en,full,empty); |
custom_fifo_dp custom_fifo_dp6(clk_rd,clk_wr,d_i[23:16],d_o[23:16],rst,wr_en,rd_en,full,empty); |
custom_fifo_dp custom_fifo_dp7(clk_rd,clk_wr,d_i[15:8],d_o[15:8],rst,wr_en,rd_en,full,empty); |
custom_fifo_dp custom_fifo_dp8(clk_rd,clk_wr,d_i[7:0],d_o[7:0],rst,wr_en,rd_en,full,empty); |
`elsif WIEGAND_WIDTH16 |
custom_fifo_dp custom_fifo_dp7(clk_rd,clk_wr,d_i[15:8],d_o[15:8],rst,wr_en,rd_en,full,empty); |
custom_fifo_dp custom_fifo_dp8(clk_rd,clk_wr,d_i[7:0],d_o[7:0],rst,wr_en,rd_en,full,empty); |
`else |
custom_fifo_dp custom_fifo_dp8(clk_rd,clk_wr,d_i[7:0],d_o[7:0],rst,wr_en,rd_en,full,empty); |
`endif |
`endif |
|
endmodule |
|
module custom_fifo_dp ( |
clk_rd, |
clk_wr, |
d_i, |
d_o, |
rst, |
wr_en, |
rd_en, |
full, |
empty |
); |
input clk_rd; |
input clk_wr; |
input [7:0] d_i; |
output [7:0] d_o; |
input rst; |
input wr_en; |
input rd_en; |
output full; |
output empty; |
|
reg [`WIEGAND_FIFODEPTH-1:0] addr_rd; |
reg [`WIEGAND_FIFODEPTH-1:0] addr_wr; |
reg [7:0] fifo_out; |
wire [7:0] mem_byte_out; |
wire [`WIEGAND_FIFODEPTH-1:0] full_int; |
|
//bytewide memory array in FIFO. user sets depth. |
genvar c; |
generate |
for (c = 0; c < `WIEGAND_FIFODEPTH; c = c + 1) begin: mem |
mem_byte mem_byte(rst,clk_wr,d_i,mem_byte_out,addr_wr[c],addr_rd[c]); |
end |
endgenerate |
|
//read logic needed here to handle clock domain change |
assign d_o = fifo_out; |
always @(posedge clk_rd or posedge rst) begin |
if (rst) fifo_out <= 8'h0; |
else fifo_out <= mem_byte_out; |
end |
|
//addressing logic is simply a circular shift register that gets reset to 1 |
always @(posedge clk_wr or posedge rst) begin |
if (rst) addr_wr <= `WIEGAND_FIFODEPTH'h1; |
else if (wr_en&(~full)) begin |
addr_wr[`WIEGAND_FIFODEPTH-1:1] <= addr_wr[`WIEGAND_FIFODEPTH-2:0]; |
addr_wr[0] <= addr_wr[`WIEGAND_FIFODEPTH-1]; |
end |
end |
|
always @(posedge clk_rd or posedge rst) begin |
if (rst) addr_rd <= `WIEGAND_FIFODEPTH'h1; |
else if (rd_en&(~empty)) begin |
addr_rd[`WIEGAND_FIFODEPTH-1:1] <= addr_rd[`WIEGAND_FIFODEPTH-2:0]; |
addr_rd[0] <= addr_rd[`WIEGAND_FIFODEPTH-1]; |
end |
end |
|
//use address logic for flags |
assign empty = (addr_wr == addr_rd); //when read addr catches write addr, we're empty |
|
assign full = empty?1'b0:|full_int; //if fifo isn't empty, then OR all full flag outputs |
|
assign full_int[0] = (addr_wr[`WIEGAND_FIFODEPTH-1] & addr_rd[0]); //when we've written to entire mem, we're full |
genvar d; |
generate |
for (d = 1; d < `WIEGAND_FIFODEPTH; d = d + 1) begin: flag |
assign full_int[d] = (addr_wr[d-1] & addr_rd[d]); //when we've written to entire mem, we're full |
end |
endgenerate |
|
endmodule |
|
module mem_byte( |
rst, |
clk, |
din, |
dout, |
wen, |
ren |
); |
|
input rst; |
input clk; |
input[7:0] din; |
output [7:0] dout; |
input wen; |
input ren; |
|
reg[7:0] byte_reg; |
|
//just a byte-wide register with input and output enables |
assign dout = ren?byte_reg:8'bz; |
|
always @(posedge clk or posedge rst) begin |
if (rst) byte_reg <= 8'h0; |
else if (wen) byte_reg <= din; |
end |
|
endmodule |
|
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: $ |
// |
/rtl/verilog/wb_interface.v.bak
0,0 → 1,195
////////////////////////////////////////////////////////////////////// |
//// //// |
//// wb_interface.v //// |
//// //// |
//// //// |
//// This file is part of the Weigand Controller //// |
//// http://www.opencores.org/projects/wiegand/ //// |
//// //// |
//// //// |
//// Author(s): //// |
//// Jeff Anderson //// |
//// jeaander@opencores.org //// |
//// //// |
//// //// |
//// All additional information is available in the README.txt //// |
//// file. //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2013 Authors //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// Revisions at end of file |
// |
|
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
//WB interface definitions imported from wiegand_defines |
`include "wiegand_defines.v" |
|
module wb_interface_wieg ( |
// WB bus |
wb_rst_i , |
wb_clk_i , |
|
wb_stb_i , |
wb_ack_o , |
wb_addr_i , |
wb_we_i , |
wb_dat_i , |
wb_sel_i , |
wb_dat_o , |
wb_cyc_i , |
wb_cti_i , |
wb_err_o , |
wb_rty_o , |
|
rst_o, |
data_o, |
start_tx, |
size, |
p2p, |
pulsewidth, |
clk_o, |
wei_rd_en, |
empty, |
lock_cfg_i, |
write_i |
); |
|
//-------------------------------------- |
// Wish Bone Interface |
// ------------------------------------- |
input wb_rst_i ; |
input wb_clk_i ; |
|
input wb_stb_i ; |
output wb_ack_o ; |
input [`WB_ADDR_WIDTH-1:0] wb_addr_i ; |
input wb_we_i ; // 1 - Write , 0 - Read |
input [`WB_WIDTH-1:0] wb_dat_i ; |
input [`WB_WIDTH/8-1:0] wb_sel_i ; // Byte enable |
output [`WB_WIDTH-1:0] wb_dat_o ; |
input wb_cyc_i ; |
input [2:0] wb_cti_i ; |
output wb_err_o ; |
output wb_rty_o ; |
|
//---------------------------------------- |
// interface to Weigand control logic |
//---------------------------------------- |
output rst_o; |
output [`WB_ADDR_WIDTH-1:0] data_o; |
reg [1:0] rst; |
|
output reg [`WB_ADDR_WIDTH-1:0] pulsewidth; |
output reg [`WB_ADDR_WIDTH-1:0] p2p; |
//output [6:0] msgLength; |
output start_tx; |
output reg [7:0] size; |
output clk_o; |
input wei_rd_en; |
output empty; |
input lock_cfg_i; |
input write_i; |
|
|
wire full; |
|
|
/************************ standard WB stuff ***************************/ |
reg ack,err,rty; |
assign wb_ack_o = ack; |
assign wb_err_o = err; |
assign wb_rty_o = rty; |
|
//ACK logic |
always @(posedge wb_clk_i or posedge rst) begin |
if (rst) ack <= 1'b0; |
else if (wb_stb_i & wb_cyc_i) ack <= 1'b1; |
else ack <= 1'b0; |
end |
|
//ERR logic if the FIFO is full |
always @(posedge wb_clk_i or posedge rst) begin |
if (rst) err <= 1'b0; |
else if (wb_stb_i & wb_cyc_i & full & wb_we_i) err <= 1'b1; |
else err <= 1'b0; |
end |
|
//retry if we're in the middle of a write cycle |
always @(posedge wb_clk_i or posedge wb_rst_i) begin |
if (wb_rst_i) rty <= 1'b0; |
else if (wb_stb_i & wb_cyc_i & ~wb_we_i & write_i & lock_cfg_i) rty <= 1'b1; |
else rty <= 1'b0; |
end |
|
//pass-thru clock |
assign clk_o = wb_clk_i; |
|
/************************ configuration registers *************************/ |
//defines the pulse width of the controller |
always @(posedge wb_clk_i or posedge rst) begin & wb_we_i |
if (rst) pulsewidth <= `WB_WIDTH'h0; |
else if (wb_addr_i == `WB_CNFG_PW && (wb_stb_i & wb_cyc_i & wb_we_i & ~lock_cfg_i)) pulsewidth <= wb_dat_i; |
end |
|
|
//defines the pulse to pulse delayof the controller |
always @(posedge wb_clk_i or posedge rst) begin |
if (rst) p2p <= `WB_WIDTH'h0; |
else if (wb_addr_i == `WB_CNFG_P2P && (wb_stb_i & wb_cyc_i & wb_we_i & ~lock_cfg_i)) p2p <= wb_dat_i; |
end |
|
//defines the message size (in bits) and starts the message tx process (MSB) |
//assign msgLength = size[6:0]; |
assign start_tx = size[7]; |
always @(posedge wb_clk_i or posedge rst) begin |
if (rst) size <= 8'h0; |
else if (wb_addr_i == `WB_CNFG_MSGSIZE && (wb_stb_i & wb_cyc_i & wb_we_i & ~lock_cfg_i)) size <= wb_dat_i[7:0]; |
else if (lock_cfg_i) size <= size & 8'b01111111; |
end |
|
|
|
/******************************* DATA FIFO ********************************************/ |
|
//fifo for TX data. |
wire wb_wr_en = (wb_addr_i == `WIEGAND_ADDR) && (wb_stb_i & wb_cyc_i & wb_we_i & ~full); |
fifo_wieg fifo(wb_clk_i,wb_clk_i,wb_data_i,data_o,rst[1],wb_wr_en,wei_rd_en,full,empty); |
|
endmodule |
|
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: $ |
// |
/rtl/verilog/wiegand_rx_top.v.bak
0,0 → 1,214
////////////////////////////////////////////////////////////////////// |
//// //// |
//// wiegand_rx_top.v //// |
//// //// |
//// //// |
//// This file is part of the Wiegand Protocol Controller //// |
//// http://www.opencores.org/projects/wiegand/ //// |
//// //// |
//// //// |
//// Author(s): //// |
//// Jeff Anderson //// |
//// jeaander@opencores.org //// |
//// //// |
//// //// |
//// All additional information is available in the README.txt //// |
//// file. //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2014 Authors //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
//// The wiegand protocol is maintained by //// |
//// This product has been tested to interoperate with certified //// |
//// devices, but has not been certified itself. This product //// |
//// should be certified through prior to claiming strict //// |
//// adherence to the standard. //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// Revisions at end of file |
// |
|
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
`include "wiegand_defines.v" |
|
module wiegand_rx_top( |
|
one_i, |
zero_i, |
|
wb_clk_i, |
wb_rst_i, |
wb_dat_i, |
wb_dat_o, |
wb_cyc_i, |
wb_stb_i, |
wb_we_i, |
wb_adr_i, |
wb_ack_o, |
wb_err_o, |
wb_rty_o |
); |
//to PHY layer |
input one_i; |
input zero_i; |
|
//wishbone interface |
input wb_clk_i; |
input wb_rst_i; |
input [`WB_WIDTH-1:0] wb_dat_i, |
output [`WB_WIDTH-1:0] wb_dat_o; |
input wb_cyc_i; |
input wb_stb_i; |
input wb_we_i; |
input [`WB_ADDR_WIDTH-1:0] wb_adr_i; |
output wb_ack_o; |
output wb_err_o; |
output wb_rty_o; |
|
//intermediate signals |
wire rst; |
reg [`WB_WIDTH:0] data; |
|
wire [`WB_ADDR_WIDTH-1:0] pulsewidth; |
wire [(`WB_ADDR_WIDTH/2)-1:0] sampleCnt; |
wire [`WB_ADDR_WIDTH-1:0] p2p; |
wire [1000:0] p2pCnt; |
wire [6:0] msgLength; |
reg [31:0] word_in; |
reg [2:0] state, next_state; |
reg [1:0] zero_edge, one_edge; |
wire zero_det, one_det; |
wire clk; |
reg lock_cfg; |
|
/***************************** RX logic **********************************************************/ |
//negedge detectors for each line |
assign zero = ~zero_det[0] & zero_det[1]; |
always @(posedge clk or posedge rst) begin |
if (rst) zero_det <= 2'b11; |
else zero_det <= {zero_det[0],zero_i}; |
end |
|
assign one = ~one_det[0] & one_det[1]; |
always @(posedge clk or posedge rst) begin |
if (rst) one_det <= 2'b11; |
else one_det <= {one_det[0],one_i}; |
end |
|
//posedge detectors for each line |
assign notzero = zero_det[0] & ~zero_det[1]; |
assign notone = one_det[0] & ~one_det[1]; |
|
//@ negedge, filter for noise on teh line; filtering for noise by 4 samples during the PW |
assign filtered1 = (~|filter1) & ~one_det[1]; |
assign filtered0 = (~|filter0) & ~zero_det[1]; |
always @(posedge clk or posedge rst) begin |
if (rst) begin |
filter1 <= 4'h0; |
filter0 <= 4'h0; |
filterCnt <= 2'h0; |
end |
else if (sampleTime) begin |
filter1 <= {filter1[2:0],one_det[0]}; |
filter0 <= {filter0[2:0],zero_det[0]}; |
filterCnt <= filterCnt+1; |
end |
end |
|
always @(posedge clk or posedge rst) begin |
if (rst) sampleCnt <= (`WB_ADDR_WIDTH/2)'h0; |
else if (filterEn) sampleCnt <= sampleCnt+1; |
end |
|
always @(posedge clk or posedge rst) begin |
if (rst) sampleTime <= 1'b0; |
else if (sampleCnt == pulsewidth[1'b0,((`WB_ADDR_WIDTH/2)-1):0]) sampleTime <= 1'b1; |
else if (sampleCnt == pulsewidth[2'h0,((`WB_ADDR_WIDTH/2)-2):0]) sampleTime <= 1'b1; |
else if (sampleCnt == pulsewidth[3'h0,((`WB_ADDR_WIDTH/2)-3):0]) sampleTime <= 1'b1; |
else if (sampleCnt == pulsewidth[4'h0,((`WB_ADDR_WIDTH/2)-4):0]) sampleTime <= 1'b1; |
else sampleTime <= 1'b0; |
end |
|
always @(negedge clk or posedge rst) begin |
if (rst) filterEn <= 1'b0; |
else if (one | zero) filterEn <= 1'b1; |
else if (filterCnt == 2'h3) filterEn <= 1'b0 |
end |
|
//then write bit to appropriate data register sub-bit; increment counter |
always @(negedge clk or posedge rst) begin |
if (rst) begin |
word_in <= 32'h0; |
bitcount <= 6'h0; |
end |
else if (filtered1 | filtered0) begin |
word_in <= {word_in[30:0],filtered1}; |
bitcount <= bitcount+1; |
end |
end |
|
//when linesa re not being driven, check to see that tpi is not exceeded; |
//exceeded tpi means data transfer is done, and packet length should be checked |
always @(negedge clk or posedge rst) begin |
if (rst) tpiCnt <= 6'h0; |
else if (&{zero,one}) tpiCnt <= tpiCnt+1; |
else tpiCnt <= 6'h0; |
end |
|
always @(posedge clk or posedge rst) begin |
if (rst) msgDone <= 1'b0; |
else msgDone <= ~|(tpiCnt ^ tpi); |
end |
|
//if rx msglength does not match expected msglength, then flag an error |
always @(negedge clk or posedge rst) begin |
if (rst) msgError <= 1'b0; |
else if (errorClr) msgError <= 1'b0; |
else msgError <= msgDone & |(bitCount ^ msgLength); |
end |
|
/***************************** input FIFO *******************************************************/ |
|
fifo_wieg datafifowrite(wb_clk_i,wb_clk_i,wb_data_i,data_o,rst[1],wb_wr_en,wei_rd_en,full,empty); |
|
|
/***************************** WB interface *******************************************************/ |
wb_interface_wieg wb_interface(wb_rst_i,wb_clk_i,wb_stb_i,wb_ack_o,wb_addr_i,wb_we_i,data,wb_sel_i, |
wb_dat_o,wb_cyc_i,wb_cti_i,wb_err_o,wb_rty_o,rst,wb_dat_o,start_tx,size, |
p2p,msg_done,clk,latchData,emptyWrite,lock_cfg); |
|
//TODO: now that we know when the message is done, we need to write to FIFO and set read bit |
|
endmodule |
|
//////////////////////////////////////////////////////////////////// |
// CVS Revision History |
// |
// $Log: $ |
// |
/rtl/verilog/fifos.v
0,0 → 1,225
////////////////////////////////////////////////////////////////////// |
//// //// |
//// fifos.v //// |
//// //// |
//// //// |
//// This file is part of the Wiegand Protocol Controller //// |
//// http://www.opencores.org/projects/wiegand/ //// |
//// //// |
//// //// |
//// Author(s): //// |
//// Jeff Anderson //// |
//// jeaander@opencores.org //// |
//// //// |
//// //// |
//// All additional information is available in the README.txt //// |
//// file. //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2013 Authors //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// Revisions at end of file |
// |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
`include "wiegand_defines.v" |
|
//pulling in data bus width from WIEGAND_defines file |
`ifdef WIEGAND_WIDTH64 |
`define WIEGAND_FIFODATAWIDTH 64 |
`elsif WIEGAND_WIDTH32 |
`define WIEGAND_FIFODATAWIDTH 32 |
`elsif WIEGAND_WIDTH16 |
`define WIEGAND_FIFODATAWIDTH 16 |
`else |
`define WIEGAND_FIFODATAWIDTH 8 |
`endif |
|
//define depth of FIFO; pulling in depth from WIEGAND_defines |
//`define WIEGAND_FIFODEPTH 16 |
|
//uncomment a single implementation of FIFO; pulling in implementation from WIEGAND_defines |
//`define WIEGAND_CUSTOMFIFO |
|
module fifo_wieg |
( |
clk_rd, |
clk_wr, |
d_i, |
d_o, |
rst, |
wr_en, |
rd_en, |
full, |
empty |
); |
input clk_rd; |
input clk_wr; |
input [`WIEGAND_FIFODATAWIDTH-1:0] d_i; |
output [`WIEGAND_FIFODATAWIDTH-1:0] d_o; |
input rst; |
input wr_en; |
input rd_en; |
output full; |
output empty; |
|
`ifdef WIEGAND_CUSTOMFIFO |
`ifdef WIEGAND_WIDTH64 |
custom_fifo_dp custom_fifo_dp1(clk_rd,clk_wr,d_i[63:56],d_o[63:56],rst,wr_en,rd_en,full,empty); |
custom_fifo_dp custom_fifo_dp2(clk_rd,clk_wr,d_i[55:48],d_o[55:48],rst,wr_en,rd_en,full,empty); |
custom_fifo_dp custom_fifo_dp3(clk_rd,clk_wr,d_i[47:40],d_o[47:40],rst,wr_en,rd_en,full,empty); |
custom_fifo_dp custom_fifo_dp4(clk_rd,clk_wr,d_i[39:32],d_o[39:32],rst,wr_en,rd_en,full,empty); |
custom_fifo_dp custom_fifo_dp5(clk_rd,clk_wr,d_i[31:24],d_o[31:24],rst,wr_en,rd_en,full,empty); |
custom_fifo_dp custom_fifo_dp6(clk_rd,clk_wr,d_i[23:16],d_o[23:16],rst,wr_en,rd_en,full,empty); |
custom_fifo_dp custom_fifo_dp7(clk_rd,clk_wr,d_i[15:8],d_o[15:8],rst,wr_en,rd_en,full,empty); |
custom_fifo_dp custom_fifo_dp8(clk_rd,clk_wr,d_i[7:0],d_o[7:0],rst,wr_en,rd_en,full,empty); |
`elsif WIEGAND_WIDTH32 |
custom_fifo_dp custom_fifo_dp5(clk_rd,clk_wr,d_i[31:24],d_o[31:24],rst,wr_en,rd_en,full,empty); |
custom_fifo_dp custom_fifo_dp6(clk_rd,clk_wr,d_i[23:16],d_o[23:16],rst,wr_en,rd_en,full,empty); |
custom_fifo_dp custom_fifo_dp7(clk_rd,clk_wr,d_i[15:8],d_o[15:8],rst,wr_en,rd_en,full,empty); |
custom_fifo_dp custom_fifo_dp8(clk_rd,clk_wr,d_i[7:0],d_o[7:0],rst,wr_en,rd_en,full,empty); |
`elsif WIEGAND_WIDTH16 |
custom_fifo_dp custom_fifo_dp7(clk_rd,clk_wr,d_i[15:8],d_o[15:8],rst,wr_en,rd_en,full,empty); |
custom_fifo_dp custom_fifo_dp8(clk_rd,clk_wr,d_i[7:0],d_o[7:0],rst,wr_en,rd_en,full,empty); |
`else |
custom_fifo_dp custom_fifo_dp8(clk_rd,clk_wr,d_i[7:0],d_o[7:0],rst,wr_en,rd_en,full,empty); |
`endif |
`endif |
|
endmodule |
|
module custom_fifo_dp ( |
clk_rd, |
clk_wr, |
d_i, |
d_o, |
rst, |
wr_en, |
rd_en, |
full, |
empty |
); |
input clk_rd; |
input clk_wr; |
input [7:0] d_i; |
output [7:0] d_o; |
input rst; |
input wr_en; |
input rd_en; |
output full; |
output empty; |
|
reg [`WIEGAND_FIFODEPTH-1:0] addr_rd; |
reg [`WIEGAND_FIFODEPTH-1:0] addr_wr; |
reg [7:0] fifo_out; |
wire [7:0] mem_byte_out; |
wire [`WIEGAND_FIFODEPTH-1:0] full_int; |
|
//bytewide memory array in FIFO. user sets depth. |
genvar c; |
generate |
for (c = 0; c < `WIEGAND_FIFODEPTH; c = c + 1) begin: mem |
mem_byte mem_byte(rst,clk_wr,d_i,mem_byte_out,addr_wr[c],addr_rd[c]); |
end |
endgenerate |
|
//read logic needed here to handle clock domain change |
assign d_o = fifo_out; |
always @(posedge clk_rd or posedge rst) begin |
if (rst) fifo_out <= 8'h0; |
else fifo_out <= mem_byte_out; |
end |
|
//addressing logic is simply a circular shift register that gets reset to 1 |
always @(posedge clk_wr or posedge rst) begin |
if (rst) addr_wr <= `WIEGAND_FIFODEPTH'h1; |
else if (wr_en&(~full)) begin |
addr_wr[`WIEGAND_FIFODEPTH-1:1] <= addr_wr[`WIEGAND_FIFODEPTH-2:0]; |
addr_wr[0] <= addr_wr[`WIEGAND_FIFODEPTH-1]; |
end |
end |
|
always @(posedge clk_rd or posedge rst) begin |
if (rst) addr_rd <= `WIEGAND_FIFODEPTH'h1; |
else if (rd_en&(~empty)) begin |
addr_rd[`WIEGAND_FIFODEPTH-1:1] <= addr_rd[`WIEGAND_FIFODEPTH-2:0]; |
addr_rd[0] <= addr_rd[`WIEGAND_FIFODEPTH-1]; |
end |
end |
|
//use address logic for flags |
assign empty = (addr_wr == addr_rd); //when read addr catches write addr, we're empty |
|
assign full = empty?1'b0:|full_int; //if fifo isn't empty, then OR all full flag outputs |
|
assign full_int[0] = (addr_wr[`WIEGAND_FIFODEPTH-1] & addr_rd[0]); //when we've written to entire mem, we're full |
genvar d; |
generate |
for (d = 1; d < `WIEGAND_FIFODEPTH; d = d + 1) begin: flag |
assign full_int[d] = (addr_wr[d-1] & addr_rd[d]); //when we've written to entire mem, we're full |
end |
endgenerate |
|
endmodule |
|
module mem_byte( |
rst, |
clk, |
din, |
dout, |
wen, |
ren |
); |
|
input rst; |
input clk; |
input[7:0] din; |
output [7:0] dout; |
input wen; |
input ren; |
|
reg[7:0] byte_reg; |
|
//just a byte-wide register with input and output enables |
assign dout = ren?byte_reg:8'bz; |
|
always @(posedge clk or posedge rst) begin |
if (rst) byte_reg <= 8'h0; |
else if (wen) byte_reg <= din; |
end |
|
endmodule |
|
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: $ |
// |
/rtl/verilog/timescale.v
0,0 → 1,225
`timescale 10ns/1ns |
/rtl/verilog/README.txt
0,0 → 1,65
////////////////////////////////////////////////////////////////////// |
//// //// |
//// README.txt //// |
//// //// |
//// //// |
//// This file is part of the Time TRiggered Protocol Controller //// |
//// http://www.opencores.org/projects/weigand/ //// |
//// //// |
//// //// |
//// Author(s): //// |
//// Jeff Anderson //// |
//// jeaander@opencores.org //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2013 Authors //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
//// The TTP/C protocol is developed by SAE International. //// |
//// The SAE standard AS6003 can be downloaded from www.sae.org //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: $ |
// |
// |
// |
|
|
This TTP/C Controller was designed according to the SAE AS6003 standard. |
Because of the licensing issue it can not be published on the Opencores web site. |
Go to www.sae.org to download the standard. |
|
The TTP/C Controller was also implemented in real HW (several boards |
were constantly talking to each other). |
|
The included test bench is not a real test bench and should be improved. |
However a volunteer is needed for such a job. I can provide some help |
but am not willing to write it by myself. |
|
Best regards, |
Jeff Anderson |
/rtl/verilog/wiegand_defines.v.bak
0,0 → 1,104
////////////////////////////////////////////////////////////////////// |
//// //// |
//// wiegand_defines.v //// |
//// //// |
//// //// |
//// This file is part of the Wiegand Controller //// |
//// http://www.opencores.org/projects/wiegand/ //// |
//// //// |
//// //// |
//// Author(s): //// |
//// Jeff Anderson //// |
//// jeaander@opencores.org //// |
//// //// |
//// //// |
//// All additional information is available in the README.txt //// |
//// file. //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2013 Authors //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// Revisions at end of file |
// |
|
/********************** WISHBONE DEFINES ***************************/ |
// define the WB bus width; uncomment ONE correct width |
//`define WB_WIDTH64 |
`define WB_WIDTH32 |
//`define WB_WIDTH16 |
//`define WB_WIDTH08 |
|
|
`ifdef WB_WIDTH64 |
`define WB_WIDTH 64 |
`define WIEGAND_WIDTH64 |
`elsif WB_WIDTH32 |
`define WB_WIDTH 32 |
`define WIEGAND_WIDTH32 |
`elsif WB_WIDTH16 |
`define WB_WIDTH 16 |
`define WIEGAND_WIDTH16 |
`else |
`define WB_WIDTH 8 |
`define WIEGAND_WIDTH8 |
`endif |
|
//define the width of WB address |
`define WB_ADDR_WIDTH 6 |
|
/*********************** WIEGAND DEFINES *****************************/ |
//WIEGAND_WIDTH defined above |
|
//define depth of FIFO for 64-bit message format; largest message I've seen in open literature; 64/`WB_WIDTH |
`define WIEGAND_FIFODEPTH 2 |
|
//uncomment a single implementation of FIFO; |
`define WIEGAND_CUSTOMFIFO |
|
//set to base address of controller; base address is data FIFO, and the config registers are relative to it |
`define WIEGAND_ADDR 6'h01 |
|
`define WB_CNFG_PW `WIEGAND_ADDR+1 |
`define WB_CNFG_P2P `WIEGAND_ADDR+2 |
`define WB_CNFG_MSGSIZE `WIEGAND_ADDR+3 |
|
//states in teh state machine |
`define ZERO 3'b111 |
`define ONE 3'b100 |
`define INIT 3'b000 |
`define DATA 3'b001 |
`define TX 3'b101 |
`define DONE 3'b110 |
|
|
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: $ |
// |
/rtl/verilog/wiegand_tx_top.v.bak
0,0 → 1,221
////////////////////////////////////////////////////////////////////// |
//// //// |
//// wiegand_tx_top.v //// |
//// //// |
//// //// |
//// This file is part of the Wiegand Protocol Controller //// |
//// Wiegand Transmitter IP core //// |
//// http://www.opencores.org/projects/wiegand/ //// |
//// //// |
//// //// |
//// Author(s): //// |
//// Jeff Anderson //// |
//// jeaander@opencores.org //// |
//// //// |
//// //// |
//// All additional information is available in the README.txt //// |
//// file. //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2014 Authors //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// Revisions at end of file |
// |
|
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
`include "wiegand_defines.v" |
|
module wiegand_tx_top( |
|
one_o, |
zero_o, |
|
wb_clk_i, |
wb_rst_i, |
wb_dat_i, |
wb_dat_o, |
wb_cyc_i, |
wb_stb_i, |
wb_we_i, |
wb_adr_i, |
wb_ack_o, |
wb_err_o, |
wb_rty_o |
); |
//to PHY layer |
output reg one_o; |
output reg zero_o; |
|
//wishbone interface |
input wb_clk_i; |
input wb_rst_i; |
input [`WB_WIDTH-1:0] wb_dat_i; |
output [`WB_WIDTH-1:0] wb_dat_o; |
input wb_cyc_i; |
input wb_stb_i; |
input wb_we_i; |
input [`WB_ADDR_WIDTH-1:0] wb_adr_i; |
output wb_ack_o; |
output wb_err_o; |
output wb_rty_o; |
|
//intermediate signals |
wire rst; |
|
wire [`WB_ADDR_WIDTH-1:0] pulsewidth; |
wire [(`WB_ADDR_WIDTH/2)-1:0] sampleCnt; |
wire [`WB_ADDR_WIDTH-1:0] p2p; |
wire [1000:0] p2pCnt; |
wire [6:0] msgLength; |
reg [31:0] word_out; |
reg [2:0] state, next_state; |
reg [1:0] zero_edge, one_edge; |
wire zero_det, one_det; |
wire clk; |
reg lock_cfg; |
reg zero,one, tx, data, done; |
reg [`WB_ADDR_WIDTH-1:0] pulseCnt; |
reg [6:0] bitCount; |
wire start_tx; |
wire [`WB_WIDTH-1:0] data_o; |
|
/***************************** TX logic *********************************************************/ |
//output registers clocked directly from the state machine |
always @(negedge clk or posedge rst) begin |
if (rst) begin |
one_o <= 1'b1; |
zero_o <= 1'b1; |
end |
else begin |
one_o <= one; |
zero_o <= zero; |
end |
end |
|
//counters enabled by state machine for programmable wiegand timing |
|
//pulse to pulse timing |
always @(negedge clk or posedge rst) begin |
if (rst) p2pCnt <= 5'h0; |
else if (tx) p2pCnt <= p2pCnt+1; |
else p2pCnt <= 5'h0; |
end |
|
//pulse width timer |
always @(negedge clk or posedge rst) begin |
if (rst) pulseCnt <= 5'h0; |
else if (zero | one) pulseCnt <= pulseCnt+1; |
else pulseCnt <= 5'h0; |
end |
|
//message bit counter |
always @(negedge clk or posedge rst) begin |
if (rst) bitCount <= 5'h0; |
else if (done) bitCount <= bitCount+1; |
else bitCount <= 5'h0; |
end |
|
//main state machine for transmitter |
always @(posedge clk or posedge rst) begin |
if (rst) state <= `IDLE; |
else state <= next_state; |
end |
|
always @ (*) begin |
next_state = `IDLE; |
zero = 1'b1; |
one = 1'b1; |
tx = 1'b0; |
data = 1'b0; |
done = 1'b0; |
case (state) |
`IDLE: begin |
if (start_tx) next_state = `DATA; |
else next_state = `IDLE; |
end |
`DATA: begin |
data = 1'b1; |
next_state = `TX; |
end |
`TX: begin |
tx = 1'b1; |
if (bitCount > msgLength) next_state = `IDLE; |
else if (bitCount == 6'd31) next_state = `DATA; |
else if (word_out[31] && (p2pCnt == p2p)) next_state = `ONE; |
else if (~word_out[31] && (p2pCnt == p2p)) next_state = `ZERO; |
else next_state = `TX; |
end |
`ONE: begin |
one = 1'b0; |
if (pulseCnt == pulsewidth) next_state = `DONE; |
else next_state = `ONE; |
end |
`ZERO: begin |
zero = 1'b0; |
if (pulseCnt == pulsewidth) next_state = `DONE; |
else next_state = `ZERO; |
end |
`DONE: begin |
done = 1'b1; |
next_state = `TX; |
end |
endcase |
end |
|
//dont want config being changed during a write cycle |
always @(negedge clk or posedge rst) begin |
if (rst) lock_cfg <= 1'b0; |
else lock_cfg <= tx | done | one | zero | data; |
end |
|
/***************************** output FIFO *******************************************************/ |
always @(posedge clk or posedge rst) begin |
if (rst) word_out <= 32'h0; |
else if (data) word_out <= data_o; |
else if (done) word_out <= {word_out[30:0],1'b0}; |
end |
|
fifo_wieg datafifowrite(wb_clk_i,wb_clk_i,wb_data_i,data_o,rst,wb_wr_en,wei_rd_en,full,empty); |
|
|
/***************************** WB interface *******************************************************/ |
wb_interface_wieg wb_interface(wb_rst_i,wb_clk_i,wb_stb_i,wb_ack_o,wb_addr_i,wb_we_i,data_o,wb_sel_i, |
wb_dat_o,wb_cyc_i,wb_cti_i,wb_err_o,wb_rty_o,rst,wb_dat_o,start_tx,size, |
p2p,msg_done,clk,latchData,emptyWrite,lock_cfg); |
|
|
endmodule |
|
//////////////////////////////////////////////////////////////////// |
// CVS Revision History |
// |
// $Log: $ |
// |
/rtl/verilog/wb_interface.v
0,0 → 1,195
////////////////////////////////////////////////////////////////////// |
//// //// |
//// wb_interface.v //// |
//// //// |
//// //// |
//// This file is part of the Weigand Controller //// |
//// http://www.opencores.org/projects/wiegand/ //// |
//// //// |
//// //// |
//// Author(s): //// |
//// Jeff Anderson //// |
//// jeaander@opencores.org //// |
//// //// |
//// //// |
//// All additional information is available in the README.txt //// |
//// file. //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2013 Authors //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// Revisions at end of file |
// |
|
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
//WB interface definitions imported from wiegand_defines |
`include "wiegand_defines.v" |
|
module wb_interface_wieg ( |
// WB bus |
wb_rst_i , |
wb_clk_i , |
|
wb_stb_i , |
wb_ack_o , |
wb_addr_i , |
wb_we_i , |
wb_dat_i , |
wb_sel_i , |
wb_dat_o , |
wb_cyc_i , |
wb_cti_i , |
wb_err_o , |
wb_rty_o , |
|
rst_o, |
data_o, |
start_tx, |
size, |
p2p, |
pulsewidth, |
clk_o, |
wei_rd_en, |
empty, |
lock_cfg_i, |
write_i |
); |
|
//-------------------------------------- |
// Wish Bone Interface |
// ------------------------------------- |
input wb_rst_i ; |
input wb_clk_i ; |
|
input wb_stb_i ; |
output wb_ack_o ; |
input [`WB_ADDR_WIDTH-1:0] wb_addr_i ; |
input wb_we_i ; // 1 - Write , 0 - Read |
input [`WB_WIDTH-1:0] wb_dat_i ; |
input [`WB_WIDTH/8-1:0] wb_sel_i ; // Byte enable |
output [`WB_WIDTH-1:0] wb_dat_o ; |
input wb_cyc_i ; |
input [2:0] wb_cti_i ; |
output wb_err_o ; |
output wb_rty_o ; |
|
//---------------------------------------- |
// interface to Weigand control logic |
//---------------------------------------- |
output rst_o; |
output [`WB_ADDR_WIDTH-1:0] data_o; |
reg [1:0] rst; |
|
output reg [`WB_ADDR_WIDTH-1:0] pulsewidth; |
output reg [`WB_ADDR_WIDTH-1:0] p2p; |
//output [6:0] msgLength; |
output start_tx; |
output reg [7:0] size; |
output clk_o; |
input wei_rd_en; |
output empty; |
input lock_cfg_i; |
input write_i; |
|
|
wire full; |
|
|
/************************ standard WB stuff ***************************/ |
reg ack,err,rty; |
assign wb_ack_o = ack; |
assign wb_err_o = err; |
assign wb_rty_o = rty; |
|
//ACK logic |
always @(posedge wb_clk_i or posedge rst) begin |
if (rst) ack <= 1'b0; |
else if (wb_stb_i & wb_cyc_i) ack <= 1'b1; |
else ack <= 1'b0; |
end |
|
//ERR logic if the FIFO is full |
always @(posedge wb_clk_i or posedge rst) begin |
if (rst) err <= 1'b0; |
else if (wb_stb_i & wb_cyc_i & full & wb_we_i) err <= 1'b1; |
else err <= 1'b0; |
end |
|
//retry if we're in the middle of a write cycle |
always @(posedge wb_clk_i or posedge wb_rst_i) begin |
if (wb_rst_i) rty <= 1'b0; |
else if (wb_stb_i & wb_cyc_i & ~wb_we_i & write_i & lock_cfg_i) rty <= 1'b1; |
else rty <= 1'b0; |
end |
|
//pass-thru clock |
assign clk_o = wb_clk_i; |
|
/************************ configuration registers *************************/ |
//defines the pulse width of the controller |
always @(posedge wb_clk_i or posedge rst) begin |
if (rst) pulsewidth <= `WB_WIDTH'h0; |
else if (wb_addr_i == `WB_CNFG_PW && (wb_stb_i & wb_cyc_i & wb_we_i & ~lock_cfg_i)) pulsewidth <= wb_dat_i; |
end |
|
|
//defines the pulse to pulse delayof the controller |
always @(posedge wb_clk_i or posedge rst) begin |
if (rst) p2p <= `WB_WIDTH'h0; |
else if (wb_addr_i == `WB_CNFG_P2P && (wb_stb_i & wb_cyc_i & wb_we_i & ~lock_cfg_i)) p2p <= wb_dat_i; |
end |
|
//defines the message size (in bits) and starts the message tx process (MSB) |
//assign msgLength = size[6:0]; |
assign start_tx = size[7]; |
always @(posedge wb_clk_i or posedge rst) begin |
if (rst) size <= 8'h0; |
else if (wb_addr_i == `WB_CNFG_MSGSIZE && (wb_stb_i & wb_cyc_i & wb_we_i & ~lock_cfg_i)) size <= wb_dat_i[7:0]; |
else if (lock_cfg_i) size <= size & 8'b01111111; |
end |
|
|
|
/******************************* DATA FIFO ********************************************/ |
|
//fifo for TX data. |
wire wb_wr_en = (wb_addr_i == `WIEGAND_ADDR) && (wb_stb_i & wb_cyc_i & wb_we_i & ~full); |
fifo_wieg fifo(wb_clk_i,wb_clk_i,wb_data_i,data_o,rst[1],wb_wr_en,wei_rd_en,full,empty); |
|
endmodule |
|
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: $ |
// |
/rtl/verilog/wiegand_rx_top.v
0,0 → 1,215
////////////////////////////////////////////////////////////////////// |
//// //// |
//// wiegand_rx_top.v //// |
//// //// |
//// //// |
//// This file is part of the Wiegand Protocol Controller //// |
//// Wiegand Receiver IP core //// |
//// http://www.opencores.org/projects/wiegand/ //// |
//// //// |
//// //// |
//// Author(s): //// |
//// Jeff Anderson //// |
//// jeaander@opencores.org //// |
//// //// |
//// //// |
//// All additional information is available in the README.txt //// |
//// file. //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2014 Authors //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
//// The wiegand protocol is maintained by //// |
//// This product has been tested to interoperate with certified //// |
//// devices, but has not been certified itself. This product //// |
//// should be certified through prior to claiming strict //// |
//// adherence to the standard. //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// Revisions at end of file |
// |
|
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
`include "wiegand_defines.v" |
|
module wiegand_rx_top( |
|
one_i, |
zero_i, |
|
wb_clk_i, |
wb_rst_i, |
wb_dat_i, |
wb_dat_o, |
wb_cyc_i, |
wb_stb_i, |
wb_we_i, |
wb_adr_i, |
wb_ack_o, |
wb_err_o, |
wb_rty_o |
); |
//to PHY layer |
input one_i; |
input zero_i; |
|
//wishbone interface |
input wb_clk_i; |
input wb_rst_i; |
input [`WB_WIDTH-1:0] wb_dat_i, |
output [`WB_WIDTH-1:0] wb_dat_o; |
input wb_cyc_i; |
input wb_stb_i; |
input wb_we_i; |
input [`WB_ADDR_WIDTH-1:0] wb_adr_i; |
output wb_ack_o; |
output wb_err_o; |
output wb_rty_o; |
|
//intermediate signals |
wire rst; |
reg [`WB_WIDTH:0] data; |
|
wire [`WB_ADDR_WIDTH-1:0] pulsewidth; |
wire [(`WB_ADDR_WIDTH/2)-1:0] sampleCnt; |
wire [`WB_ADDR_WIDTH-1:0] p2p; |
wire [1000:0] p2pCnt; |
wire [6:0] msgLength; |
reg [31:0] word_in; |
reg [2:0] state, next_state; |
reg [1:0] zero_edge, one_edge; |
wire zero_det, one_det; |
wire clk; |
reg lock_cfg; |
|
/***************************** RX logic **********************************************************/ |
//negedge detectors for each line |
assign zero = ~zero_det[0] & zero_det[1]; |
always @(posedge clk or posedge rst) begin |
if (rst) zero_det <= 2'b11; |
else zero_det <= {zero_det[0],zero_i}; |
end |
|
assign one = ~one_det[0] & one_det[1]; |
always @(posedge clk or posedge rst) begin |
if (rst) one_det <= 2'b11; |
else one_det <= {one_det[0],one_i}; |
end |
|
//posedge detectors for each line |
assign notzero = zero_det[0] & ~zero_det[1]; |
assign notone = one_det[0] & ~one_det[1]; |
|
//@ negedge, filter for noise on teh line; filtering for noise by 4 samples during the PW |
assign filtered1 = (~|filter1) & ~one_det[1]; |
assign filtered0 = (~|filter0) & ~zero_det[1]; |
always @(posedge clk or posedge rst) begin |
if (rst) begin |
filter1 <= 4'h0; |
filter0 <= 4'h0; |
filterCnt <= 2'h0; |
end |
else if (sampleTime) begin |
filter1 <= {filter1[2:0],one_det[0]}; |
filter0 <= {filter0[2:0],zero_det[0]}; |
filterCnt <= filterCnt+1; |
end |
end |
|
always @(posedge clk or posedge rst) begin |
if (rst) sampleCnt <= (`WB_ADDR_WIDTH/2)'h0; |
else if (filterEn) sampleCnt <= sampleCnt+1; |
end |
|
always @(posedge clk or posedge rst) begin |
if (rst) sampleTime <= 1'b0; |
else if (sampleCnt == pulsewidth[1'b0,((`WB_ADDR_WIDTH/2)-1):0]) sampleTime <= 1'b1; |
else if (sampleCnt == pulsewidth[2'h0,((`WB_ADDR_WIDTH/2)-2):0]) sampleTime <= 1'b1; |
else if (sampleCnt == pulsewidth[3'h0,((`WB_ADDR_WIDTH/2)-3):0]) sampleTime <= 1'b1; |
else if (sampleCnt == pulsewidth[4'h0,((`WB_ADDR_WIDTH/2)-4):0]) sampleTime <= 1'b1; |
else sampleTime <= 1'b0; |
end |
|
always @(negedge clk or posedge rst) begin |
if (rst) filterEn <= 1'b0; |
else if (one | zero) filterEn <= 1'b1; |
else if (filterCnt == 2'h3) filterEn <= 1'b0 |
end |
|
//then write bit to appropriate data register sub-bit; increment counter |
always @(negedge clk or posedge rst) begin |
if (rst) begin |
word_in <= 32'h0; |
bitcount <= 6'h0; |
end |
else if (filtered1 | filtered0) begin |
word_in <= {word_in[30:0],filtered1}; |
bitcount <= bitcount+1; |
end |
end |
|
//when linesa re not being driven, check to see that tpi is not exceeded; |
//exceeded tpi means data transfer is done, and packet length should be checked |
always @(negedge clk or posedge rst) begin |
if (rst) tpiCnt <= 6'h0; |
else if (&{zero,one}) tpiCnt <= tpiCnt+1; |
else tpiCnt <= 6'h0; |
end |
|
always @(posedge clk or posedge rst) begin |
if (rst) msgDone <= 1'b0; |
else msgDone <= ~|(tpiCnt ^ tpi); |
end |
|
//if rx msglength does not match expected msglength, then flag an error |
always @(negedge clk or posedge rst) begin |
if (rst) msgError <= 1'b0; |
else if (errorClr) msgError <= 1'b0; |
else msgError <= msgDone & |(bitCount ^ msgLength); |
end |
|
/***************************** input FIFO *******************************************************/ |
|
fifo_wieg datafifowrite(wb_clk_i,wb_clk_i,wb_data_i,data_o,rst[1],wb_wr_en,wei_rd_en,full,empty); |
|
|
/***************************** WB interface *******************************************************/ |
wb_interface_wieg wb_interface(wb_rst_i,wb_clk_i,wb_stb_i,wb_ack_o,wb_addr_i,wb_we_i,data,wb_sel_i, |
wb_dat_o,wb_cyc_i,wb_cti_i,wb_err_o,wb_rty_o,rst,wb_dat_o,start_tx,size, |
p2p,msg_done,clk,latchData,emptyWrite,lock_cfg); |
|
//TODO: now that we know when the message is done, we need to write to FIFO and set read bit |
|
endmodule |
|
//////////////////////////////////////////////////////////////////// |
// CVS Revision History |
// |
// $Log: $ |
// |