summaryrefslogtreecommitdiff
path: root/A5.1/Verilog
diff options
context:
space:
mode:
Diffstat (limited to 'A5.1/Verilog')
-rw-r--r--A5.1/Verilog/a5.v354
1 files changed, 354 insertions, 0 deletions
diff --git a/A5.1/Verilog/a5.v b/A5.1/Verilog/a5.v
new file mode 100644
index 0000000..297dc2c
--- /dev/null
+++ b/A5.1/Verilog/a5.v
@@ -0,0 +1,354 @@
+A5/1 Circuit, expressed in Verilog
+
+The following is equivalent to the purported A5/1
+pedagogical C earlier published.
+
+For non-commercial, non-governmental use only.
+
+It comes with a testbench and sample output.
+
+/*
+a5.v
+Purported A5/1 circuit, expressed in Verilog.
+13 May 99
+David Honig
+honig@sprynet.com
+
+Derived from Briceno, Goldberg, Wagner's Pedagogical C Code
+of May 99.
+
+To load key: assert Startloading, load data starting on next clock,
+bitwise (1 delay + 64 key + 22 frame clocks).
+
+Then wait for Doneloading to be asserted (100 more clocks). Then
+harvest your bits.
+
+A testbench and sample output is appended as comments.
+
+This synthesizes to about 150 LCs and runs at 80 Mhz on
+the smaller Altera CPLDs e.g., 10K30.
+
+*/
+
+
+
+module a5(Clk, Reset_n,
+ Bitout,
+ Keybit,
+ Startloading,
+ Doneloading);
+
+
+input Clk, Reset_n;
+output Bitout; // output keystream
+ reg Bitout;
+input Keybit; // input keybits 64 + 22
+input Startloading; // initial keyload
+output Doneloading; // signal done of keyloading
+ reg Doneloading;
+
+
+// internal state; lsb is leftmost
+reg [18:0] lfsr_1;
+reg [21:0] lfsr_2;
+reg [22:0] lfsr_3;
+
+reg [1:0] State; // FSM control
+reg [6:0] Counter; // for counting steps
+reg [2:0] Phase; // for sequencing phases
+
+wire hi_1, hi_2, hi_3;
+assign hi_1 = lfsr_1[18];
+assign hi_2 = lfsr_2[21];
+assign hi_3 = lfsr_3[22];
+
+
+wire mid1, mid2, mid3;
+assign mid1=lfsr_1[8];
+assign mid2=lfsr_2[10];
+assign mid3=lfsr_3[10];
+
+
+wire maj;
+assign maj=majority(mid1, mid2, mid3);
+
+wire newbit1, newbit2, newbit3;
+assign newbit1= ( lfsr_1[13] ^ lfsr_1[16] ^ lfsr_1[17] ^ lfsr_1[18] );
+assign newbit2= ( lfsr_2[20] ^ lfsr_2[21] ) ;
+assign newbit3= ( lfsr_3[7] ^ lfsr_3[20] ^ lfsr_3[21] ^ lfsr_3[22] );
+
+
+parameter IDLE=0;
+parameter KEYING=1;
+parameter RUNNING=2;
+
+
+always @(posedge Clk or negedge Reset_n) begin
+if (!Reset_n) begin: resetting
+
+ $display("a5 reset");
+ Doneloading <=0;
+ Bitout <=0;
+ {lfsr_1, lfsr_2, lfsr_3} <= 64'h 0;
+ {State, Counter, Phase} <=0;
+
+ end // reset
+else begin
+ case (State)
+
+ IDLE: begin: reset_but_no_key
+
+ if (Startloading) begin: startloadingkey
+ // $display("Loading key starts at %0d ", $time);
+ State <= KEYING;
+ {lfsr_1, lfsr_2, lfsr_3} <= 64'h 0;
+ Phase <=0; Counter<=0;
+ end // if
+ end // idle
+
+ KEYING: begin
+
+ case (Phase)
+
+ 0: begin: load64andclock
+
+ clockallwithkey;
+
+ // $display("Loading key bit %0b %0d at %0d %0x", Keybit, Counter, $time, lfsr_1);
+ if (Counter==63) begin
+ Counter <=0;
+ Phase <= Phase +1;
+ $display(" ");
+
+ end
+ else Counter <=Counter+1;
+ end
+
+ 1: begin: load22andclock
+
+ // $display("Loading frame bit %0b at %0d %0d %0x", Keybit, Counter, $time, lfsr_1);
+ clockallwithkey;
+
+ if (Counter==21) begin
+ Counter <=0;
+ Phase <= Phase +1;
+ end
+ else Counter <=Counter+1;
+ end
+
+ 2: begin: clock100
+
+ majclock;
+
+ if (Counter ==100) begin
+ $display("Done keying, now running %0d\n", $time);
+ State <= RUNNING;
+ end
+ else Counter <= Counter+1;
+ end
+ endcase // Phase
+ end // keying
+
+ RUNNING: begin
+
+ Doneloading <=1; // when done loading
+ Bitout <= hi_1 ^ hi_2 ^ hi_3;
+ majclock;
+
+ end // running
+ endcase // State
+ end // else not resetting
+end // always
+
+
+
+
+
+
+
+
+
+
+
+function majority;
+input a,b,c;
+
+begin
+ case({a,b,c}) // synopsys parallel_case
+ 3'b 000: majority=0;
+ 3'b 001: majority=0;
+ 3'b 010: majority=0;
+ 3'b 011: majority=1;
+
+ 3'b 100: majority=0;
+ 3'b 101: majority=1;
+ 3'b 110: majority=1;
+ 3'b 111: majority=1;
+ endcase
+end
+endfunction
+
+
+task clock1;
+begin
+ lfsr_1 <= ( lfsr_1 << 1 ) | newbit1;
+end
+endtask
+
+task clock2;
+begin
+ lfsr_2 <= (lfsr_2 << 1) | newbit2;
+end
+endtask
+
+task clock3;
+begin
+ lfsr_3 <= (lfsr_3 << 1) | newbit3;
+end
+endtask
+
+task clockall;
+begin
+ clock1;
+ clock2;
+ clock3;
+end
+endtask
+
+task clockallwithkey;
+begin
+ lfsr_1 <= ( lfsr_1 << 1 ) | newbit1 ^ Keybit;
+ lfsr_2 <= ( lfsr_2 << 1 ) | newbit2 ^ Keybit;
+ lfsr_3 <= ( lfsr_3 << 1 ) | newbit3 ^ Keybit;
+end
+endtask
+
+task majclock;
+begin
+ if (mid1 == maj) clock1;
+ if (mid2 == maj) clock2;
+ if (mid3 == maj) clock3;
+end
+endtask
+
+
+endmodule
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/**************** CUT HERE FOR TESTBENCH test_a5.v **************************
+
+module test_a5;
+
+
+reg Clk, Reset_n;
+wire Bitout; // output keystream
+
+reg Keybit; // input keybits 64 + 22
+reg Startloading; // initial keyload
+wire Doneloading; // signal done of keyloading
+
+
+reg [0:7] key [7:0];
+reg [22:0] frame;
+
+
+
+a5 dut(Clk, Reset_n,
+ Bitout,
+ Keybit,
+ Startloading,
+ Doneloading);
+
+
+always @(Clk) #5 Clk <= ~Clk;
+
+integer i,j;
+
+
+initial begin
+ #5
+ key[0]= 8'h 12;
+ key[1]= 8'h 23;
+ key[2]= 8'h 45;
+ key[3]= 8'h 67;
+
+ key[4]= 8'h 89;
+ key[5]= 8'h AB;
+ key[6]= 8'h CD;
+ key[7]= 8'h EF;
+
+ frame <= 22'h 134;
+ Clk <=0;
+ Reset_n <=1;
+ Startloading <=0;
+ Keybit <=0;
+
+ #10 Reset_n <=0;
+ #10 Reset_n <=1;
+
+ // key setup
+
+ #100
+ Startloading <=1; $display("Starting to key %0d", $time);
+ for (i=0; i<8; i=i+1) begin
+ for (j=0; j<8; j=j+1) begin
+ #10 Startloading <=0;
+ Keybit <= key[i] >> j;
+ end // j
+ end // i
+
+ for (i=0; i<22; i=i+1) begin
+ #10 Keybit <= frame[i];
+ end
+
+ wait(Doneloading); $display("Done keying %0d", $time);
+
+ $write("\nBits out: \n");
+ repeat (32) #10 $write("%b", Bitout);
+
+
+ $display("\nknown good=\n%b", 32'h 534EAA58);
+
+ #1000 $display("\nSim done."); $finish;
+end // init
+
+endmodule
+
+
+
+************************* END OF TESTBENCH ************************************/
+
+
+/**** SAMPLE OUTPUT
+
+a5 reset
+a5 reset
+Starting to key 125
+
+Done keying, now running 2000
+
+Done keying 2010
+
+Bits out:
+01010011010011101010101001011000
+known good=
+01010011010011101010101001011000
+
+Sim done.
+*********/
+
+
+// eof
+
personal git repositories of Harald Welte. Your mileage may vary