Compare commits
3 Commits
9ff7d002c1
...
b3d11de769
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b3d11de769 | ||
|
|
cec82dc58f | ||
|
|
5cc4b5adf4 |
24
ram/ram.v
Normal file
24
ram/ram.v
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
Ram Sincrona
|
||||||
|
*/
|
||||||
|
|
||||||
|
module ram #(
|
||||||
|
parameter DEPTH = 256, // posiciones
|
||||||
|
parameter W = 16 // bits por posicion
|
||||||
|
) (
|
||||||
|
input clk,
|
||||||
|
input wr_en,
|
||||||
|
input [$clog2(DEPTH)-1:0] addr,
|
||||||
|
input [W-1:0] wr_data,
|
||||||
|
output reg [W-1:0] rd_data
|
||||||
|
);
|
||||||
|
reg [W-1:0] mem [0:DEPTH-1];
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (wr_en)
|
||||||
|
mem[addr] <= wr_data;
|
||||||
|
else
|
||||||
|
rd_data <= mem[addr];
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
54
ram/ram_tb.v
Normal file
54
ram/ram_tb.v
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
Ram Sincrona testbench
|
||||||
|
*/
|
||||||
|
`include "ram/ram.v"
|
||||||
|
|
||||||
|
module ram_tb;
|
||||||
|
reg clk, wr_en;
|
||||||
|
reg [7:0] addr;
|
||||||
|
reg [15:0] wr_data;
|
||||||
|
wire [15:0] rd_data;
|
||||||
|
|
||||||
|
ram ram1(
|
||||||
|
.clk(clk),
|
||||||
|
.wr_en(wr_en),
|
||||||
|
.addr(addr),
|
||||||
|
.wr_data(wr_data),
|
||||||
|
.rd_data(rd_data)
|
||||||
|
);
|
||||||
|
|
||||||
|
initial clk = 0;
|
||||||
|
always #5 clk = ~clk;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$dumpfile("ram/ram.vcd");
|
||||||
|
$dumpvars(0, ram_tb);
|
||||||
|
|
||||||
|
wr_en = 0; addr = 0; wr_data = 0;
|
||||||
|
@(posedge clk);
|
||||||
|
$display("wr_en=%b, addr=%d, wr_data=%d, rd_data=%d", wr_en, addr, wr_data, rd_data);
|
||||||
|
|
||||||
|
wr_en = 1; addr = 25; wr_data = 256;
|
||||||
|
@(posedge clk);
|
||||||
|
$display("wr_en=%b, addr=%d, wr_data=%d, rd_data=%d", wr_en, addr, wr_data, rd_data);
|
||||||
|
|
||||||
|
wr_en = 0;
|
||||||
|
@(posedge clk);
|
||||||
|
$display("wr_en=%b, addr=%d, wr_data=%d, rd_data=%d", wr_en, addr, wr_data, rd_data);
|
||||||
|
|
||||||
|
@(posedge clk);
|
||||||
|
$display("wr_en=%b, addr=%d, wr_data=%d, rd_data=%d", wr_en, addr, wr_data, rd_data);
|
||||||
|
|
||||||
|
addr = 16;
|
||||||
|
|
||||||
|
@(posedge clk);
|
||||||
|
$display("wr_en=%b, addr=%d, wr_data=%d, rd_data=%d", wr_en, addr, wr_data, rd_data);
|
||||||
|
|
||||||
|
@(posedge clk);
|
||||||
|
$display("wr_en=%b, addr=%d, wr_data=%d, rd_data=%d", wr_en, addr, wr_data, rd_data);
|
||||||
|
|
||||||
|
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
38
register_file/register_file.v
Normal file
38
register_file/register_file.v
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
Registros
|
||||||
|
*/
|
||||||
|
|
||||||
|
module register_file #(
|
||||||
|
parameter REGS = 16,
|
||||||
|
parameter W = 16
|
||||||
|
) (
|
||||||
|
input clk,
|
||||||
|
input rst,
|
||||||
|
// Puerto escritura
|
||||||
|
input [$clog2(REGS)-1:0] wr_addr,
|
||||||
|
input [W-1:0] wr_data,
|
||||||
|
input wr_en,
|
||||||
|
// Puerto lectura 1
|
||||||
|
input [$clog2(REGS)-1:0] rd_addr1,
|
||||||
|
output [W-1:0] rd_data1,
|
||||||
|
// Puerto lectura 2
|
||||||
|
input [$clog2(REGS)-1:0] rd_addr2,
|
||||||
|
output [W-1:0] rd_data2
|
||||||
|
);
|
||||||
|
reg [W-1:0] regs [0:REGS-1];
|
||||||
|
|
||||||
|
// Lectura combinacional
|
||||||
|
assign rd_data1 = regs[rd_addr1];
|
||||||
|
assign rd_data2 = regs[rd_addr2];
|
||||||
|
|
||||||
|
// Escritura sincrona
|
||||||
|
integer i;
|
||||||
|
always @(posedge clk or posedge rst) begin
|
||||||
|
if (rst) begin
|
||||||
|
for (i = 0; i < REGS; i = i + 1)
|
||||||
|
regs[i] <= 0;
|
||||||
|
end else if (wr_en) begin
|
||||||
|
regs[wr_addr] <= wr_data;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
60
register_file/register_file_tb.v
Normal file
60
register_file/register_file_tb.v
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
Registros
|
||||||
|
*/
|
||||||
|
`include "./register_file/register_file.v"
|
||||||
|
module register_file_tb;
|
||||||
|
reg clk, rst, wr_en;
|
||||||
|
reg [3:0] wr_addr;
|
||||||
|
reg [15:0] wr_data;
|
||||||
|
reg [3:0] rd_addr1, rd_addr2;
|
||||||
|
wire [15:0] rd_value1, rd_value2;
|
||||||
|
|
||||||
|
register_file register(
|
||||||
|
.clk(clk),
|
||||||
|
.rst(rst),
|
||||||
|
.wr_addr(wr_addr),
|
||||||
|
.wr_data(wr_data),
|
||||||
|
.wr_en(wr_en),
|
||||||
|
.rd_addr1(rd_addr1),
|
||||||
|
.rd_data1(rd_value1),
|
||||||
|
.rd_addr2(rd_addr2),
|
||||||
|
.rd_data2(rd_value2)
|
||||||
|
);
|
||||||
|
|
||||||
|
initial clk = 0;
|
||||||
|
always #5 clk = ~clk;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$dumpfile("register_file/register_file.vcd");
|
||||||
|
$dumpvars(0, register_file_tb);
|
||||||
|
|
||||||
|
rst = 1; wr_en = 0; wr_addr = 0; wr_data = 0;
|
||||||
|
rd_addr1 = 0; rd_addr2 = 0;
|
||||||
|
@(posedge clk);
|
||||||
|
$display("rst=%b, wr_en=%b, wr_add=%d, wr_data=%d", rst, wr_en, wr_addr, wr_data);
|
||||||
|
$display("rd_addr1=%d, rd_addr2=%d, rd_value1=%d, rd_value2=%d", rd_addr1, rd_addr2, rd_value1, rd_value2);
|
||||||
|
|
||||||
|
rst = 0;
|
||||||
|
@(posedge clk);
|
||||||
|
$display("rst=%b, wr_en=%b, wr_add=%d, wr_data=%d", rst, wr_en, wr_addr, wr_data);
|
||||||
|
$display("rd_addr1=%d, rd_addr2=%d, rd_value1=%d, rd_value2=%d", rd_addr1, rd_addr2, rd_value1, rd_value2);
|
||||||
|
|
||||||
|
wr_en = 1; wr_addr = 1; wr_data = 16'hBEEF;
|
||||||
|
@(posedge clk);
|
||||||
|
$display("rst=%b, wr_en=%b, wr_add=%d, wr_data=%d", rst, wr_en, wr_addr, wr_data);
|
||||||
|
$display("rd_addr1=%d, rd_addr2=%d, rd_value1=%d, rd_value2=%d", rd_addr1, rd_addr2, rd_value1, rd_value2);
|
||||||
|
|
||||||
|
wr_en = 0;
|
||||||
|
@(posedge clk);
|
||||||
|
$display("rst=%b, wr_en=%b, wr_add=%d, wr_data=%d", rst, wr_en, wr_addr, wr_data);
|
||||||
|
$display("rd_addr1=%d, rd_addr2=%d, rd_value1=%d, rd_value2=%d", rd_addr1, rd_addr2, rd_value1, rd_value2);
|
||||||
|
|
||||||
|
rd_addr1 = 1;
|
||||||
|
@(posedge clk);
|
||||||
|
$display("rst=%b, wr_en=%b, wr_add=%d, wr_data=%d", rst, wr_en, wr_addr, wr_data);
|
||||||
|
$display("rd_addr1=%d, rd_addr2=%d, rd_value1=%d, rd_value2=%d", rd_addr1, rd_addr2, rd_value1, rd_value2);
|
||||||
|
|
||||||
|
repeat(100) @(posedge clk);
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
@@ -349,9 +349,9 @@ gtkwave modulo.vcd
|
|||||||
- [x] Fase 1.5 — Decoder / Encoder
|
- [x] Fase 1.5 — Decoder / Encoder
|
||||||
- [x] Fase 2.1 — Flip-Flop D y registro
|
- [x] Fase 2.1 — Flip-Flop D y registro
|
||||||
- [x] Fase 2.2 — Contador
|
- [x] Fase 2.2 — Contador
|
||||||
- [ ] Fase 2.3 — Shift Register
|
- [x] Fase 2.3 — Shift Register
|
||||||
- [ ] Fase 2.4 — Register File
|
- [x] Fase 2.4 — Register File
|
||||||
- [ ] Fase 3.1 — RAM sincrona
|
- [x] Fase 3.1 — RAM sincrona
|
||||||
- [ ] Fase 3.2 — ROM
|
- [ ] Fase 3.2 — ROM
|
||||||
- [ ] Fase 3.3 — Stack
|
- [ ] Fase 3.3 — Stack
|
||||||
- [ ] Fase 4.1 — FSM Semaforo
|
- [ ] Fase 4.1 — FSM Semaforo
|
||||||
|
|||||||
24
shift_register/shift_register.v
Normal file
24
shift_register/shift_register.v
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
module shift_register #(parameter N = 8) (
|
||||||
|
input clk,
|
||||||
|
input rst,
|
||||||
|
input load,
|
||||||
|
input shift_en,
|
||||||
|
input dir,
|
||||||
|
input serial_in,
|
||||||
|
input [N-1:0] parallel_in,
|
||||||
|
output reg [N-1:0] q,
|
||||||
|
output serial_out
|
||||||
|
);
|
||||||
|
|
||||||
|
assign serial_out = dir ? q[0] : q[N-1];
|
||||||
|
|
||||||
|
always @(posedge clk or posedge rst) begin
|
||||||
|
if (rst) q <= 0;
|
||||||
|
else if (load) q <= parallel_in;
|
||||||
|
else if (shift_en) begin
|
||||||
|
if (dir == 0) q <= {q[N-2:0], serial_in};
|
||||||
|
else q <= {serial_in, q[N-1:1]};
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
48
shift_register/shift_register_tb.v
Normal file
48
shift_register/shift_register_tb.v
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
`include "./shift_register/shift_register.v"
|
||||||
|
|
||||||
|
module shift_register_tb;
|
||||||
|
reg clk, rst, load, shift_en, dir, serial_in;
|
||||||
|
reg [7:0] parallel_in;
|
||||||
|
wire [7:0] q;
|
||||||
|
wire serial_out;
|
||||||
|
|
||||||
|
shift_register register(
|
||||||
|
.clk(clk),
|
||||||
|
.rst(rst),
|
||||||
|
.load(load),
|
||||||
|
.shift_en(shift_en),
|
||||||
|
.dir(dir),
|
||||||
|
.serial_in(serial_in),
|
||||||
|
.parallel_in(parallel_in),
|
||||||
|
.q(q),
|
||||||
|
.serial_out(serial_out)
|
||||||
|
);
|
||||||
|
|
||||||
|
initial clk = 0;
|
||||||
|
always #5 clk = ~clk;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$dumpfile("./shift_register/shift_register.vcd");
|
||||||
|
$dumpvars(0, shift_register_tb);
|
||||||
|
|
||||||
|
rst = 1; load = 0; shift_en = 1; dir = 0; serial_in = 0;
|
||||||
|
@(posedge clk);
|
||||||
|
|
||||||
|
$display("rst=%b, load=%b, shift_en=%b, dir=%b, serial_in=%b, q=%b", rst, load, shift_en, dir, serial_in, q);
|
||||||
|
|
||||||
|
rst = 0; load = 1; parallel_in = 64;
|
||||||
|
@(posedge clk);
|
||||||
|
|
||||||
|
$display("rst=%b, load=%b, shift_en=%b, dir=%b, serial_in=%b, q=%b", rst, load, shift_en, dir, serial_in, q);
|
||||||
|
|
||||||
|
load = 0; serial_in = 1;
|
||||||
|
@(posedge clk);
|
||||||
|
$display("rst=%b, load=%b, shift_en=%b, dir=%b, serial_in=%b, q=%b", rst, load, shift_en, dir, serial_in, q);
|
||||||
|
|
||||||
|
repeat(10) @(posedge clk);
|
||||||
|
$display("rst=%b, load=%b, shift_en=%b, dir=%b, serial_in=%b, q=%b", rst, load, shift_en, dir, serial_in, q);
|
||||||
|
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
Reference in New Issue
Block a user