问题起初是这样的,PicoBlaze读取板卡的4Bit的SWITCHes,然后把这个状态值当做ROM的读地址输入,把读取的8Bit的值显示在LEDs上.
当时我的输入输出端口是这样定义的:
module read_rom
(
input wire clk, reset,
input wire [3:0] sw,
output wire [7:0] led
);
//kcpsm3 and instruction memory
wire [9:0] address;
wire [17:0] instruction;
wire [7:0] in_port, out_port, port_id;
wire write_strobe, read_strobe;
kcpsm3 unit_proc(
.address(address),
.instruction(instruction),
.port_id(port_id),
.write_strobe(write_strobe),
.out_port(out_port),
.read_strobe(read_strobe),
.in_port(in_port),
.interrupt(1'b0),
.interrupt_ack(),
.reset(reset),
.clk(clk)) ;
program unit_rom(.address(address), .instruction(instruction), .clk(clk));
//data rom instantiation
wire [7:0] data2proc;
rom unit_data(
.clka(read_strobe),
.addra(port_id[3:0]),
.douta(data2proc));
//Input Interface
reg [7:0] in_port_data;
always @ *
if(port_id[4])
in_port_data = {4'b0, sw};
else
in_port_data = data2proc;
assign in_port = in_port_data;
//Output Interface
reg [7:0] led_r;
always @(posedge clk)
if(reset)
led_r <= 0;
else
led_r <= out_port;
assign led = led_r;
endmodule
PSM的程序很简单,就是几个读写操作的FOREVER循环,但是实验结果显示没有读到值.
怎么回事呢?PicoBlaze的开发者Xilinx 公司的Mr. Chapman给出了这样的解释(User guide已有说明,大意中犯了这个错误):
“Yes, please look at the documentation and examples available. KCPSM3_Manual.pdf page 69 will also be useful.
In brief, the key point is to keep track of pipeline stages. When you use a BRAM then it has at least a single stage pipeline (or synchronous read that takes one clock cycle). So when you perform an INPUT instruction you output a ‘port_id’ on a clock edge. When you use that to read a BRAM then you must ensure that the required data value is presented to the ‘in_port’ ready to be captured by PicoBlaze 2 clock cycles later.
So if you were to use ‘port_id’ to directly address the BRAM then the first clock edge is used to read the BRAM and that then means you must connect the output of the BRAM to the ‘in_port’ without passing through anything other than combinatorial logic. Alternatively, you perform tow identical INPUT instructions so that ‘port_id’ remains static for 4 clock cycles and gives the data path more cycles to access the data.
Ken Chapman Senior Staff Engineer, Applications Specialist, Xilinx UK”.上述引用出处
读了上面的解释这才明白.把手册上的示意图贴在这里:
修改后的逻辑
//
module read_rom
(
input wire clk, reset,
input wire [3:0] sw,
output wire [7:0] led
);
//kcpsm3 and instruction memory
wire [9:0] address;
wire [17:0] instruction;
wire [7:0] in_port, out_port, port_id;
wire write_strobe, read_strobe;
kcpsm3 unit_proc(
.address(address),
.instruction(instruction),
.port_id(port_id),
.write_strobe(write_strobe),
.out_port(out_port),
.read_strobe(read_strobe),
.in_port(in_port),
.interrupt(1'b0),
.interrupt_ack(),
.reset(reset),
.clk(clk)) ;
program unit_rom(.address(address), .instruction(instruction), .clk(clk));
//data rom instantiation
wire [7:0] data2proc;
rom unit_data(
.clka(clk),
.addra(port_id[3:0]),
.douta(data2proc));
//Input Interface
//reg [7:0] in_port_data;
assign in_port = port_id[4] ? {4'b0, sw} : data2proc;
//Output Interface
reg [7:0] led_r;
always @(posedge clk)
if(write_strobe)
led_r <= out_port;
assign led = led_r;
endmodule
Matthew 18:15“[Dealing With Sin in the Church] “If your brother or sister sins, go and point out their fault, just between the two of you. If they listen to you, you have won them over.” |