Diferență între revizuiri ale paginii „CID Aplicatii 5”
Linia 1: | Linia 1: | ||
− | ==1. | + | ==1. Barrel shifter== |
− | |||
− | [[ | + | '''Barrel shifter''' este un circuit combinational folosit pentru operatiile de rotire si deplasare. Acest circuit primeste la intrare un sir de ''n'' biti ('''in [n-1:0]''') si un alt semnal de ''m'' biti (''amount [m-1:0]''), cu ajutorul caruia se comanda numarul de pozitii cu care se va efectua operatia de rotire/deplasare. Intre dimensiunile celor doua semnale exista relatia ''n = 2<sup>m</sup>''. |
− | + | Pentru implementarea eficienta a unui astfel de circuit, il vom imparti in ''m'' etape: ''stage_0, stage_1 … stage_m-1''. In fiecare din cele ''m'' etape, vom avea un multiplexor care va avea urmatoarul comportament: daca etapa curenta este ''p'', multiplexorul va folosi ca semnal de selectie ''amount[p]''. Daca ''amount[p]'' este 0, mai departe va trece semnalul din etapa anterioara, nemodificat. Altfel, daca ''amount[p]'' este 1, va trece mai departe semnalul din etapa anterioara, deplasat sau rotit cu ''2<sup>p</sup>'' pozitii. | |
− | |||
− | + | '''Circuit de deplasare la dreapta pentru siruri de 8 biti''' | |
− | + | [[Fișier:Barrel shift right.png]] | |
− | |||
<syntaxhighlight lang="Verilog"> | <syntaxhighlight lang="Verilog"> | ||
− | module | + | module barrel_right_shifter( |
− | input [7:0] | + | input [7:0] in, |
− | input | + | input [2:0] amount, |
− | + | output [7:0] out | |
− | |||
); | ); | ||
+ | |||
+ | wire [7:0] stage0, stage1; | ||
− | + | assign stage0 = (amount[0] == 1) ? {1'b0, in[7:1]} : in; | |
− | assign | + | assign stage1 = (amount[1] == 1) ? {2'b0, stage0[7:2]} : stage0; |
− | + | assign out = (amount[2] == 1) ? {4'b0, stage1[7:4]} : stage1; | |
− | assign | ||
endmodule | endmodule | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | ''' | + | '''Exemplu de modul de test pentru circuitul de deplasare la dreapta pentru siruri de 8 biti''' |
− | |||
− | |||
− | |||
− | |||
<syntaxhighlight lang="Verilog"> | <syntaxhighlight lang="Verilog"> | ||
`timescale 1ns/1ps | `timescale 1ns/1ps | ||
− | module | + | module barrel_right_shifter_TB(); |
− | reg [7:0] | + | reg [7:0] in_t; |
− | reg | + | reg [2:0] amount_t; |
− | + | wire [7:0] out_t; | |
− | wire [7:0] | ||
− | |||
− | + | integer idx; | |
+ | reg flag; | ||
initial begin | initial begin | ||
− | + | flag = 0; | |
− | + | in_t = 8'b11000011; | |
− | + | ||
− | + | for(idx = 0; idx < 8; idx = idx + 1) begin | |
− | + | amount_t = idx[2:0]; | |
− | + | #1; | |
− | + | if(out_t != (in_t >> amount_t)) | |
− | + | flag = 1; | |
+ | end | ||
+ | |||
+ | if(flag == 0) $display("TEST_PASS"); | ||
+ | else $display("TEST_FAIL"); | ||
+ | |||
+ | $stop(); | ||
end | end | ||
− | + | barrel_right_shifter DUT( | |
− | . | + | .in(in_t), |
− | . | + | .amount(amount_t), |
− | . | + | .out(out_t) |
− | + | ); | |
− | + | ||
endmodule | endmodule | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | ''' | + | '''Circuit de rotire la dreapta pentru siruri de 8 biti''' |
− | + | [[Fișier:Barrel rotate right.png]] | |
− | + | <syntaxhighlight lang="Verilog"> | |
+ | module barrel_right_shifter( | ||
+ | input [7:0] in, | ||
+ | input [2:0] amount, | ||
+ | output [7:0] out | ||
+ | ); | ||
+ | |||
+ | wire [7:0] stage0, stage1; | ||
+ | |||
+ | assign stage0 = (amount[0] == 1) ? {in[0], in[7:1]} : in; | ||
+ | assign stage1 = (amount[1] == 1) ? {stage0[1:0], stage0[7:2]} : stage0; | ||
+ | assign out = (amount[2] == 1) ? {stage1[3:0], stage1[7:4]} : stage1; | ||
+ | endmodule | ||
+ | </syntaxhighlight> | ||
==2. Realizarea unei unitati de adunare ce are capacitatea de a selecta intre mai multi operanzi== | ==2. Realizarea unei unitati de adunare ce are capacitatea de a selecta intre mai multi operanzi== | ||
Linia 78: | Linia 89: | ||
[[Fișier:Adder 4 inputs.png]] | [[Fișier:Adder 4 inputs.png]] | ||
− | Circuitul ALU este format din trei module: doua multiplexoare identice ( | + | Circuitul ''ALU'' este format din trei module: doua multiplexoare identice (''M1'' si ''M2'') si un modul de adunare (''ADD''). |
− | Modulul | + | Modulul ''MUX'' are doua intrari pe 8 biti, selectand la iesire una dintre acestea pe baza intrarii de selectie (''SEL''). De exemplu, daca ''SEL'' este 0, iesirea multiplexorului va fi ''A''. Daca ''SEL'' este 1, iesirea multiplexorului este ''B''. |
− | Sumatorul | + | Sumatorul ''ADD'' va folosi ca operanzi cele doua iesiri ale multiplexoarelor. Daca ''SEL'' este 0, ''M1'' va avea la iesire ''A'', iar ''M2'' va avea la iesire ''C''. Asadar, operanzii sumatorului vor fi ''A'' si ''C'', iar iesirea modulului ''ALU'' va fi ''A + C''. Daca ''SEL'' este 1, ''M1'' va avea la iesire ''B'', iar ''M2'' va avea la iesire ''D''. Asadar, operanzii sumatorului vor fi ''B'' si ''D'', iar iesirea modulului ''ALU'' va fi ''B + D''. |
'''Implementarea Verilog a modulului MUX''' | '''Implementarea Verilog a modulului MUX''' |
Versiunea curentă din 27 martie 2021 10:10
1. Barrel shifter
Barrel shifter este un circuit combinational folosit pentru operatiile de rotire si deplasare. Acest circuit primeste la intrare un sir de n biti (in [n-1:0]) si un alt semnal de m biti (amount [m-1:0]), cu ajutorul caruia se comanda numarul de pozitii cu care se va efectua operatia de rotire/deplasare. Intre dimensiunile celor doua semnale exista relatia n = 2m.
Pentru implementarea eficienta a unui astfel de circuit, il vom imparti in m etape: stage_0, stage_1 … stage_m-1. In fiecare din cele m etape, vom avea un multiplexor care va avea urmatoarul comportament: daca etapa curenta este p, multiplexorul va folosi ca semnal de selectie amount[p]. Daca amount[p] este 0, mai departe va trece semnalul din etapa anterioara, nemodificat. Altfel, daca amount[p] este 1, va trece mai departe semnalul din etapa anterioara, deplasat sau rotit cu 2p pozitii.
Circuit de deplasare la dreapta pentru siruri de 8 biti
module barrel_right_shifter(
input [7:0] in,
input [2:0] amount,
output [7:0] out
);
wire [7:0] stage0, stage1;
assign stage0 = (amount[0] == 1) ? {1'b0, in[7:1]} : in;
assign stage1 = (amount[1] == 1) ? {2'b0, stage0[7:2]} : stage0;
assign out = (amount[2] == 1) ? {4'b0, stage1[7:4]} : stage1;
endmodule
Exemplu de modul de test pentru circuitul de deplasare la dreapta pentru siruri de 8 biti
`timescale 1ns/1ps
module barrel_right_shifter_TB();
reg [7:0] in_t;
reg [2:0] amount_t;
wire [7:0] out_t;
integer idx;
reg flag;
initial begin
flag = 0;
in_t = 8'b11000011;
for(idx = 0; idx < 8; idx = idx + 1) begin
amount_t = idx[2:0];
#1;
if(out_t != (in_t >> amount_t))
flag = 1;
end
if(flag == 0) $display("TEST_PASS");
else $display("TEST_FAIL");
$stop();
end
barrel_right_shifter DUT(
.in(in_t),
.amount(amount_t),
.out(out_t)
);
endmodule
Circuit de rotire la dreapta pentru siruri de 8 biti
module barrel_right_shifter(
input [7:0] in,
input [2:0] amount,
output [7:0] out
);
wire [7:0] stage0, stage1;
assign stage0 = (amount[0] == 1) ? {in[0], in[7:1]} : in;
assign stage1 = (amount[1] == 1) ? {stage0[1:0], stage0[7:2]} : stage0;
assign out = (amount[2] == 1) ? {stage1[3:0], stage1[7:4]} : stage1;
endmodule
2. Realizarea unei unitati de adunare ce are capacitatea de a selecta intre mai multi operanzi
Circuitul ALU este format din trei module: doua multiplexoare identice (M1 si M2) si un modul de adunare (ADD). Modulul MUX are doua intrari pe 8 biti, selectand la iesire una dintre acestea pe baza intrarii de selectie (SEL). De exemplu, daca SEL este 0, iesirea multiplexorului va fi A. Daca SEL este 1, iesirea multiplexorului este B.
Sumatorul ADD va folosi ca operanzi cele doua iesiri ale multiplexoarelor. Daca SEL este 0, M1 va avea la iesire A, iar M2 va avea la iesire C. Asadar, operanzii sumatorului vor fi A si C, iar iesirea modulului ALU va fi A + C. Daca SEL este 1, M1 va avea la iesire B, iar M2 va avea la iesire D. Asadar, operanzii sumatorului vor fi B si D, iar iesirea modulului ALU va fi B + D.
Implementarea Verilog a modulului MUX
module MUX(
input [7:0] in0,
input [7:0] in1,
input sel,
output [7:0] out
);
assign out = (sel == 0) ? in0 : in1;
endmodule
Implementarea Verilog a modulului Adder
module Adder(
input [7:0] in0,
input [7:0] in1,
output [7:0] sum
);
assign sum = in0 + in1;
endmodule
Implementarea Verilog a modulului ALU
module ALU(
input [7:0] A,
input [7:0] B,
input [7:0] C,
input [7:0] D,
input SEL,
output [7:0] OUT
);
wire [7:0] w1, w2;
MUX M1(
.in0(A),
.in1(B),
.sel(SEL),
.out(w1)
);
MUX M2(
.in0(C),
.in1(D),
.sel(SEL),
.out(w2)
);
Adder ADD(
.in0(w1),
.in1(w2),
.sum(OUT)
);
endmodule
Implementarea Verilog a modulului de test
module ALU_TB();
reg [7:0] A_t, B_t, C_t, D_t;
reg SEL_t;
wire OUT_t;
initial begin
A_t = 8'b00000001;
B_t = 8'b00000101;
C_t = 8'b00001111;
D_t = 8'b00001101;
SEL_t = 0;
#1 SEL_t = 1;
#1 B_t = 8'b00000000;
A_t = 8'b00000011;
#1 SEL_t = 0;
#1 $stop();
end
ALU DUT(
.A(A_t),
.B(B_t),
.C(C_t),
.D(D_t),
.SEL(SEL_t),
.OUT(OUT_t)
);
endmodule