Kraklog
Day.80 Advavnced Verilog #3 본문
728x90
module my_ram(
input [7:0] data ,
input [4:0] address ,
input wren ,
input clk ,
output reg [7:0] q
);
reg [7:0] mem [0:31];
always @ (posedge clk) begin
if (wren)
mem[address] <= data;
q <= mem[address];
end
endmodule
`timescale 1ns/1ns
`define CLK_50Mhz 20
module tb_my_ram ();
reg [7:0] data ;
reg [4:0] address ;
reg wren ;
reg clk ;
wire [7:0] q ;
my_ram uMy_ram (
.data (data ),
.address(address ),
.wren (wren ),
.clk (clk ),
.q (q )
);
initial begin
$monitor("[%x] data= %x, address=%x, q=%x", $time, data,address,q);
end
initial begin
clk = 0;
forever #(`CLK_50Mhz/2) clk = ~clk;
end
initial begin
data = 8'hA;
wren = 1'b0;
address = 5'h0;
#30;
data = 8'hA;
#20;
address = 5'h1;
data = 8'hb;
#10;
address = 5'h2;
#10;
wren = 1'b1;
address = 5'h3;
end
endmodule
`define DBUS_SIZE 8
`define ABUS_SIZE 5
module my_ram (
input clk ,
input wren ,
input [`ABUS_SIZE-1:0] address ,
input [`DBUS_SIZE-1:0] data ,
output [`DBUS_SIZE-1:0] q
);
reg [`DBUS_SIZE-1:0] mem[0:2**`ABUS_SIZE-1]//2^5 = 32 bit
always @(posedge clk) begin
if (wren)
mem[address] <= data;
q<=mem[address];
end
// means,
/*
always @(posedge clk) begin
if (wren)
mem[address] <= data;
end
always @ (posedge clk) begin
q<=mem[address];
end
*/
endmodule
`timescale 1ns/1ns
`define DBUS_SIZE 8
`define ABUS_SIZE 5
`define CLK_50MHZ 20
module tb_my_ram2();
reg clk ;
reg wren ;
reg [`ABUS_SIZE-1:0] address ;
reg [`DBUS_SIZE-1:0] data ;
wire [`DBUS_SIZE-1:0] q ;
my_ram2 uMy_ram (
.clk (clk ) ,
.wren (wren ) ,
.address(address) ,
.data (data ) ,
.q (q )
);
initial
fork
clk_gen();
cntl_gen();
data_gen();
join
task clk_gen;
begin
clk = 1'b0;
forever #(`CLK_50MHZ/2) clk = ~clk;
end
endtask
task cntl_gen;
begin
wren = 1'b0;
address = 5'b0;
repeat(3) @(negedge clk);
address = 5'h5;
@(negedge clk);
address = 5'h6;
@(negedge clk);
wren = 1'b1;
address = 5'h5;
@(negedge clk);
address = 5'h6;
end
endtask
task data_gen;
begin
data = 8'hAA;
repeat(5) @(negedge clk);
data = 8'h55;
end
endtask
endmodule
`define DBUS_SIZE 8
`define ABUS_SIZE 5
module my_ram2 (
input clk ,
input wren ,
input [`ABUS_SIZE-1:0] address ,
input [`DBUS_SIZE-1:0] data ,
output reg [`DBUS_SIZE-1:0] q
);
reg [`DBUS_SIZE-1:0] mem[0:2**`ABUS_SIZE-1];//2^5 = 32 bit
reg [`DBUS_SIZE-1:0] mem_out;
always @(posedge clk) begin
if (wren)
mem[address] <= data;
end
always @ (posedge clk) begin
mem_out <= mem[address]; // pipeline
q <= mem_out[address];
end
// means,
/*always @ (posedge clk) begin
if (wren)
mem[address] <= data;
q <= mem[address];
end */
endmodule
Pipe line 을 활용해서 클럭을 하나 미뤄서 출력을 보게 만들었음.
`timescale 1ns/1ns
`define CLK_50Mhz 20
module tb_my_ram ();
reg [7:0] data ;
reg [4:0] address ;
reg wren ;
reg clk ;
wire [7:0] q ;
my_ram uMy_ram (
.data (data ),
.address(address ),
.wren (wren ),
.clk (clk ),
.q (q )
);
initial begin
$monitor("[%x] data= %x, address=%x, q=%x", $time, data,address,q);
end
initial begin
clk = 0;
forever #(`CLK_50Mhz/2) clk = ~clk;
end
initial begin
wren= 1;
forever #(`CLK_50Mhz) wren = ~wren;
end
initial begin
address = 5'h0;
forever #30 begin
address <= address + 1;
end
end
initial begin
data = 8'h0;
forever #40 begin
data <= data +1;
end
end
endmodule
자동으로 1씩 늘어나게 코딩
wren 클럭에 따라 3 6 9 ... 값들만 할당이 되어 나타난다.
module my_shift (
input clk ,
input aclr_n ,
input enable ,
input shiftin ,
output reg [7:0] q
);
always @ (posedge clk, negedge aclr_n)
if (!aclr_n)
q[7:0] <= 0;
else if (enable)
q[7:0] <= {q[6:0],shiftin};
endmodule
`timescale 1ns/1ns
`define CLK_50Mhz 20
module tb_my_shift();
reg clk ;
reg aclr_n ;
reg enable ;
reg shiftin ;
wire [7:0] q ;
my_shift uMy_shift (
.clk (clk ),
.aclr_n (aclr_n ),
.enable (enable ),
.shiftin(shiftin),
.q (q )
);
initial fork
clk_gen();
join
task clk_gen;
begin
clk = 0;
forever #(`CLK_50Mhz/2) clk = ~clk;
end
endtask
always @(posedge clk, negedge aclr_n) begin
end
initial begin
aclr_n = 1'b0;
#20;
enable = 1'b0;
aclr_n = 1'b1;
#10;
enable = 1'b1;
shiftin = 1'b0;
#10
shiftin = 1'b1;
#10;
end
endmodule
module my_shift2 (
input clk ,
input aclr_n ,
input enable ,
input shiftin ,
output reg [7:0] q
);
always @ (posedge clk, negedge aclr_n)
if (!aclr_n)
q[7:0] <= 0;
else if (enable)
q[7:0] <= {q[6:0],shiftin};
endmodule
`timescale 1ns/1ns
`define CLK_50Mhz 20
module tb_my_shift2();
reg clk ;
reg aclr_n ;
reg enable ;
reg shiftin ;
wire [7:0] q ;
my_shift2 uMy_shift (
.clk (clk ),
.aclr_n (aclr_n ),
.enable (enable ),
.shiftin(shiftin),
.q (q )
);
initial fork
clk_gen();
reset_gen();
ctrl_gen();
data_gen();
join
task clk_gen;
begin
clk = 0;
forever #(`CLK_50Mhz/2) clk = ~clk;
end
endtask
task reset_gen;
begin
aclr_n =1'b1;
repeat(2) @(negedge clk);
aclr_n =1'b0;
repeat(2) @(negedge clk);
aclr_n =1'b1;
end
endtask
task ctrl_gen;
begin
enable = 1'b0;
repeat (6) @(negedge clk);
enable = 1'b1;
end
endtask
task data_gen;
begin
shiftin=1'b0;
repeat(5)
shiftin=1'b1;
@(negedge clk);
@(negedge clk);
shiftin=1'b0;
@(negedge clk);
@(negedge clk);
shiftin=1'b1;
@(negedge clk);
shiftin=1'b0;
@(negedge clk);
shiftin=1'b1;
@(negedge clk);
shiftin=1'b1;
@(negedge clk);
end
endtask
endmodule
728x90
'[Harman] 하만 반도체 설계 > VerilogHDL' 카테고리의 다른 글
Day.82 Advanced Verilog #5 (0) | 2023.11.15 |
---|---|
Day.81 Advanced Verilog #4 (0) | 2023.11.14 |
Day.79 Advanced Verilog #2 (0) | 2023.11.10 |
Day.78 Advanced Verilog #1-원치 않는 Latch 제거 (0) | 2023.11.09 |
Day24. Simple UART RX (0) | 2023.07.28 |