//PMK LAB 6, ZADANIE 12 //tomek@cedro.info // module cdr_pmk6 (A, B, Y, sel, clk, rst, flag, ovf); input [7:0] A, B; input [1:0] sel; input clk, rst; output [7:0] Y; output flag, ovf; reg [7:0] Y,tmpA; reg [8:0] serialCount; reg [3:0] bitcnt; reg ovf, flag; always @(posedge clk) begin if (rst==1) begin flag=1'b0; //zerujemy flage wczytania danej szeregowej. jesli wlasnie wczytany jest 8bit, flaga ustawi za chwile. case(sel) 2'b00: // A+B begin {ovf,Y}=A+B; end 2'b01: // serial input A[7], serial input LSB to MSB begin ovf=Y[7]; //wyjscie rejstru - moze byc wykorzystane do lancuchowania rejstrow Y=Y<<1|A[7]; //lub Y={Y[6:0],A[7]}; serialCount=serialCount<<1|serialCount[8]; //tutaj moglbym zrobic inkrementacje i modulo flag=serialCount[8]; //ale mysle ze 8 przerzutnikow zajmie mniej ukladu end 2'b11: // min((Y+B),A) begin if (Y+B9 -> BCD=9 begin //Zastanawialem sie czy lepiej bedzie umiescic A w rejstrze //czy uzywac za kazdym razem A[7:4]>9?9:A[7:4], co chyba jednak zuzyloby wiecej zasobow tmpA=A; if (tmpA[7:4]>9) tmpA[7:4]=9; if (tmpA[3:0]>9) tmpA[3:0]=9; if (Y[7:4]>9) Y[7:4]=9; if (Y[3:0]>9) Y[3:0]=9; //od mniejszej odejmuje sie wieksza, jesli wieksza od 9 to odejmuje sie 6 //Y[3:0]=(Y[3:0]-tmpA[3:0]>9)?(Y[3:0]-tmpA[3:0]-6; Y[7:4]=Y[7:4]-1;):Y[3:0]-tmpA[3:0]; Y[3:0]=Y[3:0]-tmpA[3:0]; if (Y[3:0]>9) begin Y[3:0]=Y[3:0]-6; Y[7:4]=Y[7:4]-1; end Y[7:4]=Y[7:4]-tmpA[7:4]; if (Y[7:4]>9) begin Y[7:4]=Y[7:4]-6; ovf=1; //ovf oznacza w tym przypadku niedobor ze starszego polbajtu end end default: begin Y=0; flag=1'b0; ovf=1'b0; end endcase end end //licznik bitow zeruje wybranie pierwszego trybu pracy (01), ale tez reset. licznik pracuje cyklicznie jako zamkniety rejstr przesowny. //rejstr przesowny zajmie mniej ukladu niz sumator z ukladem modulo..? always @(posedge sel[0]) if (sel==2'b01) serialCount=1; //reagujemy na reset always @(rst) begin if (rst==0) begin Y=0; ovf=0; flag=0; serialCount=1; end; end endmodule //testbench module testbench; reg [1:0] sel; reg [7:0] A, B; wire [7:0] Y; wire flag,ovf; reg clk, rst; cdr_pmk6 u1(A, B, Y, sel, clk, rst, flag, ovf); //instancja alu initial begin $dumpvars; //reset $display("Podstawy Mikroelektroniki, LAB6, ZAD12, TOMEK CEDRO"); $display("--------------------------------------------------- \nSTART (okres zegara: 10ns)"); #0 clk=0; rst=0; A=0; B=0; #4 rst=1; $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); #2 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); //dodawanie #4 sel=2'b00; $display("\nDODAWANIE: \ntime=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf, "\n---"); A='d3; B='d2; #10 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A='d50; B='d16; #10 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A='d150; B='d160; #10 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); //czytanie szeregowe sel=2'b01; $display("\nCZYTANIE SZEREGOWE:"); $display("0: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf, "\n---"); A='d1000_0000; B=0; #10 $display("0: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d1; #10 $display("1: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d1; #10 $display("2: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d1; #10 $display("3: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d1; #10 $display("4: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d1; #10 $display("5: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d1; #10 $display("6: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d1; #10 $display("7: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); $display("--reset 2ns--"); A[7]='d1; #2 rst=0; #2 rst=1; #6 $display("0: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d1; #10 $display("1: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d0; #10 $display("2: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d1; #10 $display("3: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d0; #10 $display("4: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d1; #10 $display("5: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d0; #10 $display("6: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d1; #10 $display("7: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); //MIN((Y+B),A) $display("\nMIN((Y+B),A):"); $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf, "\n---"); sel='b11; A='d70; B='d4; #10 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A='d75; B='d5; #10 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A='d44; B='d250; #10 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); //(Y-A)BCD $display("\n(Y-A)BCD: /UWAGA: BCD>9 -> BCD=9; BCD(1-2=9 i ovf=1)/"); $display("time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf,"\n---"); sel='b10; A='b1; #10 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); $display("time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A='d9; #10 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); $display("time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A='d16; #10 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); $display("time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A='d4; #10 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); $display("time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A='d7; #10 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); $display("time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); $display("\n"); $finish; end always begin #5 clk=~clk; end endmodule //PMK LAB 6, ZADANIE 12 //tomek@cedro.info // module cdr_pmk6 (A, B, Y, sel, clk, rst, flag, ovf); input [7:0] A, B; input [1:0] sel; input clk, rst; output [7:0] Y; output flag, ovf; reg [7:0] Y,tmpA; reg [8:0] serialCount; reg [3:0] bitcnt; reg ovf, flag; always @(posedge clk) begin if (rst==1) begin flag=1'b0; //zerujemy flage wczytania danej szeregowej. jesli wlasnie wczytany jest 8bit, flaga ustawi za chwile. case(sel) 2'b00: // A+B begin {ovf,Y}=A+B; end 2'b01: // serial input A[7], serial input LSB to MSB begin ovf=Y[7]; //wyjscie rejstru - moze byc wykorzystane do lancuchowania rejstrow Y=Y<<1|A[7]; //lub Y={Y[6:0],A[7]}; serialCount=serialCount<<1|serialCount[8]; //tutaj moglbym zrobic inkrementacje i modulo flag=serialCount[8]; //ale mysle ze 8 przerzutnikow zajmie mniej ukladu end 2'b11: // min((Y+B),A) begin if (Y+B9 -> BCD=9 begin //Zastanawialem sie czy lepiej bedzie umiescic A w rejstrze //czy uzywac za kazdym razem A[7:4]>9?9:A[7:4], co chyba jednak zuzyloby wiecej zasobow tmpA=A; if (tmpA[7:4]>9) tmpA[7:4]=9; if (tmpA[3:0]>9) tmpA[3:0]=9; if (Y[7:4]>9) Y[7:4]=9; if (Y[3:0]>9) Y[3:0]=9; //od mniejszej odejmuje sie wieksza, jesli wieksza od 9 to odejmuje sie 6 //Y[3:0]=(Y[3:0]-tmpA[3:0]>9)?(Y[3:0]-tmpA[3:0]-6; Y[7:4]=Y[7:4]-1;):Y[3:0]-tmpA[3:0]; Y[3:0]=Y[3:0]-tmpA[3:0]; if (Y[3:0]>9) begin Y[3:0]=Y[3:0]-6; Y[7:4]=Y[7:4]-1; end Y[7:4]=Y[7:4]-tmpA[7:4]; if (Y[7:4]>9) begin Y[7:4]=Y[7:4]-6; ovf=1; //ovf oznacza w tym przypadku niedobor ze starszego polbajtu end end default: begin Y=0; flag=1'b0; ovf=1'b0; end endcase end end //licznik bitow zeruje wybranie pierwszego trybu pracy (01), ale tez reset. licznik pracuje cyklicznie jako zamkniety rejstr przesowny. //rejstr przesowny zajmie mniej ukladu niz sumator z ukladem modulo..? always @(posedge sel[0]) if (sel==2'b01) serialCount=1; //reagujemy na reset always @(rst) begin if (rst==0) begin Y=0; ovf=0; flag=0; serialCount=1; end; end endmodule //testbench module testbench; reg [1:0] sel; reg [7:0] A, B; wire [7:0] Y; wire flag,ovf; reg clk, rst; cdr_pmk6 u1(A, B, Y, sel, clk, rst, flag, ovf); //instancja alu initial begin $dumpvars; //reset $display("Podstawy Mikroelektroniki, LAB6, ZAD12, TOMEK CEDRO"); $display("--------------------------------------------------- \nSTART (okres zegara: 10ns)"); #0 clk=0; rst=0; A=0; B=0; #4 rst=1; $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); #2 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); //dodawanie #4 sel=2'b00; $display("\nDODAWANIE: \ntime=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf, "\n---"); A='d3; B='d2; #10 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A='d50; B='d16; #10 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A='d150; B='d160; #10 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); //czytanie szeregowe sel=2'b01; $display("\nCZYTANIE SZEREGOWE:"); $display("0: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf, "\n---"); A='d1000_0000; B=0; #10 $display("0: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d1; #10 $display("1: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d1; #10 $display("2: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d1; #10 $display("3: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d1; #10 $display("4: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d1; #10 $display("5: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d1; #10 $display("6: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d1; #10 $display("7: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); $display("--reset 2ns--"); A[7]='d1; #2 rst=0; #2 rst=1; #6 $display("0: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d1; #10 $display("1: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d0; #10 $display("2: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d1; #10 $display("3: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d0; #10 $display("4: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d1; #10 $display("5: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d0; #10 $display("6: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A[7]='d1; #10 $display("7: time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); //MIN((Y+B),A) $display("\nMIN((Y+B),A):"); $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf, "\n---"); sel='b11; A='d70; B='d4; #10 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A='d75; B='d5; #10 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A='d44; B='d250; #10 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); //(Y-A)BCD $display("\n(Y-A)BCD: /UWAGA: BCD>9 -> BCD=9; BCD(1-2=9 i ovf=1)/"); $display("time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf,"\n---"); sel='b10; A='b1; #10 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); $display("time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A='d9; #10 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); $display("time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A='d16; #10 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); $display("time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A='d4; #10 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); $display("time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); A='d7; #10 $display("time=", $time, " sel=", sel, " A=", A, " B=", B, " Y=", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); $display("time=", $time, " sel=", sel, " A=%b", A, " B=", B, " Y=%b", Y, " clk=", clk, " flag=", flag, " ovf=", ovf); $display("\n"); $finish; end always begin #5 clk=~clk; end endmodule