Pattern detector
這個例子是用casez來做判斷,在verilog中,casez的好處就是可以不用在乎其它bit的狀態,所以拿這個來當pattern
detector,但是這只能用在FPGA,不能做成ASIC,如果要做成ASIC理論上示要寫FSM,但是如果要找的pattern
很大,那真的會令人崩潰阿阿阿阿!
因為casez只有在verilog中有,所以我在寫一層top
layer來包,duplicate
data表式上層收集下來的資料連接而成,因為兩個連續的資料中一定會有我們要找的pattern在中間,但是這個casez我發現在duplicate_data中pattern前需要都為零才能偵測到,例如pattern是1101,那duplicate資料需為00011010,如果是10011010則會找不到,這點我還沒想通為什麼
T_T
ps.
detect_pos是用來指出偵測到的位置在哪裡,然後取後面的資料當作detected_data,當然也可以把pattern當成id之類,後面接的是資料
pattern_detector_top.vhd
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity pattern_detector_top is Port ( t_clk : in STD_LOGIC; t_reset : in STD_LOGIC; t_enable : in STD_LOGIC; t_duplicate_data : in STD_LOGIC_VECTOR (7 downto 0); t_pattern_data : out STD_LOGIC_VECTOR (3 downto 0); t_pattern_detect : out STD_LOGIC); end pattern_detector_top; architecture Behavioral of pattern_detector_top is begin u_pattern_detector: entity work.pattern_detector PORT MAP( clk => t_clk, reset => t_reset, enable => t_enable, duplicate_data => t_duplicate_data, pattern_data => t_pattern_data, pattern_detect => t_pattern_detect ); end Behavioral; |
pattern_detector.v
module pattern_detector(
input wire clk, input wire reset, input wire enable, input wire[7:0] duplicate_data, output reg [3:0] pattern_data, output reg pattern_detect); parameter PATTERN = 4'b1101; reg [3:0] detect_pos; always @ (posedge clk or posedge reset) begin if(reset) begin detect_pos <= 4'h1; pattern_detect <= 1'b0; end else begin if(!enable) begin detect_pos <= 4'h1; pattern_detect <= 1'b0; end else if (!pattern_detect) // begin casez (duplicate_data) {PATTERN, 4'b????}: begin detect_pos <=#1 4'h1; pattern_detect <=#1 1'b1; end {1'b?, PATTERN, 3'b???}: begin detect_pos <=#1 4'h1 << 1; pattern_detect <=#1 1'b1; end {2'b??, PATTERN, 2'b??}: begin detect_pos <=#1 4'h1 << 2; pattern_detect <=#1 1'b1; end {3'b???, PATTERN, 1'b?}: begin detect_pos <=#1 4'h1 << 3; pattern_detect <=#1 1'b1; end default: begin detect_pos <=#1 detect_pos; pattern_detect <=#1 pattern_detect; end endcase end end end always @ (posedge clk or posedge reset) begin if(reset) begin pattern_data <= 4'h0; end else if (pattern_detect) begin case (1'b1) detect_pos[0]: pattern_data <=#1 duplicate_data[7:4]; detect_pos[1]: pattern_data <=#1 duplicate_data[6:3]; detect_pos[2]: pattern_data <=#1 duplicate_data[5:2]; detect_pos[3]: pattern_data <=#1 duplicate_data[4:1]; endcase end end endmodule |
pattern_detector_tb.vhd
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY pattern_detector_tb IS END pattern_detector_tb; ARCHITECTURE behavior OF pattern_detector_tb IS -- Component Declaration for the Unit Under Test (UUT) COMPONENT pattern_detector_top PORT( t_clk : IN std_logic; t_reset : IN std_logic; t_enable : IN std_logic; t_duplicate_data : IN std_logic_vector(7 downto 0); t_pattern_data : OUT std_logic_vector(3 downto 0); t_pattern_detect : OUT std_logic ); END COMPONENT; --Inputs signal t_clk : std_logic := '0'; signal t_reset : std_logic := '0'; signal t_enable : std_logic := '0'; signal t_duplicate_data : std_logic_vector(7 downto 0) := (others => '0'); --Outputs signal t_pattern_data : std_logic_vector(3 downto 0); signal t_pattern_detect : std_logic; -- Clock period definitions constant t_clk_period : time := 10 ns; BEGIN -- Instantiate the Unit Under Test (UUT) uut: pattern_detector_top PORT MAP ( t_clk => t_clk, t_reset => t_reset, t_enable => t_enable, t_duplicate_data => t_duplicate_data, t_pattern_data => t_pattern_data, t_pattern_detect => t_pattern_detect ); -- Clock process definitions t_clk_process :process begin t_clk <= '0'; wait for t_clk_period/2; t_clk <= '1'; wait for t_clk_period/2; end process; -- Stimulus process stim_proc: process begin -- hold reset state for 100 ns. wait for 3 us; t_reset <= '1'; wait for 30 ns; t_reset <= '0'; wait for 3 us; wait for 22 ns; t_duplicate_data <= "00000000"; wait for 5 us; t_enable <= '1'; t_duplicate_data <= "00011011"; wait for 32 ns; t_duplicate_data <= "10111011"; wait; end process; END; |
Waveform
沒有留言:
張貼留言