EDA Playground lets you type in and run HDL code (using a selection of free and commercial simulators and synthesizers).
It's great for learning HDLs, it's great for testing out unfamiliar things and it's great for sharing code.
You can start typing straight away. But to run your code, you'll need to sign or log in. Logging in with a Google account gives you access to all non-commercial simulators and some commercial simulators:
To run commercial simulators, you need to register and log in with a username and password. Registration is free, and only pre-approved email's will have access to the commercial simulators.
205
class Bus;
rand logic [7:0] valor;
constraint impares {valor[0] == 1'b1;}
constraint pares {valor[0] == 1'b0;}
endclass
`timescale 1ns/1ps
interface test_if (
input bit reloj ,
input bit rst);
logic empieza ;
logic termina ;
logic [7:0] data_in ;
logic [3:0] data_out;
clocking md @(posedge reloj);
input #1ns data_out;
input #1ns data_in;
input #1ns empieza;
input #1ns termina;
endclocking:md;
clocking sd @(posedge reloj);
input #2ns data_out;
output #2ns data_in;
input #2ns termina;
output #2ns empieza;
endclocking:sd;
modport monitor (clocking md);
modport test (clocking sd);
modport duv (
input reloj ,
input rst ,
output termina ,
input empieza ,
input data_in ,
output data_out
);
endinterface
class Scoreboard;
reg [3:0] cola_targets [$];
reg [3:0] target,pretarget,salida_obtenida;
reg FINAL;
virtual test_if.monitor mports;
function new (virtual test_if.monitor mpuertos);
begin
this.mports = mpuertos;
end
endfunction
task monitor_input;
begin
while (1)
begin
@(mports.md);
if (mports.md.empieza==1'b1)
begin
pretarget=$floor($sqrt(int'(mports.md.data_in)));//funcion ideal de obtencion e raiz cuadrada
cola_targets={pretarget,cola_targets};//meto el valor deseado en la cola
end
end
end
endtask
task monitor_output;
begin
while (1)
begin
@(mports.md);
if (mports.md.termina==1'b1)
begin
FINAL=mports.md.termina;
target= cola_targets.pop_back();
salida_obtenida=mports.md.data_out;
assert (salida_obtenida==target) else $error("operacion mal realizada: la raiz cuadrada de %d es %d y tu diste %d",mports.md.data_in,target,salida_obtenida);
end
end
end
endtask
endclass
program estimulos
(test_if.test testar,
test_if.monitor monitorizar
);
//esto nos permitirá utilziar el operador ## para los ciclcos de reloj
covergroup valores_X;
idea1:coverpoint monitorizar.md.data_in;
idea2:coverpoint monitorizar.md.data_in
{
bins cero ={8'h00};
bins extremo = {8'h80};
}
endgroup;
//declaraciones de tres objetos
Bus busInst; //objeto de la clase para RSCG
valores_X veamos; //objeto del covergroup
Scoreboard sb;//objeto de la clase scoreboard
initial
begin
busInst = new;//construimos la case de valores random
veamos=new;//construimos el covergroup
sb=new(monitorizar); //construimos el scoreboard
fork
sb.monitor_input; //lanzo el procedimiento de monitorizacion cambio entrada y calculo del valor target
sb.monitor_output;//lanzo el procedimiento de monitorizacion cambio salida y comparacion ideal
join_none
testar.sd.empieza <= 1'b0;
testar.sd.data_in <= 8'd25;
repeat(3) @(testar.sd);
testar.sd.empieza <= 1'b1;
@(testar.sd);
testar.sd.empieza <= 1'b0;
@(negedge testar.sd.termina);
while ( veamos.get_coverage()<40)
begin
busInst.pares.constraint_mode(0);
$display("pruebo con impares");
assert (busInst.randomize()) else $fatal("randomization failed");
testar.sd.data_in<= busInst.valor;
veamos.sample();
@(testar.sd);
testar.sd.empieza <= 1'b1;
@(testar.sd);
testar.sd.empieza <= 1'b0;
@(negedge testar.sd.termina);
end
while ( veamos.get_coverage()<90)
begin
busInst.impares.constraint_mode(0);
busInst.pares.constraint_mode(1);
$display("pruebo con pares");
assert (busInst.randomize()) else $fatal("randomization failed");
testar.sd.data_in <= busInst.valor;
veamos.sample();
@(testar.sd);
testar.sd.empieza <= 1'b1;
@(testar.sd);
testar.sd.empieza <= 1'b0;
@(negedge testar.sd.termina);
end
$stop;
end
endprogram
module prueba_radicador();
// constants
// general purpose registers
reg CLK;
reg RESET;
//instanciacion del interfaz
test_if interfaz(.reloj(CLK),.rst(RESET));
//instanciación del disenyo
top_duv duv (.bus(interfaz));
//instanciacion del program
estimulos estim1 (.testar(interfaz),.monitorizar(interfaz));
// CLK
always
begin
CLK = 1'b0;
CLK = #50 1'b1;
#50;
end
// RESET
initial
begin
RESET=1'b1;
# 1 RESET=1'b0;
#99 RESET = 1'b1;
end
//volcado de valores para el visualizados
initial begin
$dumpfile("radicador.vcd");
$dumpvars(1,prueba_radicador.duv.radicador_duv.X);
$dumpvars(1,prueba_radicador.duv.radicador_duv.COUNT);
end
endmodule
xxxxxxxxxx
run -all;
coverage report -detail -all;
exit
//empezamos con el top donde se unen los elementos del data-path y e control-path
module top_duv (test_if.duv bus) ;
sed radicador_duv(
.CLK (bus.reloj), // Clock input
.RESET (bus.rst), // Active LOW ASINCRONOUS reset
.X (bus.data_in), // Data input
.COUNT (bus.data_out),// Data Output
.START (bus.empieza), // duv empieza
.FIN (bus.termina) //duv termina
);
endmodule
module sed(
CLK,
START,
RESET,
X,
FIN,
COUNT
);
input wire CLK;
input wire START;
input wire RESET;
input wire [7:0] X;
output wire FIN;
output wire [3:0] COUNT;
wire ENA_C;
wire ENA_R;
wire LOAD_R;
wire LOAD_C;
wire [9:0] PROD;
wire [4:0] VALUE;
wire [3:0] entrada_contador;
wire [8:0] X_E;
wire [3:0] SYNTHESIZED_WIRE_0;
wire [3:0] SYNTHESIZED_WIRE_1;
wire SYNTHESIZED_WIRE_2;
wire SYNTHESIZED_WIRE_3;
wire [8:0] SYNTHESIZED_WIRE_4;
wire SYNTHESIZED_WIRE_5;
wire [0:3] SYNTHESIZED_WIRE_6;
reg DFF_inst3;
wire SYNTHESIZED_WIRE_7;
wire SYNTHESIZED_WIRE_8;
reg DFF_inst2;
assign COUNT = SYNTHESIZED_WIRE_0;
assign SYNTHESIZED_WIRE_2 = 0;
assign SYNTHESIZED_WIRE_3 = 1;
assign SYNTHESIZED_WIRE_5 = 0;
assign SYNTHESIZED_WIRE_6 = 0;
assign SYNTHESIZED_WIRE_8 = 1;
lpm_add_sub_0 incrementador(
.dataa(SYNTHESIZED_WIRE_0),
.datab(SYNTHESIZED_WIRE_1),
.cout(VALUE[4]),
.result(VALUE[3:0]));
assign X_E[8] = SYNTHESIZED_WIRE_2;
REGGEN REG(
.CLK(CLK),
.CLRN(SYNTHESIZED_WIRE_3),
.ENA(ENA_R),
.DATA(PROD[8:0]),
.Q(SYNTHESIZED_WIRE_4));
lpm_compare_1 compararador(
.dataa(SYNTHESIZED_WIRE_4),
.datab(X_E),
.agb(SYNTHESIZED_WIRE_7)
);
lpm_constant_2 b2v_2(
.result(SYNTHESIZED_WIRE_1));
assign entrada_contador=VALUE[3:0];
assign LOAD_C =ENA_C|LOAD_R;
COUNTER CONT(
.CLK(CLK),
.CLRN(SYNTHESIZED_WIRE_3),
.SR(LOAD_R),
.ENA(LOAD_C),
.DATA(entrada_contador),
.COUNT(SYNTHESIZED_WIRE_0));
lpm_mult_3 elevador_cuadrado(
.dataa(VALUE),
.datab(VALUE),
.result(PROD));
assign X_E[7:0] = X;
FSM control_path(
.clk(CLK),
.reset(DFF_inst3),
.mayor(SYNTHESIZED_WIRE_7),
.start(START),
.ena_r(ENA_R),
.ena_c(ENA_C),
.clear_c(LOAD_R),
.fin(FIN));
always@(posedge CLK or negedge RESET)
begin
if (!RESET)
begin
DFF_inst2 <= 0;
end
else
begin
DFF_inst2 <= SYNTHESIZED_WIRE_8;
end
end
always@(posedge CLK or negedge RESET)
begin
if (!RESET)
begin
DFF_inst3 <= 0;
end
else
begin
DFF_inst3 <= DFF_inst2;
end
end
endmodule
//empezamos con los elementos del DATA-PATH
//los puramente combinacionales
//en primer lugar el incrementador combinacional, que es utilizado dos veces
//uno para la operación incrementar del estado regist
//otro para la operación incrementar del estado inc, lo cual hace que en esa situación
//la variable CONT implementado por el registro se comporte como un contador
module lpm_add_sub_0(dataa,datab,cout,result);
/* synthesis black_box */
input [3:0] dataa;
input [3:0] datab;
output cout;
output [3:0] result;
assign {cout,result}=dataa+datab;
endmodule
//comparador combinacional
module lpm_compare_1(dataa,datab,agb);
/* synthesis black_box */
input [8:0] dataa;
input [8:0] datab;
output agb;
assign agb=(dataa>datab);
endmodule
//constante uno para el incrementador
module lpm_constant_2(result);
/* synthesis black_box */
output [3:0] result;
assign result=4'b0001;
endmodule
//elevador al cuadradado combinacional
module lpm_mult_3(dataa,datab,result);
/* synthesis black_box */
input [4:0] dataa;
input [4:0] datab;
output [9:0] result;
assign result=dataa*dataa;
endmodule
//continuamos con los elementos secuenciales del data-path
//registro que utilizaremos para la variable CONT: tiene los modos de operacion sincronos
//reset
//cargar . si DATA es el incrementado se convierte en incrementar
//mantener
module COUNTER
#(parameter WIDTH=4)
(
input CLK, ENA, CLRN,LOAD,SR,
input [WIDTH-1:0] DATA,
output reg [WIDTH-1:0] COUNT
);
// Reset if needed, or increment if counting is enabled
always_ff @ (posedge CLK or negedge CLRN)
begin
if (!CLRN)
COUNT <= 0;
else if (ENA==1'b1) begin
if (SR)
COUNT<='0;
else
COUNT<=DATA;
end
end
endmodule
//registro simple que utilizaremos para la variable REG:tiene los modos de operacion sincronos
//cargar
//mantener
module REGGEN
#(parameter WIDTH=9)
(
input CLK, ENA, CLRN,
input [WIDTH-1:0] DATA,
output reg [WIDTH-1:0] Q
);
// Reset if needed, or increment if counting is enabled
always_ff @ (posedge CLK or negedge CLRN)
begin
if (!CLRN)
Q <= '0;
else if (ENA == 1'b1)
Q<=DATA;
end
endmodule
//FINALMENTE EL CONTROL-PATH realizado con el estilo de dos procesos
module FSM (input clk, reset, mayor, start, output logic ena_c,clear_c, ena_r, fin);
enum logic [5:0] { idle = 6'b0, init = 6'b000011, regist = 6'b000101, comp = 6'b001001, inc= 6'b010001, finall= 6'b100001 } state;
always_ff@(posedge clk or negedge reset) begin
if(!reset)
state <= idle;
else
case(state)
idle: if (start) state <= init;
init: state <= regist;
regist: state <= comp;
comp: if (mayor)
state <= finall;
else
state<=inc;
inc: state <= regist;
finall: if (!start) state<=idle;
endcase
end
always_comb begin
clear_c=0;
ena_c=0;
ena_r=0;
fin=0;
case(state)
init: clear_c=1;
regist: ena_r=1;
inc: ena_c=1;
finall: fin=1;
endcase
end
endmodule
Your account is not validated. If you wish to use commercial simulators, you need a validated account.
If you have already registered (or have recently changed your email address), but have not clicked on the link in the email we sent you, please do so. If you cannot find the email, please check your spam/junk folder. Or click here to resend the email.
If you have not already registered for a full account, you can do so by clicking below. You will then need to provide us with some identification information. You may wish to save your code first.
Creating, deleting, and renaming files is not supported during Collaboration. To encourage development of these features for Collaboration, tweet to @EDAPlayground
This playground may have been modified. Please save or copy before starting collaboration.
Your exercise has been submitted.