// DeCSS.V module DeCSS(Clk, Resetn, Keyin, Secin, Start, Secout, Dvalid); input Clk, Resetn; input [7:0] Keyin; input [7:0] Secin; input Start; output [7:0] Secout; output Dvalid; // register the outputs reg [7:0] Secout; reg Dvalid; // internal state reg [8:0] t1,t5; reg [7:0] t2, t4, t6; reg [31:0] t3; reg [15:0] ctr; reg [7:0] state; // FSM state // wire up the CSTable ROMs to appropriate registers wire [7:0] tab1out, tab2out, tab3out, tab4out, tab5out; CSTable_1 tab1(Clk, Resetn, Secin, tab1out); CSTable_2 tab2(Clk, Resetn, t2, tab2out); CSTable_3 tab3(Clk, Resetn, t1, tab3out); CSTable_4 tab4(Clk, Resetn, t6, tab4out); CSTable_5 tab5(Clk, Resetn, t4, tab5out); parameter STATE_IDLE=0; parameter STATE_INIT1=1; parameter STATE_INIT2=2; parameter STATE_INIT3=3; parameter STATE_INIT4=4; parameter STATE_INIT5=5; parameter STATE_INIT6=6; parameter STATE_INIT7=7; parameter STATE_MIXSTATE=8; parameter STATE_MIX1=13; parameter STATE_MIX2=9; parameter STATE_MIX3=10; parameter STATE_MIX4=11; parameter STATE_GRIND=12; parameter STATE_WAITPADDING=14; parameter MAX_COUNT= 32'h 800; always @(posedge Clk or negedge Resetn) begin if (!Resetn) begin: reset t1<=0; t2<=0; t3<=0; t4<=0; t5<=0; t6<=0; ctr<=0; state<=0; Dvalid<=0; Secout<=0; end // reset else casex (state) STATE_IDLE: begin if (Start) begin t2<=0; t3<=0; t4<=0; t5<=0; t6<=0; t1<= Keyin^Secin | 32'h 100; // Secin is Sec[0x54], Keyin is Key[0] ctr<=0; Dvalid<=0; Secout<=0; state<=STATE_INIT1; $display("starting"); $display("time=", $time); end end STATE_INIT1: begin t2<= Keyin^Secin; state<=STATE_INIT2; end STATE_INIT2: begin t3[7:0]<= Keyin^Secin; // start of int access t4[3:0]<= Keyin^Secin; // t4=t3&7; state<=STATE_INIT3; end STATE_INIT3: begin t3[15:8]<= Keyin^Secin; state<=STATE_INIT4; end STATE_INIT4: begin t3[23:16]<= Keyin^Secin; state<=STATE_INIT5; end STATE_INIT5: begin t3[31:24]<= Keyin^Secin; state<=STATE_INIT6; end STATE_INIT6: begin $display("t3=%x", t3); t3<= (t3<<1) + 8 - t4; state<=STATE_MIX1; // WAITPADDING; end STATE_WAITPADDING: begin: waiting if (ctr==19) begin state<=STATE_MIX1; // STATE; ctr <=0; // $display("End of init: %x %x %x %x %x %x\n", t1,t2,t3,t4,t5,t6); // ok end else ctr <= ctr+1; $display("waiting...%d", ctr); end STATE_MIX1: begin // $display("End of init: %x %x %x %x %x %x", t1,t2,t3,t4,t5,t6); // ok t4<= tab2out^tab3out; // driven by t2, t1 respectively // $display("t4= %x ^ %x", tab2out, tab3out); t2<= t1>>1; t6<= (((((((t3>>3)^t3)>>1)^t3)>>8)^t3)>>5)& 32'h ff; state <= STATE_MIX2; Dvalid <=0; end STATE_MIX2: begin // $display("t6=%x t3=%x",t6,t3); t1 <= ((t1&1)<<8)^t4; t3 <= (t3<<8)|t6; state <= STATE_MIX3; end STATE_MIX3: begin t4 <= tab5out; // driven by t4 which settles in prev step t6 <= tab4out; // driven by t6 // $display("new t6=%x", t6); $display("t4=%x", tab5out); state <= STATE_MIX4; end STATE_MIX4: begin t5 <= t5 + t6 + t4; state <= STATE_GRIND; end STATE_GRIND: begin // $display("grind: in=%x %x %x %x %x %x %x", Secin, t1,t2,t3,t4,t5,t6); // $display("time=%d", $time); Secout <= tab1out ^ t5; Dvalid <=1; t5 <= t5>>8; state <= STATE_MIX1; // $display("secin=%d\n", Secin); if (ctr >= MAX_COUNT) begin $display("ctr=%d", ctr); state<= STATE_IDLE; end else ctr <= ctr+1; end endcase // main end // always endmodule // eof