加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
mem.v 4.26 KB
一键复制 编辑 原始数据 按行查看 历史
往月 提交于 2024-03-18 17:29 . FIRST COMMIT
module mem
#(parameter WIDTH=12,
parameter WIDTH_PHASE=8)
(
input clk, // 参考时钟
input rstn , // 复位信号,低有效
input en , // 启动波形生成
input [1:0] sel , // 波形选择
input [WIDTH_PHASE-1:0] addr ,
output dout_en ,
output [WIDTH-1:0] dout // 输出数据,10位宽度
);
// 从ROMs获取的数据
wire [WIDTH-1:0] q_tri ;
wire [WIDTH-1:0] q_square ;
wire [WIDTH-1:0] q_cos ;
// ROM 地址
reg [1:0] en_r ;
always @(posedge clk or posedge rstn) begin
if (rstn) begin
en_r <= 2'b0 ;
end
else begin
en_r <= {en_r[0], en} ; // 延迟一个周期以适应 en
end
end
assign dout = en_r[1] ? (q_tri | q_square | q_cos) : 12'b0 ; // 数据输出选择
assign dout_en = en_r[1] ;
// ROM 实例化
cos_rom #(WIDTH,WIDTH_PHASE) u_cos_rom (
.clk (clk),
.en (en_r[0] & ((sel == 2'b0) || (sel == 2'b11)) ), // sel = 0 或 3, 选择 cos 波形
.addr (addr[WIDTH_PHASE-1:0]),
.q (q_cos[WIDTH-1:0]));
square_rom #(WIDTH,WIDTH_PHASE) u_square_rom (
.clk (clk),
.en (en_r[0] & sel == 2'b01), // sel = 1, 选择方波
.addr (addr[WIDTH_PHASE-1:0]),
.q (q_square[WIDTH-1:0]));
tri_rom #(WIDTH,WIDTH_PHASE) u_tri_rom (
.clk (clk),
.en (en_r[0] & sel == 2'b10), // sel = 2, 选择三角波
.addr (addr[WIDTH_PHASE-1:0]),
.q (q_tri[WIDTH-1:0]));
endmodule
module square_rom
#(parameter WIDTH1=12,
parameter WIDTH_PHASE=8)
(
input clk,
input en,
input [WIDTH_PHASE-1:0] addr,
output reg [WIDTH1-1:0] q);
initial begin
q = 12'd0; // 初始值设置为0
end
reg [8:0] count = 9'd0;
always @(posedge clk) begin
if (en) begin
if (count < 9'd200) begin
count <= count + 9'd1;
q <= 12'd4095;
end
else if(count < 9'd400)begin
count <= count + 9'd1;
q <= 12'd0;
end
else
count <= 9'd0;
end
else begin
q <= 12'd0;
count <= 9'd0;
end
end
endmodule
module tri_rom
#(parameter WIDTH1=12,
parameter WIDTH_PHASE=8)
(
input clk,
input en,
input [WIDTH_PHASE-1:0] addr,
output reg [WIDTH1-1:0] q);
initial begin
q = 12'd0; // 初始值设置为0
end
reg [8:0] count = 9'd0;
always @(posedge clk) begin
if (en) begin
if (count < 9'd200) begin
count <= count + 9'd1;
q <= q + 12'd20;
end
else if(count < 9'd400) begin
count <= count + 9'd1;
q <= q - 12'd20;
end
else
count <= 9'd0;
end
else begin
q <= 12'd0;
count <= 9'd0;
end
end
endmodule
module cos_rom
#(parameter WIDTH3=12,
parameter WIDTH_PHASE=8)
(
input clk,
input en,
input [WIDTH_PHASE-1:0] addr,
output reg [WIDTH3-1:0] q);
// 由于 cos 函数的对称性,只存储一个周期的 1/4 数据
wire [WIDTH3-2:0] rom_t;
wire [WIDTH_PHASE-3:0] selected_addr;
initial begin
q = 12'd0; // 初始值设置为0
end
always @(posedge clk) begin
if (en) begin
if (addr[WIDTH_PHASE-1:WIDTH_PHASE-2] == 2'b01 ) begin // 第一象限,addr -> [0, 63]
q <= rom_t + 12'd2048 ;
end
else if (addr[WIDTH_PHASE-1:WIDTH_PHASE-2] == 2'b10 ) begin // 第二象限,addr -> [64, 127]
q <= 12'd2048 +~ rom_t;
end
else if (addr[WIDTH_PHASE-1:WIDTH_PHASE-2] == 2'b11 ) begin // 第三象限,addr -> [128, 192]
q <= 12'd2048 +~ rom_t;
end
else begin // 第四象限,addr -> [193, 256]
q <= 12'd2048 + rom_t;
end
end
else begin
q <= 'b0 ;
end
end
assign selected_addr = ~(addr[WIDTH_PHASE-1:WIDTH_PHASE-2] == 2'b10 || addr[WIDTH_PHASE-1:WIDTH_PHASE-2] == 2'b00) ? addr[WIDTH_PHASE-3:0] : ~addr[WIDTH_PHASE-3:0];
cosine_mux cos_inst(.phase(selected_addr), .data(rom_t));
endmodule
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化