来自 LRM:
23.3.3.1 端口强制 声明为输入(输出)但用作输出(输入)或输入输出的端口可以强制转换为输入输出。如果不强制转换为输入输出,则应发出警告。
LRM 没有意义,如果强制,即模拟器正在“后台”更改 rtl,则应该发出警告,难道不应该相反吗?如果不强制输入输出,编译应该会失败(如 lint 和综合)?
来自 LRM:
23.3.3.1 端口强制 声明为输入(输出)但用作输出(输入)或输入输出的端口可以强制转换为输入输出。如果不强制转换为输入输出,则应发出警告。
LRM 没有意义,如果强制,即模拟器正在“后台”更改 rtl,则应该发出警告,难道不应该相反吗?如果不强制输入输出,编译应该会失败(如 lint 和综合)?
我需要这个来做学校项目。教授想要一个 LED 序列,如果为零x
(这意味着sw
为 0),则该序列将为:
0000000000000001
0000000000000010
0000000000000100
0000000000001000
0000000000010000
0000000000100000
0000000001000000
0000000010000000
0000000100000000
0000001000000000
0000010000000000
0000100000000000
0001000000000000
0010000000000000
0100000000000000
1000000000000000
如果不是,它就会反过来。现在我被困在测试台文件中,因为它没有显示向量中led
看起来像步骤的变化。这是我的主要代码:
`timescale 1ns / 1ps
module main(
output [15:0] led,
input clk,
input btnC,
input sw
);
reg [15:0] state;
reg ovr;
reg x;
wire sec;
zaman timer (sec, clk, btnC);
initial begin
state = 16'b0000000000000001;
ovr = 1'b0;
x = 0;
end
always @ (posedge clk) begin
x <= sw;
if (btnC == 1) begin
state = 16'b0000000000000001;
ovr = 1'b0;
end
else if (sec == 1) begin
if (x == 0) begin
{ovr,state} <= state << 1;
if (ovr == 1'b1) begin
state <= 16'b0000000000000001;
ovr <= 1'b0;
end
end
else if (x == 1) begin
{state, ovr} <= state >> 1;
if (ovr == 1'b1) begin
state <= 16'b1000000000000000;
ovr <= 1'b0;
end
end
end
end
assign led = state;
endmodule
其子模块:
module zaman(
output Y,
input clock,
input reset
);
reg elapsed;
reg [25:0] state;
always @(posedge clock)
if (reset == 1) state <= 0;
else if (state == 50000000) state <= 0;// corresponds to 1 sec
else state <= state + 1;
always @(state)
if (state == 50000000) elapsed = 1;
else elapsed = 0;
assign Y = elapsed;
endmodule
和测试台文件:
`timescale 1ns / 1ps
module maintb;
reg clk;
reg btnC;
reg sw;
wire [15:0] led;
main uut(.led(led), .btnC(btnC), .sw(sw), .clk(clk));
always #5 clk = ~clk;
initial begin
clk = 0;
btnC = 0;
sw = 0;
btnC = 1;
#10;
btnC = 0;
#160000000;
end
endmodule
我得到的只是这个模拟结果:
我遇到了一个问题,即我的模拟中的缓冲区无法按预期工作。我尝试了一些测试并得到了以下结果。我在 Verilog 中创建了以不同方式生成两个缓冲区的代码:
module buffer(
input wire clk,
input wire ena,
output wire buffer,
output wire buffer2
);
reg buffer_reg = 1'b0;
reg buffer_next = 1'b0;
reg buffer2_reg = 1'b0;
assign buffer = buffer_reg;
assign buffer2 = buffer2_reg;
always @(*) begin
buffer_next = ena;
end
always @(posedge clk) begin
buffer_reg <= buffer_next;
buffer2_reg <= ena;
end
endmodule
然后我使用以下测试台在 Modelsim 中对其进行模拟:
`timescale 1ns / 1ns
module buffer_tb();
localparam CLK_CYCLE = 8;
reg clk;
reg ena;
wire buffer;
wire buffer2;
buffer dut(
.clk(clk),
.ena(ena),
.buffer(buffer),
.buffer2(buffer2)
);
// Clock generation
initial begin
clk = 1'b0;
end
always #(CLK_CYCLE/2) clk = ~clk;
// Test sequence
initial begin
// Initialize signals
ena = 0;
// change ena values based on the posedge clk
@(posedge clk) ena = 1;
@(posedge clk) ena = 0;
repeat(5) @(posedge clk);
@(posedge clk) ena = 1;
@(posedge clk) ena = 0;
repeat(2) #CLK_CYCLE;
// change ena values based on the CLK_CYCLE
#(CLK_CYCLE) ena = 1;
#CLK_CYCLE ena = 0;
repeat(5) #CLK_CYCLE;
#CLK_CYCLE ena = 1;
#CLK_CYCLE ena = 0;
// Allow simulation to run for a while
#50 $stop; // Stop simulation
end
endmodule
我在模拟中得到了以下结果:
有人能解释一下为什么buffer2
当我使用posedge clk
和使用时会得到不同的结果吗CLK_CYCLE
?
我已经实现了一个 BCD 转换器,可以在两台不同的 PC 上工作:
作为 IDE,我在两台计算机上都使用了 Vivado 2024.2,并使用了 Basys3 开发板进行实现。
在 BCD 上运行行为模拟(两台 PC 的代码相同)后,无论我在计算机上做什么,输出都保持在 X,但在笔记本电脑上,输出会根据实施的设计正确更改。对于两台 PC,从综合开始,结果都是相同的,并且在生成比特流并将程序加载到板上后,程序可以正常工作。
为了完整起见,我还将包括设计的代码:
module counter #(parameter SIZE = 4) (
input clk,
input rst,
input en,
output reg [SIZE-1:0] out
);
always @(posedge clk, negedge rst) begin
if(!rst)
out <= 0;
else
if (en) out <= out + 1;
end
endmodule
module loadRegister #(DATA_SIZE = 1, REG_SIZE = 2) (
input clk,
input rst,
input [DATA_SIZE-1:0] Din,
input Sin,
input [REG_SIZE - 1 : 0] cellAdr,
input serialLoad,
input parallelLoad,
output reg [DATA_SIZE * (2 ** REG_SIZE) - 1 : 0] data
);
always @(posedge clk) begin
if(!rst) data <= 0;
else if(parallelLoad) begin
data[DATA_SIZE*cellAdr+:DATA_SIZE] <= Din;
end
else if(serialLoad) begin
data <= {data[DATA_SIZE * (2 ** REG_SIZE) - 2 : 0],Sin};
end
else begin
data <= data;
end
end
endmodule
module Binary2BCDTranscoder #(parameter INPUT_SIZE = 12, parameter OUTPUT_DIGITS = 4, parameter ICNTR_SIZE = 4, parameter JCNTR_SIZE = 2) (
input clk,
input rst,
input convStart,
input [INPUT_SIZE-1:0] data,
output reg convDone,
output reg [4 * OUTPUT_DIGITS - 1:0] convOut
);
localparam WAIT = 2'b00;
localparam CONV_CHK = 2'b01;
localparam FINISHED = 2'b11;
reg iRst, jRst, iEn, jEn;
wire [ICNTR_SIZE-1:0] i;
wire [JCNTR_SIZE-1:0] j;
reg [1:0] state, next_state;
reg [INPUT_SIZE-1:0] inner_in;
reg loadRegRst;
reg [3:0] loadRegDin;
reg loadRegSin;
reg loadRegSerial, loadRegParallel;
reg [1:0] loadRegCellAdr;
wire [4 * OUTPUT_DIGITS - 1:0] inner_out;
always @(posedge clk) begin
if(!rst) state <= WAIT;
else state <= next_state;
end
always @(posedge clk) begin
if(!rst) inner_in <= 0;
else if(state==WAIT) inner_in <= data;
end
always @(posedge clk) begin
if(state==CONV_CHK & convDone) convOut <= inner_out;
end
counter #(.SIZE(ICNTR_SIZE)) iCounter (
.clk(clk),
.rst(iRst),
.en(iEn),
.out(i)
);
counter #(.SIZE(JCNTR_SIZE)) jCounter (
.clk(clk),
.rst(jRst),
.en(jEn),
.out(j)
);
loadRegister #(.DATA_SIZE(4),.REG_SIZE(2)) innerOutReg (
.clk(clk),
.rst(loadRegRst),
.Din(loadRegDin),
.Sin(loadRegSin),
.serialLoad(loadRegSerial),
.parallelLoad(loadRegParallel),
.cellAdr(loadRegCellAdr),
.data(inner_out)
);
always @(*) begin
case(state)
WAIT: begin
convDone = 0;
iRst = 0;
iEn = 0;
jRst = 0;
jEn = 0;
next_state = convStart ? CONV_CHK : WAIT;
end
CONV_CHK: begin
if(i == INPUT_SIZE) begin
convDone = 1;
next_state = FINISHED;
iRst = 0;
jRst = 0;
iEn = 0;
jEn = 0;
end
else if(j == OUTPUT_DIGITS-1) begin
next_state = CONV_CHK;
convDone = 0;
iRst = 1;
jRst = 0;
iEn = 1;
jEn = 0;
end
else begin
next_state = CONV_CHK;
convDone = 0;
iRst = 1;
jRst = 1;
iEn = 0;
jEn = 1;
end
end
FINISHED: begin
next_state = WAIT;
convDone = 1;
iRst = 0;
iEn = 0;
jRst = 0;
jEn = 0;
end
default: begin
next_state = WAIT;
convDone = 0;
iRst = 0;
iEn = 0;
jRst = 0;
jEn = 0;
end
endcase
end
always @(*) begin
case(state)
WAIT: begin
loadRegRst = 0;
loadRegDin = 0;
loadRegSin = 0;
loadRegParallel = 0;
loadRegSerial = 0;
loadRegCellAdr = 0;
end
CONV_CHK: begin
loadRegRst = 1;
if (iEn) begin
loadRegDin = 0;
loadRegSin = inner_in[INPUT_SIZE-1-i];
loadRegParallel = 0;
loadRegSerial = 1;
loadRegCellAdr = 0;
end
else if (jEn) begin
if(inner_out[4*j+:4] >= 5) begin
loadRegDin = inner_out[4*j+:4] + 3;
loadRegSin = 0;
loadRegParallel = 1;
loadRegSerial = 0;
loadRegCellAdr = j;
end
else begin
loadRegDin = 0;
loadRegSin = 0;
loadRegParallel = 0;
loadRegSerial = 0;
loadRegCellAdr = 0;
end
end
else begin
loadRegDin = 0;
loadRegSin = 0;
loadRegParallel = 0;
loadRegSerial = 0;
loadRegCellAdr = 0;
end
end
FINISHED: begin
loadRegRst = 1;
loadRegDin = 0;
loadRegSin = 0;
loadRegParallel = 0;
loadRegSerial = 0;
loadRegCellAdr = 0;
end
default: begin
loadRegRst = 0;
loadRegDin = 0;
loadRegSin = 0;
loadRegParallel = 0;
loadRegSerial = 0;
loadRegCellAdr = 0;
end
endcase
end
endmodule
module Bin2BCDTest();
reg clk, rst, convStart;
reg [11:0] data;
wire convDone;
wire [15:0] convOut;
Binary2BCDTranscoder #(.INPUT_SIZE(12),.OUTPUT_DIGITS(4),.ICNTR_SIZE(4),.JCNTR_SIZE(2)) dut (
.clk(clk),
.rst(rst),
.convStart(convStart),
.data(data),
.convDone(convDone),
.convOut(convOut)
);
initial begin
clk = 0;
forever #5 clk = !clk;
end
initial begin
rst = 0;
convStart = 0;
#10 rst = 1;
#10 data = 1023;
#10 convStart = 1;
#20 convStart = 0;
#1000;
#10 data = 512;
#10 convStart = 1;
#20 convStart = 0;
#1000;
#10 data = 3683;
#10 convStart = 1;
#20 convStart = 0;
#1000;
#10 data = 4091;
#10 convStart = 1;
#20 convStart = 0;
#1000;
#10 data = 4090;
#10 convStart = 1;
#20 convStart = 0;
#1000;
$stop;
end
endmodule
为什么会发生这种情况?这是两个不同操作系统之间的问题吗?如果是这样,为什么它只影响模拟而不影响综合?
我定义了一个二进制到 BCD 转换器,用于 Basys 3 开发板。在模拟中,结果符合预期,并且完全遵循时序。
我将 BCD 转换器包含在顶部模块中,在那里我使用通过另一个模块创建的输入脉冲启动转换过程。
在船上,结果很奇怪,因为大多数输入值都给出完整的零,唯一的例外是 1,它显示 BCD 值为 15|15|15|14。
因为问题仅存在于板上,所以我相信模块的合成存在问题,但我还无法找出原因。
Synthesis 向我发出以下警告:
[Synth 8-567] referenced signal 'i' should be on the sensitivity list ["C:/Xilinx/VivadoProjects/BCD/BCD.srcs/sources_1/new/Binary2BCDTranscoder.v":80]
[Synth 8-567] referenced signal 'j' should be on the sensitivity list ["C:/Xilinx/VivadoProjects/BCD/BCD.srcs/sources_1/new/Binary2BCDTranscoder.v":80]
[Synth 8-567] referenced signal 'state' should be on the sensitivity list ["C:/Xilinx/VivadoProjects/BCD/BCD.srcs/sources_1/new/Binary2BCDTranscoder.v":150]
[Synth 8-567] referenced signal 'iEn' should be on the sensitivity list ["C:/Xilinx/VivadoProjects/BCD/BCD.srcs/sources_1/new/Binary2BCDTranscoder.v":150]
[Synth 8-567] referenced signal 'inner_in' should be on the sensitivity list ["C:/Xilinx/VivadoProjects/BCD/BCD.srcs/sources_1/new/Binary2BCDTranscoder.v":150]
[Synth 8-567] referenced signal 'jEn' should be on the sensitivity list ["C:/Xilinx/VivadoProjects/BCD/BCD.srcs/sources_1/new/Binary2BCDTranscoder.v":150]
[Synth 8-327] inferring latch for variable 'inner_out_reg' ["C:/Xilinx/VivadoProjects/BCD/BCD.srcs/sources_1/new/Binary2BCDTranscoder.v":155]
[Synth 8-7080] Parallel synthesis criteria is not met
以下是BCD转换器代码:
`timescale 1ns / 1ps
module Binary2BCDTranscoder #(parameter INPUT_SIZE = 12, parameter OUTPUT_DIGITS = 4, parameter ICNTR_SIZE = 4, parameter JCNTR_SIZE = 2) (
input clk,
input rst,
input convStart,
input [INPUT_SIZE-1:0] data,
output reg convDone,
output reg [4 * OUTPUT_DIGITS - 1:0] convOut
);
localparam WAIT = 2'b00;
localparam CONV_CHK = 2'b01;
localparam FINISHED = 2'b11;
reg iRst, jRst, iEn, jEn;
wire [ICNTR_SIZE-1:0] i;
wire [JCNTR_SIZE-1:0] j;
reg [1:0] state, next_state;
reg [INPUT_SIZE-1:0] inner_in;
reg [4 * OUTPUT_DIGITS - 1:0] inner_out;
always @(posedge clk) begin
if(!rst) state <= WAIT;
else state <= next_state;
end
always @(posedge clk) begin
if(!rst) inner_in <= 0;
else if(convDone) inner_in <= data;
end
always @(posedge convDone) begin
convOut <= inner_out;
end
counter #(.SIZE(ICNTR_SIZE)) iCounter (
.clk(clk),
.rst(iRst),
.en(iEn),
.out(i)
);
counter #(.SIZE(JCNTR_SIZE)) jCounter (
.clk(clk),
.rst(jRst),
.en(jEn),
.out(j)
);
always @(state, convStart) begin
case(state)
WAIT: begin
convDone = 1;
iRst = 0;
iEn = 0;
jRst = 0;
jEn = 0;
next_state = convStart ? CONV_CHK : WAIT;
end
CONV_CHK: begin
if(i == INPUT_SIZE) begin
convDone = 1;
next_state = FINISHED;
iRst = 0;
jRst = 0;
iEn = 0;
jEn = 0;
end
else if(j == OUTPUT_DIGITS-1) begin
next_state = CONV_CHK;
convDone = 0;
iRst = 1;
jRst = 0;
iEn = 1;
jEn = 0;
end
else begin
next_state = CONV_CHK;
convDone = 0;
iRst = 1;
jRst = 1;
iEn = 0;
jEn = 1;
end
end
FINISHED: begin
next_state = WAIT;
convDone = 1;
iRst = 0;
iEn = 0;
jRst = 0;
jEn = 0;
end
default: begin
next_state = WAIT;
convDone = 1;
iRst = 0;
iEn = 0;
jRst = 0;
jEn = 0;
end
endcase
end
always @(i,j) begin
case(state)
WAIT: begin
inner_out = 0;
end
CONV_CHK: begin
if(iEn) begin
inner_out = {inner_out[4*OUTPUT_DIGITS - 2 : 0], inner_in[INPUT_SIZE - 1 - i]};
end
else if(jEn) begin
inner_out = inner_out;
if(inner_out[4*j+:4] >= 5) inner_out[4*j+:4] = inner_out[4*j+:4] + 3;
end
else begin
inner_out = inner_out;
end
end
FINISHED: begin
inner_out = 0;
end
default: begin
inner_out = 0;
end
endcase
end
endmodule
顶层模块如下:
module top(
input clk,
input rst,
input convStart,
input [11:0] data,
output convDone,
output [15:0] convOut
);
wire convPulse;
wire [9:0] clkDivOut;
counter #(.SIZE(10)) CLK_DIVIDER(
.clk(clk),
.rst(!rst),
.en(1'b1),
.out(clkDivOut)
);
pulseCreator #(.NUM_BITS(2)) convStartPulse (
.clk(clkDivOut[9]),
.in(convStart),
.out(convPulse),
.regOutput()
);
Binary2BCDTranscoder #(.INPUT_SIZE(12),.OUTPUT_DIGITS(4),.ICNTR_SIZE(4),.JCNTR_SIZE(2)) B2BCD (
.clk(clkDivOut[9]),
.rst(!rst),
.convStart(convPulse),
.data(data),
.convDone(convDone),
.convOut(convOut)
);
endmodule
为了完整起见,这里是计数器和脉冲发生器的代码:
module counter #(parameter SIZE = 4) (
input clk,
input rst,
input en,
output reg [SIZE-1:0] out
);
always @(posedge clk) begin
if(!rst)
out <= 0;
else
if (en) out <= out + 1;
end
endmodule
module serialRegister #(SIZE = 4)(
input clk,
input rst,
input in,
input en,
output reg [SIZE-1:0] out
);
always @(posedge clk, negedge rst) begin
if(!rst) begin
out <= 0;
end
else begin
if(en) out <= {out[SIZE-2:0],in};
end
end
endmodule
module pulseCreator #(NUM_BITS=3) (
input clk,
input in,
output out,
output [NUM_BITS-1:0] regOutput
);
//wire [NUM_BITS-1:0] regOutput;
serialRegister #(.SIZE(NUM_BITS)) pulseReg(
.clk(clk),
.rst(in),
.en(in),
.in(in),
.out(regOutput)
);
assign out = in & !regOutput[NUM_BITS-1];
endmodule
SystemVerilog 标准是否允许将 SystemVerilog 文件 ( .sv
) 与 Verilog 文件 ( .v
) 混合?
这是我的设计和测试台环境代码。
这是设计模块:
module router_1x3 (
input wire clk,
input wire rst,
input wire [7:0] data_in, // 8-bit data input
input wire [1:0] sel, // 2-bit select signal
output reg [7:0] out0, // Output channel 0
output reg [7:0] out1, // Output channel 1
output reg [7:0] out2 // Output channel 2
);
always @(posedge clk or posedge rst) begin
if (rst) begin
out0 <= 8'b0; // Reset output 0
out1 <= 8'b0; // Reset output 1
out2 <= 8'b0; // Reset output 2
end else begin
case (sel)
2'b00: begin
out0 <= data_in;
out1 <= 8'b0;
out2 <= 8'b0;
end
2'b01: begin
out0 <= 8'b0;
out1 <= data_in;
out2 <= 8'b0;
end
2'b10: begin
out0 <= 8'b0;
out1 <= 8'b0;
out2 <= data_in;
end
default: begin
out0 <= 8'b0;
out1 <= 8'b0;
out2 <= 8'b0;
end
endcase
end
end
endmodule
接口.sv
interface intf();
logic clk;
logic rst;
logic [7:0] data_in;
logic [1:0] sel;
logic [7:0] out0;
logic [7:0] out1;
logic [7:0] out2;
endinterface
交易.sv
class transaction;
rand bit [7:0] data_in;
rand bit [1:0] sel;
bit [7:0] out0;
bit [7:0] out1;
bit [7:0] out2;
constraint valid_sel {sel <= 2'b10;}
function void display(string name);
$display("---------- %s --------- %t", name, $time);
$display("data_in=%h, sel=%h, out0=%h, out1=%h, out2=%h",
data_in, sel, out0, out1, out2);
endfunction
endclass
发电机.sv
class generator;
transaction tx;
mailbox gen2drv;
// Constructor
function new(mailbox gen2drv);
this.gen2drv = gen2drv;
endfunction
task main();
tx = new();
if (tx.randomize()) begin
tx.display("generator");
gen2drv.put(tx);
end
endtask
endclass
驱动程序
class driver;
transaction trans;
virtual intf vif;
mailbox gen2driv;
function new(virtual intf vif, mailbox gen2driv);
this.vif = vif;
this.gen2driv = gen2driv;
endfunction
task main();
repeat(1)
begin
gen2driv.get(trans);
trans.display("Driver");
// vif.data_in = trans.data_in;
// vif.sel = trans.sel;
// vif.out0 = trans.out0;
// vif.out1 = trans.out1;
// vif.out2 = trans.out2 ;
vif.data_in <= trans.data_in;
vif.sel <= trans.sel;
vif.out0 <= trans.out0;
vif.out1 <= trans.out1;
vif.out2 <= trans.out2 ;
end
endtask
endclass
监视器
class monitor;
virtual intf vif;
mailbox mon2sbc;
transaction trans;
function new(virtual intf vif, mailbox mon2sbc);
this.vif = vif;
this.mon2sbc = mon2sbc;
endfunction
task main();
repeat(1)
#3;
begin
trans = new();
trans.data_in = vif.data_in;
trans.sel = vif.sel;
// trans.out0 = vif.out0;
// trans.out1 = vif.out1;
// trans.out2 = vif.out2;
vif.out0 = trans.out0;
vif.out1 = trans.out1;
vif.out2 = trans.out2;
mon2sbc.put(trans);
#1
trans.display("Monitor");
end
endtask
endclass
记分牌.sv
class scoreboard;
mailbox mon2sbc;
transaction trans;
function new(mailbox mon2sbc);
this.mon2sbc = mon2sbc;
endfunction
task main();
repeat(1)
begin
mon2sbc.get(trans);
trans.display("Scoreboard");
end
endtask
endclass
环境.sv
`include "transaction.sv"
`include "generator.sv"
`include "driver.sv"
`include "scoreboard.sv"
`include "monitor.sv"
class environment;// it's complete environment of dut
// which is contain all component of testbench and connect tham
generator gen;
driver driv;
monitor mon;
scoreboard scb;
mailbox m1;
mailbox m2;
virtual intf vif;
function new(virtual intf vif);
this.vif = vif;
m1 = new();
m2 = new();
gen = new(m1);
driv = new(vif,m1);
mon = new(vif, m2);
scb = new(m2);
endfunction
task test();
fork
gen.main();
driv.main();
mon.main();
scb.main();
join_none
endtask
task run;
test();
#100
$finish;
endtask
endclass
测试文件
`include "environment.sv"
program test(intf i_intf);//this connect interface to testbech environment
environment env;
initial
begin
env = new(i_intf);
env.run();
end
endprogram
测试台.sv
// Code your testbench here
// or browse Examples
`include "interface.sv"
`include "test.sv"
module tbench_top;
intf router_vif();
test t1(router_vif);
router_1x3 dut (
.clk(router_vif.clk),
.rst(router_vif.rst),
.data_in(router_vif.data_in),
.sel(router_vif.sel),
.out0(router_vif.out0),
.out1(router_vif.out1),
.out2(router_vif.out2)
);
// Clock generation
initial begin
router_vif.clk = 0;
forever #5 router_vif.clk = ~router_vif.clk;
end
// Reset logic
initial begin
router_vif.rst = 1;
#20;
router_vif.rst = 0;
end
initial
begin
$dumpfile("dump.vcd");
$dumpvars;
end
endmodule
通过在 eda 中运行此代码(代码链接: https: //edaplayground.com/x/F7jS)我得到以下输出
ERNEL: ASDB file was created in location /home/runner/dataset.asdb
# KERNEL: ---------- generator --------- 0
# KERNEL: data_in=35, sel=2, out0=00, out1=00, out2=00
# KERNEL: ---------- Driver --------- 0
# KERNEL: data_in=35, sel=2, out0=00, out1=00, out2=00
# KERNEL: ---------- Scoreboard --------- 3
# KERNEL: data_in=35, sel=2, out0=00, out1=00, out2=00
# KERNEL: ---------- Monitor --------- 4
# KERNEL: data_in=35, sel=2, out0=00, out1=00, out2=00
# RUNTIME: Info: RUNTIME_0068 environment.sv (44): $finish called.
正如我所料,当监视器运行时,out2 = 35,但没有给出。
请建议我需要在代码中更改哪些内容?
我定义了一个 3 位进位超前加法器模块并尝试将其连接起来,首先找到第二个输入的 2 的补码,然后使用该数字与更多的 3 位 CLA 进行加法。
我的代码编译没有问题,但是当我尝试查看 VCD 中的波形时,一些变量以十六进制显示,尽管我没有在任何地方明确使用十六进制定义。我试图将显示转换为有符号十进制,但我不知道从哪里开始。这是完整的测试台,因为我不知道要删除哪些案例:
module CLA_15bit_tb ();
reg [14:0] A, B; // Inputs
reg mode; // mode (add or subtract)
wire [14:0] S ; // result
wire Ovf ; // Outputs are wires.
wire Cout;
CLA_15bit_top dut (A,B,mode,S,Cout,Ovf);
initial begin
$dumpfile("CLA_15bit_top.vcd");
$dumpvars(0,CLA_15bit_tb);
$display("Simulation started.");
A = 15'd0; // Set all inputs to zero.
B = 15'd0;
mode = 1'd0;
#10; // Wait 10 time units.
A = 15'd25;
B = 15'd50;
mode = 1'd0; // For addition
#10; // Wait 10 time units.
A = 15'd30;
B = 15'd100;
mode = 1'd1; // For subtraction
#10; // Wait 10 time units.
A = 15'd578;
B = 15'd421;
mode = 1'd0;
#10;
A = 15'd7865;
B = 15'd1065;
mode = 1'd1;
#10;
A = 15'd25000;
B = 15'd16000;
mode = 1'd0;
#10;
A = 15'd865;
B = 15'd1065;
mode = 1'd1;
#10;
A = 15'd32767;
B = 15'd32766;
mode = 1'd1;
#10;
$display("Simulation finished.");
$finish();
end
endmodule
当我尝试使用 Verilog在门级创建左移位器时,出现了这个问题。要求是想出一个移位器,
我使用多路复用器来帮助我进行移位。这是我使用的多路复用器的示意图,它是我教授 Kaushik Patra 博士的视频的截图 https://www.youtube.com/watch?v=-uDFf6bef_U&ab_channel=KaushikPatra%27sSJSUClassroom 模块名称:MUX1_2x1
这是 Dr.Patra 对支持 2 位移位量的移位器的演示,“S0”是移位量的第一位,如果移位量位的值为 1,则我们在该“阶段”执行移位(即,四位移位器有 4 个阶段,“S0”,第一个移位位是“阶段 1”移位,移位 2^0(1 位)如果移位“S1”,第二个移位位是“阶段 2”移位,移位 2^1(2 位)如果移位第三个移位位是“阶段 3”移位,移位 2^2(4 位)第四个移位位是“阶段 4”移位,移位 2^3(8 位),依此类推)
因此,当我在做作业时,我想重用我在生成块中声明的 genvar
//port list of MUX1_2x1: (Y,I0, I1, S)
// Y: output, I0, I1: input, S: control signal
// st1_result is a wire
//D[] is input of the shifter
//I0 is not shift, I1 is shift
genvar i; //for normal shifting bits
genvar j; //for zero filling bits
generate
begin: first_stage_shift //shift amount = 1
// first bit
MUX1_2x1 inst_0(st1_result[0], D[0], 1'b0, S[0]);
for (i = 1; i<32; i = i+1)
MUX1_2x1 inst_1(st1_result[i], D[i], D[i-1], S[0]);
end
// this is the line that has error (81)
i=0; //reset the genvar
begin: second_stage_shift //shift amount = 2
// first bit
MUX1_2x1 inst_0(st2_result[0], St1_result[0], 1'b0, S[1]);
// second bit
MUX1_2x1 inst_1(st2_result[1], St1_result[1], 1'b0, S[1]);
for (i = 2; i<32; i = i+1)
MUX1_2x1 inst_1(st2_result[i], st1_result[i], st1_result[i-2], S[1]);
end
如屏幕截图所示,我想通过写入 i=0 来重置 genvar,以便可以在下一个 for 循环中使用它,但是,我在第 81 行出现此错误:
** Error: (vlog-13069) D:/barrel_shifter.v(81): near "=": syntax error, unexpected '='.
** Error: D:/barrel_shifter.v(81): (vlog-13205) Syntax error found in the scope following 'i'. Is there a missing '::'?
我在网上搜索了一下,但没有找到我想要的东西。是否可以在 verilog 中重用/重置 genvar,而不是声明多个 genvar?
我使用 VHDL 已有一段时间了,习惯了其中的 to_string 和 integer'image 函数。我正在尝试编写一些 SystemVerilog,刚刚意识到字符串连接,尤其是整数到字符串的工作方式不同。
我正在尝试to_string
用 SystemVerilog 编写一个整数函数。它需要三个参数。第一个是需要转换的整数(显然)。第二个是其字符串表示必须占用的位置数。这可以是 0 的形式,也可以是空格的形式,因此第三个参数应该是填充字符。
我不确定如何告诉$sformat
函数填充量应该是可变的,并指定填充字符。编写具有字节级字符串操作的低级函数是唯一的方法吗?
Convert 12 to string to fit in 5 places, pad with zeros and not empty space. This gives:
00012