当前位置: 首页 > news >正文

LPC总线设计及其仿真验证

简述

因为项目只用到了IO cycle,故只对IO Write/Read进行设计

时序

Typical Timing for LFRAME

image

Extended Timing for LFRAME

image

Abort Mechanism

image

正常情况下,START只存在1个clock,EXTEND情况是2个clock(代码里已考虑到)。
按照LDC规范的表述,Abort是在Sync状态发生的,也就是在Data状态之前,此次传输无效,如果发生在Data则按正常传输进行

peripheral代码

点击查看代码
`resetall
`timescale 1ns / 1ns
`default_nettype none
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2025/07/21 08:56:23
// Design Name: 
// Module Name: lpc
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: limited for I/O read/write 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////`include "apb_lpc_defines.vh"
module lpc_peripheral(// LPCinput   wire                lclk                ,input   wire                lreset_n            ,input   wire                lframe              ,output  reg                 lad_oe              ,input   wire   [3:0]        lad_in              ,  output  reg    [3:0]        lad_out             ,// User interfaceoutput  reg                 m_apb_lpc_penable   , output  reg                 m_apb_lpc_psel      ,output  reg                 m_apb_lpc_write     , output  reg     [15:0]      m_apb_lpc_paddr     ,output  wire    [ 7:0]      m_apb_lpc_wdata     ,input   wire    [ 7:0]      m_apb_lpc_rdata     ,input   wire                m_apb_lpc_pready        
);/*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/      /*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/reg [13:0]   state_reg = `LPC_ST_START, state_next;reg [ 1:0]   count_reg = 2'b0, count_next;reg [15:0]   lpc_addr = 16'h0, lpc_addr_next;reg [ 7:0]   lpc_wdata = 8'h0, lpc_wdata_next;reg [ 7:0]   lpc_rdata;reg          rw_indicator,rw_indicator_next;    // 1 for write, 0 for read
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/ always @(*) beginstate_next = state_reg;lpc_addr_next = lpc_addr;lpc_wdata_next = lpc_wdata;rw_indicator_next = rw_indicator;count_next = 2'b0;lad_oe  = 4'b0; lad_out = `LPC_STOP;case (state_reg)`LPC_ST_START    : beginrw_indicator_next = 1'b0;lpc_wdata_next = 8'h0;lpc_addr_next = 16'h0;if (~lframe) beginstate_next = (lad_in == `LPC_START)? `LPC_ST_CYCTYP:`LPC_ST_START;end else beginstate_next = `LPC_ST_START;endend   `LPC_ST_CYCTYP  : beginif (~lframe) beginstate_next = `LPC_ST_CYCTYP;end else beginstate_next = `LPC_ST_ADDR;if (lad_in[1]) beginrw_indicator_next = 1'b1;end else beginrw_indicator_next = 1'b0;endend  end`LPC_ST_ADDR    : begincount_next = count_reg + 1;case (count_reg)0: lpc_addr_next[15:12] = lad_in;1: lpc_addr_next[11: 8] = lad_in;2: lpc_addr_next[ 7: 4] = lad_in;3: lpc_addr_next[ 3: 0] = lad_in;endcaseif (count_reg == 2'h3)state_next = `LPC_ST_H_TAR1;else beginstate_next = `LPC_ST_ADDR;endend`LPC_ST_H_TAR1  : beginstate_next = `LPC_ST_H_TAR2;end`LPC_ST_H_TAR2  : begin // host float LADstate_next = `LPC_ST_SYNC1;       end`LPC_ST_SYNC1    : beginlad_oe  = 1'b1;lad_out = `LPC_SYNC_SWAIT; if (~lframe) state_next = `LPC_ST_START;            else state_next = `LPC_ST_SYNC2;                end `LPC_ST_SYNC2   : begin   if (~lframe) begin state_next = `LPC_ST_START; end else begin lad_oe  = 1'b1;lad_out = `LPC_SYNC_READY;                if (rw_indicator) state_next = `LPC_ST_H_DATA;elsestate_next = `LPC_ST_P_DATA;endend `LPC_ST_H_DATA  : begincount_next = count_reg + 1;if (count_reg == 0) beginlpc_wdata_next[3:0] = lad_in;end else beginlpc_wdata_next[7:4] = lad_in;state_next = `LPC_ST_P_TAR1;endend`LPC_ST_P_DATA  : begincount_next = count_reg + 1;lad_oe = 1'b1;if (count_reg == 0) beginlad_out = lpc_rdata[3:0];end else beginlad_out = lpc_rdata[7:4];state_next = `LPC_ST_P_TAR1;endend `LPC_ST_P_TAR1  : beginlad_oe = 1'b1;lad_out = `LPC_STOP;state_next = `LPC_ST_P_TAR2;end`LPC_ST_P_TAR2  : beginlad_oe = 1'b0;  // peripherals float LADstate_next = `LPC_ST_START;end            default: state_next = `LPC_ST_START; endcase
end  always @(posedge lclk or negedge lreset_n) beginif (~lreset_n) beginstate_reg <= `LPC_ST_START;count_reg <= 2'h0;lpc_addr <= 16'h0; rw_indicator <= 1'b0;lpc_wdata <= 8'h0;end else beginstate_reg <= state_next;count_reg <= count_next;lpc_addr <= lpc_addr_next;lpc_wdata <= lpc_wdata_next;rw_indicator <= rw_indicator_next;end   
endwire    host_write = m_apb_lpc_penable & m_apb_lpc_psel & m_apb_lpc_write & m_apb_lpc_pready;
wire    host_read  = m_apb_lpc_penable & m_apb_lpc_psel & (~m_apb_lpc_write) & m_apb_lpc_pready;assign m_apb_lpc_wdata = lpc_wdata;always @(posedge lclk) beginif (~lreset_n) beginm_apb_lpc_penable <= 1'b0;m_apb_lpc_psel    <= 1'b0;m_apb_lpc_paddr   <= 16'h0;m_apb_lpc_write   <= 1'b0;lpc_rdata <= 8'h0; end else beginif (rw_indicator) beginif (state_reg == `LPC_ST_H_DATA) beginm_apb_lpc_psel    <= 1'b1;m_apb_lpc_penable <= 1'b0;                m_apb_lpc_write   <= 1'b1;              end else if (state_reg == `LPC_ST_P_TAR1) beginm_apb_lpc_psel    <= 1'b1;m_apb_lpc_penable <= 1'b1;  m_apb_lpc_write   <= 1'b1; end else beginm_apb_lpc_penable <= 1'b0;m_apb_lpc_psel    <= 1'b0;   m_apb_lpc_write   <= 1'b0;                  end            end else beginif (state_reg == `LPC_ST_H_TAR2) beginm_apb_lpc_psel    <= 1'b1;m_apb_lpc_penable <= 1'b0;                m_apb_lpc_write   <= 1'b0;              end else if (state_reg == `LPC_ST_SYNC1) beginm_apb_lpc_psel    <= 1'b1;m_apb_lpc_penable <= 1'b1;  m_apb_lpc_write   <= 1'b0; end else beginm_apb_lpc_penable <= 1'b0;m_apb_lpc_psel    <= 1'b0;   m_apb_lpc_write   <= 1'b0;                  end            endm_apb_lpc_paddr   <= lpc_addr;if (host_read) beginlpc_rdata <= m_apb_lpc_rdata;endend
endendmodule
`resetall

搭建Host进行仿真

host task代码搭建

点击查看代码
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2025/07/24 16:16:14
// Design Name: 
// Module Name: lpc_host
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////module lpc_host(input   wire            lclk    , output  reg             lframe  ,output  reg             lad_oe  ,output  reg     [3:0]   lad_o   ,input   wire    [3:0]   lad_i    
);/*----------------------------------------------------------------------------------------------------------------------------------------------------------------*/`define LPC_START 4'h0`define LPC_STOP  4'hf`define LPC_SWAIT 4'h5`define LPC_READY 4'h0`define IO_WRITE    4'h2`define IO_READ     4'h0integer index = 0;/*----------------------------------------------------------------------------------------------------------------------------------------------------------------*/task Start;begin@(posedge lclk);lframe = 1'b1;lad_oe = 1'b1;lad_o  = `LPC_STOP;@(posedge lclk);lframe = 1'b0;        lad_oe = 1'b1;lad_o  = `LPC_START;     end
endtasktask Start_extend;begin@(posedge lclk);lframe = 1'b1;lad_oe = 1'b1;lad_o  = `LPC_STOP;@(posedge lclk);lframe = 1'b0;        lad_oe = 1'b1;lad_o  = `LPC_START;@(posedge lclk);end
endtasktask Cyctype;input  [3:0] dir_type;begin@(posedge lclk);lframe = 1'b1;lad_oe = 1'b1; lad_o  = dir_type;end
endtasktask Addr;input  [15:0]    host_addr;beginwhile(index < 4) begin@(posedge lclk);lad_oe = 1'b1;lad_o  = host_addr[(15-index*4)-:4];index = index + 1;endend
endtasktask Tar_h;begin@(posedge lclk);lad_oe = 1'b1;lad_o  = 4'b1111;// turn-around@(posedge lclk);lad_oe = 1'b0;lad_o  = 4'b1111;end
endtasktask Sync;beginrepeat(2) begin@(posedge lclk);end        end
endtasktask Sync_abort;beginrepeat(2) begin@(posedge lclk);endlframe = 1'b0;        end
endtasktask Host_write;input  [7:0] host_dout;begin@(posedge lclk);lad_oe = 1'b1;lad_o  = host_dout[3:0];@(posedge lclk);lad_oe = 1'b1;lad_o  = host_dout[7:4];        end
endtasktask Host_read;output  [7:0] host_din;begin@(posedge lclk);lad_oe = 1'b0;host_din[3:0] = lad_i;@(posedge lclk);host_din[7:4] = lad_i;        end
endtasktask Tar_peripheral;begin@(posedge lclk);lad_oe = 1'b1;lad_o  = `LPC_STOP;@(posedge lclk);lad_oe = 1'b0;lad_o  = `LPC_STOP;index = 0;  end
endtask/*----------------------------------------------------------------------------------------------------------------------------------------------------------------*/
task lpc_host_write(input  [15:0] host_addr ,input  [ 7:0] host_wdata
);beginStart();Cyctype(`IO_WRITE);Addr(host_addr);Tar_h();Sync();Host_write(host_wdata);Tar_peripheral();end
endtasktask lpc_host_read(input  [15:0] host_addr ,output [ 7:0] host_rdata
);beginStart();Cyctype(`IO_READ);Addr(host_addr);Tar_h();Sync();Host_read(host_rdata);Tar_peripheral();end
endtasktask host_ex_write(input  [15:0] host_addr ,input  [ 7:0] host_wdata
);beginStart_extend();Cyctype(`IO_WRITE);Addr(host_addr);Tar_h();Sync();Host_write(host_wdata);Tar_peripheral();end
endtasktask host_ex_read(input  [15:0] host_addr ,output [ 7:0] host_rdata
);beginStart_extend();Cyctype(`IO_READ);Addr(host_addr);Tar_h();Sync();Host_read(host_rdata);Tar_peripheral();end
endtasktask host_write_abort(input  [15:0] host_addr ,input  [ 7:0] host_wdata
);beginStart();Cyctype(`IO_WRITE);Addr(host_addr);Tar_h();Sync_abort();end
endtasktask host_read_abort(input  [15:0] host_addr ,output [ 7:0] host_rdata
);beginStart();Cyctype(`IO_READ);Addr(host_addr);Tar_h();Sync_abort();end
endtaskinitial beginlframe = 1'b1;lad_oe = 1'b1;lad_o  = 4'hf;
end endmodule

仿真顶层

点击查看代码
`timescale 1ns / 1ns
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2025/07/24 08:31:32
// Design Name: 
// Module Name: tb_lpc
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////module tb_lpc();reg             LCLK,LRESET_N;
wire            LFRAME; wire    [3:0]   LAD;wire            lad_oe;
wire    [3:0]   lad_o,lad_i;reg             serirq_oe,serirq_o;
wire            serirq_i;wire    [31:0]  IRQ = 32'h1234;
reg     [ 7:0]   host_di     ;always #15 LCLK = ~LCLK;initial beginLCLK = 1'b0;LRESET_N = 1'b0;host_di = 8'h0;    #200LRESET_N = 1'b1;
#200host.lpc_host_write(16'h0,8'h0);host.lpc_host_write(16'h1,8'h1);host.lpc_host_write(16'h2,8'h2);host.lpc_host_write(16'h3,8'h3);host.lpc_host_write(16'h4,8'h4);host.lpc_host_write(16'h5,8'h5);host.lpc_host_write(16'h6,8'h6);host.lpc_host_write(16'h7,8'h7);
#200    host.host_ex_read(16'h0,host_di);  host.host_ex_read(16'h1,host_di); host.host_ex_read(16'h2,host_di); host.host_ex_read(16'h3,host_di); host.host_ex_read(16'h4,host_di);     host.host_ex_read(16'h5,host_di); host.host_ex_read(16'h6,host_di); host.host_ex_read(16'h7,host_di); 
#200    host.host_ex_write(16'h0,8'h7);host.host_ex_write(16'h1,8'h6);host.host_ex_write(16'h2,8'h5);host.host_ex_write(16'h3,8'h4);host.host_ex_write(16'h4,8'h3);host.host_ex_write(16'h5,8'h2);host.host_ex_write(16'h6,8'h1);host.host_ex_write(16'h7,8'h0);
#200    host.lpc_host_read(16'h0,host_di);host.lpc_host_read(16'h1,host_di);host.lpc_host_read(16'h2,host_di);host.lpc_host_read(16'h3,host_di);host.lpc_host_read(16'h4,host_di);host.lpc_host_read(16'h5,host_di);host.lpc_host_read(16'h6,host_di);host.lpc_host_read(16'h7,host_di);
#200    host.host_write_abort(16'h3,8'h3);
#200host.host_read_abort(16'h4,host_di);
#2000$stop;
end
/*------------------------------------------------------------------------------------------------------------------------------------------*/
genvar i;
generatefor (i = 0; i < 4; i=i+1) beginpullup(LAD[i]);     end
endgeneratepullup(SERIRQ);assign lad_i = LAD;
assign LAD = (lad_oe)? lad_o : 4'bzzzz;super_io_top super_io(.LCLK        (LCLK    ),.LRESET_N    (LRESET_N),.LFRAME      (LFRAME  ),.LAD         (LAD     ),.SERIRQ      (SERIRQ  ),.IRQ         (IRQ     )
);lpc_host host(.lclk       (LCLK       ), .lframe     (LFRAME     ),.lad_oe     (lad_oe     ),.lad_o      (lad_o      ),.lad_i      (lad_i      ) 
);endmodule

仿真结果

IO write部分波形

image

IO read部分波形

image

不知道为啥,读回来的结果高低位是反的,但代码没看出毛病

http://www.wooajung.com/news/35381.html

相关文章:

  • Fluent许可证类型
  • 多值依赖
  • Windows 验证耳机输入是否正常
  • ABC典题总结
  • springboot项目解决报错:spring boot application in default package
  • LaTeX中为何推荐substack而不使用\atop?
  • 手机网页版浏览器seo案例分析及解析
  • 知名品牌vi设计宁波优化推广找哪家
  • 做国际贸易的网站沧州网站推广优化
  • 网站框架都有什么用重庆网站快速排名提升
  • 凡科自助建站靠谱吗网站安全检测在线
  • 哪些国家网站无须备案企业所得税优惠政策
  • 泰安房产网信息网官网seo服务 收费
  • ps怎样做网站详情页建立免费个人网站
  • 风中有朵雨做的云网站观看网站如何提交百度收录
  • wps做网站框架seddog站长之家
  • .net 网站开发架构重庆seo排名软件
  • asp.net 做网站文章是怎么存储的seo搜索优化是什么呢
  • 伊川网站开发网络营销的四个特点
  • 做最好的网站新新广州百度首页优化
  • 有哪些做封面的网站seo技术团队
  • 可以做装修效果图的网站新网站怎么推广
  • 跟有流量的网站做友情链接国家反诈中心app下载
  • 个人网站建设流程 域名注册的选择百度影响力排名顺序
  • b站必看的纪录片百度号码认证平台官网
  • 网站建设公司的公司哪家好广州市疫情最新
  • 北京时代 网站建设苹果被曝开发搜索引擎对标谷歌
  • 广告制作合同范本信息流优化师是干什么的
  • 门户网站开发怎么收费电商平台怎么运营的
  • 外国人做汉字网站网络宣传的方法渠道