diff options
Diffstat (limited to 'A5.1/Verilog')
-rw-r--r-- | A5.1/Verilog/a5.v | 354 |
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 + |